X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Fmain.c;h=8b6b08e0a57b7b4cad9ccf47698771a284e26749;hp=624d4fa2b4a105f6361c48a8be8ee6076a227013;hb=b8f7cbe65e70f2ec792c447995ba00ca360ec0c9;hpb=394240ceca86d02b0219f84aead0483209db12fd diff --git a/restore/main.c b/restore/main.c index 624d4fa..8b6b08e 100644 --- a/restore/main.c +++ b/restore/main.c @@ -2,7 +2,8 @@ * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 - * Stelian Pop , 1999 + * Stelian Pop , 1999-2000 + * Stelian Pop - AlcĂ´ve , 2000 */ /* @@ -40,15 +41,23 @@ #ifndef lint static const char rcsid[] = - "$Id: main.c,v 1.7 1999/11/22 21:39:42 tiniou Exp $"; + "$Id: main.c,v 1.26 2001/07/18 13:12:33 stelian Exp $"; #endif /* not lint */ +#include +#include #include #include #include #ifdef __linux__ +#include +#include +#ifdef HAVE_EXT2FS_EXT2_FS_H +#include +#else #include +#endif #include #include #include @@ -72,7 +81,7 @@ static const char rcsid[] = #include "extern.h" int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; -int hflag = 1, mflag = 1, Nflag = 0; +int hflag = 1, mflag = 1, Nflag = 0, zflag = 0; int uflag = 0; int dokerberos = 0; char command = '\0'; @@ -81,13 +90,16 @@ long volno = 0; long ntrec; char *dumpmap; char *usedinomap; -ino_t maxino; +dump_ino_t maxino; time_t dumptime; time_t dumpdate; FILE *terminal; char *tmpdir; int compare_ignore_not_found; -char *filesys = NULL; +int compare_errors; +char filesys[NAMELEN]; +static const char *stdin_opt = NULL; +char *bot_script = NULL; #ifdef __linux__ char *__progname; @@ -95,19 +107,28 @@ char *__progname; static void obsolete __P((int *, char **[])); static void usage __P((void)); +static void use_stdin __P((const char *)); int main(int argc, char *argv[]) { int ch; - ino_t ino; + dump_ino_t ino; char *inputdev = _PATH_DEFTAPE; char *symtbl = "./restoresymtable"; char *p, name[MAXPATHLEN]; + FILE *filelist = NULL; + char fname[MAXPATHLEN]; +#ifdef USE_QFA + tapeposflag = 0; +#endif +#ifdef USE_QFADEBUG + time_t tistart, tiend, titaken; +#endif /* Temp files should *not* be readable. We set permissions later. */ (void) umask(077); - + filesys[0] = '\0'; #ifdef __linux__ __progname = argv[0]; #endif @@ -124,12 +145,16 @@ main(int argc, char *argv[]) for (p = tmpdir + strlen(tmpdir) - 1; p >= tmpdir && *p == '/'; p--) ; obsolete(&argc, &argv); + while ((ch = getopt(argc, argv, + "b:CcdD:f:F:hi" #ifdef KERBEROS -#define optlist "b:CcdD:f:hikmMNRrs:tT:uvxy" -#else -#define optlist "b:CcdD:f:himMNRrs:tT:uvxy" + "k" +#endif + "mMN" +#ifdef USE_QFA + "Q:" #endif - while ((ch = getopt(argc, argv, optlist)) != -1) + "Rrs:tT:uvxX:y")) != -1) switch(ch) { case 'b': /* Change default tape blocksize. */ @@ -144,7 +169,8 @@ main(int argc, char *argv[]) cvtflag = 1; break; case 'D': - filesys = optarg; + strncpy(filesys, optarg, NAMELEN); + filesys[NAMELEN - 1] = '\0'; break; case 'T': tmpdir = optarg; @@ -153,8 +179,13 @@ main(int argc, char *argv[]) dflag = 1; break; case 'f': + if( !strcmp(optarg,"-") ) + use_stdin("-f"); inputdev = optarg; break; + case 'F': + bot_script = optarg; + break; case 'h': hflag = 0; break; @@ -184,6 +215,12 @@ main(int argc, char *argv[]) case 'N': Nflag = 1; break; +#ifdef USE_QFA + case 'Q': + gTapeposfile = optarg; + tapeposflag = 1; + break; +#endif case 's': /* Dumpnum (skip to) for multifile dump tapes. */ dumpnum = strtol(optarg, &p, 10); @@ -198,6 +235,15 @@ main(int argc, char *argv[]) case 'v': vflag = 1; break; + case 'X': + if( !strcmp(optarg,"-") ) { + use_stdin("-X"); + filelist = stdin; + } + else + if ( !(filelist = fopen(optarg,"r")) ) + errx(1, "can't open file for reading -- %s", optarg); + break; case 'y': yflag = 1; break; @@ -210,6 +256,11 @@ main(int argc, char *argv[]) if (command == '\0') errx(1, "none of C, i, R, r, t or x options specified"); +#ifdef USE_QFA + if (!mflag && tapeposflag) + errx(1, "m and Q options are mutually exclusive"); +#endif + if (signal(SIGINT, onintr) == SIG_IGN) (void) signal(SIGINT, SIG_IGN); if (signal(SIGTERM, onintr) == SIG_IGN) @@ -220,23 +271,63 @@ main(int argc, char *argv[]) setinput(inputdev); - if (argc == 0) { + if (argc == 0 && !filelist) { argc = 1; *--argv = "."; } +#ifdef USE_QFA + if (tapeposflag) { + msg("reading QFA positions from %s\n", gTapeposfile); + if ((gTapeposfp = fopen(gTapeposfile, "r")) == NULL) + errx(1, "can't open file for reading -- %s", + gTapeposfile); + /* start reading header info */ + if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL) + errx(1, "not requested format of -- %s", gTapeposfile); + gTps[strlen(gTps) - 1] = 0; /* delete end of line */ + if (strcmp(gTps, QFA_MAGIC) != 0) + errx(1, "not requested format of -- %s", gTapeposfile); + if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL) + errx(1, "not requested format of -- %s", gTapeposfile); + gTps[strlen(gTps) - 1] = 0; + if (strcmp(gTps, QFA_VERSION) != 0) + errx(1, "not requested format of -- %s", gTapeposfile); + /* read dumpdate */ + if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL) + errx(1, "not requested format of -- %s", gTapeposfile); + gTps[strlen(gTps) - 1] = 0; + /* TODO: check dumpdate from QFA file with current dump file's + * dump date */ + /* if not equal either output warning and continue without QFA + * or abort */ + /* read empty line */ + if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL) + errx(1, "not requested format of -- %s", gTapeposfile); + gTps[strlen(gTps) - 1] = 0; + /* read table header line */ + if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL) + errx(1, "not requested format of -- %s", gTapeposfile); + gTps[strlen(gTps) - 1] = 0; + /* end reading header info */ + /* tape position table starts here */ + gSeekstart = ftell(gTapeposfp); /* remember for later use */ +} +#endif /* USE_QFA */ + switch (command) { /* * Compare contents of tape. */ case 'C': { - struct stat stbuf; + struct STAT stbuf; Vprintf(stdout, "Begin compare restore\n"); compare_ignore_not_found = 0; + compare_errors = 0; setup(); printf("filesys = %s\n", filesys); - if (stat(filesys, &stbuf) < 0) + if (STAT(filesys, &stbuf) < 0) err(1, "cannot stat directory %s", filesys); if (chdir(filesys) < 0) err(1, "cannot cd to %s", filesys); @@ -246,6 +337,10 @@ main(int argc, char *argv[]) treescan(".", ROOTINO, nodeupdates); compareleaves(); checkrestore(); + if (compare_errors) { + printf("Some files were modified!\n"); + exit(2); + } break; } @@ -308,6 +403,23 @@ main(int argc, char *argv[]) checkrestore(); dumpsymtable(symtbl, (long)1); break; + +/* handle file names from either text file (-X) or the command line */ +#define NEXTFILE(p) \ + p = NULL; \ + if (argc) { \ + --argc; \ + p = *argv++; \ + } \ + else if (filelist) { \ + if ((p = fgets(fname, MAXPATHLEN, filelist))) { \ + if ( *p && *(p + strlen(p) - 1) == '\n' ) /* possible null string */ \ + *(p + strlen(p) - 1) = '\0'; \ + if ( !*p ) /* skip empty lines */ \ + continue; \ + } \ + } + /* * List contents of tape. */ @@ -315,8 +427,11 @@ main(int argc, char *argv[]) setup(); extractdirs(0); initsymtable((char *)0); - while (argc--) { - canon(*argv++, name, sizeof(name)); + for (;;) { + NEXTFILE(p); + if (!p) + break; + canon(p, name, sizeof(name)); ino = dirlookup(name); if (ino == 0) continue; @@ -327,11 +442,17 @@ main(int argc, char *argv[]) * Batch extraction of tape contents. */ case 'x': +#ifdef USE_QFADEBUG + tistart = time(NULL); +#endif setup(); extractdirs(1); initsymtable((char *)0); - while (argc--) { - canon(*argv++, name, sizeof(name)); + for (;;) { + NEXTFILE(p); + if (!p) + break; + canon(p, name, sizeof(name)); ino = dirlookup(name); if (ino == 0) continue; @@ -344,6 +465,12 @@ main(int argc, char *argv[]) setdirmodes(0); if (dflag) checkrestore(); +#ifdef USE_QFADEBUG + tiend = time(NULL); + titaken = tiend - tistart; + msg("restore took %d:%02d:%02d\n", titaken / 3600, + (titaken % 3600) / 60, titaken % 60); +#endif /* USE_QFADEBUG */ break; } exit(0); @@ -354,20 +481,36 @@ main(int argc, char *argv[]) static void usage(void) { +#ifdef __linux__ + const char *ext2ver, *ext2date; + + ext2fs_get_library_version(&ext2ver, &ext2date); + (void)fprintf(stderr, "%s %s (using libext2fs %s of %s)\n", + __progname, _DUMP_VERSION, ext2ver, ext2date); +#else + (void)fprintf(stderr, "%s %s\n", __progname, _DUMP_VERSION); +#endif + #ifdef KERBEROS #define kerbflag "k" #else #define kerbflag #endif - (void)fprintf(stderr, - "%s %s\n", __progname, _DUMP_VERSION); + +#ifdef USE_QFA +#define qfaflag "[-Q file] " +#else +#define qfaflag +#endif + (void)fprintf(stderr, - "usage:\t%s%s\n\t%s%s\n\t%s%s\n\t%s%s\n\t%s%s\n", - __progname, " -i [-ch" kerbflag "mMuvy] [-b blocksize] [-f file] [-s fileno]", - __progname, " -r [-c" kerbflag "Muvy] [-b blocksize] [-f file] [-s fileno]", - __progname, " -R [-c" kerbflag "Muvy] [-b blocksize] [-f file] [-s fileno]", - __progname, " -x [-ch" kerbflag "mMuvy] [-b blocksize] [-f file] [-s fileno] [file ...]", - __progname, " -t [-ch" kerbflag "Muvy] [-b blocksize] [-f file] [-s fileno] [file ...]"); + "usage:\t%s%s\n\t%s%s\n\t%s%s\n\t%s%s\n\t%s%s\n\t%s%s\n", + __progname, " -C [-c" kerbflag "Mvy] [-b blocksize] [-D filesystem] [-f file] [-F script] [-s fileno]", + __progname, " -i [-ch" kerbflag "mMuvy] [-b blocksize] [-f file] [-F script] " qfaflag "[-s fileno]", + __progname, " -r [-c" kerbflag "Muvy] [-b blocksize] [-f file] [-F script] [-s fileno] [-T directory]", + __progname, " -R [-c" kerbflag "Muvy] [-b blocksize] [-f file] [-F script] [-s fileno] [-T directory]", + __progname, " -t [-ch" kerbflag "Muvy] [-b blocksize] [-f file] [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]", + __progname, " -x [-ch" kerbflag "mMuvy] [-b blocksize] [-f file] [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]"); exit(1); } @@ -402,8 +545,13 @@ obsolete(int *argcp, char **argvp[]) for (flags = 0; *ap; ++ap) { switch (*ap) { case 'b': + case 'D': case 'f': + case 'F': + case 'Q': case 's': + case 'T': + case 'X': if (*argv == NULL) { warnx("option requires an argument -- %c", *ap); usage(); @@ -438,3 +586,16 @@ obsolete(int *argcp, char **argvp[]) /* Update argument count. */ *argcp = nargv - *argvp - 1; } + +/* + * use_stdin -- + * reserve stdin for opt (avoid conflicts) + */ +void +use_stdin(const char *opt) +{ + if (stdin_opt) + errx(1, "can't handle standard input for both %s and %s", + stdin_opt, opt); + stdin_opt = opt; +}