]> git.wh0rd.org - dump.git/blobdiff - restore/tape.c
kill "register".
[dump.git] / restore / tape.c
index 344ca3b46fadd47079622653e5fcc07f19ac47d4..3c9085bfece3e55b61c8493e4c63ef815343190a 100644 (file)
@@ -2,8 +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@noos.fr>, 1999-2000
- *     Stelian Pop <pop@noos.fr> - Alcôve <www.alcove.fr>, 2000
+ *     Stelian Pop <stelian@popies.net>, 1999-2000
+ *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  */
 
 /*
@@ -46,7 +46,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.47 2001/09/12 10:21:49 stelian Exp $";
+       "$Id: tape.c,v 1.56 2002/01/25 15:09:00 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -97,7 +97,7 @@ int           noresyncmesg = 0;
 #endif /* USE_QFA */
 static long    fssize = MAXBSIZE;
 static int     mt = -1;
-static int     pipein = 0;
+int            pipein = 0;
 static int     magtapein = 0;          /* input is from magtape */
 static char    magtape[MAXPATHLEN];
 static char    magtapeprefix[MAXPATHLEN];
@@ -116,7 +116,7 @@ static long tpblksread = 0;         /* TP_BSIZE blocks read */
 static long    tapesread;
 static sigjmp_buf      restart;
 static int     gettingfile = 0;        /* restart has a valid frame */
-static char    *host = NULL;
+char           *host = NULL;
 
 static int     ofile;
 static char    *map;
@@ -154,6 +154,7 @@ static void  setmagtapein __P((void));
 
 #if defined(HAVE_ZLIB) || defined(HAVE_BZLIB)
 static void    newcomprbuf __P((int));
+static void    (*readtape_func) __P((char *));
 static void    readtape_set __P((char *));
 static void    readtape_uncompr __P((char *));
 static void    readtape_comprfile __P((char *));
