// // hfstools - a Macintosh filesystem access tool // (C) Copyright 1993 by Equivalence // // This file part of hfs. // // hfs is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // hfs is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with hfs; see the file COPYING. If not, write to // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // // $Id: copy.cxx,v 1.11 1994/07/04 10:21:46 craigs Exp $ // $Log: copy.cxx,v $ // Revision 1.11 1994/07/04 10:21:46 craigs // Fixed problem with Latin1 coversion truncating directory displays // Fixed various compile time problems with FreeBSD // // Revision 1.10 1994/07/02 05:04:21 craigs // Added support for CDROM drives under MSDOS // // Revision 1.9 1994/06/30 14:39:24 craigs // Changes for bigger blocks and partitions // // Revision 1.8 1994/01/11 00:41:50 craigs // Added additional name mangling for MSDOS/NT // // Revision 1.7 1994/01/06 03:09:01 craigs // Changed hget to hread // // Revision 1.6 1994/01/06 03:05:08 craigs // Final checkin to include GNU header // // Revision 1.5 1993/12/31 02:32:11 craigs // Removed non-globbing copy code // // Revision 1.4 1993/12/30 07:48:49 craigs // Added filename globbing // // Revision 1.3 1993/12/23 22:50:51 craigs // Removed warning about uninitialised variable // // Revision 1.2 1993/12/23 22:39:39 craigs // Removed redundant error messag // // Revision 1.1 1993/12/23 14:59:45 craigs // Initial revision // // #include #include #include #include #include #if defined (__FreeBSD__) #include #include #endif #include #if defined(_MSDOS) || defined(WIN32) #include #else #include #endif extern "C" { #include "glob.h" }; #include "config.h" #include "mdir.h" #include "cmd.h" static char * MangleName (char * mac_name) { char * new_name = new char [strlen(mac_name) + 1]; char * p = new_name; // remove illegal characters while (*mac_name != '\0') { #if defined(_MSDOS) || defined(WIN32) if (strchr("/\\' \"*+,:<>=?()|", *mac_name) != NULL) *p = '_'; #else if (*mac_name == '/') *p = ':'; #endif else if (*mac_name <= 0x20 || *mac_name == 0x7f) *p = '_'; else *p = *mac_name; mac_name++; p++; } *p = '\0'; // chop filename to 8.3 if MSDOS or NT // Not all NT filesystems need this, but we do it anyway! #if defined(_MSDOS) || defined(WIN32) if (new_name[0] == '.') new_name[0] = '_'; char * dot_pos = strchr(new_name, '.'); if (dot_pos == NULL) { if (strlen(new_name) > 8) new_name[8] = '\0'; } else { if (dot_pos - new_name > 8) { new_name[8] = '.'; for (int i = 0; *(dot_pos+1+i) != '\0'; i++) { new_name [9+i] = *(dot_pos+1+i); if (new_name[9+i] == '.') new_name[9+i] = '_'; } new_name[9+i] = '\0'; if (strlen(new_name) > 12) new_name [12] = '\0'; } } #endif return new_name; } static void CopyFromMacDisk (char * from, char * to, Filesystem & fs, UINT flags, BOOL mangle) { FileBuffer fb; char * os_dir; char * os_to = NULL; BOOL copy = TRUE; // find the source file if (!fs.ResolvePath(fb, from, status_file->GetDir())) return; // if the source file is really a directory, don't copy it if (!fb.IsFile()) { cout << "omitting directory " << from << "\n"; return; } // if there is a destination specified, and it exists, it must be a directory os_dir = "."; if (to != NULL) { if (access(to, 0) == 0) os_dir = to; else { os_to = new char [strlen(to) + 1]; strcpy(os_to, to); } } // if os_to is NULL at this point, then use os_dir to construct a filename if (os_to == NULL) { char * to_base; int l; if (mangle) to_base = MangleName(fb.name); else to_base = strdup(fb.name); os_to = new char [(l = strlen(os_dir)) + 1 + strlen(to_base) + 1]; strcpy(os_to, os_dir); if ((l > 0) && (os_to[l-1] != DIR_SEP)) { os_to[l] = DIR_SEP; os_to[l+1] = '\0'; } strcat(os_to, to_base); } // see if the file we are about to copy to exists if (access (os_to, 0) == 0) { char buff; cout << "Overwrite " << os_to << "(y/n) ? "; cin >> buff; if (tolower(buff) != 'y') { cout << "Skipping " << os_to << "\n"; copy = FALSE; } if (unlink(os_to)) { perror(os_to); exit(1); } } cout << "Copying " << fb.name << " to " << os_to << "\n"; if (copy) { FILE * osfile; MacFile macfile(fs); if ((osfile = fopen(os_to, "w")) == NULL) { perror(os_to); exit(1); } macfile.Open(fb, flags); macfile.CopyToOS(osfile); macfile.Close(); if (fclose(osfile)) { perror(os_to); exit(1); } } delete os_to; } int GetFunction (ArgList & args, Filesystem & fs) { UINT flags = 0; BOOL mangle; // if less than one argument, print usage if (args.argc() < 1) { cerr << "usage: hread source dest\n"; exit (1); } // if t option specified, convert newlines if (args.OptionSpecified('t')) flags |= MacFile::ConvertToText; // if R option specified, open resource fork if (args.OptionSpecified('R')) flags |= MacFile::ResourceFork; // if M option specified, don't mange filenames mangle = !args.OptionSpecified('M'); glob_t g; char * dest = NULL; // tell the globber where the filesystem is SetMDirFilesystem(fs); // glob the first argument g.gl_offs = 0; glob(args[0], GLOB_DOOFFS, NULL, &g); // if more than one argument, glob everything except the last one if (args.argc() > 1) { dest = args[args.argc()-1]; for (int i = 1; i < args.argc()-1; i++) glob(args[i], GLOB_DOOFFS | GLOB_APPEND, NULL, &g); } // if copying multiple files, last parameter must be a directory or NULL if (dest != NULL && g.gl_pathc > 1) { struct stat sb; if (stat (dest, &sb) || ((sb.st_mode & S_IFMT) != S_IFDIR)) { cerr << "error: when copying multiple files, last argument must be a directory\n"; exit(1); } } // copy the files for (int i = 0; i < g.gl_pathc; i++) CopyFromMacDisk(g.gl_pathv[i], dest, fs, flags, mangle); return 0; }