]> git.wh0rd.org - dump.git/blobdiff - dump/optr.c
noos -> popies.net
[dump.git] / dump / optr.c
index 41aa20e4b3b6242c896859c67f83d6934995e7c8..73347fabdc2dc743c8d9373fc16da88fc2ca2ca4 100644 (file)
@@ -2,7 +2,8 @@
  *     Ported to Linux's Second Extended File System as part of the
  *     dump and restore backup suit
  *     Remy Card <card@Linux.EU.Org>, 1994-1997
- *     Stelian Pop <pop@cybercable.fr>, 1999 
+ *     Stelian Pop <stelian@popies.net>, 1999-2000
+ *     Stelian Pop <stelian@popies.net> - AlcĂ´ve <www.alcove.com>, 2000-2002
  */
 
 /*-
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: optr.c,v 1.7 1999/10/18 09:48:00 tiniou Exp $";
+       "$Id: optr.c,v 1.29 2002/01/16 09:32:14 stelian Exp $";
 #endif /* not lint */
 
+#include <config.h>
 #include <sys/param.h>
 #include <sys/wait.h>
 #include <sys/time.h>
+#include <time.h>
 
 #include <errno.h>
 #include <fstab.h>
@@ -59,7 +62,11 @@ static const char rcsid[] =
 #include <sys/stat.h>
 
 #ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
 #include <linux/ext2_fs.h>
+#endif
 #include <ext2fs/ext2fs.h>
 #include <bsdcompat.h>
 #include <signal.h>
@@ -67,11 +74,15 @@ static const char rcsid[] =
 
 #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.
@@ -94,11 +105,13 @@ query(const char *question)
        FILE    *mytty;
        time_t  firstprompt, when_answered;
 
-#ifdef __linux__
-       (void)time4(&(firstprompt));
-#else
-       (void)time((time_t *)&(firstprompt));
-#endif
+       if (qflag) {
+               msg("%s - forced abort\n", question);
+               dumpabort(0);
+               /* NOTREACHED */
+       }
+
+       firstprompt = time(NULL);
 
        if ((mytty = fopen(_PATH_TTY, "r")) == NULL)
                quit("fopen on %s fails: %s\n", _PATH_TTY, strerror(errno));
@@ -131,16 +144,12 @@ query(const char *question)
        if (signal(SIGALRM, sig) == SIG_IGN)
                signal(SIGALRM, SIG_IGN);
        (void) fclose(mytty);
-#ifdef __linux__
-       (void)time4(&(when_answered));
-#else
-       (void)time((time_t *)&(when_answered));
-#endif
+       when_answered = time(NULL);
        /*
         * Adjust the base for time estimates to ignore time we spent waiting
         * for operator input.
         */
-       if ((tstart_writing != 0) && (when_answered != (time_t)-1) && (firstprompt != (time_t)-1))
+       if (tstart_writing != 0)
                tstart_writing += (when_answered - firstprompt);
        return(back);
 }
@@ -240,7 +249,7 @@ broadcast(const char *message)
                return;
        }
 
-       clock = time((time_t *)0);
+       clock = time(NULL);
        localclock = localtime(&clock);
 
        if ((f_utmp = fopen(_PATH_UTMP, "r")) == NULL) {
@@ -317,23 +326,16 @@ time_t    tschedule = 0;
 void
 timeest(void)
 {
-       time_t  tnow, deltat;
+       time_t tnow = time(NULL);
 
-#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);
+               }
        }
 }
 
@@ -427,9 +429,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;
@@ -439,6 +445,7 @@ allocfsent(struct fstab *fs)
 
 struct pfstab {
        struct  pfstab *pf_next;
+       struct  dumpdates *pf_dd;
        struct  fstab *pf_fstab;
 };
 
@@ -447,8 +454,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",
@@ -464,8 +472,15 @@ getfstab(void)
                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();
 }
@@ -486,7 +501,7 @@ fstabsearch(const char *key)
 {
        register struct pfstab *pf;
        register struct fstab *fs;
-       char *rn;
+       const char *rn;
 
        for (pf = table; pf != NULL; pf = pf->pf_next) {
                fs = pf->pf_fstab;
@@ -524,7 +539,7 @@ fstabsearchdir(const char *key, char *directory)
        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) &&
                    strncmp(fs->fs_file, key, strlen(fs->fs_file)) == 0 &&
                    (key[strlen(fs->fs_file)] == '/' ||
                     fs->fs_file[strlen(fs->fs_file) - 1] == '/')) {
@@ -545,49 +560,129 @@ 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)
+{
+#ifdef FDEBUG
+       printf("checking dev %s: lvl %d, mtpt %s\n", dev, level, mtpt);
+#endif
+       if (!dumpme && arg == 'w')
+               return;
+
+       (void) printf("%c %8s\t(%6s) Last dump: ",
+                     dumpme && (arg != 'w') ? '>' : ' ',
+                     dev,
+                     mtpt ? mtpt : "");
+
+       /*
+        * Check ddate > 365 to avoid issues with fs in stab but not dumpdates.
+        * Not a problem, because ddate is in seconds since the epoch anyways.
+        */
+       if (ddate > 365) {
+               char *date, *d;
+
+               date = (char *)ctime(&ddate);
+               d = strchr(date, '\n');
+               if (d) *d = '\0';
+               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=NULL;
-       char *lastname, *date;
-       int dumpme;
+       struct pfstab *pf;
        time_t tnow;
 
-       (void) time(&tnow);
+       tnow = time(NULL);
        getfstab();             /* /etc/fstab input */
        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");
+
+       /* For files in dumpdates, get the last dump level and date */
        if (ddatev != NULL) {
+               struct dumpdates *dtwalk = NULL;
+               int i;
+               char *lastname;
+
                qsort((char *) ddatev, nddates, sizeof(struct dumpdates *), datesort);
 
-               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) {
+                       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 positive 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;
+                               else
+                                       dt->fs_freq = -dtwalk->dd_level;
+#ifdef FDEBUG
+                               printf("%s fs_freq set to %d\n", lastname,
+                                       dt->fs_freq);
+#endif
+                       }
+               }
+       }
+
+       /* 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 :
+                                                             dt->fs_freq,
+                                          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)
+                               sizeof(dtwalk->dd_name)) == 0 ||
+                           dtwalk->dd_fstab != NULL)
                                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);
+                       print_wmsg(arg, 0, dtwalk->dd_name,
+                                  dtwalk->dd_level, NULL, dtwalk->dd_ddate);
                }
        }
 }