@@ -264,9 +265,10 @@ setup(void)
 {
        int i, j, *ip, bot_code;
        struct STAT stbuf;
+       char *temptape;
 
        Vprintf(stdout, "Verify tape and initialize maps\n");
-       if (bot_script) {
+       if (Afile == NULL && bot_script) {
                msg("Launching %s\n", bot_script);
                bot_code = system_command(bot_script, magtape, 1);
                if (bot_code != 0 && bot_code != 1) {
@@ -274,20 +276,31 @@ setup(void)
                        exit(1);
                }
        }
+
+       if (Afile)
+               temptape = Afile;
+       else
+               temptape = magtape;
+
 #ifdef RRESTORE
        if (host)
-               mt = rmtopen(magtape, 0);
+               mt = rmtopen(temptape, 0);
        else
 #endif
        if (pipein)
                mt = 0;
        else
-               mt = OPEN(magtape, O_RDONLY, 0);
+               mt = OPEN(temptape, O_RDONLY, 0);
        if (mt < 0)
                err(1, "%s", magtape);
-       volno = 1;
-       setmagtapein();
-       setdumpnum();
+       if (!Afile) {
+               volno = 1;
+               setmagtapein();
+               setdumpnum();
+       }
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB)
+       readtape_func = readtape_set;
+#endif
        FLUSHTAPEBUF();
        findtapeblksize();
        if (gethead(&spcl) == FAIL) {
@@ -302,11 +315,9 @@ setup(void)
 
        if (zflag) {
                fprintf(stderr, "Dump tape is compressed.\n");
-#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB)
-               newcomprbuf(ntrec);
-#else
+#if !defined(HAVE_ZLIB) && !defined(HAVE_BZLIB)
                errx(1,"This restore version doesn't support decompression");
-#endif /* HAVE_ZLIB */
+#endif /* !HAVE_ZLIB && !HAVE_BZLIB */
        }
        if (pipein) {
                endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : NFS_MAGIC;
@@ -406,7 +417,7 @@ getvol(long nextvol)
 again:
        if (pipein)
                exit(1); /* pipes do not get a second chance */
-       if (command == 'R' || command == 'r' || curfile.action != SKIP) {
+       if (aflag || curfile.action != SKIP) {
                newvol = nextvol;
                wantnext = 1;
        } else {
@@ -432,12 +443,16 @@ again:
                        fprintf(stderr, "\n");
                }
                do      {
-                       fprintf(stderr, "Specify next volume #: ");
+                       fprintf(stderr, "Specify next volume # (none if no more volumes): ");
                        (void) fflush(stderr);
                        (void) fgets(buf, TP_BSIZE, terminal);
                } while (!feof(terminal) && buf[0] == '\n');
                if (feof(terminal))
                        exit(1);
+               if (!strcmp(buf, "none\n")) {
+                       terminateinput();
+                       return;
+               }
                newvol = atoi(buf);
                if (newvol <= 0) {
                        fprintf(stderr,
@@ -497,6 +512,9 @@ again:
        }
 gethdr:
        setmagtapein();
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB)
+       readtape_func = readtape_set;
+#endif
        volno = newvol;
        setdumpnum();
        FLUSHTAPEBUF();
@@ -538,6 +556,12 @@ gethdr:
         * If coming to this volume at random, skip to the beginning
         * of the next record.
         */
+       if (zflag) {
+               fprintf(stderr, "Dump tape is compressed.\n");
+#if !defined(HAVE_ZLIB) && !defined(HAVE_BZLIB)
+               errx(1,"This restore version doesn't support decompression");
+#endif /* !HAVE_ZLIB && !HAVE_BZLIB */
+       }
        Dprintf(stdout, "read %ld recs, tape starts with %ld\n",
                tpblksread, (long)tmpbuf.c_firstrec);
        if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
@@ -634,6 +658,18 @@ printdumpinfo(void)
        fprintf(stdout, "Label: %s\n", spcl.c_label);
 }
 
+void 
+printvolinfo(void)
+{
+       int i;
+
+       if (volinfo[1] == ROOTINO) {
+               printf("Starting inode numbers by volume:\n");
+               for (i = 1; i < TP_NINOS && volinfo[i] != 0; ++i)
+                       printf("\tVolume %d: %lu\n", i, (unsigned long)volinfo[i]);
+       }
+}
+
 int
 extractfile(char *name)
 {
@@ -817,7 +853,7 @@ skipfile(void)
 void
 getfile(void (*fill) __P((char *, size_t)), void (*skip) __P((char *, size_t)))
 {
-       register int i;
+       int i;
        volatile int curblk = 0;
        volatile quad_t size = spcl.c_dinode.di_size;
        volatile int last_write_was_hole = 0;
@@ -1076,14 +1112,14 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk)
        if (STAT(tapefile, &sbuf_tape) != 0) {
                panic("Can't lstat tmp file %s: %s\n", tapefile,
                      strerror(errno));
-               compare_errors = 1;
+               do_compare_error;
        }
 
        if (sbuf_disk->st_size != sbuf_tape.st_size) {
                fprintf(stderr,
                        "%s: size changed from %ld to %ld.\n",
                        diskfile, (long)sbuf_tape.st_size, (long)sbuf_disk->st_size);
-               compare_errors = 1;
+               do_compare_error;
 #ifdef COMPARE_FAIL_KEEP_FILE
                return (0);
 #else
@@ -1093,12 +1129,12 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk)
 
        if ((fd_tape = OPEN(tapefile, O_RDONLY)) < 0) {
                panic("Can't open %s: %s\n", tapefile, strerror(errno));
-               compare_errors = 1;
+               do_compare_error;
        }
        if ((fd_disk = OPEN(diskfile, O_RDONLY)) < 0) {
                close(fd_tape);
                panic("Can't open %s: %s\n", diskfile, strerror(errno));
-               compare_errors = 1;
+               do_compare_error;
        }
 
        if (do_cmpfiles(fd_tape, fd_disk, sbuf_tape.st_size)) {
@@ -1106,7 +1142,7 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk)
                        diskfile);
                close(fd_tape);
                close(fd_disk);
-               compare_errors = 1;
+               do_compare_error;
 #ifdef COMPARE_FAIL_KEEP_FILE
                /* rename the file to live in /tmp */
                /* rename `tapefile' to /tmp/<basename of diskfile> */
@@ -1159,7 +1195,7 @@ comparefile(char *name)
 
        if ((r = LSTAT(name, &sb)) != 0) {
                warn("%s: does not exist (%d)", name, r);
-               compare_errors = 1;
+               do_compare_error;
                skipfile();
                return;
        }
@@ -1174,7 +1210,7 @@ comparefile(char *name)
        if (sb.st_mode != mode) {
                fprintf(stderr, "%s: mode changed from 0%o to 0%o.\n",
                        name, mode & 07777, sb.st_mode & 07777);
-               compare_errors = 1;
+               do_compare_error;
        }
        switch (mode & IFMT) {
        default:
@@ -1196,7 +1232,7 @@ comparefile(char *name)
                if (!(sb.st_mode & S_IFLNK)) {
                        fprintf(stderr, "%s: is no longer a symbolic link\n",
                                name);
-                       compare_errors = 1;
+                       do_compare_error;
                        return;
                }
                lnkbuf[0] = '\0';
@@ -1206,20 +1242,20 @@ comparefile(char *name)
                        fprintf(stderr,
                                "%s: zero length symbolic link (ignored)\n",
                                name);
-                       compare_errors = 1;
+                       do_compare_error;
                        return;
                }
                if ((lsize = readlink(name, lbuf, MAXPATHLEN)) < 0) {
                        panic("readlink of %s failed: %s", name,
                              strerror(errno));
-                       compare_errors = 1;
+                       do_compare_error;
                }
                lbuf[lsize] = 0;
                if (strcmp(lbuf, lnkbuf) != 0) {
                        fprintf(stderr,
                                "%s: symbolic link changed from %s to %s.\n",
                                name, lnkbuf, lbuf);
-                       compare_errors = 1;
+                       do_compare_error;
                        return;
                }
                return;
@@ -1230,7 +1266,7 @@ comparefile(char *name)
                if (!(sb.st_mode & (S_IFCHR|S_IFBLK))) {
                        fprintf(stderr, "%s: no longer a special file\n",
                                name);
-                       compare_errors = 1;
+                       do_compare_error;
                        skipfile();
                        return;
                }
@@ -1243,7 +1279,7 @@ comparefile(char *name)
                                (int)curfile.dip->di_rdev & 0xff,
                                ((int)sb.st_rdev >> 8) & 0xff,
                                (int)sb.st_rdev & 0xff);
-                       compare_errors = 1;
+                       do_compare_error;
                }
                skipfile();
                return;
@@ -1253,7 +1289,7 @@ comparefile(char *name)
                if ((ifile = OPEN(name, O_RDONLY)) < 0) {
                        panic("Can't open %s: %s\n", name, strerror(errno));
                        skipfile();
-                       compare_errors = 1;
+                       do_compare_error;
                }
                else {
                        cmperror = 0;
@@ -1267,7 +1303,7 @@ comparefile(char *name)
                                }
                        }
                        if (cmperror)
