X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Fmain.c;h=496391d759f612660c3568407edb78a5e3f3f723;hp=77ae96d1c466a2315a9cc8692b8c669c3a4a2d33;hb=df3d2ef98b911ebb7a7b7c6137e60e28eb39e5f1;hpb=11856e771fadee7ddb9b5a613c91f562bf363da7 diff --git a/restore/main.c b/restore/main.c index 77ae96d..496391d 100644 --- a/restore/main.c +++ b/restore/main.c @@ -18,11 +18,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -41,11 +37,13 @@ #ifndef lint static const char rcsid[] = - "$Id: main.c,v 1.34 2002/01/16 09:32:14 stelian Exp $"; + "$Id: main.c,v 1.50 2005/07/07 09:16:08 stelian Exp $"; #endif /* not lint */ #include #include +#include +#include #include #include #include @@ -62,7 +60,15 @@ static const char rcsid[] = #include #include #else /* __linux__ */ +#ifdef sunos +#include +#include +#include +#include +#include +#else #include +#endif #endif /* __linux__ */ #include @@ -80,16 +86,21 @@ static const char rcsid[] = #include "restore.h" #include "extern.h" -int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; +int abortifconnerr = 1; /* set to 1 if lib dumprmt.o should exit on connection errors + otherwise just print a message using msg */ + +int aflag = 0, bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; int hflag = 1, mflag = 1, Mflag = 0, Nflag = 0, Vflag = 0, zflag = 0; -int uflag = 0, lflag = 0, Lflag = 0; +int uflag = 0, lflag = 0, Lflag = 0, oflag = 0; +int ufs2flag = 0; +char *Afile = NULL; int dokerberos = 0; char command = '\0'; long dumpnum = 1; long volno = 0; long ntrec; -char *dumpmap; -char *usedinomap; +char *dumpmap = NULL; +char *usedinomap = NULL; dump_ino_t maxino; time_t dumptime; time_t dumpdate; @@ -100,6 +111,9 @@ int compare_errors; char filesys[NAMELEN]; static const char *stdin_opt = NULL; char *bot_script = NULL; +dump_ino_t volinfo[TP_NINOS]; +int wdfd; +int dirhash_size = 1; #ifdef USE_QFA FILE *gTapeposfp; @@ -107,9 +121,15 @@ char *gTapeposfile; char gTps[255]; long gSeekstart; int tapeposflag; +int gTapeposfd; +int createtapeposflag; +unsigned long qfadumpdate; +long long curtapepos; #endif /* USE_QFA */ -#ifdef __linux__ +long smtc_errno; + +#if defined(__linux__) || defined(sunos) char *__progname; #endif @@ -117,6 +137,8 @@ static void obsolete __P((int *, char **[])); static void usage __P((void)); static void use_stdin __P((const char *)); +#define FORCED_UMASK (077) + int main(int argc, char *argv[]) { @@ -127,17 +149,19 @@ main(int argc, char *argv[]) char *p, name[MAXPATHLEN]; FILE *filelist = NULL; char fname[MAXPATHLEN]; -#ifdef USE_QFA - tapeposflag = 0; -#endif -#ifdef USE_QFADEBUG + mode_t orig_umask; +#ifdef DEBUG_QFA time_t tistart, tiend, titaken; #endif +#ifdef USE_QFA + tapeposflag = 0; + createtapeposflag = 0; +#endif /* USE_QFA */ /* Temp files should *not* be readable. We set permissions later. */ - (void) umask(077); + orig_umask = umask(FORCED_UMASK); filesys[0] = '\0'; -#ifdef __linux__ +#if defined(__linux__) || defined(sunos) __progname = argv[0]; #endif @@ -154,16 +178,23 @@ main(int argc, char *argv[]) ; obsolete(&argc, &argv); while ((ch = getopt(argc, argv, - "b:CcdD:f:F:hi" + "aA:b:CcdD:f:F:hH:i" #ifdef KERBEROS "k" #endif - "lL:mMN" + "lL:mMNo" #ifdef USE_QFA - "Q:" + "P:Q:" #endif "Rrs:tT:uvVxX:y")) != -1) switch(ch) { + case 'a': + aflag = 1; + break; + case 'A': + Afile = optarg; + aflag = 1; + break; case 'b': /* Change default tape blocksize. */ bflag = 1; @@ -197,6 +228,13 @@ main(int argc, char *argv[]) case 'h': hflag = 0; break; + case 'H': + dirhash_size = strtol(optarg, &p, 10); + if (*p) + errx(1, "illegal hash size -- %s", optarg); + if (dirhash_size < 1) + errx(1, "hash size must be greater than 0"); + break; #ifdef KERBEROS case 'k': dokerberos = 1; @@ -204,6 +242,9 @@ main(int argc, char *argv[]) #endif case 'C': case 'i': +#ifdef USE_QFA + case 'P': +#endif case 'R': case 'r': case 't': @@ -213,6 +254,13 @@ main(int argc, char *argv[]) "%c and %c options are mutually exclusive", ch, command); command = ch; +#ifdef USE_QFA + if (ch == 'P') { + gTapeposfile = optarg; + createtapeposflag = 1; + } +#endif + break; case 'l': lflag = 1; @@ -233,10 +281,14 @@ main(int argc, char *argv[]) case 'N': Nflag = 1; break; + case 'o': + oflag = 1; + break; #ifdef USE_QFA case 'Q': gTapeposfile = optarg; tapeposflag = 1; + aflag = 1; break; #endif case 's': @@ -280,7 +332,13 @@ main(int argc, char *argv[]) #ifdef USE_QFA if (!mflag && tapeposflag) errx(1, "m and Q options are mutually exclusive"); + + if (tapeposflag && command != 'i' && command != 'x' && command != 't') + errx(1, "Q option is not valid for %c command", command); #endif + + if (Afile && command != 'i' && command != 'x' && command != 't') + errx(1, "A option is not valid for %c command", command); if (signal(SIGINT, onintr) == SIG_IGN) (void) signal(SIGINT, SIG_IGN); @@ -307,6 +365,10 @@ main(int argc, char *argv[]) else setinput(inputdev); + wdfd = open(".", O_RDONLY); + if (wdfd < 0) + err(1, "can't get current directory"); + if (argc == 0 && !filelist) { argc = 1; *--argv = "."; @@ -333,10 +395,7 @@ main(int argc, char *argv[]) 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 */ + qfadumpdate = atol(gTps); /* read empty line */ if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL) errx(1, "not requested format of -- %s", gTapeposfile); @@ -348,7 +407,19 @@ main(int argc, char *argv[]) /* end reading header info */ /* tape position table starts here */ gSeekstart = ftell(gTapeposfp); /* remember for later use */ -} +#ifdef sunos + if (GetSCSIIDFromPath(inputdev, &scsiid)) { + errx(1, "can't get SCSI-ID for %s\n", inputdev); + } + if (scsiid < 0) { + errx(1, "can't get SCSI-ID for %s\n", inputdev); + } + sprintf(smtcpath, "/dev/rsmtc%ld,0", scsiid); + if ((fdsmtc = open(smtcpath, O_RDWR)) == -1) { + errx(1, "can't open smtc device: %s, %d\n", smtcpath, errno); + } +#endif + } #endif /* USE_QFA */ switch (command) { @@ -361,6 +432,7 @@ main(int argc, char *argv[]) Vprintf(stdout, "Begin compare restore\n"); compare_ignore_not_found = 0; compare_errors = 0; + Nflag = 1; setup(); printf("filesys = %s\n", filesys); if (STAT(filesys, &stbuf) < 0) @@ -369,9 +441,10 @@ main(int argc, char *argv[]) err(1, "cannot cd to %s", filesys); compare_ignore_not_found = dumptime > 0; initsymtable((char *)0); - extractdirs(0); + extractdirs(1); treescan(".", ROOTINO, nodeupdates); compareleaves(); + comparedirmodes(); checkrestore(); if (compare_errors) { printf("Some files were modified!\n"); @@ -393,6 +466,7 @@ main(int argc, char *argv[]) * Incremental restoration of a file system. */ case 'r': + aflag = 1; /* in -r or -R mode, -a is default */ setup(); if (dumptime > 0) { /* @@ -430,6 +504,7 @@ main(int argc, char *argv[]) * Resume an incremental file system restoration. */ case 'R': + aflag = 1; /* in -r or -R mode, -a is default */ initsymtable(symtbl); skipmaps(); skipdirs(); @@ -463,6 +538,7 @@ main(int argc, char *argv[]) setup(); extractdirs(0); initsymtable((char *)0); + printvolinfo(); for (;;) { NEXTFILE(p); if (!p) @@ -478,7 +554,7 @@ main(int argc, char *argv[]) * Batch extraction of tape contents. */ case 'x': -#ifdef USE_QFADEBUG +#ifdef DEBUG_QFA tistart = time(NULL); #endif setup(); @@ -498,16 +574,82 @@ main(int argc, char *argv[]) } createfiles(); createlinks(); - setdirmodes(0); + setdirmodes(oflag ? FORCE : 0); if (dflag) checkrestore(); -#ifdef USE_QFADEBUG +#ifdef sunos + if (fdsmtc != -1) { + close(fdsmtc); + } +#endif /* sunos */ +#ifdef DEBUG_QFA tiend = time(NULL); titaken = tiend - tistart; msg("restore took %d:%02d:%02d\n", titaken / 3600, (titaken % 3600) / 60, titaken % 60); -#endif /* USE_QFADEBUG */ +#endif /* DEBUG_QFA */ break; +#ifdef USE_QFA + case 'P': +#ifdef DEBUG_QFA + tistart = time(NULL); +#endif +#ifdef sunos + if (GetSCSIIDFromPath(inputdev, &scsiid)) { + errx(1, "can't get SCSI-ID for %s\n", inputdev); + } + if (scsiid < 0) { + errx(1, "can't get SCSI-ID for %s\n", inputdev); + } + sprintf(smtcpath, "/dev/rsmtc%ld,0", scsiid); + if ((fdsmtc = open(smtcpath, O_RDWR)) == -1) { + errx(1, "can't open smtc device: %s, %d\n", smtcpath, errno); + } +#endif /* sunos */ + setup(); + msg("writing QFA positions to %s\n", gTapeposfile); + (void) umask(orig_umask); + if ((gTapeposfd = open(gTapeposfile, O_WRONLY|O_CREAT|O_TRUNC, + S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP + |S_IROTH|S_IWOTH)) < 0) + errx(1, "can't create tapeposfile\n"); + (void) umask(FORCED_UMASK); + /* print QFA-file header */ + sprintf(gTps, "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION, (unsigned long)spcl.c_date); + if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) + errx(1, "can't write tapeposfile\n"); + sprintf(gTps, "ino\ttapeno\ttapepos\n"); + if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) + errx(1, "can't write tapeposfile\n"); + + extractdirs(1); + initsymtable((char *)0); + for (;;) { + NEXTFILE(p); + if (!p) + break; + canon(p, name, sizeof(name)); + ino = dirlookup(name); + if (ino == 0) + continue; + if (mflag) + pathcheck(name); + treescan(name, ino, addfile); + } + createfiles(); +#ifdef sunos + if (fdsmtc != -1) { + close(fdsmtc); + } +#endif /* sunos */ +#ifdef DEBUG_QFA + tiend = time(NULL); + titaken = tiend - tistart; + msg("writing QFA positions took %d:%02d:%02d\n", titaken / 3600, + (titaken % 3600) / 60, titaken % 60); +#endif /* DEBUG_QFA */ + break; +#endif /* USE_QFA */ } exit(0); /* NOTREACHED */ @@ -517,9 +659,13 @@ main(int argc, char *argv[]) static void usage(void) { -#ifdef __linux__ + char white[MAXPATHLEN]; const char *ext2ver, *ext2date; + memset(white, ' ', MAXPATHLEN); + white[MIN(strlen(__progname), MAXPATHLEN - 1)] = '\0'; + +#ifdef __linux__ ext2fs_get_library_version(&ext2ver, &ext2date); (void)fprintf(stderr, "%s %s (using libext2fs %s of %s)\n", __progname, _DUMP_VERSION, ext2ver, ext2date); @@ -539,14 +685,33 @@ usage(void) #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\t%s%s\n", - __progname, " -C [-c" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file] [-F script] [-L limit] [-s fileno]", - __progname, " -i [-ch" kerbflag "lmMuvVy] [-b blocksize] [-f file] [-F script] " qfaflag "[-s fileno]", - __progname, " -r [-c" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script] [-s fileno] [-T directory]", - __progname, " -R [-c" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script] [-s fileno] [-T directory]", - __progname, " -t [-ch" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]", - __progname, " -x [-ch" kerbflag "lmMuvVy] [-b blocksize] [-f file] [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]"); + fprintf(stderr, + "usage:" + "\t%s -C [-cdH" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file]\n" + "\t%s [-F script] [-L limit] [-s fileno]\n" + "\t%s -i [-acdhH" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n" + "\t%s [-F script] " qfaflag "[-s fileno]\n" +#ifdef USE_QFA + "\t%s -P file [-acdhH" kerbflag "lmMuvVy] [-A file] [-b blocksize]\n" + "\t%s [-f file] [-F script] [-s fileno] [-X filelist] [file ...]\n" +#endif + "\t%s -r [-cdH" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n" + "\t%s [-s fileno] [-T directory]\n" + "\t%s -R [-cdH" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n" + "\t%s [-s fileno] [-T directory]\n" + "\t%s -t [-cdhH" kerbflag "lMuvVy] [-A file] [-b blocksize] [-f file]\n" + "\t%s [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n" + "\t%s -x [-acdhH" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n" + "\t%s [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n", + __progname, white, + __progname, white, +#ifdef USE_QFA + __progname, white, +#endif + __progname, white, + __progname, white, + __progname, white, + __progname, white); exit(1); } @@ -580,10 +745,12 @@ obsolete(int *argcp, char **argvp[]) for (flags = 0; *ap; ++ap) { switch (*ap) { + case 'A': case 'b': case 'D': case 'f': case 'F': + case 'H': case 'L': case 'Q': case 's':