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

  1. /******************************************************/
  2. /* EasyBackup, Backup.c (c)1989 Oliver Enseling       */
  3. /******************************************************/
  4.  
  5. extern void     EndBackup(), UserRequest();
  6.  
  7.  
  8.  
  9. #include "support.c"
  10.  
  11. long            CompDate[3];           /* DateStamp zum vergleichen */
  12. int             Drive;                 /* Nummer des selektierten
  13.                                         * Disk-Drives */
  14. char           *Source;                /* Source-Directorypath */
  15. char            Buffer[FMSIZE];        /* Hilfspuffer zum
  16.                                         * "Zusammenbau" des ganzen
  17.                                         * filenamens */
  18. char            DirPath[FMSIZE] = "";  /* aktueller Directorypath */
  19. BOOL            FoundInter = FALSE, FoundArchiviere = FALSE, FoundArchivstatus = FALSE;
  20. FILE           *ListFile = NULL;
  21.  
  22. /* Variablen */
  23.  
  24. LONG            TrackNr, ByteNr;
  25.  
  26. /* NewDisk: neue Diskette anfordern */
  27.  
  28. LONG            DiskNr;
  29. void
  30. NewDisk()
  31. {
  32.   BOOL            diskcorrect;
  33.   char            buf[5];
  34.  
  35.   TrackDiskBlock->iotd_Req.io_Length = 0;       /* Drive-Motor aus */
  36.   DeviceCommand(TrackDiskBlock, (UWORD) TD_MOTOR);
  37.   DiskNr++;
  38.   do {
  39.     setmem(buf, 5, 0);
  40.     Beep(880, 25, 64);
  41. #ifdef DEUTSCH
  42.     printf("Neue Kopie-Diskette #%d in Laufwerk DF%d: einlegen\n", DiskNr,
  43.            Drive);
  44. #else
  45.     printf("Insert new backup disk #%d in drive DF%d:", DiskNr, Drive);
  46. #endif
  47.     WaitDisk(TrackDiskBlock);
  48.     ReadTrack(TrackDiskBlock,
  49.               &TrackBuffer[TRACK_SIZE], LabelBuffer, 0);
  50.     strncpy(buf, &TrackBuffer[TRACK_SIZE], 4);
  51.     if (buf[0] != 'B')
  52.       diskcorrect = TRUE;
  53.     else {
  54.       int             dnr = atoi(buf + 1);
  55.  
  56.       if (dnr < DiskNr && dnr > 0) {
  57. #ifdef DEUTSCH
  58.         printf("Achtung Kopie-Diskette #%d wird überschrieben !!!\n", dnr);
  59.         printf("Diskette wechseln ? ");
  60. #else
  61.         printf("Old backup disk #%d is being overwritten\n", dnr);
  62.         printf("Change disk ? ");
  63. #endif
  64.         diskcorrect = FileAbfrage();
  65.       } else
  66.         diskcorrect = TRUE;
  67.     }
  68.   } while (!diskcorrect);
  69. #ifdef DEUTSCH
  70.   printf("Diskette OK\n");
  71. #else
  72.   printf("Disk OK\n");
  73. #endif
  74.   sprintf(TrackBuffer, "B%d%d%d", DiskNr / 100 % 10, DiskNr / 10 % 10,
  75.           DiskNr % 10);
  76.   setmem(&TrackBuffer[4], 4, 0xff);
  77.   TrackNr = 0;
  78.   ByteNr = 0;
  79.   PrintDisk(DiskNr);
  80.   PrintTrack(0);
  81. }
  82.  
  83. /* FormatTrack: einen Track formatieren */
  84.  
  85. void
  86. FormatTrack(db, nr, buf)
  87.     struct IOExtTD *db;
  88.     LONG            nr;
  89.     BYTE           *buf;
  90. {
  91.   PrintTrack((nr + 1) % MAX_TRACKS);
  92.   FOREVER
  93.   {
  94.     DeviceCommand(db, (UWORD) TD_CHANGENUM);
  95.     db->iotd_Count = db->iotd_Req.io_Actual;
  96.     db->iotd_Req.io_Data = (APTR) buf;
  97.     db->iotd_Req.io_Length = (ULONG) TRACK_SIZE;
  98.     db->iotd_Req.io_Offset = nr * TRACK_SIZE;
  99.     DeviceCommand(db, (UWORD) ETD_FORMAT);
  100.     if (db->iotd_Req.io_Error) {
  101. #ifdef DEUTSCH
  102.       printf("Fehler beim Schreiben auf Spur #%d:\n%s\n",
  103.              nr, TrackDiskError((LONG) db->iotd_Req.io_Error));
  104. #else
  105.       printf("Error writing track #%d:\n%s\n",
  106.              nr, TrackDiskError((LONG) db->iotd_Req.io_Error));
  107. #endif
  108.       UserRequest();
  109.     } else
  110.       break;
  111.   }
  112. }
  113.  
  114. /* RawPutByte: ein Byte in ein Backup schreiben */
  115.  
  116. void
  117. RawPutByte(b)
  118.     BYTE            b;
  119. {
  120.   ByteNr++;
  121.   if (ByteNr >= TRACK_SIZE) {
  122.     TrackNr++;
  123.     if (TrackNr >= MAX_TRACKS) {
  124. #ifdef DEUTSCH
  125.       printf("Diskette voll\n");
  126. #else
  127.       printf("Disk full\n");
  128. #endif
  129.       NewDisk();
  130.     } else if (TrackNr != MAX_TRACKS - 1)
  131.       ByteNr = 0;
  132.     else {
  133.       strcpy(&TrackBuffer[8], DirPath);
  134.       ByteNr = strlen(&TrackBuffer[8]) + 1 + 8;
  135.     }
  136.     FormatTrack(TrackDiskBlock, TrackNr, TrackBuffer);
  137.   }
  138.   TrackBuffer[ByteNr] = b;
  139. }
  140.  
  141. /* Bytes mit Dateiendemarkierung kodieren */
  142.  
  143. void
  144. EncodeByte(b)
  145.     char            b;
  146. {
  147.   if (b == DATEIENDEMARKE) {
  148.     RawPutByte(DATEIENDEMARKE);
  149.     RawPutByte(DATEIENDEMARKE);
  150.   } else
  151.     RawPutByte(b);
  152. }
  153.  
  154. /* RawWrite: Anzahl Bytes auf das Backup schreiben */
  155.  
  156. void
  157. RawWrite(buf, len)
  158.     BYTE           *buf;
  159.     LONG            len;
  160. {
  161.   LONG            i;
  162.  
  163.   for (i = 0; i < len; i++)
  164.     EncodeByte(buf[i]);
  165. }
  166.  
  167. /*
  168.  * ByteCount: Anzahl der aufeinanderfolgenden gleichen Bytes
  169.  * ermitteln
  170.  */
  171.  
  172. LONG
  173. ByteCount(begin, max)
  174.     UBYTE          *begin, *max;
  175. {
  176.   int             count;
  177.   UBYTE           b;
  178.  
  179.   b = *begin;
  180.   for (count = 0L; count < 255L; count++)
  181.     if ((begin[count] != b) || ((UBYTE *) (begin + count) > max))
  182.       break;
  183.   return (count);
  184. }
  185.  
  186. /*
  187.  * EndBackup: Backup beenden / letzten Buffer schreiben + Endmarke
  188.  * setzen Drive-Motor ausschalten
  189.  */
  190.  
  191. void
  192. EndBackup()
  193. {
  194.   LONG            diskfull;
  195.  
  196.   diskfull = (TrackNr + 1) * TRACK_SIZE + ByteNr;
  197.   RawPutByte(ID_ENDDIR);
  198.   ByteNr = TRACK_SIZE - 1;
  199.   RawPutByte((BYTE) - 1);
  200.   ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, 0);
  201.   memcpy(&TrackBuffer[4], (char *) &diskfull, 4);
  202.   FormatTrack(TrackDiskBlock, 0, TrackBuffer);
  203.   TrackDiskBlock->iotd_Req.io_Length = 0;       /* Drive-Motor aus */
  204.   DeviceCommand(TrackDiskBlock, (UWORD) TD_MOTOR);
  205. }
  206.  
  207. /*
  208.  * BackupFile: ein File überprüfen, ggf. packen und auf die
  209.  * BackupDisk schreiben
  210.  */
  211.  
  212. BOOL
  213. BackupFile(path, fib)
  214.     char           *path;
  215.     struct FileInfoBlock *fib;
  216. {
  217.   LONG            ssize = fib->fib_Size;
  218.   int             file;
  219.   char           *fn = fib->fib_FileName;
  220.  
  221.   ConcatPath(Buffer, Source, path);
  222.   if (datecmp((long *) &fib->fib_Date, CompDate) < 0) {
  223.     if (FoundArchivstatus && (fib->fib_Protection & FIBF_ARCHIVE))
  224.       return (TRUE);
  225. #ifdef DEUTSCH
  226.     printf("Kopie für \033[33m%s\033[0m %d Bytes ... ", Buffer, fib->fib_Size);
  227. #else
  228.     printf("Backup for \033[33m%s\033[0m %d Bytes ... ", Buffer, fib->fib_Size);
  229. #endif
  230.     if (FoundInter)
  231.       if (!FileAbfrage())
  232.         return (TRUE);
  233.     RawPutByte(ID_FILE);
  234.     RawWrite(fn, strlen(fn) + 1);
  235.     RawWrite((BYTE *) & fib->fib_Protection, sizeof(fib->fib_Protection));
  236.     if (FoundArchiviere) {
  237.       fib->fib_Protection |= FIBF_ARCHIVE;
  238.       SetProtection(Buffer, fib->fib_Protection);
  239.     }
  240.     RawWrite((BYTE *) & fib->fib_Date, sizeof(fib->fib_Date));
  241.     RawWrite(fib->fib_Comment, strlen(fib->fib_Comment) + 1);
  242.     if (ListFile)
  243.       fprintf(ListFile, "%8d%5d%5d %-51s%9d\n",
  244.          DiskNr, (TrackNr + 1) / 2, (TrackNr + 1) % 2, path, ssize);
  245.     if (ssize > 0) {
  246.       if ((file = open(Buffer, O_RDONLY, 0)) != -1) {
  247.         LONG            remain;
  248.  
  249.         for (remain = ssize; remain > BUFFER_SIZE; remain -= BUFFER_SIZE) {
  250.           read(file, FileBuffer, BUFFER_SIZE);
  251.           RawWrite(FileBuffer, BUFFER_SIZE);
  252.         }
  253.         read(file, FileBuffer, remain);
  254.         RawWrite(FileBuffer, remain);
  255.         close(file);
  256.         printf("OK\n");
  257.       } else {
  258. #ifdef DEUTSCH
  259.         printf("Lesefehler, DOS-Fehlernummer: %d\n", _OSERR);
  260. #else
  261.         poserr(Buffer);
  262. #endif
  263.         UserRequest();
  264.       }
  265.       RawPutByte(DATEIENDEMARKE);
  266.       return ((BOOL) (file > 0));
  267.     } else {
  268. #ifdef DEUTSCH
  269.       printf("Leere Datei --> 0 Bytes\n");
  270. #else
  271.       printf("Empty file --> 0 Bytes\n");
  272. #endif
  273.       RawPutByte(DATEIENDEMARKE);
  274.       return (TRUE);
  275.     }
  276.   }
  277.   return (TRUE);
  278. }
  279.  
  280. /* ein Verzeichnis "backuppen" */
  281.  
  282. BOOL
  283. BackupDir(path, fib)
  284.     char           *path;
  285.     struct FileInfoBlock *fib;
  286. {
  287.   char           *dn = fib->fib_FileName;
  288.  
  289.   if (datecmp((long *) &fib->fib_Date, CompDate) >= 0)
  290.     return (FALSE);
  291.   if (FoundArchivstatus && (fib->fib_Protection & FIBF_ARCHIVE))
  292.     return (FALSE);
  293.   strcpy(DirPath, path);
  294.   ConcatPath(Buffer, Source, path);
  295.   if (datecmp((long *) &fib->fib_Date, CompDate) < 0) {
  296. #ifdef DEUTSCH
  297.     printf("Verzeichnis \033[33;2m%s\033[0m", Buffer);
  298. #else
  299.     printf("Directory \033[33;2m%s\033[0m", Buffer);
  300. #endif
  301.     if (FoundInter) {
  302.       if (!FileAbfrage())
  303.         return (FALSE);
  304.     } else
  305.       printf("\n");
  306.     RawPutByte(ID_DIR);
  307.     RawWrite(dn, strlen(dn) + 1);
  308.     return (TRUE);
  309.   } else
  310.     return (FALSE);
  311. }
  312.  
  313. /* BackupEndDir: ENDE-Markierung für ein Verzeichnis "backuppen" */
  314.  
  315. void
  316. BackupEndDir()
  317. {
  318.   RawPutByte(ID_ENDDIR);
  319. }
  320.  
  321. /* BackupTree: Verzeichnisbaum rekursiv backuppen */
  322.  
  323. BOOL
  324. BackupTree(s)
  325.     char           *s;
  326. {
  327.   struct FileInfoBlock *fib;
  328.   BOOL            ok = TRUE;
  329.   LONG            err;
  330.   char            path[FMSIZE];
  331.   BPTR            lock;
  332.  
  333.   ConcatPath(Buffer, Source, s);
  334.   if (fib = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR | MEMF_CHIP)) {
  335.     if (lock = Lock(Buffer, ACCESS_READ)) {
  336.       if (Examine(lock, fib)) {
  337.         while (ok && ExNext(lock, fib)) {
  338.           ConcatPath(path, s, fib->fib_FileName);
  339.           if (fib->fib_DirEntryType > 0) {
  340.             if (BackupDir(path, fib)) {
  341.               ok = BackupTree(path);
  342.               BackupEndDir();
  343.             }
  344.           } else
  345.             ok = BackupFile(path, fib);
  346.         }
  347.       }
  348.       UnLock(lock);
  349.     }
  350.     FreeMem(fib, sizeof(struct FileInfoBlock));
  351.   } else {
  352.     ok = FALSE;
  353. #ifdef DEUTSCH
  354.     printf("Nicht genügend Speicher für den FileInfoBlock !!!\n");
  355. #else
  356.     printf("Not enough memory for FileInfoBlock\n");
  357. #endif
  358.   }
  359.   if (err = IoErr())
  360.     if (!(ok = (err == ERROR_NO_MORE_ENTRIES))) {
  361. #ifdef DEUTSCH
  362.       printf("Fehler beim Lesen des Verzeichnisses.\n"
  363.              "DOS-Fehlernummer:%4d\n", err);
  364. #else
  365.       printf("Error reading directory.\n"
  366.              "DOS-Error:%4d\n", err);
  367. #endif
  368.       UserRequest();
  369.     }
  370.   return (ok);
  371. }
  372.  
  373. /* Umwandlung von String nach DateStamp */
  374.  
  375. BYTE            MonthDays[12] =
  376. {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  377. LONG            LeapYears = 0x44444444;
  378. BOOL
  379. StrToDs(s, ds)
  380.     char           *s;
  381.     struct DateStamp *ds;
  382. {
  383.   int             i, d = atoi(s), m = atoi(&s[3]), y = atoi(&s[6]) - 78;
  384.  
  385.   if ((d > 0) && (m > 0) && (y >= 0)) {
  386.     for (i = 0; i < y; i++)
  387.       ds->ds_Days += LeapYears & (1 << i) ? 366 : 365;
  388.     for (i = 0; i < m - 1; i++)
  389.       ds->ds_Days += MonthDays[i];
  390.     ds->ds_Days += d - 1 + ((LeapYears & (1 << y)) && (m > 2) ? 1 : 0);
  391.     return (TRUE);
  392.   }
  393.   return (FALSE);
  394. }
  395.  
  396. /* Hauptprogramm: Parameter parsen, Error-Messages ausgeben */
  397.  
  398. void
  399. main(argc, argv)
  400.     int             argc;
  401.     char          **argv;
  402. {
  403.   BOOL            foundfrom = FALSE, foundto = FALSE, foundsince = FALSE, foundappend = FALSE,
  404.                   foundliste = FALSE;
  405.   char           *dest, *date, *listname;
  406.   int             i;
  407.   FILE           *file;
  408.  
  409.   printf("EasyBackup V1.0, Backup  ©1990 Oliver Enseling\n\n");
  410.   for (i = 1; i < argc; i++) {
  411. #ifdef DEUTSCH
  412.     if (stricmp(argv[i], "VON") == 0)
  413. #else
  414.     if (stricmp(argv[i], "FROM") == 0)
  415. #endif
  416.     {
  417.       foundfrom = TRUE;
  418.       i++;
  419.       Source = argv[i];
  420.     } else {
  421. #ifdef DEUTSCH
  422.       if (stricmp(argv[i], "NACH") == 0)
  423. #else
  424.       if (stricmp(argv[i], "TO") == 0)
  425. #endif
  426.       {
  427.         foundto = TRUE;
  428.         i++;
  429.         dest = argv[i];
  430.       } else {
  431. #ifdef DEUTSCH
  432.         if (stricmp(argv[i], "SEIT") == 0)
  433. #else
  434.         if (stricmp(argv[i], "SINCE") == 0)
  435. #endif
  436.         {
  437.           foundsince = TRUE;
  438.           i++;
  439.           date = argv[i];
  440.         } else {
  441. #ifdef DEUTSCH
  442.           if (stricmp(argv[i], "ERWEITERN") == 0)
  443. #else
  444.           if (stricmp(argv[i], "APPEND") == 0)
  445. #endif
  446.               {
  447.             foundappend = TRUE;
  448.             i++;
  449.             DiskNr = atoi(argv[i]);
  450.             if (DiskNr < 1)
  451.               DiskNr = 1;
  452.           } else {
  453. #ifdef DEUTSCH
  454.             if (stricmp(argv[i], "INTERAKTIV") == 0)
  455. #else
  456.             if (stricmp(argv[i], "QUERY") == 0)
  457. #endif
  458.             {
  459.               FoundInter = TRUE;
  460.             } else {
  461. #ifdef DEUTSCH
  462.               if (stricmp(argv[i], "LISTE") == 0)
  463. #else
  464.               if (stricmp(argv[i], "LIST") == 0)
  465. #endif
  466.               {
  467.                 foundliste = TRUE;
  468.                 i++;
  469.                 listname = argv[i];
  470.               } else {
  471. #ifdef DEUTSCH
  472.                 if (stricmp(argv[i], "ARCHIVIERE") == 0)
  473. #else
  474.                 if (stricmp(argv[i], "ARCHIVATE") == 0)
  475. #endif
  476.                 {
  477.                   FoundArchiviere = TRUE;
  478.                 } else {
  479. #ifdef DEUTSCH
  480.                   if (stricmp(argv[i], "ARCHIVSTATUS") == 0)
  481. #else
  482.                   if (stricmp(argv[i], "CHECKARCHIVE") == 0)
  483. #endif
  484.                   {
  485.                     FoundArchivstatus = TRUE;
  486.                   } else {
  487.                     if (!foundfrom) {
  488.                       Source = argv[i];
  489.                       foundfrom = TRUE;
  490.                     } else {
  491.                       if (!foundto) {
  492.                         dest = argv[i];
  493.                         foundto = TRUE;
  494.                       }
  495. #ifdef DEUTSCH
  496.                       else
  497.                         printf("Parameter \033[32m%s\033[31m wird ignoriert !\n",
  498.                                argv[i]);
  499. #else
  500.                       else
  501.                         printf("Argument \033[32m%s\033[31m ignored\n", argv[i]);
  502. #endif
  503.                     }
  504.                   }
  505.                 }
  506.               }
  507.             }
  508.           }
  509.         }
  510.       }
  511.     }
  512.   }
  513.   if (!(foundfrom && foundto)) {
  514. #ifdef DEUTSCH
  515.     printf("Syntax: Backup [VON] <ver> [NACH] <laufwerk> [SEIT <datum>|ZULETZT]\n"
  516.            "               [ERWEITERN <disk>] [INTERAKTIV] [LISTE <listfile>]\n"
  517.            "               [ARCHIVIERE] [ARCHIVSTATUS]\n"
  518.            "       ver ------ Das zu kopierende Verzeichnis\n"
  519.            "       laufwerk - Das Laufwerk mit dem gearbeitet wird\n"
  520.            "       datum ---- Das Datum von dem aus alle zu einem späteren\n"
  521.            "                  Zeitpunkt erstellten oder veränderten Dateien\n"
  522.          "                  kopiert werden, das Format: DD MM YY.\n"
  523.       "                  Es kann ZULETZT eingegeben werden um das\n"
  524.       "                  Datum des letzten Aufrufes von BACKUP zu\n"
  525.            "                  verwenden.\n"
  526.     "       disk ----- Die Nummer der Kopie-Diskette, ab der eine\n"
  527.            "                  Sichertheitskopie erweitert werden soll, wenn\n"
  528.            "                  die ERWEITERN-Option benutzt wird\n"
  529.     "       listfile - Name der Datei für das Backup-Verzeichniss\n"
  530.            "\n"
  531.            "       Die Schlüsselwörter VON und NACH können weggelassen werden.\n");
  532. #else
  533.     printf("Usage: Backup [FROM] <dir> [TO] <drive> [SINCE <date>|LAST]\n"
  534.        "              [APPEND <disknr>] [QUERY] [LIST <listfile>]\n"
  535.            "     dir ------ Directory, which is being backed up\n"
  536.            "     drive ---- Disk-drive for backup-disks\n"
  537.            "     date ----- only files created later than <date> are being\n"
  538.            "                backed up\n"
  539.     "     disknr --- Number of disk to start an incremental backup\n"
  540.            "     listfile - Filename for listing file\n");
  541. #endif
  542.            CloseAll(1);
  543.   }
  544.   Drive = -1;
  545.   if (stricmp("DF0:", dest) == 0)
  546.     Drive = 0;
  547.   if (stricmp("DF1:", dest) == 0)
  548.     Drive = 1;
  549.   if (stricmp("DF2:", dest) == 0)
  550.     Drive = 2;
  551.   if (stricmp("DF3:", dest) == 0)
  552.     Drive = 3;
  553.   if (Drive < 0) {
  554. #ifdef DEUTSCH
  555.     printf("Kein Laufwerk %s\n", dest);
  556. #else
  557.     printf("Not a disk drive %s\n", dest);
  558. #endif
  559.     CloseAll(5);
  560.   }
  561.   if (foundsince) {
  562. #ifdef DEUTSCH
  563.     if (stricmp(date, "ZULETZT") == 0)
  564. #else
  565.     if (stricmp(date, "LAST") == 0)
  566. #endif
  567.     {
  568.       if (file = fopen(CONFIG_NAME, "r")) {
  569.         fread((char *) CompDate, 1, sizeof(CompDate), file);
  570.         fclose(file);
  571.       }
  572. #ifdef DEUTSCH
  573.       else
  574.         printf("Altes Datum kann nicht gelesen werden.\n"
  575.              "Es wird eine komplette Sicherheitskopie erstellt.\n");
  576. #else
  577.       else
  578.         printf("Error reading old date\n"
  579.                "Doing complete backup instead\n");
  580. #endif
  581.     } else if (!StrToDs(date, (struct DateStamp *) CompDate)) {
  582. #ifdef DEUTSCH
  583.       printf("Falsches Datumsformat !!!\n");
  584. #else
  585.       printf("Wrong date format\n");
  586. #endif
  587.       CloseAll(5);
  588.     }
  589.   }
  590.   OpenAll(Drive);
  591.   if (foundappend) {
  592.     LONG            dnr, pos;
  593.  
  594.     do {
  595.       do {
  596.         char            buf[5];
  597.  
  598.         buf[4] = 0;
  599.         TrackDiskBlock->iotd_Req.io_Length = 0;
  600.         DeviceCommand(TrackDiskBlock, (UWORD) TD_MOTOR);
  601. #ifdef DEUTSCH
  602.         printf("Kopie-Diskette #%d in Laufwerk DF%d: einlegen\n", DiskNr, Drive);
  603. #else
  604.         printf("Insert backup disk #%d in drive DF%d:\n", DiskNr, Drive);
  605. #endif
  606.         WaitDisk(TrackDiskBlock);
  607.         ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, 0);
  608.         strncpy(buf, TrackBuffer, 4);
  609.         if (buf[0] != 'B') {
  610. #ifdef DEUTSCH
  611.           printf("Keine Kopie-Diskette !!!\n");
  612. #else
  613.           printf("Not a backup disk\n");
  614. #endif
  615.           UserRequest();
  616.           dnr = 0;
  617.         } else {
  618.           dnr = atoi(buf + 1);
  619.           if (dnr != DiskNr)
  620.             printf("Falsche Diskette #%d !!!\n", dnr);
  621.         }
  622.       } while (dnr != DiskNr);
  623.       pos = ((LONG *) TrackBuffer)[1];
  624.       if (pos == -1) {
  625. #ifdef DEUTSCH
  626.         printf("Diskette voll\n");
  627. #else
  628.         printf("Disk full\n");
  629. #endif
  630.         DiskNr++;
  631.       }
  632.     } while (pos == -1);
  633.     TrackBuffer[4] = TrackBuffer[5] = TrackBuffer[6] = TrackBuffer[7] = 0xff;
  634.     FormatTrack(TrackDiskBlock, 0, TrackBuffer);
  635.     TrackNr = pos / TRACK_SIZE;
  636.     ByteNr = pos % TRACK_SIZE - 1;
  637.     ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, TrackNr + 1);
  638.   } else {
  639.     NewDisk();
  640.     TrackBuffer[8] = 0;
  641.     ByteNr = 8;
  642.   }
  643.   TrackNr--;
  644.   if (foundliste) {
  645.     if (ListFile = fopen(listname, "w")) {
  646.       unsigned char   clock[8];
  647.       char            time[9];
  648. #ifndef DEUTSCH
  649.       char            date[20];
  650. #endif
  651.  
  652.       fprintf(ListFile, "EasyBackup V1.0 ©1990 Oliver Enseling\n");
  653.       getclk(clock);
  654.       stptime(time, 2, clock);
  655. #ifdef DEUTSCH
  656.       fprintf(ListFile, "Verzeichnis der Sicherheitskopie  %d.%d.%d %s\n",
  657.               (int) clock[3], (int) clock[2], 1980 + clock[1], time);
  658. #else
  659.       stpdate(date, 5, clock);
  660.       fprintf(ListFile, "Backup directory  %s %s\n", date, time);
  661. #endif
  662.       fprintf(ListFile, "========================================="
  663.               "========================================\n");
  664. #ifdef DEUTSCH
  665.       fprintf(ListFile, "Diskette Spur Kopf Dateiname                    "
  666.               "                          Länge\n");
  667. #else
  668.       fprintf(ListFile, "   Disk Track Head Filename                     "
  669.               "                         Length\n");
  670. #endif
  671.       fprintf(ListFile, "-----------------------------------------"
  672.               "----------------------------------------\n");
  673.     }
  674. #ifdef DEUTSCH
  675.     else
  676.       printf("Listfile-Error: %d\n", _OSERR);
  677. #else
  678.     else
  679.       poserr("ListFile");
  680. #endif
  681.   }
  682.   if (BackupTree("")) {
  683.     DateStamp(CompDate);
  684.     if (file = fopen(CONFIG_NAME, "w")) {
  685.       fwrite((char *) CompDate, 1, sizeof(CompDate), file);
  686.       fclose(file);
  687.     }
  688. #ifdef DEUTSCH
  689.     printf("Sicherheitskopie komplett.\n");
  690. #else
  691.     printf("Backup complete\n");
  692. #endif
  693.   }
  694. #ifdef DEUTSCH
  695.   else
  696.     printf("Sicherheitskopie abgebrochen.\n");
  697. #else
  698.   else
  699.     printf("Backup aborted\n");
  700. #endif
  701.   if (ListFile)
  702.     fclose(ListFile);
  703.   CloseAll(0);
  704. }
  705.