home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d01xx / d0128.lha / MRBackup / Restore.c < prev    next >
C/C++ Source or Header  |  1988-01-02  |  7KB  |  295 lines

  1. /* Filename:    restore.c
  2.  * Author:        Mark R. Rinfret
  3.  * Date:        08/02/87
  4.  * Description:    Restore processing module for MRBackup
  5.  *
  6.  * History:        (most recent change first)
  7.  *
  8.  * 09/19/87 -MRR- Added NewHomeDir() which creates subdirectories as
  9.  *                necessary when the initial backup path specifies a
  10.  *                subdirectory.
  11.  */
  12.  
  13.  
  14. #include "MRBackup.h"
  15.  
  16. #ifdef DEBUG
  17. extern char debugmsg[];
  18. #endif
  19.  
  20. static char fullbackpath[256], fullhomepath[256];
  21.  
  22. static unsigned home_is_device;        /* true => home is "DH<N>:" */
  23.  
  24.  
  25. /* Create a new directory on the home device.
  26.  * Called with:
  27.  *        name:        directory pathname
  28.  * Returns:
  29.  *        false => success
  30.  *        true  => failure
  31.  */
  32. int
  33. NewHomeDir(name)
  34.     char   *name;
  35. {
  36.     char c;
  37.     struct Lock *dirlock;
  38.     int dirleng;
  39.     int errnum;
  40.     char dirname[256];
  41.     int nameindx = 0, nameleng;
  42.  
  43.     *dirname = '\0';
  44.     dirleng = 0;
  45.     nameleng = strlen(name);
  46.  
  47.     /* Parse the pathname, one directory node at a time, creating
  48.      * directories as needed.
  49.      */
  50.  
  51.     while (nameindx < nameleng) {
  52.         if (nameindx)                /* 2nd - nth pass? */
  53.             dirname[dirleng++] = '/'; /* directory separator */
  54.         while ((c = name[nameindx++]) && c != '/')
  55.             dirname[dirleng++] = c;
  56.         dirname[dirleng] = '\0';    /* terminate with null */
  57.         if (dirlock = Lock(dirname,SHARED_LOCK)) /* subdir exists? */
  58.             UnLock(dirlock);
  59.         else {                        /* create subdirectory */
  60.             if ((dirlock = CreateDir(dirname))== NULL){
  61.                 if ((errnum = IoErr())== ERROR_DIRECTORY_NOT_EMPTY){
  62.                     sprintf(conmsg,
  63.                         "Directory %s already exists!\n",dirname);
  64.                     TypeAndSpeak(conmsg);
  65.                 }
  66.                 else {
  67.                     sprintf(conmsg,
  68.                         "ERROR %d: Unable to create directory %s\n",
  69.                         errnum,dirname);
  70.                     TypeAndSpeak(conmsg);
  71.                     return errnum;
  72.                 }
  73.             }
  74.             else
  75.                 UnLock(dirlock);
  76.         }
  77.     }                                /* endwhile */
  78.     return 0;
  79. }
  80. /* Restore files from floppy disk. */
  81.  
  82. int
  83. Restore()
  84. {
  85.     int status = 0;
  86.  
  87.     Speak("And away we go!");
  88.  
  89.     if (!IsDir(backpath)) {
  90.         TypeAndSpeak("Backup path must be a device or directory name!\n");
  91.         return ERR_ABORT;
  92.     }
  93.  
  94.     BreakPath(backpath, srcvol, srcpath);
  95.  
  96.     home_is_device = (homepath[strlen(homepath)-1] == ':');
  97.  
  98.     status = RestoreFile(srcpath);
  99.     if (status == 0) {
  100.         TypeAndSpeak("Your restoration project is completed, sire.\n");
  101.     }
  102.     else {
  103.         sprintf(conmsg,"Restore terminated with status %d.\n",status);
  104.         TypeAndSpeak(conmsg);
  105.         TypeAndSpeak(
  106.             "Perhaps you should check things out and try it again.\n");
  107.     }
  108.     return status;
  109. }
  110.  
  111. /* Restore all the files in a directory.
  112.  * Called with:
  113.  *        lock:        lock on the directory
  114.  *        fib:        pointer to file info block
  115.  *        path:        directory pathname (without volume)
  116.  * Returns:
  117.  *        status (0 => success)
  118.  */
  119. int
  120. RestoreDir(lock, fib, path)
  121.     struct Lock *lock; struct FileInfoBlock *fib; char *path;
  122. {
  123.     struct Lock *dirlock = NULL, *filelock = NULL;
  124.     char newpath[256];
  125.     int status = 0;
  126.  
  127.     strcpy(temp, homepath);
  128.     if (*path) {
  129.         if (!home_is_device) strcat(temp, "/");
  130.         strcat(temp, path);
  131.     }
  132. #ifdef DEBUG
  133.     sprintf(debugmsg,"Checking for directory %s\n",temp);
  134.     DebugWrite(debugmsg);
  135. #endif
  136.     if (!(dirlock = Lock(temp, SHARED_LOCK))) {
  137.         if ((status = IoErr()) == ERROR_OBJECT_NOT_FOUND) {
  138. #ifdef DEBUG
  139.             sprintf(debugmsg,"Creating directory %s\n",temp);
  140.             DebugWrite(debugmsg);
  141. #endif
  142.             if (status = NewHomeDir(temp))
  143.                 return status;
  144.         }
  145.         else {
  146.             sprintf(conmsg,"RestoreDir cannot lock %s: %d\n",temp, status);
  147.             TypeAndSpeak(conmsg);
  148.             return status;
  149.         }
  150.     }
  151.     if (dirlock) UnLock(dirlock);
  152.  
  153.     while (ExNext(lock,fib)) {
  154.         strcpy(newpath, path);
  155.         if (*newpath)
  156.             strcat(newpath, "/");
  157.         strcat(newpath, fib->fib_FileName);
  158.         if (status = RestoreFile(newpath)) {
  159.  
  160.             /* filter out "permissable:" errors */
  161.  
  162.             if (status == ERROR_OBJECT_IN_USE ||
  163.                 status == ERROR_WRITE_PROTECTED)
  164.                 status = 0;
  165.             else
  166.                 break;
  167.         }
  168.     }
  169. done:
  170.     return status;
  171. }
  172.  
  173. /* Restore one or more files according to the calling pathname.
  174.  * The path argument does not contain the backup volume name.
  175.  */
  176. int
  177. RestoreFile(path)
  178.     char *path;
  179. {
  180.     struct FileInfoBlock *fib = NULL, *fib2 = NULL;
  181.     UBYTE exists = FALSE, ignore = FALSE;
  182.     struct Lock *lock = NULL;
  183.     USHORT namelength;
  184.     UBYTE savechar;
  185.     int status = 0;
  186.  
  187.     if (status = CheckStop()) return status;
  188.  
  189.     if (!(fib = (struct FileInfoBlock *)
  190.         AllocMem((long) sizeof (struct FileInfoBlock), 
  191.                     MEMF_PUBLIC | MEMF_CHIP))) {
  192.         TypeAndSpeak("RestoreFile could not allocate FIB!\n");
  193.         return ERROR_NO_FREE_STORE;
  194.     }
  195.  
  196.     sprintf(fullbackpath, "%s:%s",srcvol,path);
  197.     strcpy(fullhomepath, homepath);
  198.     if (*path) {
  199.         if (!home_is_device) strcat(fullhomepath, "/");
  200.         strcat(fullhomepath, path);
  201.     }
  202.  
  203. #ifdef DEBUG
  204.         sprintf(conmsg,"fullbackpath = %s\n",fullbackpath);
  205.         DebugWrite(conmsg);
  206.         sprintf(conmsg,"fullhomepath = %s\n",fullhomepath);
  207.         DebugWrite(conmsg);
  208. #endif
  209.  
  210.     if (!(lock = Lock(fullbackpath, SHARED_LOCK))) {
  211.         status = IoErr();
  212.         sprintf(conmsg, "RestoreFile: can't lock %s: %d\n",
  213.                 fullbackpath, status);
  214.         TypeAndSpeak(conmsg);
  215.         goto done;
  216.     }
  217.  
  218.     if (!Examine(lock, fib)) {
  219.         status = IoErr();
  220.         sprintf(conmsg, "RestoreFile can't examine %s: %d\n", 
  221.                 fullbackpath, status);
  222.         TypeAndSpeak(conmsg);
  223.         goto done;
  224.     }
  225.  
  226.     if (fib->fib_DirEntryType > 0) {    /* path is a directory */
  227.         status = RestoreDir(lock, fib, path);
  228.         UnLock(lock);
  229.         lock = NULL;
  230.     }
  231.     else {
  232.         UnLock(lock);
  233.         lock = NULL;
  234. /*#define NOCOPY*/
  235. #ifndef NOCOPY
  236.         /* If this file exists, then check its modification date.  If
  237.          * it's newer than the backup, don't replace it.
  238.          */
  239.  
  240.         if ((lock = Lock(fullhomepath, SHARED_LOCK))) {
  241.  
  242.             if (!(fib2 = (struct FileInfoBlock *)
  243.                 AllocMem((long) sizeof (struct FileInfoBlock), 
  244.                             MEMF_PUBLIC | MEMF_CHIP))) {
  245.                 TypeAndSpeak("RestoreFile could not allocate FIB!\n");
  246.                 status = ERROR_NO_FREE_STORE;
  247.                 goto done;
  248.             }
  249.             Examine(lock, fib2);
  250.             UnLock(lock);
  251.             lock = NULL;
  252.             if (CompareDS(&fib2->fib_Date, &fib->fib_Date) >= 0)
  253.                 ignore = TRUE;
  254.         }
  255.         if (ignore) {
  256.             sprintf(conmsg,"Skipping %s.  Current version is newer.\n",
  257.                     path);
  258.             TypeAndSpeak(conmsg);
  259.         }
  260.         else {
  261.             if (!do_compress || !IsCompressed(fullhomepath)) {
  262. copyfile:
  263.                 sprintf(conmsg,"Copying %s\n", fullbackpath);
  264.                 WriteConsole(conmsg);
  265.                 status = CopyFile(fullbackpath, fullhomepath);
  266.             }
  267.             else {
  268.                 /* truncate the destination pathname (remove ".z") */
  269.  
  270.                 namelength = strlen(fullhomepath);
  271.                 fullhomepath[namelength-2] = '\0';
  272.                 sprintf(conmsg, "Decompressing %s\n", fullbackpath);
  273.                 WriteConsole(conmsg);
  274.                 if (status = decompress(fullbackpath, fullhomepath)) {
  275.                     sprintf(conmsg, 
  276.                         "Decompression of %s failed;  status is %d.\n",
  277.                         fullbackpath, status);
  278.                     TypeAndSpeak(conmsg);
  279.                     TypeAndSpeak("I will try to copy the file, instead.\n");
  280.                     /* restore ".z" to name */
  281.                     fullhomepath[namelength-2] = '.'; 
  282.                     goto copyfile;
  283.                 }
  284.                 CopyFileDate(fullbackpath, fullhomepath);
  285.             }
  286.         }
  287. #endif
  288.     }
  289. done:
  290.     if (lock) UnLock(lock);
  291.     if (fib) FreeMem(fib, (long) sizeof(struct FileInfoBlock));
  292.     if (fib2) FreeMem(fib2, (long) sizeof(struct FileInfoBlock));
  293.     return status;
  294. }
  295.