/************************************************************/ /* EasyBackup,Restore.c (c)1989 Oliver Enseling */ /************************************************************/ extern void UserRequest(), EndRestore(); #define EndBackup EndRestore #define DEUTSCH #include "support.c" #include "restore.i" LONG TrackNr, ByteNr; int Drive; char *Dest, *Pattern; char DirPath[FMSIZE] = ""; BOOL FoundInter = FALSE, FoundArchiviere = FALSE; /* SetDate: Datum einer Datei setzen */ void SetDate(fn, ds) char *fn; struct DateStamp *ds; { struct StandardPacket *sp; BPTR fl, dl; char *buf; char name[80]; if (fl = Lock(fn, SHARED_LOCK)) { if (!(dl = ParentDir(fl))) { UnLock(fl); return; } } else return; UnLock(fl); stcgfn(name, fn); if (buf = AllocMem(strlen(name) + 2, MEMF_CLEAR | MEMF_PUBLIC)) { strcpy(buf + 1, name); buf[0] = strlen(name); if (sp = AllocMem(sizeof(struct StandardPacket), MEMF_CLEAR | MEMF_PUBLIC)) { struct Process *p = (struct Process *) FindTask(NULL); sp->sp_Msg.mn_Node.ln_Name = (char *) &sp->sp_Pkt; sp->sp_Pkt.dp_Link = &sp->sp_Msg; sp->sp_Pkt.dp_Port = &p->pr_MsgPort; sp->sp_Pkt.dp_Type = 34; sp->sp_Pkt.dp_Arg2 = (LONG) dl; sp->sp_Pkt.dp_Arg3 = (LONG) buf >> 2; sp->sp_Pkt.dp_Arg4 = (LONG) ds; PutMsg((struct MsgPort *) ((struct FileLock *) ((LONG) dl << 2))->fl_Task, (struct Message *) sp); WaitPort(&p->pr_MsgPort); GetMsg(&p->pr_MsgPort); FreeMem(sp, sizeof(*sp)); } FreeMem(buf, buf[0] + 2); } UnLock(dl); } /* NewDisk: neue Diskette anfordern */ LONG DiskNr = 0, EndNr = 0x7fffffff; void NewDisk() { char buf[5]; LONG dnr; TrackDiskBlock->iotd_Req.io_Length = 0; DeviceCommand((struct IORequest *)TrackDiskBlock, (UWORD) TD_MOTOR); DiskNr++; do { #ifdef DEUTSCH printf("Kopie-Diskette #%d in Laufwerk DF%d: einlegen.\n", DiskNr, Drive); #else printf("Insert backup disk #%d in drive DF%d:\n", DiskNr, Drive); #endif Beep(880, 25, 64); WaitDisk(TrackDiskBlock); ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, 0); setmem(buf, 5, 0); strncpy(buf, TrackBuffer, 4); if (buf[0] != 'B') { dnr = 0; #ifdef DEUTSCH printf("Keine Kopie-Diskette !!!"); #else printf("Not a backup disk\n"); #endif UserRequest(); } else { dnr = atoi(buf + 1); #ifdef DEUTSCH if (dnr != DiskNr) printf("Falsche Diskette #%d !!!\n", dnr); #else if (dnr != DiskNr) printf("Wrong disk #%d !!!\n", dnr); #endif } } while (dnr != DiskNr); #ifdef DEUTSCH printf("Diskette OK\n"); #else printf("Disk OK\n"); #endif TrackNr = 0; ByteNr = 8 + strlen(&TrackBuffer[8]) + 1; strcpy(DirPath, &TrackBuffer[8]); PrintDisk(DiskNr); PrintTrack(0); } /* RawGetByte: ein Byte aus dem Backup lesen */ BYTE RawGetByte() { BYTE b; ByteNr++; if (ByteNr >= TRACK_SIZE) { TrackNr++; if (TrackNr >= MAX_TRACKS) { #ifdef DEUTSCH printf("Diskette fertig reinstalliert\n"); #else printf("Disk completely reinstalled\n"); #endif NewDisk(); } else { ByteNr = 0; ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, TrackNr); PrintTrack(TrackNr); } } b = TrackBuffer[ByteNr]; return (b); } /* Byte unter Berücksichtigung von Dateiendemarkierungen lesen */ BOOL DateiEnde = FALSE; char DecodeByte() { char b; static unsigned char buffer; static BOOL buffer_on = FALSE; if (buffer_on) { b = buffer; buffer_on = FALSE; } else b = RawGetByte(); if (b == DATEIENDEMARKE) { buffer = RawGetByte(); if (buffer == DATEIENDEMARKE) { buffer_on = FALSE; DateiEnde = FALSE; } else { buffer_on = TRUE; DateiEnde = TRUE; } return (DATEIENDEMARKE); } else { DateiEnde = FALSE; return (b); } } /* RawReadString: eine String mit Endung 0 aus dem Backup lesen */ void RawReadString(str) char *str; { char c; do { c = DecodeByte(); *str++ = c; } while (c != 0); } /* RawRead: Anzahl Bytes aus dem Backup lesen */ void RawRead(buf, len) BYTE *buf; LONG len; { LONG i; for (i = 0; i < len; i++) buf[i] = DecodeByte(); } /* EndRestore: Drive-Motor ausschalten + KontrollMsg ausgeben */ void EndRestore() { TrackDiskBlock->iotd_Req.io_Length = 0; DeviceCommand((struct IORequest *)TrackDiskBlock, (UWORD) TD_MOTOR); } /* * MakePath: testen, ob alle dirs zu einem kompletten Dateinamen * vorhanden sind, ggf. neue dirs erstellen */ void MakePath(path) char *path; { char buffer[512]; BPTR lock; char *pos = path; while (pos = stpchr(pos + 1, '/')) { strncpy(buffer, path, (int) pos - (int) path); buffer[(int) pos - (int) path] = 0; if (!(lock = Lock(buffer, ACCESS_READ))) if (!(lock = CreateDir(buffer))) { #ifdef DEUTSCH printf("Verzeichnis %s kann nicht erstellt werden.\n", buffer); #else printf("Unable to create directory %s\n", buffer); #endif UserRequest(); return; } UnLock(lock); } } /* RestoreFileData: Inhalt einer Datei lesen und in File kopieren */ void RestoreFileData(file) int file; { BYTE b; LONG i = 0; for (b = DecodeByte(); !DateiEnde; b = DecodeByte()) { FileBuffer[i] = b; i++; if (i >= BUFFER_SIZE) { write(file, FileBuffer, BUFFER_SIZE); i = 0; } } write(file, FileBuffer, i); } /* Ende einer Datei suchen */ void GotoDateiEnde() { BYTE b; for (b = DecodeByte(); !DateiEnde; b = DecodeByte()); } /* RestoreDir: Verzeichnisse rekursiv reinstallieren */ BOOL RestoreDir(doinstall) BOOL doinstall; { LONG err, protection; char d[FMSIZE], filename[FMSIZE], path[FMSIZE], fullpath[FMSIZE], comment[116]; struct DateStamp date; int file; strcpy(d, DirPath); FOREVER { err = 0; if (DiskNr > EndNr) CloseAll(0); switch (DecodeByte()) { case ID_DIR: RawReadString(filename); ConcatPath(DirPath, d, filename); if (doinstall) { #ifdef DEUTSCH printf("Verzeichnis \033[32m%s\033[0m ", DirPath); #else printf("Directory \033[32m%s\033[0m ", DirPath); #endif if (FoundInter) { if (FileAbfrage()) RestoreDir(TRUE); else RestoreDir(FALSE); } else RestoreDir(TRUE); } else RestoreDir(FALSE); break; case ID_ENDDIR: return (TRUE); case ID_FILE: RawReadString(filename); RawRead((BYTE *) & protection, sizeof(LONG)); RawRead((BYTE *) & date, sizeof(struct DateStamp)); RawReadString(comment); ConcatPath(path, d, filename); if (doinstall && (!Pattern || astcsma(path, Pattern))) { BOOL restorefile = TRUE; ConcatPath(fullpath, Dest, path); #ifdef DEUTSCH printf("Reinstallation von \033[33m%s\033[31m ... ", fullpath); #else printf("reinstalling \033[33m%s\033[31m ... ", fullpath); #endif if (FoundInter) restorefile = FileAbfrage(); if (restorefile) { MakePath(fullpath); if ((file = open(fullpath, O_WRONLY | O_CREAT)) != -1) { RestoreFileData(file); close(file); if (FoundArchiviere) protection |= FIBF_ARCHIVE; SetProtection(fullpath, protection); if (!(err = IoErr())) { SetComment(fullpath, comment); if (!(err = IoErr())) { SetDate(fullpath, &date); } } } else err = _OSERR; if (err) { #ifdef DEUTSCH printf("\nFehler bei der Reinstallation.\nDOS-Fehlernummer:%4d\n", err); #else printf("\nError while reinstalling\nDOS-Error:%4d\n", err); #endif UserRequest(); } else printf("OK\n"); } else GotoDateiEnde(); } else GotoDateiEnde(); break; default: #ifdef DEUTSCH printf("Backupstruktur fehlerhaft !!!\n" "Suche nächsten Eintrag\n"); #else printf("Error in backup structure\n" "Searching next entry\n"); #endif GotoDateiEnde(); } } return (TRUE); } /* Hauptprogramm: Parameter parsen, Error-Messages ausgeben */ void main(argc, argv) int argc; char **argv; { BOOL foundfrom = FALSE, foundto = FALSE, foundpattern = FALSE, foundstart = TRUE, foundend = FALSE; char *source; int i; printf("EasyBackup V1.0, Restore ©1990 Oliver Enseling\n\n"); for (i = 1; i < argc; i++) { #ifdef DEUTSCH if (stricmp(argv[i], "VON") == 0) #else if (stricmp(argv[i], "FROM") == 0) #endif { foundfrom = TRUE; i++; source = argv[i]; } else { #ifdef DEUTSCH if (stricmp(argv[i], "NACH") == 0) #else if (stricmp(argv[i], "TO") == 0) #endif { foundto = TRUE; i++; Dest = argv[i]; } else { #ifdef DEUTSCH if (stricmp(argv[i], "MUSTER") == 0) #else if (stricmp(argv[i], "PATTERN") == 0) #endif { foundpattern = TRUE; i++; Pattern = argv[i]; } else { #ifdef DEUTSCH if (stricmp(argv[i], "START") == 0) #else if (stricmp(argv[i], "START") == 0) #endif { foundstart = TRUE; i++; stcd_l(argv[i], &DiskNr); DiskNr--; } else { #ifdef DEUTSCH if (stricmp(argv[i], "ENDE") == 0) #else if (stricmp(argv[i], "END") == 0) #endif { foundend = TRUE; i++; stcd_l(argv[i], &EndNr); } else { #ifdef DEUTSCH if (stricmp(argv[i], "INTERAKTIV") == 0) #else if (stricmp(argv[i], "QUERY") == 0) #endif { FoundInter = TRUE; } else { #ifdef DEUTSCH if (stricmp(argv[i], "ARCHIVIERE") == 0) #else if (stricmp(argv[i], "ARCHIVATE") == 0) #endif { FoundArchiviere = TRUE; } else { if (!foundfrom) { source = argv[i]; foundfrom = TRUE; } else { if (!foundto) { Dest = argv[i]; foundto = TRUE; } #ifdef DEUTSCH else printf("Parameter \033[32m%s\033[31m wird ignoriert !\n"); #else else printf("Argument \033[32m%sy\033[31m ignored\n"); #endif } } } } } } } } } if (!(foundfrom && foundto)) { #ifdef DEUTSCH printf("Syntax: Restore [VON] [NACH] [MUSTER ]\n" " [START ] [ENDE ] [INTERAKTIV]\n" " [ARCHIVIERE]\n" " laufwerk - Das Laufwerk, mit dem gearbeitet werden soll\n" " ver ------ Das Zielverzeichnis\n" " muster --- Ein AmigaDOS-übliches Muster, nur die Dateien,\n" " die hierauf passen werden reinstalliert\n" " startnr -- Nummer der Diskette, bei der die Reinstallation\n" " starten soll\n" " endenr --- Nummer der Diskette, bei der die Reinstallation\n" " enden soll\n" " \n" " Die Schlüsselwörter VON und NACH können\n" " weggelassen werden.\n"); #else printf("Usage: Restore [FROM] [TO] [PATTERN ]\n" " [START ] [END ] [QUERY] [ARCHIVATE]\n" " drive ---- Disk drive for backup disks\n" " dir ------ Target directory for restoration\n" " pattern -- standard pattern for wildcard pattern matching like\n" " AmigaDOS commands to select files to be restored\n" " startno -- first disk to be restored\n" " endno ---- last disk to be restored\n" " keywords FROM and TO can be left out\n"); #endif CloseAll(1); } Drive = -1; if (stricmp("DF0:", source) == 0) Drive = 0; if (stricmp("DF1:", source) == 0) Drive = 1; if (stricmp("DF2:", source) == 0) Drive = 2; if (stricmp("DF3:", source) == 0) Drive = 3; if (Drive < 0) { #ifdef DEUTSCH printf("Falsches Diskettenlaufwerk %s !!!\n", source); #else printf("Wrong disk drive %s\n", source); #endif CloseAll(5); } OpenAll(Drive); NewDisk(); ByteNr--; if (DiskNr > 1) GotoDateiEnde(); #ifdef DEUTSCH if (RestoreDir(TRUE)) printf("Reinstallation komplett\n"); else printf("Reinstallation abgebrochen\n"); #else if (RestoreDir(TRUE)) printf("Restoration complete\n"); else printf("Restoration aborted\n"); #endif CloseAll(0); }