home *** CD-ROM | disk | FTP | other *** search
- /* ================================================================= */
- /* EAPREP.CMD - Create EA Backup/Restore Command Files */
- /* ================================================================= */
- /* */
- /* Author: Mercer H. Harz */
- /* Compuserve ID: 70431,150 */
- /* Written: 14 Aug 1993 */
- /* */
- /* 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 */
- /* ------------------------------------------------------------------ */
- TimeStamp = time()
- DateStamp = date()
- hdr = "EAP"
- say " "
- say hdr"00I: EAPREP v1.1 - Ext. Attribute Backup/Restore Preparation"
- say hdr"01I: Written by Mercer H. Harz, 14 Aug 1993."
- 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- */
- CurrentDir = word3 /* cessing for each directory */
- if CurrentDir = Drive":\" then CurrentDir = Drive":"
- 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
-