]> git.wh0rd.org - dump.git/blobdiff - dump/main.c
Cleaned up the external variables definition mess...
[dump.git] / dump / main.c
index 0c896738608f9e8b318db313cd31a7a6262f84ab..7a5884b36ff44547e296e88f90abc38d79183d1d 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.47 2001/04/27 12:23:23 stelian Exp $";
+       "$Id: main.c,v 1.56 2001/08/13 16:17:52 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
@@ -83,6 +88,67 @@ static const char rcsid[] =
 #define SBOFF (SBLOCK * DEV_BSIZE)
 #endif
 
+/*
+ * Dump maps used to describe what is to be dumped.
+ */
+int    mapsize;        /* size of the state maps */
+char   *usedinomap;    /* map of allocated inodes */
+char   *dumpdirmap;    /* map of directories to be dumped */
+char   *dumpinomap;    /* map of files to be dumped */
+
+const char *disk;      /* name of the disk file */
+char   tape[MAXPATHLEN];/* name of the tape file */
+char   *tapeprefix;    /* prefix of the tape file */
+char   *dumpdates;     /* name of the file containing dump date information*/
+char   lastlevel;      /* dump level of previous dump */
+char   level;          /* dump level of this dump */
+int    uflag;          /* update flag */
+int    Mflag;          /* multi-volume flag */
+char   *eot_script;    /* end of volume script fiag */
+int    diskfd;         /* disk file descriptor */
+int    tapefd;         /* tape file descriptor */
+int    pipeout;        /* true => output to standard output */
+int    fifoout;        /* true => output to fifo */
+dump_ino_t curino;     /* current inumber; used globally */
+int    newtape;        /* new tape flag */
+int    density;        /* density in 0.1" units */
+long   tapesize;       /* estimated tape size, blocks */
+long   tsize;          /* tape size in 0.1" units */
+long   asize;          /* number of 0.1" units written on current tape */
+int    etapes;         /* estimated number of tapes */
+int    nonodump;       /* if set, do not honor UF_NODUMP user flags */
+int    unlimited;      /* if set, write to end of medium */
+int    compressed;     /* if set, dump is to be compressed */
+long long bytes_written;/* total bytes written to tape */
+long   uncomprblks;    /* uncompressed blocks written to tape */
+int    notify;         /* notify operator flag */
+int    blockswritten;  /* number of blocks written on current tape */
+int    tapeno;         /* current tape number */
+time_t tstart_writing; /* when started writing the first tape block */
+time_t tend_writing;   /* after writing the last tape block */
+#ifdef __linux__
+ext2_filsys fs;
+#else
+struct fs *sblock;     /* the file system super block */
+char   sblock_buf[MAXBSIZE];
+#endif
+long   xferrate;       /* averaged transfer rate of all volumes */
+long   dev_bsize;      /* block size of underlying disk device */
+int    dev_bshift;     /* log2(dev_bsize) */
+int    tp_bshift;      /* log2(TP_BSIZE) */
+
+#ifdef USE_QFA
+int    gTapeposfd;
+char   *gTapeposfile;
+char   gTps[255];
+int32_t        gThisDumpDate;
+#endif /* USE_QFA */
+
+struct dumptime *dthead;       /* head of the list version */
+int    nddates;                /* number of records (might be zero) */
+int    ddates_in;              /* we have read the increment file */
+struct dumpdates **ddatev;     /* the arrayfied version */
+
 int    notify = 0;     /* notify operator flag */
 int    blockswritten = 0;      /* number of blocks written on current tape */
 int    tapeno = 0;     /* current tape number */
@@ -109,9 +175,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 +192,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;
@@ -163,7 +231,7 @@ main(int argc, char *argv[])
 #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 +287,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 */
@@ -348,7 +416,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 +582,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 +619,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,7 +680,7 @@ main(int argc, char *argv[])
 
        nonodump = spcl.c_level < honorlevel;
 
-       if (!sizeest) {
+       if (!sizest) {
                msg("Label: %s\n", spcl.c_label);
 
                if (compressed)
@@ -622,7 +698,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);
@@ -639,7 +715,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);
@@ -730,7 +806,7 @@ main(int argc, char *argv[])
 #ifdef USE_QFA
        if (tapepos) {
                msg("writing QFA positions to %s\n", gTapeposfile);
-               if ((gTapeposfd = open(gTapeposfile, O_RDWR|O_CREAT)) < 0)
+               if ((gTapeposfd = open(gTapeposfile, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR)) < 0)
                        quit("can't open tapeposfile\n");
                /* print QFA-file header */
                sprintf(gTps, "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION, (unsigned long)spcl.c_date);
@@ -815,7 +891,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
@@ -875,12 +951,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
@@ -918,7 +993,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);
@@ -987,6 +1062,7 @@ obsolete(int *argcp, char **argvp[])
                case 'b':
                case 'd':
                case 'e':
+               case 'E':
                case 'f':
                case 'F':
                case 'h':
@@ -1028,3 +1104,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);
+}