home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 421.lha / EasyBackup / restore.c < prev    next >
C/C++ Source or Header  |  1990-09-29  |  14KB  |  544 lines

  1. /************************************************************/
  2. /* EasyBackup,Restore.c (c)1989 Oliver Enseling             */
  3. /************************************************************/
  4.  
  5. extern void     UserRequest(), EndRestore();
  6.  
  7. #define EndBackup EndRestore
  8.  
  9. #define DEUTSCH
  10.  
  11. #include "support.c"
  12. #include "restore.i"
  13.  
  14. LONG            TrackNr, ByteNr;
  15. int             Drive;
  16. char           *Dest, *Pattern;
  17. char            DirPath[FMSIZE] = "";
  18. BOOL            FoundInter = FALSE, FoundArchiviere = FALSE;
  19.  
  20. /* SetDate: Datum einer Datei setzen */
  21.  
  22. void
  23. SetDate(fn, ds)
  24.     char           *fn;
  25.     struct DateStamp *ds;
  26. {
  27.   struct StandardPacket *sp;
  28.   BPTR            fl, dl;
  29.   char           *buf;
  30.   char            name[80];
  31.  
  32.   if (fl = Lock(fn, SHARED_LOCK)) {
  33.     if (!(dl = ParentDir(fl))) {
  34.       UnLock(fl);
  35.       return;
  36.     }
  37.   } else
  38.     return;
  39.   UnLock(fl);
  40.   stcgfn(name, fn);
  41.   if (buf = AllocMem(strlen(name) + 2, MEMF_CLEAR | MEMF_PUBLIC)) {
  42.     strcpy(buf + 1, name);
  43.     buf[0] = strlen(name);
  44.     if (sp = AllocMem(sizeof(struct StandardPacket), MEMF_CLEAR | MEMF_PUBLIC)) {
  45.       struct Process *p = (struct Process *) FindTask(NULL);
  46.       sp->sp_Msg.mn_Node.ln_Name = (char *) &sp->sp_Pkt;
  47.       sp->sp_Pkt.dp_Link = &sp->sp_Msg;
  48.       sp->sp_Pkt.dp_Port = &p->pr_MsgPort;
  49.       sp->sp_Pkt.dp_Type = 34;
  50.       sp->sp_Pkt.dp_Arg2 = (LONG) dl;
  51.       sp->sp_Pkt.dp_Arg3 = (LONG) buf >> 2;
  52.       sp->sp_Pkt.dp_Arg4 = (LONG) ds;
  53.       PutMsg((struct MsgPort *) ((struct FileLock *) ((LONG) dl << 2))->fl_Task,
  54.              (struct Message *) sp);
  55.       WaitPort(&p->pr_MsgPort);
  56.       GetMsg(&p->pr_MsgPort);
  57.       FreeMem(sp, sizeof(*sp));
  58.     }
  59.     FreeMem(buf, buf[0] + 2);
  60.   }
  61.   UnLock(dl);
  62. }
  63.  
  64. /* NewDisk: neue Diskette anfordern */
  65.  
  66. LONG            DiskNr = 0, EndNr = 0x7fffffff;
  67. void
  68. NewDisk()
  69. {
  70.   char            buf[5];
  71.   LONG            dnr;
  72.  
  73.   TrackDiskBlock->iotd_Req.io_Length = 0;
  74.   DeviceCommand((struct IORequest *)TrackDiskBlock, (UWORD) TD_MOTOR);
  75.   DiskNr++;
  76.   do {
  77. #ifdef DEUTSCH
  78.     printf("Kopie-Diskette #%d in Laufwerk DF%d: einlegen.\n", DiskNr, Drive);
  79. #else
  80.     printf("Insert backup disk #%d in drive DF%d:\n", DiskNr, Drive);
  81. #endif
  82.     Beep(880, 25, 64);
  83.     WaitDisk(TrackDiskBlock);
  84.     ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, 0);
  85.     setmem(buf, 5, 0);
  86.     strncpy(buf, TrackBuffer, 4);
  87.     if (buf[0] != 'B') {
  88.       dnr = 0;
  89. #ifdef DEUTSCH
  90.       printf("Keine Kopie-Diskette !!!");
  91. #else
  92.       printf("Not a backup disk\n");
  93. #endif
  94.       UserRequest();
  95.     } else {
  96.       dnr = atoi(buf + 1);
  97. #ifdef DEUTSCH
  98.       if (dnr != DiskNr)
  99.         printf("Falsche Diskette #%d !!!\n", dnr);
  100. #else
  101.       if (dnr != DiskNr)
  102.         printf("Wrong disk #%d !!!\n", dnr);
  103. #endif
  104.     }
  105.   } while (dnr != DiskNr);
  106. #ifdef DEUTSCH
  107.   printf("Diskette OK\n");
  108. #else
  109.   printf("Disk OK\n");
  110. #endif
  111.   TrackNr = 0;
  112.   ByteNr = 8 + strlen(&TrackBuffer[8]) + 1;
  113.   strcpy(DirPath, &TrackBuffer[8]);
  114.   PrintDisk(DiskNr);
  115.   PrintTrack(0);
  116. }
  117.  
  118. /* RawGetByte: ein Byte aus dem Backup lesen */
  119.  
  120. BYTE
  121. RawGetByte()
  122. {
  123.   BYTE            b;
  124.  
  125.   ByteNr++;
  126.   if (ByteNr >= TRACK_SIZE) {
  127.     TrackNr++;
  128.     if (TrackNr >= MAX_TRACKS) {
  129. #ifdef DEUTSCH
  130.       printf("Diskette fertig reinstalliert\n");
  131. #else
  132.       printf("Disk completely reinstalled\n");
  133. #endif
  134.       NewDisk();
  135.     } else {
  136.       ByteNr = 0;
  137.       ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, TrackNr);
  138.       PrintTrack(TrackNr);
  139.     }
  140.   }
  141.   b = TrackBuffer[ByteNr];
  142.   return (b);
  143. }
  144.  
  145. /* Byte unter Berücksichtigung von Dateiendemarkierungen lesen */
  146.  
  147. BOOL            DateiEnde = FALSE;
  148.  
  149. char
  150. DecodeByte()
  151. {
  152.   char            b;
  153.   static unsigned char buffer;
  154.   static BOOL     buffer_on = FALSE;
  155.  
  156.   if (buffer_on) {
  157.     b = buffer;
  158.     buffer_on = FALSE;
  159.   } else
  160.     b = RawGetByte();
  161.   if (b == DATEIENDEMARKE) {
  162.     buffer = RawGetByte();
  163.     if (buffer == DATEIENDEMARKE) {
  164.       buffer_on = FALSE;
  165.       DateiEnde = FALSE;
  166.     } else {
  167.       buffer_on = TRUE;
  168.       DateiEnde = TRUE;
  169.     }
  170.     return (DATEIENDEMARKE);
  171.   } else {
  172.     DateiEnde = FALSE;
  173.     return (b);
  174.   }
  175. }
  176.  
  177. /* RawReadString: eine String mit Endung 0 aus dem Backup lesen */
  178.  
  179. void
  180. RawReadString(str)
  181.     char           *str;
  182. {
  183.   char            c;
  184.  
  185.   do {
  186.     c = DecodeByte();
  187.     *str++ = c;
  188.   } while (c != 0);
  189. }
  190.  
  191. /* RawRead: Anzahl Bytes aus dem Backup lesen */
  192.  
  193. void
  194. RawRead(buf, len)
  195.     BYTE           *buf;
  196.     LONG            len;
  197. {
  198.   LONG            i;
  199.  
  200.   for (i = 0; i < len; i++)
  201.     buf[i] = DecodeByte();
  202. }
  203.  
  204. /* EndRestore: Drive-Motor ausschalten + KontrollMsg ausgeben */
  205.  
  206. void
  207. EndRestore()
  208. {
  209.   TrackDiskBlock->iotd_Req.io_Length = 0;
  210.   DeviceCommand((struct IORequest *)TrackDiskBlock, (UWORD) TD_MOTOR);
  211. }
  212.  
  213. /*
  214.  * MakePath: testen, ob alle dirs zu einem kompletten Dateinamen
  215.  * vorhanden sind, ggf. neue dirs erstellen
  216.  */
  217.  
  218. void
  219. MakePath(path)
  220.     char           *path;
  221. {
  222.   char            buffer[512];
  223.   BPTR            lock;
  224.   char           *pos = path;
  225.  
  226.   while (pos = stpchr(pos + 1, '/')) {
  227.     strncpy(buffer, path, (int) pos - (int) path);
  228.     buffer[(int) pos - (int) path] = 0;
  229.     if (!(lock = Lock(buffer, ACCESS_READ)))
  230.       if (!(lock = CreateDir(buffer))) {
  231. #ifdef DEUTSCH
  232.         printf("Verzeichnis %s kann nicht erstellt werden.\n", buffer);
  233. #else
  234.         printf("Unable to create directory %s\n", buffer);
  235. #endif
  236.         UserRequest();
  237.         return;
  238.       }
  239.     UnLock(lock);
  240.   }
  241. }
  242.  
  243. /* RestoreFileData: Inhalt einer Datei lesen und in File kopieren */
  244.  
  245. void
  246. RestoreFileData(file)
  247.     int             file;
  248. {
  249.   BYTE            b;
  250.   LONG            i = 0;
  251.  
  252.   for (b = DecodeByte(); !DateiEnde; b = DecodeByte()) {
  253.     FileBuffer[i] = b;
  254.     i++;
  255.     if (i >= BUFFER_SIZE) {
  256.       write(file, FileBuffer, BUFFER_SIZE);
  257.       i = 0;
  258.     }
  259.   }
  260.   write(file, FileBuffer, i);
  261. }
  262.  
  263. /* Ende einer Datei suchen */
  264.  
  265. void
  266. GotoDateiEnde()
  267. {
  268.   BYTE            b;
  269.  
  270.   for (b = DecodeByte(); !DateiEnde; b = DecodeByte());
  271. }
  272.  
  273. /* RestoreDir: Verzeichnisse rekursiv reinstallieren */
  274.  
  275. BOOL
  276. RestoreDir(doinstall)
  277.     BOOL            doinstall;
  278. {
  279.   LONG            err, protection;
  280.   char            d[FMSIZE], filename[FMSIZE], path[FMSIZE], fullpath[FMSIZE],
  281.                   comment[116];
  282.   struct DateStamp date;
  283.   int             file;
  284.  
  285.   strcpy(d, DirPath);
  286.   FOREVER
  287.   {
  288.     err = 0;
  289.     if (DiskNr > EndNr)
  290.       CloseAll(0);
  291.     switch (DecodeByte()) {
  292.     case ID_DIR:
  293.       RawReadString(filename);
  294.       ConcatPath(DirPath, d, filename);
  295.       if (doinstall) {
  296. #ifdef DEUTSCH
  297.         printf("Verzeichnis \033[32m%s\033[0m ", DirPath);
  298. #else
  299.         printf("Directory   \033[32m%s\033[0m ", DirPath);
  300. #endif
  301.         if (FoundInter) {
  302.           if (FileAbfrage())
  303.             RestoreDir(TRUE);
  304.           else
  305.             RestoreDir(FALSE);
  306.         } else
  307.           RestoreDir(TRUE);
  308.       } else
  309.         RestoreDir(FALSE);
  310.       break;
  311.     case ID_ENDDIR:
  312.       return (TRUE);
  313.     case ID_FILE:
  314.       RawReadString(filename);
  315.       RawRead((BYTE *) & protection, sizeof(LONG));
  316.       RawRead((BYTE *) & date, sizeof(struct DateStamp));
  317.       RawReadString(comment);
  318.       ConcatPath(path, d, filename);
  319.       if (doinstall && (!Pattern || astcsma(path, Pattern))) {
  320.         BOOL            restorefile = TRUE;
  321.         ConcatPath(fullpath, Dest, path);
  322. #ifdef DEUTSCH
  323.         printf("Reinstallation von \033[33m%s\033[31m ... ", fullpath);
  324. #else
  325.         printf("reinstalling       \033[33m%s\033[31m ... ", fullpath);
  326. #endif
  327.         if (FoundInter)
  328.           restorefile = FileAbfrage();
  329.         if (restorefile) {
  330.           MakePath(fullpath);
  331.           if ((file = open(fullpath, O_WRONLY | O_CREAT)) != -1) {
  332.             RestoreFileData(file);
  333.             close(file);
  334.             if (FoundArchiviere)
  335.               protection |= FIBF_ARCHIVE;
  336.             SetProtection(fullpath, protection);
  337.             if (!(err = IoErr()))
  338.               {
  339.               SetComment(fullpath, comment);
  340.               if (!(err = IoErr()))
  341.                 {
  342.                 SetDate(fullpath, &date);
  343.                 }
  344.               }
  345.           }
  346.           else err = _OSERR;
  347.           if (err) {
  348. #ifdef DEUTSCH
  349.             printf("\nFehler bei der Reinstallation.\nDOS-Fehlernummer:%4d\n", err);
  350. #else
  351.             printf("\nError while reinstalling\nDOS-Error:%4d\n", err);
  352. #endif
  353.             UserRequest();
  354.           } else
  355.             printf("OK\n");
  356.         } else
  357.           GotoDateiEnde();
  358.       } else
  359.         GotoDateiEnde();
  360.       break;
  361.     default:
  362. #ifdef DEUTSCH
  363.       printf("Backupstruktur fehlerhaft !!!\n"
  364.              "Suche nächsten Eintrag\n");
  365. #else
  366.       printf("Error in backup structure\n"
  367.              "Searching next entry\n");
  368. #endif
  369.       GotoDateiEnde();
  370.     }
  371.   }
  372.   return (TRUE);
  373. }
  374.  
  375. /* Hauptprogramm: Parameter parsen, Error-Messages ausgeben */
  376.  
  377. void
  378. main(argc, argv)
  379.     int             argc;
  380.     char          **argv;
  381. {
  382.   BOOL            foundfrom = FALSE, foundto = FALSE, foundpattern = FALSE, foundstart = TRUE,
  383.                   foundend = FALSE;
  384.   char           *source;
  385.   int             i;
  386.  
  387.   printf("EasyBackup V1.0, Restore  ©1990 Oliver Enseling\n\n");
  388.   for (i = 1; i < argc; i++) {
  389. #ifdef DEUTSCH
  390.     if (stricmp(argv[i], "VON") == 0)
  391. #else
  392.     if (stricmp(argv[i], "FROM") == 0)
  393. #endif
  394.     {
  395.       foundfrom = TRUE;
  396.       i++;
  397.       source = argv[i];
  398.     } else {
  399. #ifdef DEUTSCH
  400.       if (stricmp(argv[i], "NACH") == 0)
  401. #else
  402.       if (stricmp(argv[i], "TO") == 0)
  403. #endif
  404.       {
  405.         foundto = TRUE;
  406.         i++;
  407.         Dest = argv[i];
  408.       } else {
  409. #ifdef DEUTSCH
  410.         if (stricmp(argv[i], "MUSTER") == 0)
  411. #else
  412.         if (stricmp(argv[i], "PATTERN") == 0)
  413. #endif
  414.         {
  415.           foundpattern = TRUE;
  416.           i++;
  417.           Pattern = argv[i];
  418.         } else {
  419. #ifdef DEUTSCH
  420.           if (stricmp(argv[i], "START") == 0)
  421. #else
  422.           if (stricmp(argv[i], "START") == 0)
  423. #endif
  424.           {
  425.             foundstart = TRUE;
  426.             i++;
  427.             stcd_l(argv[i], &DiskNr);
  428.             DiskNr--;
  429.           } else {
  430. #ifdef DEUTSCH
  431.             if (stricmp(argv[i], "ENDE") == 0)
  432. #else
  433.             if (stricmp(argv[i], "END") == 0)
  434. #endif
  435.             {
  436.               foundend = TRUE;
  437.               i++;
  438.               stcd_l(argv[i], &EndNr);
  439.             } else {
  440. #ifdef DEUTSCH
  441.               if (stricmp(argv[i], "INTERAKTIV") == 0)
  442. #else
  443.               if (stricmp(argv[i], "QUERY") == 0)
  444. #endif
  445.               {
  446.                 FoundInter = TRUE;
  447.               } else {
  448. #ifdef DEUTSCH
  449.                 if (stricmp(argv[i], "ARCHIVIERE") == 0)
  450. #else
  451.                 if (stricmp(argv[i], "ARCHIVATE") == 0)
  452. #endif
  453.                 {
  454.                   FoundArchiviere = TRUE;
  455.                 } else {
  456.                   if (!foundfrom) {
  457.                     source = argv[i];
  458.                     foundfrom = TRUE;
  459.                   } else {
  460.                     if (!foundto) {
  461.                       Dest = argv[i];
  462.                       foundto = TRUE;
  463.                     }
  464. #ifdef DEUTSCH
  465.                     else
  466.                       printf("Parameter \033[32m%s\033[31m wird ignoriert !\n");
  467. #else
  468.                     else
  469.                       printf("Argument \033[32m%sy\033[31m ignored\n");
  470. #endif
  471.                   }
  472.                 }
  473.               }
  474.             }
  475.           }
  476.         }
  477.       }
  478.     }
  479.   }
  480.   if (!(foundfrom && foundto)) {
  481. #ifdef DEUTSCH
  482.     printf("Syntax: Restore [VON] <laufwerk> [NACH] <ver> [MUSTER <muster>]\n"
  483.            "                [START <startnr>] [ENDE <endenr>] [INTERAKTIV]\n"
  484.            "                [ARCHIVIERE]\n"
  485.            "        laufwerk - Das Laufwerk, mit dem gearbeitet werden soll\n"
  486.            "        ver ------ Das Zielverzeichnis\n"
  487.            "        muster --- Ein AmigaDOS-übliches Muster, nur die Dateien,\n"
  488.       "                   die hierauf passen werden reinstalliert\n"
  489.            "        startnr -- Nummer der Diskette, bei der die Reinstallation\n"
  490.            "                   starten soll\n"
  491.            "        endenr --- Nummer der Diskette, bei der die Reinstallation\n"
  492.            "                   enden soll\n"
  493.            "        \n"
  494.            "        Die Schlüsselwörter VON und NACH können\n"
  495.            "        weggelassen werden.\n");
  496. #else
  497.     printf("Usage: Restore [FROM] <drive> [TO] <dir> [PATTERN <pattern>]\n"
  498.            "               [START <startno>] [END <endno>] [QUERY] [ARCHIVATE]\n"
  499.            "       drive ---- Disk drive for backup disks\n"
  500.            "       dir ------ Target directory for restoration\n"
  501.            "       pattern -- standard pattern for wildcard pattern matching like\n"
  502.            "                  AmigaDOS commands to select files to be restored\n"
  503.            "       startno -- first disk to be restored\n"
  504.            "       endno ---- last disk to be restored\n"
  505.            "       keywords FROM and TO can be left out\n");
  506. #endif
  507.     CloseAll(1);
  508.   }
  509.   Drive = -1;
  510.   if (stricmp("DF0:", source) == 0)
  511.     Drive = 0;
  512.   if (stricmp("DF1:", source) == 0)
  513.     Drive = 1;
  514.   if (stricmp("DF2:", source) == 0)
  515.     Drive = 2;
  516.   if (stricmp("DF3:", source) == 0)
  517.     Drive = 3;
  518.   if (Drive < 0) {
  519. #ifdef DEUTSCH
  520.     printf("Falsches Diskettenlaufwerk %s !!!\n", source);
  521. #else
  522.     printf("Wrong disk drive %s\n", source);
  523. #endif
  524.     CloseAll(5);
  525.   }
  526.   OpenAll(Drive);
  527.   NewDisk();
  528.   ByteNr--;
  529.   if (DiskNr > 1)
  530.     GotoDateiEnde();
  531. #ifdef DEUTSCH
  532.   if (RestoreDir(TRUE))
  533.     printf("Reinstallation komplett\n");
  534.   else
  535.     printf("Reinstallation abgebrochen\n");
  536. #else
  537.   if (RestoreDir(TRUE))
  538.     printf("Restoration complete\n");
  539.   else
  540.     printf("Restoration aborted\n");
  541. #endif
  542.   CloseAll(0);
  543. }
  544.