]> git.wh0rd.org - dump.git/blobdiff - dump/main.c
Pretty printing when excluding inodes.
[dump.git] / dump / main.c
index d3ebc8285a73dc58ce9c2519a4be01dd6f8e9fdf..d7462c89fc6030c9c8c8cae93115297aaa17ad69 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.45 2001/04/12 16:03:29 stelian Exp $";
+       "$Id: main.c,v 1.54 2001/07/19 09:49:35 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
+#include <compatlfs.h>
 #include <ctype.h>
 #include <compaterr.h>
 #include <fcntl.h>
@@ -57,10 +58,14 @@ static const char rcsid[] =
 
 #include <sys/param.h>
 #include <sys/time.h>
+#include <time.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 <time.h>
 #include <sys/stat.h>
 #include <bsdcompat.h>
 #elif defined sunos
@@ -91,7 +96,7 @@ int   ntrec = NTREC;  /* # tape blocks in each tape record */
 int    cartridge = 0;  /* Assume non-cartridge tape */
 #ifdef USE_QFA
 int    tapepos = 0;    /* assume no QFA tapeposition needed by user */
-#endif /* USA_QFA */
+#endif /* USE_QFA */
 int    dokerberos = 0; /* Use Kerberos authentication */
 long   dev_bsize = 1;  /* recalculated below */
 long   blocksperfile;  /* output blocks per file */
@@ -109,9 +114,11 @@ int        maxbsize = 64*1024;     /* XXX MAXBSIZE from sys/param.h */
 static long numarg __P((const char *, long, long));
 static void obsolete __P((int *, char **[]));
 static void usage __P((void));
+static void do_exclude_from_file __P((char *));
+static void do_exclude_ino_str __P((char *));
 
-dump_ino_t iexclude_list[IEXCLUDE_MAXNUM];/* the inode exclude list */
-int iexclude_num = 0;                  /* number of elements in the list */
+static dump_ino_t iexclude_list[IEXCLUDE_MAXNUM];/* the inode exclude list */
+static int iexclude_num = 0;                   /* number of elements in the list */
 
 int
 main(int argc, char *argv[])
@@ -124,7 +131,7 @@ main(int argc, char *argv[])
        register int ch;
        int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
        dump_ino_t maxino;
-       struct stat statbuf;
+       struct STAT statbuf;
        dev_t filedev = 0;
 #ifdef __linux__
        errcode_t retval;
@@ -160,10 +167,10 @@ main(int argc, char *argv[])
 
 #ifdef USE_QFA
        gTapeposfd = -1;
