home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d365
/
easybackup.lha
/
EasyBackup
/
backup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-12
|
19KB
|
705 lines
/******************************************************/
/* EasyBackup, Backup.c (c)1989 Oliver Enseling */
/******************************************************/
extern void EndBackup(), UserRequest();
#include "support.c"
long CompDate[3]; /* DateStamp zum vergleichen */
int Drive; /* Nummer des selektierten
* Disk-Drives */
char *Source; /* Source-Directorypath */
char Buffer[FMSIZE]; /* Hilfspuffer zum
* "Zusammenbau" des ganzen
* filenamens */
char DirPath[FMSIZE] = ""; /* aktueller Directorypath */
BOOL FoundInter = FALSE, FoundArchiviere = FALSE, FoundArchivstatus = FALSE;
FILE *ListFile = NULL;
/* Variablen */
LONG TrackNr, ByteNr;
/* NewDisk: neue Diskette anfordern */
LONG DiskNr;
void
NewDisk()
{
BOOL diskcorrect;
char buf[5];
TrackDiskBlock->iotd_Req.io_Length = 0; /* Drive-Motor aus */
DeviceCommand(TrackDiskBlock, (UWORD) TD_MOTOR);
DiskNr++;
do {
setmem(buf, 5, 0);
Beep(880, 25, 64);
#ifdef DEUTSCH
printf("Neue Kopie-Diskette #%d in Laufwerk DF%d: einlegen\n", DiskNr,
Drive);
#else
printf("Insert new backup disk #%d in drive DF%d:", DiskNr, Drive);
#endif
WaitDisk(TrackDiskBlock);
ReadTrack(TrackDiskBlock,
&TrackBuffer[TRACK_SIZE], LabelBuffer, 0);
strncpy(buf, &TrackBuffer[TRACK_SIZE], 4);
if (buf[0] != 'B')
diskcorrect = TRUE;
else {
int dnr = atoi(buf + 1);
if (dnr < DiskNr && dnr > 0) {
#ifdef DEUTSCH
printf("Achtung Kopie-Diskette #%d wird überschrieben !!!\n", dnr);
printf("Diskette wechseln ? ");
#else
printf("Old backup disk #%d is being overwritten\n", dnr);
printf("Change disk ? ");
#endif
diskcorrect = FileAbfrage();
} else
diskcorrect = TRUE;
}
} while (!diskcorrect);
#ifdef DEUTSCH
printf("Diskette OK\n");
#else
printf("Disk OK\n");
#endif
sprintf(TrackBuffer, "B%d%d%d", DiskNr / 100 % 10, DiskNr / 10 % 10,
DiskNr % 10);
setmem(&TrackBuffer[4], 4, 0xff);
TrackNr = 0;
ByteNr = 0;
PrintDisk(DiskNr);
PrintTrack(0);
}
/* FormatTrack: einen Track formatieren */
void
FormatTrack(db, nr, buf)
struct IOExtTD *db;
LONG nr;
BYTE *buf;
{
PrintTrack((nr + 1) % MAX_TRACKS);
FOREVER
{
DeviceCommand(db, (UWORD) TD_CHANGENUM);
db->iotd_Count = db->iotd_Req.io_Actual;
db->iotd_Req.io_Data = (APTR) buf;
db->iotd_Req.io_Length = (ULONG) TRACK_SIZE;
db->iotd_Req.io_Offset = nr * TRACK_SIZE;
DeviceCommand(db, (UWORD) ETD_FORMAT);
if (db->iotd_Req.io_Error) {
#ifdef DEUTSCH
printf("Fehler beim Schreiben auf Spur #%d:\n%s\n",
nr, TrackDiskError((LONG) db->iotd_Req.io_Error));
#else
printf("Error writing track #%d:\n%s\n",
nr, TrackDiskError((LONG) db->iotd_Req.io_Error));
#endif
UserRequest();
} else
break;
}
}
/* RawPutByte: ein Byte in ein Backup schreiben */
void
RawPutByte(b)
BYTE b;
{
ByteNr++;
if (ByteNr >= TRACK_SIZE) {
TrackNr++;
if (TrackNr >= MAX_TRACKS) {
#ifdef DEUTSCH
printf("Diskette voll\n");
#else
printf("Disk full\n");
#endif
NewDisk();
} else if (TrackNr != MAX_TRACKS - 1)
ByteNr = 0;
else {
strcpy(&TrackBuffer[8], DirPath);
ByteNr = strlen(&TrackBuffer[8]) + 1 + 8;
}
FormatTrack(TrackDiskBlock, TrackNr, TrackBuffer);
}
TrackBuffer[ByteNr] = b;
}
/* Bytes mit Dateiendemarkierung kodieren */
void
EncodeByte(b)
char b;
{
if (b == DATEIENDEMARKE) {
RawPutByte(DATEIENDEMARKE);
RawPutByte(DATEIENDEMARKE);
} else
RawPutByte(b);
}
/* RawWrite: Anzahl Bytes auf das Backup schreiben */
void
RawWrite(buf, len)
BYTE *buf;
LONG len;
{
LONG i;
for (i = 0; i < len; i++)
EncodeByte(buf[i]);
}
/*
* ByteCount: Anzahl der aufeinanderfolgenden gleichen Bytes
* ermitteln
*/
LONG
ByteCount(begin, max)
UBYTE *begin, *max;
{
int count;
UBYTE b;
b = *begin;
for (count = 0L; count < 255L; count++)
if ((begin[count] != b) || ((UBYTE *) (begin + count) > max))
break;
return (count);
}
/*
* EndBackup: Backup beenden / letzten Buffer schreiben + Endmarke
* setzen Drive-Motor ausschalten
*/
void
EndBackup()
{
LONG diskfull;
diskfull = (TrackNr + 1) * TRACK_SIZE + ByteNr;
RawPutByte(ID_ENDDIR);
ByteNr = TRACK_SIZE - 1;
RawPutByte((BYTE) - 1);
ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, 0);
memcpy(&TrackBuffer[4], (char *) &diskfull, 4);
FormatTrack(TrackDiskBlock, 0, TrackBuffer);
TrackDiskBlock->iotd_Req.io_Length = 0; /* Drive-Motor aus */
DeviceCommand(TrackDiskBlock, (UWORD) TD_MOTOR);
}
/*
* BackupFile: ein File überprüfen, ggf. packen und auf die
* BackupDisk schreiben
*/
BOOL
BackupFile(path, fib)
char *path;
struct FileInfoBlock *fib;
{
LONG ssize = fib->fib_Size;
int file;
char *fn = fib->fib_FileName;
ConcatPath(Buffer, Source, path);
if (datecmp((long *) &fib->fib_Date, CompDate) < 0) {
if (FoundArchivstatus && (fib->fib_Protection & FIBF_ARCHIVE))
return (TRUE);
#ifdef DEUTSCH
printf("Kopie für \033[33m%s\033[0m %d Bytes ... ", Buffer, fib->fib_Size);
#else
printf("Backup for \033[33m%s\033[0m %d Bytes ... ", Buffer, fib->fib_Size);
#endif
if (FoundInter)
if (!FileAbfrage())
return (TRUE);
RawPutByte(ID_FILE);
RawWrite(fn, strlen(fn) + 1);
RawWrite((BYTE *) & fib->fib_Protection, sizeof(fib->fib_Protection));
if (FoundArchiviere) {
fib->fib_Protection |= FIBF_ARCHIVE;
SetProtection(Buffer, fib->fib_Protection);
}
RawWrite((BYTE *) & fib->fib_Date, sizeof(fib->fib_Date));
RawWrite(fib->fib_Comment, strlen(fib->fib_Comment) + 1);
if (ListFile)
fprintf(ListFile, "%8d%5d%5d %-51s%9d\n",
DiskNr, (TrackNr + 1) / 2, (TrackNr + 1) % 2, path, ssize);
if (ssize > 0) {
if ((file = open(Buffer, O_RDONLY, 0)) != -1) {
LONG remain;
for (remain = ssize; remain > BUFFER_SIZE; remain -= BUFFER_SIZE) {
read(file, FileBuffer, BUFFER_SIZE);
RawWrite(FileBuffer, BUFFER_SIZE);
}
read(file, FileBuffer, remain);
RawWrite(FileBuffer, remain);
close(file);
printf("OK\n");
} else {
#ifdef DEUTSCH
printf("Lesefehler, DOS-Fehlernummer: %d\n", _OSERR);
#else
poserr(Buffer);
#endif
UserRequest();
}
RawPutByte(DATEIENDEMARKE);
return ((BOOL) (file > 0));
} else {
#ifdef DEUTSCH
printf("Leere Datei --> 0 Bytes\n");
#else
printf("Empty file --> 0 Bytes\n");
#endif
RawPutByte(DATEIENDEMARKE);
return (TRUE);
}
}
return (TRUE);
}
/* ein Verzeichnis "backuppen" */
BOOL
BackupDir(path, fib)
char *path;
struct FileInfoBlock *fib;
{
char *dn = fib->fib_FileName;
if (datecmp((long *) &fib->fib_Date, CompDate) >= 0)
return (FALSE);
if (FoundArchivstatus && (fib->fib_Protection & FIBF_ARCHIVE))
return (FALSE);
strcpy(DirPath, path);
ConcatPath(Buffer, Source, path);
if (datecmp((long *) &fib->fib_Date, CompDate) < 0) {
#ifdef DEUTSCH
printf("Verzeichnis \033[33;2m%s\033[0m", Buffer);
#else
printf("Directory \033[33;2m%s\033[0m", Buffer);
#endif
if (FoundInter) {
if (!FileAbfrage())
return (FALSE);
} else
printf("\n");
RawPutByte(ID_DIR);
RawWrite(dn, strlen(dn) + 1);
return (TRUE);
} else
return (FALSE);
}
/* BackupEndDir: ENDE-Markierung für ein Verzeichnis "backuppen" */
void
BackupEndDir()
{
RawPutByte(ID_ENDDIR);
}
/* BackupTree: Verzeichnisbaum rekursiv backuppen */
BOOL
BackupTree(s)
char *s;
{
struct FileInfoBlock *fib;
BOOL ok = TRUE;
LONG err;
char path[FMSIZE];
BPTR lock;
ConcatPath(Buffer, Source, s);
if (fib = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR | MEMF_CHIP)) {
if (lock = Lock(Buffer, ACCESS_READ)) {
if (Examine(lock, fib)) {
while (ok && ExNext(lock, fib)) {
ConcatPath(path, s, fib->fib_FileName);
if (fib->fib_DirEntryType > 0) {
if (BackupDir(path, fib)) {
ok = BackupTree(path);
BackupEndDir();
}
} else
ok = BackupFile(path, fib);
}
}
UnLock(lock);
}
FreeMem(fib, sizeof(struct FileInfoBlock));
} else {
ok = FALSE;
#ifdef DEUTSCH
printf("Nicht genügend Speicher für den FileInfoBlock !!!\n");
#else
printf("Not enough memory for FileInfoBlock\n");
#endif
}
if (err = IoErr())
if (!(ok = (err == ERROR_NO_MORE_ENTRIES))) {
#ifdef DEUTSCH
printf("Fehler beim Lesen des Verzeichnisses.\n"
"DOS-Fehlernummer:%4d\n", err);
#else
printf("Error reading directory.\n"
"DOS-Error:%4d\n", err);
#endif
UserRequest();
}
return (ok);
}
/* Umwandlung von String nach DateStamp */
BYTE MonthDays[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
LONG LeapYears = 0x44444444;
BOOL
StrToDs(s, ds)
char *s;
struct DateStamp *ds;
{
int i, d = atoi(s), m = atoi(&s[3]), y = atoi(&s[6]) - 78;
if ((d > 0) && (m > 0) && (y >= 0)) {
for (i = 0; i < y; i++)
ds->ds_Days += LeapYears & (1 << i) ? 366 : 365;
for (i = 0; i < m - 1; i++)
ds->ds_Days += MonthDays[i];
ds->ds_Days += d - 1 + ((LeapYears & (1 << y)) && (m > 2) ? 1 : 0);
return (TRUE);
}
return (FALSE);
}
/* Hauptprogramm: Parameter parsen, Error-Messages ausgeben */
void
main(argc, argv)
int argc;
char **argv;
{
BOOL foundfrom = FALSE, foundto = FALSE, foundsince = FALSE, foundappend = FALSE,
foundliste = FALSE;
char *dest, *date, *listname;
int i;
FILE *file;
printf("EasyBackup V1.0, Backup ©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], "SEIT") == 0)
#else
if (stricmp(argv[i], "SINCE") == 0)
#endif
{
foundsince = TRUE;
i++;
date = argv[i];
} else {
#ifdef DEUTSCH
if (stricmp(argv[i], "ERWEITERN") == 0)
#else
if (stricmp(argv[i], "APPEND") == 0)
#endif
{
foundappend = TRUE;
i++;
DiskNr = atoi(argv[i]);
if (DiskNr < 1)
DiskNr = 1;
} 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], "LISTE") == 0)
#else
if (stricmp(argv[i], "LIST") == 0)
#endif
{
foundliste = TRUE;
i++;
listname = argv[i];
} else {
#ifdef DEUTSCH
if (stricmp(argv[i], "ARCHIVIERE") == 0)
#else
if (stricmp(argv[i], "ARCHIVATE") == 0)
#endif
{
FoundArchiviere = TRUE;
} else {
#ifdef DEUTSCH
if (stricmp(argv[i], "ARCHIVSTATUS") == 0)
#else
if (stricmp(argv[i], "CHECKARCHIVE") == 0)
#endif
{
FoundArchivstatus = 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",
argv[i]);
#else
else
printf("Argument \033[32m%s\033[31m ignored\n", argv[i]);
#endif
}
}
}
}
}
}
}
}
}
}
if (!(foundfrom && foundto)) {
#ifdef DEUTSCH
printf("Syntax: Backup [VON] <ver> [NACH] <laufwerk> [SEIT <datum>|ZULETZT]\n"
" [ERWEITERN <disk>] [INTERAKTIV] [LISTE <listfile>]\n"
" [ARCHIVIERE] [ARCHIVSTATUS]\n"
" ver ------ Das zu kopierende Verzeichnis\n"
" laufwerk - Das Laufwerk mit dem gearbeitet wird\n"
" datum ---- Das Datum von dem aus alle zu einem späteren\n"
" Zeitpunkt erstellten oder veränderten Dateien\n"
" kopiert werden, das Format: DD MM YY.\n"
" Es kann ZULETZT eingegeben werden um das\n"
" Datum des letzten Aufrufes von BACKUP zu\n"
" verwenden.\n"
" disk ----- Die Nummer der Kopie-Diskette, ab der eine\n"
" Sichertheitskopie erweitert werden soll, wenn\n"
" die ERWEITERN-Option benutzt wird\n"
" listfile - Name der Datei für das Backup-Verzeichniss\n"
"\n"
" Die Schlüsselwörter VON und NACH können weggelassen werden.\n");
#else
printf("Usage: Backup [FROM] <dir> [TO] <drive> [SINCE <date>|LAST]\n"
" [APPEND <disknr>] [QUERY] [LIST <listfile>]\n"
" dir ------ Directory, which is being backed up\n"
" drive ---- Disk-drive for backup-disks\n"
" date ----- only files created later than <date> are being\n"
" backed up\n"
" disknr --- Number of disk to start an incremental backup\n"
" listfile - Filename for listing file\n");
#endif
CloseAll(1);
}
Drive = -1;
if (stricmp("DF0:", dest) == 0)
Drive = 0;
if (stricmp("DF1:", dest) == 0)
Drive = 1;
if (stricmp("DF2:", dest) == 0)
Drive = 2;
if (stricmp("DF3:", dest) == 0)
Drive = 3;
if (Drive < 0) {
#ifdef DEUTSCH
printf("Kein Laufwerk %s\n", dest);
#else
printf("Not a disk drive %s\n", dest);
#endif
CloseAll(5);
}
if (foundsince) {
#ifdef DEUTSCH
if (stricmp(date, "ZULETZT") == 0)
#else
if (stricmp(date, "LAST") == 0)
#endif
{
if (file = fopen(CONFIG_NAME, "r")) {
fread((char *) CompDate, 1, sizeof(CompDate), file);
fclose(file);
}
#ifdef DEUTSCH
else
printf("Altes Datum kann nicht gelesen werden.\n"
"Es wird eine komplette Sicherheitskopie erstellt.\n");
#else
else
printf("Error reading old date\n"
"Doing complete backup instead\n");
#endif
} else if (!StrToDs(date, (struct DateStamp *) CompDate)) {
#ifdef DEUTSCH
printf("Falsches Datumsformat !!!\n");
#else
printf("Wrong date format\n");
#endif
CloseAll(5);
}
}
OpenAll(Drive);
if (foundappend) {
LONG dnr, pos;
do {
do {
char buf[5];
buf[4] = 0;
TrackDiskBlock->iotd_Req.io_Length = 0;
DeviceCommand(TrackDiskBlock, (UWORD) TD_MOTOR);
#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
WaitDisk(TrackDiskBlock);
ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, 0);
strncpy(buf, TrackBuffer, 4);
if (buf[0] != 'B') {
#ifdef DEUTSCH
printf("Keine Kopie-Diskette !!!\n");
#else
printf("Not a backup disk\n");
#endif
UserRequest();
dnr = 0;
} else {
dnr = atoi(buf + 1);
if (dnr != DiskNr)
printf("Falsche Diskette #%d !!!\n", dnr);
}
} while (dnr != DiskNr);
pos = ((LONG *) TrackBuffer)[1];
if (pos == -1) {
#ifdef DEUTSCH
printf("Diskette voll\n");
#else
printf("Disk full\n");
#endif
DiskNr++;
}
} while (pos == -1);
TrackBuffer[4] = TrackBuffer[5] = TrackBuffer[6] = TrackBuffer[7] = 0xff;
FormatTrack(TrackDiskBlock, 0, TrackBuffer);
TrackNr = pos / TRACK_SIZE;
ByteNr = pos % TRACK_SIZE - 1;
ReadTrack(TrackDiskBlock, TrackBuffer, LabelBuffer, TrackNr + 1);
} else {
NewDisk();
TrackBuffer[8] = 0;
ByteNr = 8;
}
TrackNr--;
if (foundliste) {
if (ListFile = fopen(listname, "w")) {
unsigned char clock[8];
char time[9];
#ifndef DEUTSCH
char date[20];
#endif
fprintf(ListFile, "EasyBackup V1.0 ©1990 Oliver Enseling\n");
getclk(clock);
stptime(time, 2, clock);
#ifdef DEUTSCH
fprintf(ListFile, "Verzeichnis der Sicherheitskopie %d.%d.%d %s\n",
(int) clock[3], (int) clock[2], 1980 + clock[1], time);
#else
stpdate(date, 5, clock);
fprintf(ListFile, "Backup directory %s %s\n", date, time);
#endif
fprintf(ListFile, "========================================="
"========================================\n");
#ifdef DEUTSCH
fprintf(ListFile, "Diskette Spur Kopf Dateiname "
" Länge\n");
#else
fprintf(ListFile, " Disk Track Head Filename "
" Length\n");
#endif
fprintf(ListFile, "-----------------------------------------"
"----------------------------------------\n");
}
#ifdef DEUTSCH
else
printf("Listfile-Error: %d\n", _OSERR);
#else
else
poserr("ListFile");
#endif
}
if (BackupTree("")) {
DateStamp(CompDate);
if (file = fopen(CONFIG_NAME, "w")) {
fwrite((char *) CompDate, 1, sizeof(CompDate), file);
fclose(file);
}
#ifdef DEUTSCH
printf("Sicherheitskopie komplett.\n");
#else
printf("Backup complete\n");
#endif
}
#ifdef DEUTSCH
else
printf("Sicherheitskopie abgebrochen.\n");
#else
else
printf("Backup aborted\n");
#endif
if (ListFile)
fclose(ListFile);
CloseAll(0);
}