CopyDir ver 1.16 -- A utility to robustly copy a directory tree. Created by: Daniel Hellerstein (danielh@crosslink.net) Last modified: 25 Feb 2002 Usage. From an OS/2 command prompt: COPYDIR source_dir dest_dir [-opts] where: source_dir -- source directory dest_dir -- destination directory [-opts ] -- list of options (they MUST follow dest_dir) Alternatively, enter COPYDIR at an OS/2 prompt, and answer the questions. Note: Use * to specify the current directory (for either source or dest dir) Options include: -8 -- Always convert "long" (HPFS) style file names to unique 8.3 (FAT) names; even if destination drive can support long file names. -ALL -- Aggressive replace. -ALL is a shortcut for: -Rar -Share -Attribs=**** -Check -ALL allows you to take a snapshot of a drive or a directory. If you use -ALL, only a subset of the other options are recognized. These are: -MERGE -NOMERGE -LOG -LOGNEW -NOPAUSE and -V -ATTRIBS=xxxx -- Set AHRS attributes of destination files and directories. x can be: - (clear), + (set) , or * (use source) The four positions correspond to AHRS respectively: the archive, hidden, readonly, and system attributes. By default (if -ATTRIBS is not set), all attributes on the destination files (& directories) are cleared. -ERRFILE=filename -- specify fully qualified name of an "error file". The error file is created ONLY if an error occurs (such as the failure to copy a locked file, or a failure to copy a file with bad sectors). If no absolute path is specified in filename, then filename will be written relative to the current (default) directory. If you do NOT specify an -ERRFILE option, then if any error occurs a file named COPYDIR.ERR will be created in the directory containing this program. For example, if you installed COPYDIR.CMD to C:\OS2\APPS, then C:\OS2\APPS\COPYDIR.ERR will be created (assuming an error occurs). Notes: * Actually, the name of the default error file can be set with the ERRFILE user changeable parameter. * in contrast to the LOG file, the error files is ALWAYS overwritten. * we do NOT recommend putting the error file, or the log file, in the directory being copied. Doing so might cause a 32= sharing violation for source or target file error -- due to the log (or error) file being locked by COPYDIR! While not fatal, it is sort of ugly. * To include spaces in the filename, bracket the filename with " characters. For example: -ERRFILE="MY ERRORS" -CHECK -- Check if destination drive has enough space -FilesOnly -- Do NOT process subdirectories (that is, just copy the files in the source directory to the target directory) -I=astring -- Only include files that contain astring You can specify multiple occurences of -I= Use double quotes (") to include spaces, -, &, and other wierd characters in astring -LOG=filename -- log ALL actions to a logfile. This is written in addition to the ERRFILE (the ERRFILE is only created if an error occurs). If no absolute path is specified in filename, then filename will be written relative to the current (default) directory. If you do NOT a "filename" (that is, you just include a -LOG option), then a file named COPYDIR.LOG will be created in the directory containing this program. For example, if you installed COPYDIR.CMD to C:\OS2\APPS, then C:\OS2\APPS\COPYDIR.LOG will be created. Notes: * Actually, the name of the default error file can be set with the LOGFILE user changeable parameter. * The logfile is appended to. Each new addition starts with the time, date and parameters used in the COPYDIR command. * If you want to overwrite prior versions of the log file, use the -LOGNEW option. * we do NOT recommend putting the log file, or the error file, in the directory being copied. Doing so might cause a 32= sharing violation for source or target file error -- due to the log (or error) file being locked by COPYDIR! While not fatal, it is sort of ugly. * To include spaces in the filename, bracket the filename with " characters. For example: -ERRFILE="MY LOGFILE.LOG" -LOGNEW=filename -- Same as -LOG, but overwrite filename. -LOGEVENT=event_type -- Select what types of events to log The currently recognized event types are: ALL -- log all events. THIS IS THE DEFAULT. COPY= log all successful and unsuccessful copies Do NOT log "did not replace" events EXCLUDE= log "excluded" files COPY_EXCLUDE= Combination of copy and exclude -MERGE -- Copy source files and subdirectories "into" the destination. This overrides the to_under parameter (that can be modified in COPYDIR.CMD). It has the same effect as using a trailing \* in the destination directory. -METIC=x -- Read file lists, and copy files, meticulously. This means that rather then doing these actions all at once, they will be done in smaller chunks. While slower, this does allow for more frequent status reports, and gives the user more chance to interevene (say, to hit ESC to abort). This overrides the METICULOUS user changeable parameter. x= Y : enable meticulous mode x= N : normal (non-meticulous)mode -NOMERGE -- Copy source files and subdirectories "under" the destination. This override the to_under parameter. It also overrides a trailing \* on the destination directory. -MOVE -- Rename files, or copy and delete source. Within the same drive, a rename is use. Across drives, copy followed by deletion of source file (given a sucessful copy). -NOCHECK -- Do not check if destination drive has enough space -NOPAUSE=v -- Overrides the DOPAUSE parameter (see below) Use -NOPAUSE to suppress cancellation & confirmation queries. v is optional, it can be 0,1, or 2 0: do NOT override dopause. -NOPAUSE=0 is the same as not specifying -NOPAUSE 1: override dopause. -NOPAUSE=1 is the same as -NOPAUSE 2: aggressive no-pause: NEVER ask for user input (fail instead) -PARAMFILE=filename -- The fully qualified name of a parameter file. Since the list of options can be quite long, you can specify them in a "parameter file", and use -PARAMFILE=filename to tell COPYDIR to read the command line options from this parameter file The contents of filename will be read and added to the list of command line options. Precisely, the "-PARAMFILE=filename" phrase will be replaced by the contents of filename. The contents of filename should consist of a set of COPYDIR options; entered just as you would have entered them from the command line. For readability purposes, you can use CRLFs (new lines) -- they are treated as if they were spaces. Notes: * you can have use zero, one, or several -PARAMFILE options * -PARAMFILE is recursive (-PARAMFILE options in a parameter file will BE processed). * if you specify a relative filename, the filename is assumed to be in the current directory. Note that this is different then the LOG and ERRFILES, which use the "COPYDIR.CMD directory" as the default directory. * Lines in a parameter file that begin with a semi colon (;) are ignored * COPYDIR.SMP is a sample of a very simple parameter file * To include spaces in the filename, bracket the filename with " characters. For example: -PARAMFILE="COPYDIR PARAMS.1" -Q -- Quiet mode -QQ -- Very quiet mode -R[abcdfonqrs0Z] -- Replacement criteria. If -R is not specified, newer (or same aged) files are never replaced. Criteria include: a(lways), b(igger), c(heck crc), d(elete), f(uture), o(lder), n(ewer), q(uery), r(readony), s(maller), 0(ero length), z(never) By default -R is the same as -Raq. You can change this by setting the rdefault parameter (see below) For details on -R, see below. -SHARE -- Copy even if source file is open. That is, copy even if a normal copy would cause a "sharing error" (i.e.; a sys0032 file being used by another process error). -SHARE is supported ONLY if the FILEREXX library is available. Note the -SHARE suppresses "true moves" -- when -MOVE is specified, rename is not used (instead, copy followed by source file deletion is used, though "shared" files will never be deleted). -TEST -- Test mode. No files will be copied or moved. Useful when combined with -LOG, to see what will be done. Perhaps this should be called "dry run mode" -V -- Verify all copies, and cross drive moves (using CRC check). Make up to 3 attempts if verification fails. Note the -V suppresses "true moves" -- when -MOVE is specified, rename is not used (instead, copy followed by source file deletion is used). -X=astring -- Exclude files that contain astring You can specify multiple occurences of -X= Use double quotes (") to include spaces, -, &, and other wierd characters in astring -ZIP=filename -- Create directory specific filename.ZIP files on the the destination drive, with each of these ZIP files containing the contents of the source directory. FOR THIS -ZIP OPTION TO WORK, ZIP.EXE MUST BE SOMEWHERE IN YOUR PATH (for example, in x:\OS2\APPS, where x: is your bootdrive). Notes: * The -V, -R, -MOVE, and -ATTRIBS are ignored if -ZIP is specified. * The -X and -I options are not applied to file names (they are applied to directory names) * To include spaces in the filename, bracket the filename with " characters. For example: -ZIP="MY ZIPFILE" Notes: * if the destination drive is FAT, the 8.3 conversion of filenames will always be done (if necessary). * when an 8.3 conversion occurs, a name of the form XXXXXnnn.EXT is used; where XXXXX is the first 5 characters of the source file's name, nnn is an integer from 001 to 999, and EXT is the first 3 characters of the source file's extension. * When copying from an HPFS to a FAT drive: If a long directory name is encountered (on the HPFS drive) the directory's contents will NOT be copied. A note WILL be made in the ErrorFile for each such failure. * If a bad sector (or some other form of error) prevents copying a file, the file will be skipped (that is, COPYDIR will try and copy the other files). If -MOVE is specified, files that are not copied (due to an error) are NOT deleted. * By default, if any problems occur a file with the name COPYDIR.ERR is created. This file contains entries that identify problems encountered -- such as a "failure to copy a file" or "longname converted". For more details, see the description of the -ERRFILE option. * If there is not enough room on the destination drive, you will be asked to "continue anyway". Note that this "not enough room" calculation is made without accounting for the possibility of overwriting a file, hence is conservative. * If the source or destination directory contains spaces, be sure to place the directory name between double quote (") characters. * -ATTRIBS examples Note: you can use a shortcut of -ATTRIBS=x where x is -, +, or *. This is equivalent to ----, ++++, and **** (respectively) -ATTRIBS=**** : destination files and directories will have same attributes as source -ATTRIBS=*--- : archive same as attributes; read, hidden, and system attributes are cleared -ATTRIBS=-*+* : archive attribute cleared, hidden and system attributes from source file, readonly attribute set. -ATTRIBS=- : clear all attributes in destination file * -R notes -R is used to specify replacement critieria. They are NOT used if the destination file does not exist. You can specify several case-insensitive criteria, which will be processed in the order entered. Definition: Replace means "copy, or move, the source file to the destination file" The currently recognized (case-insensitive) criteria are: These two are "termination" criteria; criteria following them are never considered. > a : Always replace. > z : Never replace. These next are "necessary" criteria. If they are not satisfied, replacement does NOT occur > b : source file MUST be bigger (or same size) > s : source file MUST be smaller > n : source file MUST be newer > o : source file MUST be older (or same age) > c : source and destination files MUST have different CRC These are sufficient critieria. If true, replacement occurs. If not true, then subsequent criteria are examined. > 0 : if destination files is 0 length, replace (even if it is newer) > f : if destination file has date later then today (a date in the future), replace it (even though it's newer!) Careful, this uses local time! These are modifiers. Their order in the criteria list does not matter. > q : Always ask the user to verify the replacment. This query only occurs if all the other replacement criteria are satisfied (if replacement would otherwise occur). > d : if -MOVE is specified, then ALWAYS delete the source file. This occurs regardless of whether a copy occurs. However, if a failure occurs (say, due to a bad sector) then the source file will NOT be deleted. > r : if the destination file is read only, then you MAY overwrite it. Note that if r is not specified, read only files (files with a +r attribute) are NEVER replaced. That is, -Ra does NOT replace read-only files, but -Rra (or -Rar) DOES. If all of the specified "necessary" criteria are satisfied (and z is not specified), replacement occurs (regardless of file age). More notes on -R criteria: + If -R is not specified, newer files will not be replaced. + If z is specified but the destination file does not exist, the source file WILL be copied + the q and d criteria can be anywhere + q does not apply to files that do not satisfy the other replacement, inclusion, or exclusion criteria. In other words, the user is queried only about files that are not otherwise skipped. + By default, -Raq is the same as -R. This default can be changed by modifying the rdefault parameter. + When a readonly file is replaced, it's replacement is NOT set to be readonly (the new destination file has a -r attribute). -R Examples: -R : depends on value of rdefault. Typically, -R is same as -Raq -R0n : always replace zero length, and older, files, -Rs : replace if source is smaller -Rb : replace if source is bigger -Rso : replace if source is smaller and older -Rc : replace if CRC's don't match (regardless of age) -Rsr : replace smaller & older files, even if they are read only (older only is the default) -Rac : same as -Ra -- the "c" is never considered -Rqn : replace if source is newer, but first ask -Rdb : replace if source is bigger. Regardless of whether source is bigger or smaller, if -MOVE is specified, delete the source file * -ZIP notes: + If you do not include =filename after a -ZIP option, a name derived from today's date is used. For example, 20NOV01.ZIP (corresponding to 20 Nov 2001) + The -ZIP option causes a .ZIP file to be created on the destination drive, and filled with files from the corresponding source drive. The same .ZIP filename is used in each destination directory (though, of course, each of these .ZIP files will contain unique content). Thus, if you ran COPYDIR on 28 Mar 2001, then COPYDIR C:\OLD D:\NEW -ZIP might lead to the following ZIP files being created D:\NEW\28MAR01.ZIP D:\NEW\DIR1\28MAR01.ZIP D:\NEW\DIR2\28MAR01.ZIP D:\NEW\DIR2\SAMPLES\28MAR01.ZIP (assuming that C:\OLD had DIR1, DIR2, and DIR2\SAMPLES subdirectories). * -LOG and -LOGNEW notes + Do NOT include spaces in the -LOG (or -LOGNEW) filename! + For -LOG, if a logfile exists, it will be appended to. For -LOGNEW, it will be overwritten + If the destination directory of a logfile does not exist, the program exits. * -MERGE and -NOMERGE notes When copying a directory (it's files and it's subdirectories) to a preexisting destination directory, one can either ... a) copy TO. This is a "merge", and is equivalent to xcopy source\*.* destination\*.* b) copy UNDER. This is a "directory replication", and is equivalent to xcopy source\*.* destination\source\*.* For example, assuming that E:\MYFILES and F:\OURFILES exist, and that E:\MYFILES\FOO.BAR exists. Then, given the action ... COPYDIR E:\MYFILES F:\OURFILES a) TO mode yields F:\OURFILES\FOO.bAR b) UNDER mode yields F:\OURFILES\MYFILES\FOO.BAR There are three ways of selecting which mode to use: 1) Use a -MERGE or -NOMERGE switch -MERGE selects the TO mode -NOMERGE selects the UNDER mode 2) Select TO mode by appending a \* to the destination directory. Alternatively, use COPYDIR SOURCE DESTINATION\SOURCE\* to perform an UNDER copy. For example: COPYDIR E:\NEW\MYFILES F:\OURFILES\* is the same as COPYDIR E:\NEW\MYFILES F:\OURFILES -MERGE and COPYDIR E:\NEW\MYFILES F:\OURFILES\MYFILES\* is the same as COPYDIR E:\NEW\MYFILES F:\OURFILES -NOMERGE 3) Modify the TO_UNDER parameter If there is any ambiguity, COPYDIR will ask you which you want to do. Note that -MERGE and -NOMERGE override a trailing \*, and a trailing \* overrides the TO_UNDER parameter. * -X and -I notes: + You can specify multiple "exclusion" strings, and you can specify multiple "inclusion" strings. Note that the fully qualified filename (including drive and directory information) is compared to each string. Thus, for ... -x=:\TEMP\ -- exclude d:\TEMP\foo.bar include d:\www\temp\goo.bar include d:\www\temp2\hoo.bar -X=\TEMP\ -- exclude d:\TEMP\foo.bar exclude d:\www\temp\goo.bar include d:\www\temp2\hoo.bar -X=\TEMP -- exclude d:\TEMP\foo.bar exclude d:\www\temp\goo.bar exclude d:\www\temp2\hoo.bar + If you specify both -I= and -X= entries, then only files that -- match (one of) the -I= entries and -- do NOT match (any of) the -X= entries will be copied (or moved). + The -I= or -X= string should NOT contain * or ? wildcard characters (a substring match of "string" against the filename is attempted). * The following options can be modified in the program file (COPYDIR.CMD): dopause = pause a few seconds before starting (allow for cancellation) errfile = default filename where errors should be recorded fileSeconds = use seconds when comparing file ages forceYes = when used with >0 values of dopause, default is NOT continue logfile = default filename to use when -LOG or -LOGNEW is specified loglister = program to use to display logfile metic = enable meticulous mode one_per_line = display one file message per line to_under = default: copy source "to", or "under" destination rdefault = sets the default action of -R testsize = similar to -CHECK verbosity = similar to -Q and -QQ zip_opts = specify options to use when ZIPping files Examples: COPYDIR E:\DOCS G:\DOCS COPYDIR F:\GAMES\NEW E:\FUN -8 -CHECK -R COPYDIR F:\MAIL G:\MAILARC -8 -CHECK -Rz COPYDIR "My Docs" "F:\archive\Old Docs" -NOCHECK COPYDIR F:\DOCS\CURRENT I:\ARCHIVE\Y1998 -ZIP COPYDIR F:\MYFILES M:\ARC\MYFILES\15MAR01 -x=\TEMP\ -x=.BAK -x="Back UP" COPYDIR F:\PHOTOS E:\GIFFILES -I=.GIF COPYDIR F:\ANIMALS D:\FELINES -I=CAT -X=DOG This next will do a systematic backup of all files on the C:\ drive, including hidden and system files. Copied files will have the same attributes as the originals. COPYDIR C:\ F:\ARCHIVE\C_TODAY\* -Ra -ATTRIBS=* Requires: The REXXLIB library (which may be included in the distribution file) Disclaimer: This is freeware. It is to be used at one's risk, the authors and any potentially affiliated institutions bear no responsibility for any untoward, unexpected, or disasterous effects arising from the use or misuse of this program. You may freely use and/or distribute this program, or pieces of it. I DO ask for proper attribution.