-#endif /* USA_QFA */
+#endif /* USE_QFA */
 
        while ((ch = getopt(argc, argv,
-                           "0123456789aB:b:cd:e:f:F:h:L:"
+                           "0123456789aB:b:cd:e:E:f:F:h:L:"
 #ifdef KERBEROS
                            "k"
 #endif
@@ -219,19 +226,19 @@ main(int argc, char *argv[])
                        
                                        /* 04-Feb-00 ILC */
                case 'e':               /* exclude an inode */
-                       if (iexclude_num == IEXCLUDE_MAXNUM) {
-                               msg("Too many -e options\n");
-                               msg("The ENTIRE dump is aborted.\n");
-                               exit(X_STARTUP);
+                       {
+                       char *p = optarg, *q;
+                       while ((q = strchr(p, ','))) {
+                               *q = '\0';
+                               do_exclude_ino_str(p);
+                               p = q + 1;
                        }
-                       iexclude_list[iexclude_num++] = numarg("inode to exclude",0L,0L);
-                       if (iexclude_list[iexclude_num-1] <= ROOTINO) {
-                               msg("Cannot exclude inode %ld\n", (long)iexclude_list[iexclude_num-1]);
-                               msg("The ENTIRE dump is aborted.\n");
-                               exit(X_STARTUP);
+                       do_exclude_ino_str(p);
                        }
-                       msg("Added %d to exclude list\n",
-                           iexclude_list[iexclude_num-1]);
+                       break;
+
+               case 'E':               /* exclude inodes read from file */
+                       do_exclude_from_file(optarg);
                        break;
 
                case 'f':               /* output file */
@@ -282,7 +289,7 @@ main(int argc, char *argv[])
                        gTapeposfile = optarg;
                        tapepos = 1;
                        break;
-#endif /* USA_QFA */
+#endif /* USE_QFA */
                        
                case 's':               /* tape size, feet */
                        unlimited = 0;
@@ -348,7 +355,7 @@ main(int argc, char *argv[])
                tapeprefix = "standard output";
        }
 
-       if (blocksperfile)
+       if (blocksperfile && !compressed)
                blocksperfile = blocksperfile / ntrec * ntrec; /* round down */
        else if (!unlimited) {
                /*
@@ -514,10 +521,18 @@ main(int argc, char *argv[])
                strncpy(tape, tapeprefix, MAXPATHLEN);
        tape[MAXPATHLEN - 1] = '\0';
 
+       if (!pipeout) {
+               if (STAT(tape, &statbuf) != -1)
+                       fifoout= statbuf.st_mode & S_IFIFO;
+       }
+
        if (!sizest) {
 
                msg("Date of this level %c dump: %s", level,
                    ctime4(&spcl.c_date));
+#ifdef USE_QFA
+               gThisDumpDate = spcl.c_date;
+#endif
                if (spcl.c_ddate)
                        msg("Date of last level %c dump: %s", lastlevel,
                            ctime4(&spcl.c_ddate));
@@ -543,7 +558,7 @@ main(int argc, char *argv[])
                msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
        }
-       if ((diskfd = open(disk, O_RDONLY)) < 0) {
+       if ((diskfd = OPEN(disk, O_RDONLY)) < 0) {
                msg("Cannot open %s\n", disk);
                msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
@@ -604,10 +619,13 @@ main(int argc, char *argv[])
 
        nonodump = spcl.c_level < honorlevel;
 
-       msg("Label: %s\n", spcl.c_label);
+       if (!sizest) {
+               msg("Label: %s\n", spcl.c_label);
 
-       if (compressed)
-               msg("Compressing output at compression level %d\n", compressed);
+               if (compressed)
+                       msg("Compressing output at compression level %d\n", 
+                           compressed);
+       }
 
 #if defined(SIGINFO)
        (void)signal(SIGINFO, statussig);
@@ -619,7 +637,7 @@ main(int argc, char *argv[])
        if (directory[0] == 0)
                anydirskipped = mapfiles(maxino, &tapesize);
        else {
-               if (stat(pathname, &statbuf) == -1) {
+               if (STAT(pathname, &statbuf) == -1) {
                        msg("File cannot be accessed (%s).\n", pathname);
                        msg("The ENTIRE dump is aborted.\n");
                        exit(X_STARTUP);
@@ -636,7 +654,7 @@ main(int argc, char *argv[])
                int anydirskipped2;
                char *p = *argv;
                /* check if file is available */
-               if (stat(p, &statbuf) == -1) {
+               if (STAT(p, &statbuf) == -1) {
                        msg("File cannot be accessed (%s).\n", p);
                        msg("The ENTIRE dump is aborted.\n");
                        exit(X_STARTUP);
@@ -812,7 +830,7 @@ main(int argc, char *argv[])
 
        tnow = trewind();
 
-       if (pipeout)
+       if (pipeout || fifoout)
                msg("%ld tape blocks (%.2fMB)\n", spcl.c_tapea,
                        ((double)spcl.c_tapea * TP_BSIZE / 1048576));
        else
@@ -872,12 +890,11 @@ usage(void)
 #endif
                "MnSu"
                "] [-B records] [-b blocksize] [-d density]\n"
-               "\t%s [-e inode#] [-f file] [-h level] "
+               "\t%s [-e inode#,inode#,...] [-E file] [-f file] [-h level] "
 #ifdef USE_QFA
                "[-Q file] "
 #endif
-               "[-s feet]\n"
-               "\t%s [-T date] "
+               "\n\t%s [-s feet] [-T date] "
 #ifdef HAVE_ZLIB
                "[-z zlevel] "
 #endif
@@ -915,7 +932,7 @@ sig(int signo)
        case SIGHUP:
        case SIGTERM:
        case SIGTRAP:
-               if (pipeout)
+               if (pipeout || fifoout)
                        quit("Signal on pipe: cannot recover\n");
                msg("Rewriting attempted as response to unknown signal: %d.\n", signo);
                (void)fflush(stderr);
@@ -984,6 +1001,7 @@ obsolete(int *argcp, char **argvp[])
                case 'b':
                case 'd':
                case 'e':
+               case 'E':
                case 'f':
                case 'F':
                case 'h':
@@ -1025,3 +1043,78 @@ obsolete(int *argcp, char **argvp[])
        /* Update argument count. */
        *argcp = nargv - *argvp - 1;
 }
+
+/*
+ * This tests whether an inode is in the exclude list
+ */
+int
+exclude_ino(dump_ino_t ino)
+{
+       /* 04-Feb-00 ILC */
+       if (iexclude_num) {     /* if there are inodes in the exclude list */
+               int idx;        /* then check this inode against it */
+               for (idx = 0; idx < iexclude_num; idx++)
+                       if (ino == iexclude_list[idx])
+                               return 1;
+       }
+       return 0;
+}
+
+/*
+ * This tests adds an inode to the exclusion list if it isn't already there
+ */
+void
+do_exclude_ino(dump_ino_t ino, const char *reason)
+{
+       if (!exclude_ino(ino)) {
+               if (iexclude_num == IEXCLUDE_MAXNUM) {
+                       msg("Too many exclude options\n");
+                       msg("The ENTIRE dump is aborted.\n");
+                       exit(X_STARTUP);
+               }
+               if (reason)
+                       msg("Added inode %u to exclude list (%s)\n", 
+                           ino, reason);
+               else
+                       msg("Added inode %u to exclude list\n", ino);
+               iexclude_list[iexclude_num++] = ino;
+       }
+}
+
+static void
+do_exclude_ino_str(char * ino) {
+       char *r;
+       unsigned long inod;
+
+       inod = strtoul(ino, &r, 10);
+       if (*r != '\0' || inod <= ROOTINO) {
+               msg("Invalid inode argument %s\n", ino);
+               msg("The ENTIRE dump is aborted.\n");
+               exit(X_STARTUP);
+       }
+       do_exclude_ino(inod, NULL);
+}
+
+/*
+ * This reads a file containing one inode number per line and exclude them all
+ */
+static void 
+do_exclude_from_file(char *file) {
+       FILE *f;
+       char *p, fname[MAXPATHLEN];
+       
+
+       if (!( f = fopen(file, "r")) ) {
+               msg("Cannot open file for reading: %s\n", file);
+               msg("The ENTIRE dump is aborted.\n");
+               exit(X_STARTUP);
+       }
+       while (( p = fgets(fname, MAXPATHLEN, f))) {
+               if ( *p && *(p + strlen(p) - 1) == '\n' ) /* possible null string */
+                       *(p + strlen(p) - 1) = '\0';
+               if ( !*p ) /* skip empty lines */
+                       continue;
+               do_exclude_ino_str(p);
+       }
+       fclose(f);
+}