home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d365
/
easybackup.lha
/
EasyBackup
/
restore.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-12
|
14KB
|
544 lines
/************************************************************/
/* 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] <laufwerk> [NACH] <ver> [MUSTER <muster>]\n"
" [START <startnr>] [ENDE <endenr>] [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] <drive> [TO] <dir> [PATTERN <pattern>]\n"
" [START <startno>] [END <endno>] [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);
}