home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / BACK2FT2.ZIP / BACK2FAT.CMD next >
OS/2 REXX Batch file  |  1993-02-06  |  20KB  |  581 lines

  1. /* *****************************************************************************
  2.  
  3.         File:   BACK2FAT.CMD
  4.  
  5.         Author: Ralf Hauser (c│o)
  6.                 e-mail:  affie@frege.sns.neuphilologie.uni-tuebingen.de
  7.  
  8.         Date:   22-07-92
  9.  
  10.         Ver:    1.00
  11.  
  12.         Desc:   Backs Up specified fileset on FAT drive
  13.                 using EABACKUP and ZOO.
  14.                 Resulting file may be further processed using a
  15.                 tape streamer running under DOS.
  16.  
  17.         Usage:  BACK2FAT  [{/|-}switches]  <fileset>  [target_path]
  18.  
  19.         Note:   Refer to the "b2f_init" function to setup
  20.                 user specific constants
  21.  
  22.         Requirements:
  23.  
  24.                 OS/2 2.0 (V1.3 not tested, but should do)
  25.                 EABACKUP.EXE V2.x in PATH
  26.                 ZOO.EXE V2.x in PATH
  27.  
  28.                 for restoring the backuped data:
  29.                 EARESTOR.EXE V2.x in PATH
  30.                 ZOO.EXE V2.x in PATH
  31.  
  32. --------------------------------------------------------------------------
  33. History:
  34. 22-07-92 co     Created
  35. -------------------------------------------------------------------------- */
  36.  
  37. /* ----------------------------------------------------------------------- */
  38. /*      Globals                                                            */
  39. /* ----------------------------------------------------------------------- */
  40.  
  41. '@ECHO OFF'                       /* do not display any SHELL commands */
  42. global. = ""                      /* init */
  43.  
  44. /* ----------------------------------------------------------------------- */
  45. /*      Main                                                               */
  46. /* ----------------------------------------------------------------------- */
  47.  
  48. Main :
  49.         CALL b2f_init             /* initialize global data structures */
  50.  
  51.         /*
  52.          *    handle arguments
  53.          */
  54.  
  55.         Parse Arg switches fileset target
  56.  
  57.         IF Arg() = 0 THEN
  58.            CALL b2f_help
  59.  
  60.         /* header */
  61.         Say " "
  62.         Say global.title || "   V" || global.version,
  63.             "       a c│o tool - 4 use if u like it"
  64.         Say " "
  65.  
  66.         /* look whether switches are specified */
  67.         IF Substr(switches, 1, 1) <> "-" & Substr(switches, 1, 1) <> "/" THEN DO
  68.            /* no, so shift arguments */
  69.            target   = fileset
  70.            fileset  = switches
  71.            switches = ""
  72.            END
  73.         ELSE DO /* handle switches */
  74.            IF Pos("?", switches) > 0 THEN
  75.               CALL b2f_help
  76.            global.log       = Pos("l", switches)
  77.            global.debug     = Pos("d", switches)
  78.            global.overwrite = Pos("k", switches)
  79.            END
  80.  
  81.         /*
  82.          *    determine filespec in fileset
  83.          */
  84.  
  85.         source = b2f_get_filespec(fileset)
  86.         Say global.title || ": Creating backup of '" || source || "\" || global.filespec || "' ..."
  87.  
  88.         /*
  89.          *    create target directory
  90.          */
  91.  
  92.         IF target = "" THEN
  93.            target = global.target_drive || global.target_path
  94.  
  95.         /* test for absolute path specification */
  96.         IF Substr(target, 2, 1) <> ":" | Substr(target, 3, 1) <> "\" THEN
  97.            CALL b2f_error "A full targetpath must be specified - ", "'" || target || "' is not a full targetpath."
  98.  
  99.         Say global.title || ": Creating target directory '" || target || "' ..."
  100.  
  101.         IF b2f_dir_exist(target) THEN DO
  102.            IF global.overwrite = 0 THEN DO
  103.               Say global.title || ": Target directory '" || target "' already exists! Clear? [Y/N]"
  104.               Pull answer
  105.               IF answer <> "y" & answer <> "Y" THEN
  106.                  CALL b2f_error "Cannot work on '" || target || "' as it contains files."
  107.               END
  108.            Say global.title || ": Deleting contents of target directory ..."
  109.            CALL b2f_kill_dir target
  110.            END
  111.         ELSE
  112.            CALL b2f_make_dir target
  113.  
  114.         /*
  115.          *    create a filelist
  116.          */
  117.  
  118.         CALL b2f_filelist source target
  119.  
  120.         /*
  121.          *    create a backup of extended attributes
  122.          */
  123.  
  124.         CALL b2f_ea_backup source target
  125.  
  126.         /*
  127.          *    create a backup of files
  128.          */
  129.  
  130.         CALL b2f_backup source target
  131.  
  132.         /*
  133.          *    create a backup of fileslisting of all errors
  134.          */
  135.  
  136.         IF global.log <> 0 THEN
  137.            CALL b2f_list_errors target
  138.  
  139.         /*
  140.          *    create an info file
  141.          */
  142.  
  143.         CALL b2f_info source target fileset
  144.  
  145.         /*
  146.          *    close
  147.          */
  148.  
  149.         IF global.debug <> 0 THEN DO
  150.            Say global.title || ": DEBUG: All files in " || target
  151.            DIR "/P /N" target
  152.            END
  153.  
  154.         /* that's it */
  155.         Say global.title || ": Successfully terminated!"
  156.         /* jippeeh */
  157.         Call beep 2000, 200
  158.         Call beep 1600, 200
  159. EXIT
  160.  
  161. /* ----------------------------------------------------------------------- */
  162. /*      b2f_init                                                           */
  163. /* ----------------------------------------------------------------------- */
  164.  
  165. b2f_init : PROCEDURE EXPOSE global.
  166. /*
  167.  *      initializes all global data
  168.  */
  169.         /* check whether RxFuncs are loaded, if not, load them */
  170.         IF RxFuncQuery('SysLoadFuncs') THEN DO
  171.            /* load the load-function */
  172.            CALL RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  173.            /* load the Sys* utilities */
  174.            CALL SysLoadFuncs
  175.            END
  176.         /* set default values */
  177.         global.title         = "BACK2FAT"
  178.         global.version       = "1.00"
  179.         global.fnam_infofile = "BACKUP.DOC"
  180.         global.fnam_listfile = "BACKUP.LST"
  181.         global.fnam_errfile  = "BACKUP.ERR"
  182.         global.fnam_backup   = "BACKUP.ZOO"
  183.         global.fnam_eabkup1  = "EA@BDATA.EAB"
  184.         global.fnam_eabkup2  = "EA@INDEX.EAB"
  185.         global.sepline       = "-------------------------------------------------------------------------"
  186.         global.log           = 0
  187.         global.debug         = 0
  188.         global.overwrite     = 0
  189.  
  190.         /*****************************************************************
  191.          *    USER-SPECIFIC section
  192.          */
  193.  
  194.         /* EA Backup service */
  195.         global.eabckup_pgm   = "EABACKUP.EXE"    /* must be executable; you may add a path */
  196.         global.eabckup_add   = " "     /* additional switches for EABACKUP program */
  197.         /* Backup service */
  198.         global.bckup_pgm     = "ZOO.EXE"         /* must be executable; you may add a path */
  199.         global.bckup_add     = " "     /* additional switches for BACKUP program */
  200.  
  201.         global.target_drive  = "D:"         /* FAT drive */
  202.         global.target_path   = "\_BACKUP_"  /* default directory on FAT drive */
  203.         global.filespec      = "*"          /* wildcard for files to be backuped */
  204.  
  205.         /*
  206.          *      fileset: not only a name but a subdirectory in the root directory;
  207.          *               all files in the subdirectory are backuped
  208.          *
  209.          *      A fileset must be a string of the form "set --> drive/path spec"
  210.          */
  211.  
  212.         global.fileset.1     = "OS2  -->   C:\OS2"    /* OS2 system files */
  213.         global.fileset.2     = "APP  -->   C:\APP"    /* applications */
  214.         global.fileset.3     = "BIN  -->   C:\BIN"    /* 'binaries', tools */
  215.         global.fileset.4     = "ETC  -->   C:\ETC"    /* other system files */
  216.         global.fileset.5     = "LIB  -->   C:\LIB"    /* libraries */
  217.         /* ... more ... */
  218.         global.fileset_num   = 5       /* must contain number of filesets! */
  219.  
  220.         /*
  221.          *    END OF USER-SPECIFIC section
  222.          *****************************************************************/
  223.  
  224.         /* check user defined section */
  225.         /* because there are always some guys wanting to see the program fail */
  226.         DO i = 1 TO global.fileset_num
  227.            IF Words(global.fileset.i) <> 3 THEN
  228.               CALL b2f_error "Syntax error in user section:", "'" || global.fileset.i "' is invalid."
  229.            IF Word(global.fileset.i, 2) <> "-->" THEN
  230.               CALL b2f_error "Syntax error in user section:", "'-->' missing in: '" || global.fileset.i "'"
  231.         END
  232.  
  233.         RETURN
  234.  
  235. /* b2f_init */
  236.  
  237. /* ----------------------------------------------------------------------- */
  238. /*      b2f_error                                                          */
  239. /* ----------------------------------------------------------------------- */
  240.  
  241. b2f_error : PROCEDURE EXPOSE global.
  242. Parse Arg msg, msg1, msg2
  243.  
  244.         Say global.title || ": An error occured:"
  245.         CALL Beep 500, 200
  246.         CALL Beep 900, 200
  247.         CALL Beep 500, 200
  248.         Say " "
  249.         Say "   Error: " || msg
  250.         IF msg1 <> "" THEN
  251.            Say "          " || msg1
  252.         IF msg2 <> "" THEN
  253.            Say "          " || msg2
  254.  
  255.         EXIT
  256.  
  257. /* b2f_error */
  258.  
  259. /* ----------------------------------------------------------------------- */
  260. /*      b2f_help                                                           */
  261. /* ----------------------------------------------------------------------- */
  262.  
  263. b2f_help : PROCEDURE EXPOSE global.
  264. /*
  265.  *      Prints a help
  266.  */
  267.         Say " "
  268.         Say " Usage: " || global.title || " [{/|-}switches]  <fileset>  [targetpath]"
  269.         Say " "
  270.         Say "     Possible switches are:"
  271.         Say " "
  272.         Say "        ?      this help"
  273.         Say "        l      create log files"
  274.         Say "        d      display additional debug info"
  275.         Say "        k      kill files in target directory"
  276.         Say " "
  277.         Say "     Possible filesets are: "
  278.         Say " "
  279.  
  280.         DO i = 1 TO global.fileset_num
  281.            Say "        " || global.fileset.i
  282.         END
  283.  
  284.         Say " "
  285.         Say "     Manually generated by Ralf Hauser (c│o), 7400 Tübingen"
  286.         Say "     e-mail: affie@frege.sns.neuphilologie.uni-tuebingen.de"
  287.  
  288.         EXIT
  289.  
  290. /* b2f_help */
  291.  
  292. /* ----------------------------------------------------------------------- */
  293. /*      b2f_get_filespec                                                   */
  294. /* ----------------------------------------------------------------------- */
  295.  
  296. b2f_get_filespec : PROCEDURE EXPOSE global.
  297. /*
  298.  *      return the filespec of the corresponding fileset
  299.  */
  300. Arg fset
  301.         DO i = 1 TO global.fileset_num
  302.            IF Word(global.fileset.i, 1) = fset THEN
  303.               RETURN Word(global.fileset.i, 3)
  304.         END
  305.         CALL b2f_error "The specified set '" || fset || "' does not exist."
  306.         RETURN " "          /* shutup compiler */
  307.  
  308. /* b2f_get_filespec */
  309.  
  310. /* ----------------------------------------------------------------------- */
  311. /*      b2f_dir_exist                                                      */
  312. /* ----------------------------------------------------------------------- */
  313.  
  314. b2f_dir_exist : PROCEDURE
  315. /*
  316.  *      return TRUE if specified directory exists
  317.  */
  318. Arg dirname
  319.  
  320.         CALL SysFileTree dirname, "file", "D"
  321.  
  322.         RETURN file.0
  323.  
  324. /* b2f_dir_exist */
  325.  
  326. /* ----------------------------------------------------------------------- */
  327. /*      b2f_kill_dir                                                       */
  328. /* ----------------------------------------------------------------------- */
  329.  
  330. b2f_kill_dir : PROCEDURE
  331. /*
  332.  *      kill the contents of the spec directory
  333.  *      return TRUE if successfull
  334.  */
  335. Arg dirname
  336.  
  337.         CALL SysFileTree dirname || "\*", "file", "F"
  338.  
  339.         DO i = 1 TO file.0
  340.            filename = word(file.i, 5)
  341.            /* Say "     (Deleting '" || filename || "')" */
  342.            CALL SysFileDelete filename
  343.         END
  344.  
  345.         RETURN
  346.  
  347. /* b2f_kill_dir  */
  348.  
  349. /* ----------------------------------------------------------------------- */
  350. /*      b2f_make_dir                                                       */
  351. /* ----------------------------------------------------------------------- */
  352.  
  353. b2f_make_dir : PROCEDURE
  354. /*
  355.  *      create a new directory
  356.  */
  357. Arg dirname
  358.  
  359.         IF SysMkDir(dirname) <> 0 THEN
  360.            CALL b2f_error "Could not create '" || dirname || "' as a directory."
  361.  
  362.         RETURN
  363.  
  364. /* b2f_make_dir  */
  365.  
  366. /* ----------------------------------------------------------------------- */
  367. /*      b2f_info                                                         */
  368. /* ----------------------------------------------------------------------- */
  369.  
  370. b2f_info : PROCEDURE EXPOSE global.
  371. Arg source target fileset
  372.  
  373.         filename = target || "\" || global.fnam_infofile
  374.         rc = 0
  375.  
  376.         Say global.title || ": Creating infofile '" || filename || "' ..."
  377.  
  378.         CALL Lineout filename, "BACKUP INFO"
  379.         CALL Lineout filename, global.sepline
  380.         CALL Lineout filename, "Programname......:" global.title
  381.         CALL Lineout filename, "Date.............:" Date("L")
  382.         CALL Lineout filename, "Time.............:" Time("N")
  383.         CALL Lineout filename, " "
  384.         CALL Lineout filename, "Fileset..........:" fileset
  385.         CALL Lineout filename, "Sourcepath.......:" source
  386.         CALL Lineout filename, "Filespec.........:" global.filespec
  387.         CALL Lineout filename, "Targetpath.......:" target
  388.         CALL Lineout filename, " "
  389.         CALL Lineout filename, "Infofile.........:" global.fnam_infofile "(This file)"
  390.         CALL Lineout filename, "Listfile.........:" global.fnam_listfile
  391.         CALL Lineout filename, "Backupfile.......:" global.fnam_backup
  392.         CALL Lineout filename, "EA Backupfile 1..:" global.fnam_eabkup1
  393.         CALL Lineout filename, "EA Backupfile 2..:" global.fnam_eabkup2
  394.         CALL Lineout filename, "Error listing....:" global.fnam_errfile
  395.         IF global.log <> 0 THEN DO
  396.            CALL Lineout filename, " "
  397.            CALL Lineout filename, "Log files........: *.LOG"
  398.            END
  399.         CALL Lineout filename, global.sepline
  400.         CALL Lineout filename
  401.  
  402.         IF rc > 0 THEN
  403.            CALL b2f_error "Could not create '" || filename || "' as an infofile.", "RC: " || rc
  404.  
  405.         IF global.debug <> 0 THEN DO
  406.            Say global.title || ": DEBUG: INFOFILE"
  407.            TYPE filename " | more "
  408.            END
  409.  
  410.         RETURN
  411.  
  412. /* b2f_info */
  413.  
  414. /* ----------------------------------------------------------------------- */
  415. /*      b2f_filelist                                                       */
  416. /* ----------------------------------------------------------------------- */
  417.  
  418. b2f_filelist : PROCEDURE EXPOSE global.
  419. Arg source target
  420.  
  421.         filename = target || "\" || global.fnam_listfile
  422.         rc = 0
  423.  
  424.         Say global.title || ": Creating filelist '" || filename || "' ..."
  425.  
  426.         CALL Lineout filename, "FILELIST"
  427.         CALL Lineout filename, global.sepline
  428.  
  429.         CALL SysFileTree source || "\" || global.filespec, "file", "FS"
  430.  
  431.         DO i=1 to file.0
  432.            CALL Lineout filename, file.i
  433.         END
  434.  
  435.         CALL Lineout filename, global.sepline
  436.         CALL Lineout filename, " " || file.0 || " files."
  437.         CALL Lineout filename, global.sepline
  438.         CALL Lineout filename
  439.  
  440.         IF rc > 0 THEN
  441.            CALL b2f_error "Could not create '" || filename || "' as a filelist.", "RC: " || rc
  442.  
  443.         IF global.debug <> 0 THEN DO
  444.            Say global.title || ": DEBUG: FILELIST"
  445.            TYPE filename " | more "
  446.            END
  447.  
  448.         RETURN
  449.  
  450. /* b2f_filelist */
  451.  
  452. /* ----------------------------------------------------------------------- */
  453. /*      b2f_ea_backup                                                      */
  454. /* ----------------------------------------------------------------------- */
  455.  
  456. b2f_ea_backup : PROCEDURE EXPOSE global.
  457. Arg source target
  458.  
  459.         IF SysSearchPath("PATH", global.eabckup_pgm) = "" THEN
  460.            CALL b2f_error "Could not find EABACKUP service:", "'" || global.eabckup_pgm "' must exist in Environment PATH"
  461.  
  462.         Say global.title || ": Spawning '" || global.eabckup_pgm || "' ..."
  463.         rc = 0
  464.  
  465.         IF global.log <> 0 THEN
  466.            global.eabckup_pgm source target,
  467.                     "/S /Q /I" global.eabckup_add,
  468.                     " > " target || "\EABACKUP.LOG"
  469.         ELSE
  470.            global.eabckup_pgm source target,
  471.                     "/S /Q /I" global.eabckup_add
  472.  
  473.         IF rc > 0 THEN
  474.            CALL b2f_error "Could not run EABACKUP service:", "'" || global.eabckup_pgm || "' terminated abnormally!", "RC: " || rc
  475.  
  476.         RETURN
  477.  
  478. /* b2f_ea_backup */
  479.  
  480. /* ----------------------------------------------------------------------- */
  481. /*      b2f_backup                                                         */
  482. /* ----------------------------------------------------------------------- */
  483.  
  484. b2f_backup : PROCEDURE EXPOSE global.
  485. Arg source target
  486.  
  487.         IF SysSearchPath("PATH", global.bckup_pgm) = "" THEN
  488.            CALL b2f_error "Could not find BACKUP service in path", "'" || global.bckup_pgm "' must exist in Environment PATH"
  489.  
  490.         tmpfile = target || "\" || "_list_.tmp"
  491.  
  492.         /* create a tmp file containg all filenames to be backuped */
  493.         CALL SysFileTree source || "\" || global.filespec, "file", "FS"
  494.         /* (I know that this "tree walking job" is done twice, but I prefered
  495.            an encapsulation of procedures. If you use another backup service
  496.            as ZOO you must use another way of specifying files either...) */
  497.  
  498.         offset = 38   /* column where filename starts in output of FileTree */
  499.         DO i=1 to file.0
  500.            filename = Substr(file.i, offset)
  501.            /* Say "filename: " filename */
  502.            CALL Lineout tmpfile, filename
  503.         END
  504.         CALL Lineout tmpfile
  505.  
  506.         IF global.debug <> 0 THEN DO
  507.            Say global.title || ": DEBUG: FILELIST FOR ZOO.EXE"
  508.            TYPE tmpfile " | more "
  509.            END
  510.  
  511.         Say global.title || ": Spawning '" || global.bckup_pgm || "' ..."
  512.         rc = 0
  513.  
  514.         IF global.log <> 0 THEN
  515.           TYPE tmpfile " | " ,
  516.                global.bckup_pgm "aPI" global.bckup_add,
  517.                target || "\" || global.fnam_backup,
  518.                " > " target || "\ZOO.LOG"
  519.         ELSE
  520.           TYPE tmpfile " | " ,
  521.                global.bckup_pgm "aPI" global.bckup_add,
  522.                target || "\" || global.fnam_backup
  523.  
  524.         /* it seems that something is wrong with ZOO.EXE
  525.            since it returns with an exitcode of "1"
  526.            although no errors occur... */
  527.         IF rc > 1 THEN
  528.            CALL b2f_error "Could not run BACKUP service:", "'" || global.bckup_pgm || "' terminated abnormally!", "RC: " || rc
  529.  
  530.         /* remove tmp file */
  531.         CALL SysFileDelete tmpfile
  532.  
  533.         RETURN
  534.  
  535. /* b2f_backup */
  536.  
  537. /* ----------------------------------------------------------------------- */
  538. /*      b2f_list_errors                                                    */
  539. /* ----------------------------------------------------------------------- */
  540.  
  541. b2f_list_errors : PROCEDURE EXPOSE global.
  542. Arg target
  543.  
  544.         /* examine all .LOG files */
  545.         CALL SysFileTree target || "\*.LOG", "file", "F"
  546.         offset = 38   /* column where filename starts in output of FileTree */
  547.         DO i=1 to file.0
  548.            filename = Substr(file.i, offset)
  549.            CALL b2f_list_errors_in_file filename
  550.         END
  551.         RETURN
  552.  
  553. /* b2f_list_errors target */
  554.  
  555. /* ----------------------------------------------------------------------- */
  556. /*      b2f_list_errors_in_file                                            */
  557. /* ----------------------------------------------------------------------- */
  558.  
  559. b2f_list_errors_in_file : PROCEDURE EXPOSE global.
  560. Arg filename
  561.  
  562.         Say global.title || ": Checking '" || filename || "' for errors ..."
  563.         linenum = 0;
  564.  
  565.         DO FOREVER
  566.            buffer = Linein(filename)
  567.            linenum = linenum + 1
  568.            IF Pos("error", buffer) > 0 THEN DO
  569.               Say "   #" || Format(linenum, 4) || ":  " Strip(buffer, "B")
  570.               END
  571.            IF lines(filename) = 0 THEN
  572.               LEAVE
  573.         END
  574.  
  575.         RETURN
  576.  
  577. /* b2f_list_errors_in_file */
  578.  
  579. /* <EOF> */
  580.  
  581.