X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=dump%2Foptr.c;h=f0be80bc263c59ae0f3c779049e6226b897052ed;hb=401a4d13e4c30d46074531c6c26efefcaf3bbdaf;hp=96b829af656f9c8e93d30b5a1d371cc73de2f8c0;hpb=ddd2ef55b78a62c4bc3daad18bef8a90e85a2052;p=dump.git diff --git a/dump/optr.c b/dump/optr.c index 96b829a..f0be80b 100644 --- a/dump/optr.c +++ b/dump/optr.c @@ -2,8 +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,13 +40,11 @@ */ #ifndef lint -#if 0 -static char sccsid[] = "@(#)optr.c 8.2 (Berkeley) 1/6/94"; -#endif static const char rcsid[] = - "$Id: optr.c,v 1.3 1999/10/11 12:59:19 stelian Exp $"; + "$Id: optr.c,v 1.20 2001/02/22 10:57:40 stelian Exp $"; #endif /* not lint */ +#include #include #include #include @@ -60,21 +58,27 @@ static const char rcsid[] = #include #include #include +#include #ifdef __linux__ #include #include #include #include +#include #endif #include "dump.h" #include "pathnames.h" +#include "bylabel.h" static void alarmcatch __P((int)); int datesort __P((const void *, const void *)); static void sendmes __P((const char *, const char *)); +/* List of filesystem types that we can dump (same ext2 on-disk format) */ +static char *fstypes[] = { "ext2", "ext3", "InterMezzo", NULL }; + /* * Query the operator; This previously-fascist piece of code * no longer requires an exact response. @@ -97,7 +101,11 @@ query(const char *question) FILE *mytty; time_t firstprompt, when_answered; - firstprompt = time(NULL); +#ifdef __linux__ + (void)time4(&(firstprompt)); +#else + (void)time((time_t *)&(firstprompt)); +#endif if ((mytty = fopen(_PATH_TTY, "r")) == NULL) quit("fopen on %s fails: %s\n", _PATH_TTY, strerror(errno)); @@ -130,12 +138,16 @@ query(const char *question) if (signal(SIGALRM, sig) == SIG_IGN) signal(SIGALRM, SIG_IGN); (void) fclose(mytty); - when_answered = time(NULL); +#ifdef __linux__ + (void)time4(&(when_answered)); +#else + (void)time((time_t *)&(when_answered)); +#endif /* * Adjust the base for time estimates to ignore time we spent waiting * for operator input. */ - if (tstart_writing != 0) + if ((tstart_writing != 0) && (when_answered != (time_t)-1) && (firstprompt != (time_t)-1)) tstart_writing += (when_answered - firstprompt); return(back); } @@ -312,19 +324,21 @@ time_t tschedule = 0; void timeest(void) { - time_t tnow, deltat; + time_t tnow; +#ifdef __linux__ + (void) time4(&tnow); +#else (void) time((time_t *) &tnow); +#endif if (tnow >= tschedule) { + char *buf = mktimeest(tnow); tschedule = tnow + 300; - if (blockswritten < 500) - return; - deltat = tstart_writing - tnow + - (1.0 * (tnow - tstart_writing)) - / blockswritten * tapesize; - msg("%3.2f%% done, finished in %d:%02d\n", - (blockswritten * 100.0) / tapesize, - deltat / 3600, (deltat % 3600) / 60); + if (buf) { + fprintf(stderr, " DUMP: "); + fwrite(buf, strlen(buf), 1, stderr); + fflush(stderr); + } } } @@ -349,8 +363,14 @@ msg(fmt, va_alist) va_start(ap); #endif (void) vfprintf(stderr, fmt, ap); + va_end(ap); (void) fflush(stdout); (void) fflush(stderr); +#ifdef __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif (void) vsnprintf(lastmsg, sizeof(lastmsg), fmt, ap); va_end(ap); } @@ -412,9 +432,13 @@ allocfsent(struct fstab *fs) register struct fstab *new; new = (struct fstab *)malloc(sizeof (*fs)); - if (new == NULL || - (new->fs_file = strdup(fs->fs_file)) == NULL || + if (new == NULL) + quit("%s\n", strerror(errno)); + if (strlen(fs->fs_file) > 1 && fs->fs_file[strlen(fs->fs_file) - 1] == '/') + fs->fs_file[strlen(fs->fs_file) - 1] = '\0'; + if ((new->fs_file = strdup(fs->fs_file)) == NULL || (new->fs_type = strdup(fs->fs_type)) == NULL || + (new->fs_vfstype = strdup(fs->fs_vfstype)) == NULL || (new->fs_spec = strdup(fs->fs_spec)) == NULL) quit("%s\n", strerror(errno)); new->fs_passno = fs->fs_passno; @@ -424,6 +448,7 @@ allocfsent(struct fstab *fs) struct pfstab { struct pfstab *pf_next; + struct dumpdates *pf_dd; struct fstab *pf_fstab; }; @@ -432,8 +457,9 @@ static struct pfstab *table; void getfstab(void) { - register struct fstab *fs; - register struct pfstab *pf; + struct fstab *fs; + struct pfstab *pf; + struct pfstab *pfold = NULL; if (setfsent() == 0) { msg("Can't open %s for dump table information: %s\n", @@ -446,11 +472,19 @@ getfstab(void) strcmp(fs->fs_type, FSTAB_RQ)) continue; fs = allocfsent(fs); + fs->fs_passno = 0; if ((pf = (struct pfstab *)malloc(sizeof (*pf))) == NULL) quit("%s\n", strerror(errno)); pf->pf_fstab = fs; - pf->pf_next = table; - table = pf; + pf->pf_next = NULL; + + /* keep table in /etc/fstab order for use with -w and -W */ + if (pfold) { + pfold->pf_next = pf; + pfold = pf; + } else + pfold = table = pf; + } (void) endfsent(); } @@ -501,11 +535,15 @@ fstabsearchdir(const char *key, char *directory) register struct fstab *fs; register struct fstab *found_fs = NULL; unsigned int size = 0; + struct stat buf; + + if (stat(key, &buf) == 0 && S_ISBLK(buf.st_mode)) + return NULL; for (pf = table; pf != NULL; pf = pf->pf_next) { fs = pf->pf_fstab; if (strlen(fs->fs_file) > size && - strlen(key) > strlen(fs->fs_file) + 2 && + strlen(key) > strlen(fs->fs_file) + 1 && strncmp(fs->fs_file, key, strlen(fs->fs_file)) == 0 && (key[strlen(fs->fs_file)] == '/' || fs->fs_file[strlen(fs->fs_file) - 1] == '/')) { @@ -526,48 +564,123 @@ fstabsearchdir(const char *key, char *directory) } #endif +static void +print_wmsg(char arg, int dumpme, const char *dev, int level, + const char *mtpt, time_t ddate) +{ + char *date = NULL; + + if (ddate) { + char *d; + date = (char *)ctime(&ddate); + d = strchr(date, '\n'); + if (d) *d = '\0'; + } + + if (!dumpme && arg == 'w') + return; + + (void) printf("%c %8s\t(%6s) Last dump: ", + dumpme && (arg != 'w') ? '>' : ' ', + dev, + mtpt ? mtpt : ""); + + if (ddate) + printf("Level %c, Date %s\n", + level, date); + else + printf("never\n"); +} + /* * Tell the operator what to do */ void lastdump(char arg) /* w ==> just what to do; W ==> most recent dumps */ { - register int i; - register struct fstab *dt; - register struct dumpdates *dtwalk; - char *lastname, *date; - int dumpme; + struct pfstab *pf; time_t tnow; (void) time(&tnow); getfstab(); /* /etc/fstab input */ - initdumptimes(); /* /etc/dumpdates input */ - qsort((char *) ddatev, nddates, sizeof(struct dumpdates *), datesort); + initdumptimes(0); /* dumpdates input */ + if (ddatev == NULL && table == NULL) { + (void) printf("No %s or %s file found\n", + _PATH_FSTAB, _PATH_DUMPDATES); + return; + } if (arg == 'w') (void) printf("Dump these file systems:\n"); else (void) printf("Last dump(s) done (Dump '>' file systems):\n"); - lastname = "??"; - ITITERATE(i, dtwalk) { - if (strncmp(lastname, dtwalk->dd_name, - sizeof(dtwalk->dd_name)) == 0) - continue; - date = (char *)ctime(&dtwalk->dd_ddate); - date[16] = '\0'; /* blast away seconds and year */ - lastname = dtwalk->dd_name; - dt = fstabsearch(dtwalk->dd_name); - dumpme = (dt != NULL && - dt->fs_freq != 0 && - dtwalk->dd_ddate < tnow - (dt->fs_freq * 86400)); - if (arg != 'w' || dumpme) - (void) printf( - "%c %8s\t(%6s) Last dump: Level %c, Date %s\n", - dumpme && (arg != 'w') ? '>' : ' ', - dtwalk->dd_name, - dt ? dt->fs_file : "", - dtwalk->dd_level, - date); + + if (ddatev != NULL) { + struct dumpdates *dtwalk = NULL; + int i; + char *lastname; + + qsort((char *) ddatev, nddates, sizeof(struct dumpdates *), datesort); + + lastname = "??"; + ITITERATE(i, dtwalk) { + struct fstab *dt; + if (strncmp(lastname, dtwalk->dd_name, + sizeof(dtwalk->dd_name)) == 0) + continue; + lastname = dtwalk->dd_name; + if ((dt = dtwalk->dd_fstab) != NULL) { + /* Overload fs_freq as dump level and + * fs_passno as date, because we can't + * change struct fstab format. + * A negative fs_freq means this + * filesystem needs to be dumped. + */ + dt->fs_passno = dtwalk->dd_ddate; + if (dt->fs_freq > 0 && (dtwalk->dd_ddate < + tnow - (dt->fs_freq * 86400))) + dt->fs_freq = -dtwalk->dd_level - 1; + else + dt->fs_freq = dtwalk->dd_level + 1; + + } + } + } + + /* print in /etc/fstab order only those filesystem types we can dump */ + for (pf = table; pf != NULL; pf = pf->pf_next) { + struct fstab *dt = pf->pf_fstab; + char **type; + + for (type = fstypes; *type != NULL; type++) { + if (strncmp(dt->fs_vfstype, *type, + sizeof(dt->fs_vfstype)) == 0) { + const char *disk = get_device_name(dt->fs_spec); + print_wmsg(arg, dt->fs_freq < 0, + disk ? disk : dt->fs_spec, + dt->fs_freq < 0 ? -dt->fs_freq - 1 : dt->fs_freq - 1, + dt->fs_file, + dt->fs_passno); + } + } + } + + /* print in /etc/dumpdates order if not in /etc/fstab */ + if (ddatev != NULL) { + struct dumpdates *dtwalk = NULL; + char *lastname; + int i; + + lastname = "??"; + ITITERATE(i, dtwalk) { + if (strncmp(lastname, dtwalk->dd_name, + sizeof(dtwalk->dd_name)) == 0 || + dtwalk->dd_fstab != NULL) + continue; + lastname = dtwalk->dd_name; + print_wmsg(arg, 0, dtwalk->dd_name, + dtwalk->dd_level, NULL, dtwalk->dd_ddate); + } } }