home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD1.img
/
d1xx
/
d128
/
mrbackup
/
restore.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-01-02
|
7KB
|
295 lines
/* Filename: restore.c
* Author: Mark R. Rinfret
* Date: 08/02/87
* Description: Restore processing module for MRBackup
*
* History: (most recent change first)
*
* 09/19/87 -MRR- Added NewHomeDir() which creates subdirectories as
* necessary when the initial backup path specifies a
* subdirectory.
*/
#include "MRBackup.h"
#ifdef DEBUG
extern char debugmsg[];
#endif
static char fullbackpath[256], fullhomepath[256];
static unsigned home_is_device; /* true => home is "DH<N>:" */
/* Create a new directory on the home device.
* Called with:
* name: directory pathname
* Returns:
* false => success
* true => failure
*/
int
NewHomeDir(name)
char *name;
{
char c;
struct Lock *dirlock;
int dirleng;
int errnum;
char dirname[256];
int nameindx = 0, nameleng;
*dirname = '\0';
dirleng = 0;
nameleng = strlen(name);
/* Parse the pathname, one directory node at a time, creating
* directories as needed.
*/
while (nameindx < nameleng) {
if (nameindx) /* 2nd - nth pass? */
dirname[dirleng++] = '/'; /* directory separator */
while ((c = name[nameindx++]) && c != '/')
dirname[dirleng++] = c;
dirname[dirleng] = '\0'; /* terminate with null */
if (dirlock = Lock(dirname,SHARED_LOCK)) /* subdir exists? */
UnLock(dirlock);
else { /* create subdirectory */
if ((dirlock = CreateDir(dirname))== NULL){
if ((errnum = IoErr())== ERROR_DIRECTORY_NOT_EMPTY){
sprintf(conmsg,
"Directory %s already exists!\n",dirname);
TypeAndSpeak(conmsg);
}
else {
sprintf(conmsg,
"ERROR %d: Unable to create directory %s\n",
errnum,dirname);
TypeAndSpeak(conmsg);
return errnum;
}
}
else
UnLock(dirlock);
}
} /* endwhile */
return 0;
}
/* Restore files from floppy disk. */
int
Restore()
{
int status = 0;
Speak("And away we go!");
if (!IsDir(backpath)) {
TypeAndSpeak("Backup path must be a device or directory name!\n");
return ERR_ABORT;
}
BreakPath(backpath, srcvol, srcpath);
home_is_device = (homepath[strlen(homepath)-1] == ':');
status = RestoreFile(srcpath);
if (status == 0) {
TypeAndSpeak("Your restoration project is completed, sire.\n");
}
else {
sprintf(conmsg,"Restore terminated with status %d.\n",status);
TypeAndSpeak(conmsg);
TypeAndSpeak(
"Perhaps you should check things out and try it again.\n");
}
return status;
}
/* Restore all the files in a directory.
* Called with:
* lock: lock on the directory
* fib: pointer to file info block
* path: directory pathname (without volume)
* Returns:
* status (0 => success)
*/
int
RestoreDir(lock, fib, path)
struct Lock *lock; struct FileInfoBlock *fib; char *path;
{
struct Lock *dirlock = NULL, *filelock = NULL;
char newpath[256];
int status = 0;
strcpy(temp, homepath);
if (*path) {
if (!home_is_device) strcat(temp, "/");
strcat(temp, path);
}
#ifdef DEBUG
sprintf(debugmsg,"Checking for directory %s\n",temp);
DebugWrite(debugmsg);
#endif
if (!(dirlock = Lock(temp, SHARED_LOCK))) {
if ((status = IoErr()) == ERROR_OBJECT_NOT_FOUND) {
#ifdef DEBUG
sprintf(debugmsg,"Creating directory %s\n",temp);
DebugWrite(debugmsg);
#endif
if (status = NewHomeDir(temp))
return status;
}
else {
sprintf(conmsg,"RestoreDir cannot lock %s: %d\n",temp, status);
TypeAndSpeak(conmsg);
return status;
}
}
if (dirlock) UnLock(dirlock);
while (ExNext(lock,fib)) {
strcpy(newpath, path);
if (*newpath)
strcat(newpath, "/");
strcat(newpath, fib->fib_FileName);
if (status = RestoreFile(newpath)) {
/* filter out "permissable:" errors */
if (status == ERROR_OBJECT_IN_USE ||
status == ERROR_WRITE_PROTECTED)
status = 0;
else
break;
}
}
done:
return status;
}
/* Restore one or more files according to the calling pathname.
* The path argument does not contain the backup volume name.
*/
int
RestoreFile(path)
char *path;
{
struct FileInfoBlock *fib = NULL, *fib2 = NULL;
UBYTE exists = FALSE, ignore = FALSE;
struct Lock *lock = NULL;
USHORT namelength;
UBYTE savechar;
int status = 0;
if (status = CheckStop()) return status;
if (!(fib = (struct FileInfoBlock *)
AllocMem((long) sizeof (struct FileInfoBlock),
MEMF_PUBLIC | MEMF_CHIP))) {
TypeAndSpeak("RestoreFile could not allocate FIB!\n");
return ERROR_NO_FREE_STORE;
}
sprintf(fullbackpath, "%s:%s",srcvol,path);
strcpy(fullhomepath, homepath);
if (*path) {
if (!home_is_device) strcat(fullhomepath, "/");
strcat(fullhomepath, path);
}
#ifdef DEBUG
sprintf(conmsg,"fullbackpath = %s\n",fullbackpath);
DebugWrite(conmsg);
sprintf(conmsg,"fullhomepath = %s\n",fullhomepath);
DebugWrite(conmsg);
#endif
if (!(lock = Lock(fullbackpath, SHARED_LOCK))) {
status = IoErr();
sprintf(conmsg, "RestoreFile: can't lock %s: %d\n",
fullbackpath, status);
TypeAndSpeak(conmsg);
goto done;
}
if (!Examine(lock, fib)) {
status = IoErr();
sprintf(conmsg, "RestoreFile can't examine %s: %d\n",
fullbackpath, status);
TypeAndSpeak(conmsg);
goto done;
}
if (fib->fib_DirEntryType > 0) { /* path is a directory */
status = RestoreDir(lock, fib, path);
UnLock(lock);
lock = NULL;
}
else {
UnLock(lock);
lock = NULL;
/*#define NOCOPY*/
#ifndef NOCOPY
/* If this file exists, then check its modification date. If
* it's newer than the backup, don't replace it.
*/
if ((lock = Lock(fullhomepath, SHARED_LOCK))) {
if (!(fib2 = (struct FileInfoBlock *)
AllocMem((long) sizeof (struct FileInfoBlock),
MEMF_PUBLIC | MEMF_CHIP))) {
TypeAndSpeak("RestoreFile could not allocate FIB!\n");
status = ERROR_NO_FREE_STORE;
goto done;
}
Examine(lock, fib2);
UnLock(lock);
lock = NULL;
if (CompareDS(&fib2->fib_Date, &fib->fib_Date) >= 0)
ignore = TRUE;
}
if (ignore) {
sprintf(conmsg,"Skipping %s. Current version is newer.\n",
path);
TypeAndSpeak(conmsg);
}
else {
if (!do_compress || !IsCompressed(fullhomepath)) {
copyfile:
sprintf(conmsg,"Copying %s\n", fullbackpath);
WriteConsole(conmsg);
status = CopyFile(fullbackpath, fullhomepath);
}
else {
/* truncate the destination pathname (remove ".z") */
namelength = strlen(fullhomepath);
fullhomepath[namelength-2] = '\0';
sprintf(conmsg, "Decompressing %s\n", fullbackpath);
WriteConsole(conmsg);
if (status = decompress(fullbackpath, fullhomepath)) {
sprintf(conmsg,
"Decompression of %s failed; status is %d.\n",
fullbackpath, status);
TypeAndSpeak(conmsg);
TypeAndSpeak("I will try to copy the file, instead.\n");
/* restore ".z" to name */
fullhomepath[namelength-2] = '.';
goto copyfile;
}
CopyFileDate(fullbackpath, fullhomepath);
}
}
#endif
}
done:
if (lock) UnLock(lock);
if (fib) FreeMem(fib, (long) sizeof(struct FileInfoBlock));
if (fib2) FreeMem(fib2, (long) sizeof(struct FileInfoBlock));
return status;
}