-                               compare_errors = 1;
+                               do_compare_error;
                        close(ifile);
                }
 #else
@@ -1929,7 +1965,7 @@ setmagtapein(void) {
                /* need to know if input is really from a tape */
 #ifdef RRESTORE
                if (host)
-                       magtapein = rmtioctl(MTNOP, 1) != -1;
+                       magtapein = !lflag;
                else
 #endif
                        magtapein = ioctl(mt, MTIOCGET, (char *)&mt_stat) == 0;
@@ -1978,7 +2014,7 @@ gethead(struct s_spcl *buf)
                                int32_t odi_ctime;
                        } c_dinode;
                        int32_t c_count;
-                       char    c_addr[256];
+                       char    c_fill[256];
                } s_ospcl;
        } u_ospcl;
 
@@ -2024,7 +2060,7 @@ gethead(struct s_spcl *buf)
        buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
 #endif /* __linux__ */
        buf->c_count = u_ospcl.s_ospcl.c_count;
-       memmove(buf->c_addr, u_ospcl.s_ospcl.c_addr, (long)256);
+       memmove(buf->c_addr, u_ospcl.s_ospcl.c_fill, (long)256);
        if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
            checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
                return(FAIL);
@@ -2070,6 +2106,11 @@ good:
                /* fall through */
        case TS_END:
                buf->c_inumber = 0;
