home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
eaprep.zip
/
EAPREP.CMD
Wrap
OS/2 REXX Batch file
|
1994-03-06
|
24KB
|
422 lines
/* ================================================================= */
/* EAPREP.CMD - Create EA Backup/Restore Command Files */
/* ================================================================= */
/* */
/* Author: Mercer H. Harz */
/* Compuserve ID: 70431,150 */
/* Written: 26 May 1992 v1.0 */
/* Modified: 14 Aug 1993 v1.1 rewritten to handle directories */
/* and add comments */
/* 09 Oct 1993 v1.2 modified for compatibility with */
/* 4OS2 command processor */
/* 06 Mar 1994 v1.3 corrects a bug introduced by */
/* the v1.2 4OS2 modifications */
/* */
/* All standard disclaimers apply; this procedure is provided "as */
/* is and no guarantees or warranties are provided regarding its */
/* fitness for a particular task. */
/* */
/* This program is placed in the public domain by the author. */
/* */
/* ================================================================= */
/* */
/* syntax: EAPREP <drive> <EADir> */
/* */
/* <drive> is a required parameter. It specifies the drive to be */
/* processed. */
/* <EADir> is a required parameter. It specifies the location where */
/* the DOS-visible Extended Attribute files are to be stored.*/
/* If the directory does not exist, it will be created. */
/* */
/* output: Two command files: EADir\x_BKP.CMD (for BACKUP) */
/* EADir\x_RST.CMD (for RESTORE) */
/* */
/* where x = drive being processed */
/* */
/* ================================================================= */
/* */
/* This procedure creates OS/2 command files that can be executed to */
/* copy and reattach extended attributes to/from files that are */
/* visible to a DOS backup/restore program that would otherwise not */
/* be able to handle Extended Attributes. To backup HPFS volumes */
/* with your DOS backup software, you must run the backup in an OS/2 */
/* DOS session rather than under native DOS. If your hardware isn't */
/* usable inside an OS/2 DOS session, you won't be able to backup an */
/* HPFS partition with a DOS backup program. You can backup FAT */
/* partitions with your DOS backup software from either an OS/2 DOS */
/* session or from native DOS. This program (since it's written in */
/* OS/2 Rexx) must run from within an OS/2 command-line session. */
/* */
/* NOTE!!!!! */
/* */
/* EAPREP does not perform the actual copy and reattach operations */
/* on the extended attributes. It merely creates command files that */
/* you must execute when you are ready to: */
/* 1. BACKUP - */
/* create the DOS-visible copies of the extended attributes */
/* or 2. RESTORE - */
/* reattach the extended attributes after a full restore */
/* using the DOS backup/restore software */
/* */
/* You should run EAPREP, followed by the backup command file that */
/* it creates, immediately prior to running the DOS backup software. */
/* Ensure that your DOS backup software backs up the command files */
/* created by this program, as well as the files containing the EA */
/* copies that were created by the backup command file created by */
/* EAPREP. */
/* */
/* EAPREP does not backup/restore the Workplace Shell desktop, even */
/* though some WPS state info may be saved in EAs. Use one of the */
/* other utilities in the CIS OS/2 librarires for this purpose, */
/* either the WPSBackup program (WPSBKP.ZIP) or the DeskMan/2 */
/* program (DSKMN2.ZIP). You will need to contact the authors and */
/* pay a fee to receive unrestricted use of these other utilities. */
/* */
/* Currently the procedure uses a brute force method to achieve its */
/* ends, since there is no built-in way in REXX to determine whether */
/* a file has extended attributes. EAPREP builds a list of files on */
/* the drive, then scans the list looking for a non-zero value in */
/* the extended attribute size field; for each hit, it creates a */
/* command in the backup and restore command files. Files that are */
/* "in use" by OS/2 (such as OS2KRNL on my system) will generate */
/* errors during execution of the backup and restore command files. */
/* These can, in my experience, be ignored. */
/* */
/* The backup and restore command files use the EAUTIL program that */
/* is furnished with OS/2. Operation of EAUTIL is documented in the */
/* online command reference. */
/* */
/* EAPREP has no selective processing capability; the entire drive */
/* will be scanned. You can further refine the process by editing */
/* the output with any ASCII text editor. */
/* */
/* EAPREP assumes you are not disk-space-constrained. At a minimum, */
/* when you run the backup command file generated by this procedure, */
/* you will need slightly more free space on the drive than is */
/* occupied by the extended attributes on that drive. The reason is */
/* that the backup command file preserves the existing EAs as it */
/* makes copies that are visible to EA-unaware DOS programs. To see */
/* how much space you'll need, run CHKDSK against the drive before */
/* you run this procedure, then double the amount allocated to */
/* extended attributes, and add a "fudge" factor for directory space */
/* overhead and wasted space at the end of clusters. For those with */
/* tight disk space requirements, there are instructions below on */
/* how to change the behavior of the backup command file so that the */
/* extended attributes are deleted as the backup copy is created. */
/* EAPREP uses the <EADir> value as the ouput location for the work */
/* files and command files that are the output of this program, as */
/* well as the storage directory for the extended attribute copies. */
/* Work files could occupy several hundred kilobytes but are deleted */
/* at the end of the program. Each file or directory with EAs adds */
/* about 90 bytes to the backup and restore command files. */
/* */
/* The backup copies of the extended attributes will be stored in the*/
/* location pointed to by the <EADir> parameter. They are stored as */
/* a set of files named dnnnnnnn.EA, where "d" represents the drive */
/* letter being processed, and "nnnnnnn" is a sequence number. The */
/* directory, if it does not currently exist, will be created by */
/* this program, but its existence will not be checked for by the */
/* generated command files. It is not necessary, but it is probably */
/* a good idea, for you to empty the <EADir> subdirectory before */
/* running this program. The naming convention allows you to store */
/* all DOS-visible EA files for all drives on your system in the */
/* same location, though you do not have to do so. */
/* */
/* The restore command file contains the mirror commands required to */
/* join the EAs to their owners after you've restored the system */
/* from a DOS backup. */
/* */
/* The backup command file uses the /P /R /S switches; these split */
/* (/S) the EAs into a backup copy, preserving (/P) the EAs with the */
/* parent file, and replacing (/R) any existing backup copy of the */
/* parent's EAs that might be stored in the <EADir> subdirectory. */
/* */
/* The restore command file uses the /O /J switches; these join (/J) */
/* the EAs to the parent file, overlaying (/O) any existing EAs */
/* associated with the parent. The backup copy will be erased. To */
/* prevent the erasure of the backup, add the /P switch to these */
/* commands. If, rather than overlaying the current EAs (if any), */
/* you want to merge the backup EAs with the current EAs, use the */
/* /M switch rather than /O for the restoration. */
/* */
/* Long file names may not operate properly with DOS backup/restore */
/* software; this will depend on whether OS/2 will properly create */
/* filenames in 8.3 format when backing up/restoring with DOS s/w. */
/* I haven't tested long file names because I don't have any HPFS */
/* volumes right now. My advice is to stick with 8.3 filenames on */
/* HPFS volumes until you have long-name-aware backup/restore s/w. */
/* */
/* ================================================================= */
/* ------------------------------------------------------------------ */
/* MAKE COMMAND-LINE ARGUMENTS AVAILABLE */
/* ------------------------------------------------------------------ */
arg Drive EADir
/* ------------------------------------------------------------------ */
/* MAKE REXX UTILITY FUNCTIONS AVAILABLE */
/* ------------------------------------------------------------------ */
call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
call SysLoadFuncs
/* ------------------------------------------------------------------ */
/* SAY HELLO */
/* ------------------------------------------------------------------ */
Version = "1.3"
Written = "6 Mar 1994"
TimeStamp = time()
DateStamp = date()
hdr = "EAP"
say " "
say hdr"00I: EAPREP v"Version" - Ext. Attribute Backup/Restore Preparation"
say hdr"01I: Written by Mercer H. Harz, "Written"."
say hdr"02I: Starting at "TimeStamp" on "DateStamp"."
say " "
/* ------------------------------------------------------------------ */
/* CHECK FOR PRESENCE OF COMMAND-LINE ARGUMENTS */
/* ------------------------------------------------------------------ */
if length(Drive) = 0 then signal USAGE
if length(EADir) = 0 then signal USAGE
if right(EADir,1) = '\' then
EADir = substr(EADir, 1, length(EADir) - 1)
/* ------------------------------------------------------------------ */
/* CHECK FOR VALIDITY OF SELECTED DRIVE */
/* ------------------------------------------------------------------ */
ValDrives = SysDriveMap()
Drive = left(Drive,1)
if pos(Drive,ValDrives) = 0 then signal BADDRV
/* ------------------------------------------------------------------ */
/* CHECK FOR VALIDITY OF SELECTED EA STORAGE DIRECTORY */
/* ------------------------------------------------------------------ */
CurrDir = directory() /* save current directory */
CheckDir = directory(EADir) /* does EADir exist? */
if CheckDir = EADir then signal SETWORK /* if so, continue */
rc = SysMkDir(EADir) /* if not, create it */
if rc <> 0 then signal BADMD /* advise user of failure */
say hdr"03W: Created directory "EADir
/* ------------------------------------------------------------------ */
/* SETUP AND INITIALIZE THE WORK FILES */
/* ------------------------------------------------------------------ */
SETWORK:
CurrDir = directory(CurrDir) /* return to starting dir */
WorkFile = EADir'\'Drive'.wrk'
BackupFile = EADir'\'Drive'_bkp.cmd' /* now initialize the */
RestoreFile = EADir'\'Drive'_rst.cmd' /* work files */
if length(stream(BackupFile,'c','query exists')) > 0 then
call SysFileDelete(BackupFile)
if length(stream(RestoreFile,'c','query exists')) > 0 then
call SysFileDelete(RestoreFile)
/* ------------------------------------------------------------------ */
/* CREATE THE WORK FILE DIRECTORY LISTING IN HPFS FORMAT */
/* ------------------------------------------------------------------ */
say hdr'10I: Obtaining directory for drive 'Drive':... please be patient...'
say " "
'@dir 'Drive':\*.* /N /S /A /O:GN > 'WorkFile
if rc <> 0 then signal BADDIR
/* ------------------------------------------------------------------ */
/* OPEN THE WORK FILES FOR USE BY THE PROGRAM */
/* ------------------------------------------------------------------ */
Result = stream(WorkFile,'c','open read')
if Result <> "READY:" then signal BADWRK
Result = stream(BackupFile,'c','open write')
if Result <> "READY:" then signal BADBKP
Result = stream(RestoreFile,'c','open write')
if Result <> "READY:" then signal BADRST
/* ------------------------------------------------------------------ */
/* FINAL INITIALIZATIONS */
/* ------------------------------------------------------------------ */
EACount = 0 /* number of objects with extended attributes */
NumDirs = 0 /* number of (sub)directories processed */
NumFiles = 0 /* number of directory entries processed */
say hdr"11I: Directories Entries Entries"
say hdr"12I: Processed Processed with EAs"
say hdr"13I: ----------- --------- --------"
parse value SysCurPos() with row col
/* ------------------------------------------------------------------ */
/* MAIN PROCESSING LOOP --- look for entries with EAs */
/* ------------------------------------------------------------------ */
do until lines(WorkFile) = 0 /* run until end-of-file */
buff = linein(WorkFile)
parse var buff word1 word2 word3 EASize FName word6
if buff = " " then iterate /* --------------------- */
if word1 = "The" then iterate /* Ignore the whitespace */
if word1 = "Totals" then iterate /* in the directory */
if word1 = "Volume" then iterate /* listing */
if word2 = "bytes" then iterate /* */
if word2 = "file(s)" then iterate /* --------------------- */
if word1 = "Directory" then do
NumDirs = NumDirs + 1 /* perform control-break pro- */
/* cessing for each directory */
Len = length(word3) /* v1.3 */
LastChar = substr(word3,Len,1) /* v1.3 */
if LastChar <> '\' then word3 = word3'\' /* v1.3 */
LastSlash = lastpos('\',word3) /* v1.2 */
CurrentDir = substr(word3,1,(LastSlash-1)) /* v1.2 */
rc = SysCurPos(row,0)
buff = hdr'14I: 'right(NumDirs,11)' 'right(NumFiles,9)' 'right(EACount,8)
call charout ,buff
iterate
end
NumFiles = NumFiles + 1 /* this is a file/directory entry */
if EASize > 0 then do /* if it has EAs attached, create */
EACount = EACount + 1 /* the backup/restore commands */
EAIndex = right(EACount,7,'0')
DataFile = CurrentDir'\'FName
Len = length(DataFile)
if Len < 50 then Len = 50
DataFile = left(DataFile,Len,' ')
EAFile = EADir'\'Drive||EAIndex'.EA'
Len = length(EAFile)
if Len < 20 then Len = 20
EAFile = left(EAFile,Len,' ')
BackupCmd = 'EAUTIL 'DataFile' 'EAFile' /P /R /S'
RestoreCmd = 'EAUTIL 'DataFile' 'EAFile' /O /J'
call lineout BackupFile, BackupCmd
call lineout RestoreFile, RestoreCmd
end
end
rc = SysCurPos(row,0)
buff = hdr'14I: 'right(NumDirs,11)' 'right(NumFiles,9)' 'right(EACount,8)
call charout ,buff
/* ------------------------------------------------------------------ */
/* WE'RE DONE - TIME TO CLEAN UP AFTER OURSELVES */
/* ------------------------------------------------------------------ */
Result = stream(WorkFile,'c','close')
Result = stream(BackupFile,'c','close')
Result = stream(RestoreFile,'c','close')
call SysFileDelete(WorkFile)
if EACount = 0 then do
call SysFileDelete(BackupFile)
call SysFileDelete(RestoreFile)
end
say " "
say " "
if EACount > 0 then do
say hdr"96I: "EACount" Commands to BACKUP EAs are stored in "BackupFile
say hdr"97I: "EACount" Commands to RESTORE EAs are stored in "RestoreFile
end
else say hdr"98W: EA Backup and Restore command files were not created."
signal ENDPGM
/* ------------------------------------------------------------------ */
/* DIRECTORY WORK FILE COULD NOT BE CREATED */
/* ------------------------------------------------------------------ */
BADDIR:
savrc = rc
call SysFileDelete(WorkFile)
say hdr"51E: Sorry, there was a problem obtaining a directory for drive "Drive":."
rc = savrc
signal DOSERR /* clean up after ourselves */
/* ------------------------------------------------------------------ */
/* DIRECTORY WORK FILE COULD NOT BE OPENED FOR INPUT */
/* ------------------------------------------------------------------ */
BADWRK:
call SysFileDelete(WorkFile)
say hdr"53E: Sorry, there was a problem reading directory file "WorkFile"."
signal BADSTRM /* clean up after ourselves */
/* ------------------------------------------------------------------ */
/* BACKUP FILE COULD NOT BE OPENED FOR OUTPUT */
/* ------------------------------------------------------------------ */
BADBKP:
call SysFileDelete(BackupFile)
call SysFileDelete(WorkFile)
say hdr"54E: Sorry, there was a problem opening backup command file "BackupFile"."
signal BADSTRM /* clean up after ourselves */
/* ------------------------------------------------------------------ */
/* RESTORE FILE COULD NOT BE OPENED FOR OUTPUT */
/* ------------------------------------------------------------------ */
BADRST:
call SysFileDelete(RestoreFile)
call SysFileDelete(BackupFile)
call SysFileDelete(WorkFile)
say hdr"55E: Sorry, there was a problem opening restore command file "RestoreFile"."
signal BADSTRM /* clean up after ourselves */
/* ------------------------------------------------------------------ */
/* ERROR ACCESSING STREAM DEVICE */
/* ------------------------------------------------------------------ */
BADSTRM:
say hdr"59E: Stream Error ("Reason")"
signal ENDPGM
/* ------------------------------------------------------------------ */
/* USER HAS NOT ENTERED A VALID DRIVE LETTER */
/* ------------------------------------------------------------------ */
BADDRV:
say hdr"61E: Drive "Drive": is not a valid selection."
say hdr"62W: Please select a drive from the following list."
say hdr"63W: "ValDrives
signal ENDPGM
/* ------------------------------------------------------------------ */
/* UNABLE TO CREATE EA STORAGE DIRECTORY */
/* ------------------------------------------------------------------ */
BADMD:
say hdr"71E: Sorry, unable to create "EADir
signal DOSERR
/* ------------------------------------------------------------------ */
/* TRANSLATE DOS ERROR CODES */
/* ------------------------------------------------------------------ */
DOSERR:
select
when rc = 2 then reason = "File not found."
when rc = 3 then reason = "Path not found."
when rc = 5 then reason = "Access Denied."
when rc = 26 then reason = "Not a DOS disk."
when rc = 87 then reason = "Invalid Parameter."
when rc = 108 then reason = "Drive Locked."
when rc = 206 then reason = "Filename exceeds range."
otherwise reason = "Unknown Error."
end
say hdr"90E: Return Code = "right(rc,3,'0')" : "reason
signal ENDPGM
/* ------------------------------------------------------------------ */
/* USER HAS NOT ENTERED A REQUIRED PARAMETER */
/* ------------------------------------------------------------------ */
USAGE:
say hdr"80E: A required parameter is missing."
say " "
say hdr"81I: Usage:"
say hdr"82I: EAPREP Drive EADir"
say hdr"83I: where"
say hdr"84I: Drive = disk drive to be processed"
say hdr"85I: EADir = location (on any drive with adequate space)"
say hdr"86I: where EAPREP will store its output and the"
say hdr"87I: files containing extended attribute copies."
say " "
say hdr"88I: Both parameters are required; no defaults are taken."
say hdr"89I: EADir will be created if it does not exist."
/* ------------------------------------------------------------------ */
/* ALL ROUTINES EXIT FROM THIS POINT TO ENSURE CORRECT CLEANUP */
/* ------------------------------------------------------------------ */
ENDPGM:
call SysDropFuncs
TimeStamp = time()
DateStamp = date()
say " "
say hdr"99I: Finished at "TimeStamp" on "DateStamp"."
return