+               if (buf->c_flags & DR_INODEINFO) {
+                       memcpy(volinfo, buf->c_inos, TP_NINOS * sizeof(dump_ino_t));
+                       if (Bcvt)
+                               swabst((u_char *)"128i", (u_char *)volinfo);
+               }
                break;
 
        case TS_INODE:
@@ -2224,7 +2265,7 @@ findinode(struct s_spcl *header)
 static int
 checksum(int *buf)
 {
-       register int i, j;
+       int i, j;
 
        j = sizeof(union u_spcl) / sizeof(int);
        i = 0;
@@ -2377,14 +2418,32 @@ swabl(u_long x)
  * get the current position of the tape
  */
 int
-GetTapePos(long *pos)
+GetTapePos(long long *pos)
 {
        int err = 0;
 
-       *pos = 0;
-       if (ioctl(mt, MTIOCPOS, pos) == -1) {
+#ifdef RDUMP
+       if (host) {
+               *pos = (long long) rmtseek(0, SEEK_CUR);
+               err = *pos < 0;
+       }
+       else
+#endif
+       {
+       if (magtapein) {
+               long mtpos;
+               *pos = 0;
+               err = (ioctl(mt, MTIOCPOS, &mtpos) < 0);
+               *pos = (long long)mtpos;
+       }
+       else {
+               *pos = LSEEK(mt, 0, SEEK_CUR);
+               err = (*pos < 0);
+       }
+       }
+       if (err) {
                err = errno;
-               fprintf(stdout, "[%ld] error: %d (getting tapepos: %ld)\n", 
+               fprintf(stdout, "[%ld] error: %d (getting tapepos: %lld)\n", 
                        (unsigned long)getpid(), err, *pos);
                return err;
        }
@@ -2400,16 +2459,30 @@ typedef struct mt_pos {
  * go to specified position on tape
  */
 int
-GotoTapePos(long pos)
+GotoTapePos(long long pos)
 {
        int err = 0;
-       struct mt_pos buf;
 
-       buf.mt_op = MTSEEK;
-       buf.mt_count = pos;
-       if (ioctl(mt, MTIOCTOP, &buf) == -1) {
+#ifdef RDUMP
+       if (host)
+               err = (rmtseek((long)pos, SEEK_SET) < 0);
+       else
+#endif
+       {
+       if (magtapein) {
+               struct mt_pos buf;
+               buf.mt_op = MTSEEK;
+               buf.mt_count = (int) pos;
+               err = (ioctl(mt, MTIOCTOP, &buf) < 0);
+       }
+       else {
+               pos = LSEEK(mt, pos, SEEK_SET);
+               err = (pos < 0);
+       }
+       }
+       if (err) {
                err = errno;
-               fprintf(stdout, "[%ld] error: %d (setting tapepos: %ld)\n", 
+               fprintf(stdout, "[%ld] error: %d (setting tapepos: %lld)\n", 
                        (unsigned long)getpid(), err, pos);
                return err;
        }
@@ -2432,6 +2505,7 @@ ReReadFromTape(void)
        findinode(&spcl);
        noresyncmesg = 0;
 }
+#endif /* USE_QFA */
 
 void
 RequestVol(long tnum)
@@ -2439,4 +2513,3 @@ RequestVol(long tnum)
        FLUSHTAPEBUF();
        getvol(tnum);
 }
-#endif /* USE_QFA */