must flush stderr before reading from the terminal
[unix-history] / usr / src / sbin / restore / tape.c
index 85c8885..8615f6e 100644 (file)
@@ -1,7 +1,7 @@
 /* Copyright (c) 1983 Regents of the University of California */
 
 #ifndef lint
 /* Copyright (c) 1983 Regents of the University of California */
 
 #ifndef lint
-static char sccsid[] = "@(#)tape.c     3.6     (Berkeley)      83/03/05";
+static char sccsid[] = "@(#)tape.c     3.15    (Berkeley)      83/05/06";
 #endif
 
 #include "restore.h"
 #endif
 
 #include "restore.h"
@@ -50,9 +50,19 @@ nohost:
                done(1);
        setuid(getuid());       /* no longer need or want root privileges */
 #else
                done(1);
        setuid(getuid());       /* no longer need or want root privileges */
 #else
-       if (strcmp(source, "-") == 0) {
+       if (strcmp(source, "-") != 0) {
+               terminal = stdin;
+       } else {
+               /*
+                * Since input is coming from a pipe we must establish
+                * our own connection to the terminal.
+                */
+               terminal = fopen("/dev/tty", "r");
+               if (terminal == NULL) {
+                       perror("open(\"/dev/tty\")");
+                       done(1);
+               }
                pipein++;
                pipein++;
-               yflag++;
        }
        magtape = source;
 #endif RRESTOR
        }
        magtape = source;
 #endif RRESTOR
@@ -65,7 +75,6 @@ nohost:
 setup()
 {
        int i, j, *ip;
 setup()
 {
        int i, j, *ip;
-       struct mtop tcom;
        struct stat stbuf;
        extern char *ctime();
        extern int xtrmap(), xtrmapskip();
        struct stat stbuf;
        extern char *ctime();
        extern int xtrmap(), xtrmapskip();
@@ -82,21 +91,8 @@ setup()
                fprintf(stderr, "%s: cannot open tape\n", magtape);
                done(1);
        }
                fprintf(stderr, "%s: cannot open tape\n", magtape);
                done(1);
        }
-       if (dumpnum != 1) {
-               if (pipein) {
-                       fprintf(stderr,
-                               "Cannot have multiple dumps on pipe input\n");
-                       done(1);
-               }
-               tcom.mt_op = MTFSF;
-               tcom.mt_count = dumpnum - 1;
-#ifdef RRESTOR
-               rmtioctl(MTFSF, dumpnum - 1);
-#else
-               if (ioctl(mt, MTIOCTOP, &tcom) < 0)
-                       perror("ioctl MTFSF");
-#endif
-       }
+       volno = 1;
+       setdumpnum();
        flsht();
        if (gethead(&spcl) == FAIL) {
                bct--; /* push back this block */
        flsht();
        if (gethead(&spcl) == FAIL) {
                bct--; /* push back this block */
@@ -118,8 +114,10 @@ setup()
                while (--j);
                endoftapemark.s_spcl.c_checksum = CHECKSUM - i;
        }
                while (--j);
                endoftapemark.s_spcl.c_checksum = CHECKSUM - i;
        }
-       vprintf(stdout, "Dump   date: %s", ctime(&spcl.c_date));
-       vprintf(stdout, "Dumped from: %s", ctime(&spcl.c_ddate));
+       if (vflag || command == 't') {
+               fprintf(stdout, "Dump   date: %s", ctime(&spcl.c_date));
+               fprintf(stdout, "Dumped from: %s", ctime(&spcl.c_ddate));
+       }
        dumptime = spcl.c_ddate;
        dumpdate = spcl.c_date;
        if (stat(".", &stbuf) < 0) {
        dumptime = spcl.c_ddate;
        dumpdate = spcl.c_date;
        if (stat(".", &stbuf) < 0) {
@@ -143,23 +141,23 @@ setup()
                done(1);
        }
        maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1;
                done(1);
        }
        maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1;
-       dprintf(stderr, "maxino = %d\n", maxino);
-       map = (char *)calloc(1, (int)howmany(maxino, NBBY));
+       dprintf(stdout, "maxino = %d\n", maxino);
+       map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
        if (map == (char *)NIL)
                panic("no memory for file removal list\n");
        if (map == (char *)NIL)
                panic("no memory for file removal list\n");
+       clrimap = map;
        curfile.action = USING;
        getfile(xtrmap, xtrmapskip);
        curfile.action = USING;
        getfile(xtrmap, xtrmapskip);
-       clrimap = map;
        if (checktype(&spcl, TS_BITS) == FAIL) {
                fprintf(stderr, "Cannot find file dump list\n");
                done(1);
        }
        if (checktype(&spcl, TS_BITS) == FAIL) {
                fprintf(stderr, "Cannot find file dump list\n");
                done(1);
        }
-       map = (char *)calloc(1, (int)howmany(maxino, NBBY));
+       map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
        if (map == (char *)NULL)
                panic("no memory for file dump list\n");
        if (map == (char *)NULL)
                panic("no memory for file dump list\n");
+       dumpmap = map;
        curfile.action = USING;
        getfile(xtrmap, xtrmapskip);
        curfile.action = USING;
        getfile(xtrmap, xtrmapskip);
-       dumpmap = map;
 }
 
 getvol(nextvol)
 }
 
 getvol(nextvol)
@@ -170,16 +168,6 @@ getvol(nextvol)
        union u_spcl tmpspcl;
 #      define tmpbuf tmpspcl.s_spcl
 
        union u_spcl tmpspcl;
 #      define tmpbuf tmpspcl.s_spcl
 
-       if (dumpnum > 1) {
-               /*
-                * if this is a multi-dump tape we always start with 
-                * volume 1, so as to avoid accidentally restoring
-                * from a different dump!
-                */
-               if (volno != 1)
-                       panic("multiple dump at volno %d\n", volno);
-               dumpnum = 1;
-       }
        if (pipein) {
                if (nextvol != 1)
                        panic("Changing volumes on pipe input?\n");
        if (pipein) {
                if (nextvol != 1)
                        panic("Changing volumes on pipe input?\n");
@@ -196,9 +184,13 @@ again:
        else 
                newvol = 0;
        while (newvol <= 0) {
        else 
                newvol = 0;
        while (newvol <= 0) {
-               fprintf(stderr, "Specify next volume #: ");
-               if (gets(tbf) == NULL)
-                       continue;
+               do      {
+                       fprintf(stderr, "Specify next volume #: ");
+                       (void) fflush(stderr);
+                       (void) fgets(tbf, BUFSIZ, terminal);
+               } while (!feof(terminal) && tbf[0] == '\n');
+               if (feof(terminal))
+                       done(1);
                newvol = atoi(tbf);
                if (newvol <= 0) {
                        fprintf(stderr,
                newvol = atoi(tbf);
                if (newvol <= 0) {
                        fprintf(stderr,
@@ -209,7 +201,8 @@ again:
                return;
        closemt();
        fprintf(stderr, "Mount tape volume %d then type return ", newvol);
                return;
        closemt();
        fprintf(stderr, "Mount tape volume %d then type return ", newvol);
-       while (getchar() != '\n')
+       (void) fflush(stderr);
+       while (getc(terminal) != '\n')
                ;
 #ifdef RRESTOR
        if ((mt = rmtopen(magtape, 0)) == -1)
                ;
 #ifdef RRESTOR
        if ((mt = rmtopen(magtape, 0)) == -1)
@@ -222,6 +215,7 @@ again:
        }
 gethdr:
        volno = newvol;
        }
 gethdr:
        volno = newvol;
+       setdumpnum();
        flsht();
        if (readhdr(&tmpbuf) == FAIL) {
                fprintf(stderr, "tape is not dump tape\n");
        flsht();
        if (readhdr(&tmpbuf) == FAIL) {
                fprintf(stderr, "tape is not dump tape\n");
@@ -234,7 +228,9 @@ gethdr:
                goto again;
        }
        if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) {
                goto again;
        }
        if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) {
-               fprintf(stderr, "Wrong dump date (%s)\n", ctime(tmpbuf.c_date));
+               fprintf(stderr, "Wrong dump date\n\tgot: %s",
+                       ctime(&tmpbuf.c_date));
+               fprintf(stderr, "\twanted: %s", ctime(&dumpdate));
                volno = 0;
                goto again;
        }
                volno = 0;
                goto again;
        }
@@ -252,6 +248,30 @@ gethdr:
        }
 }
 
        }
 }
 
+/*
+ * handle multiple dumps per tape by skipping forward to the
+ * appropriate one.
+ */
+setdumpnum()
+{
+       struct mtop tcom;
+
+       if (dumpnum == 1 || volno != 1)
+               return;
+       if (pipein) {
+               fprintf(stderr, "Cannot have multiple dumps on pipe input\n");
+               done(1);
+       }
+       tcom.mt_op = MTFSF;
+       tcom.mt_count = dumpnum - 1;
+#ifdef RRESTOR
+       rmtioctl(MTFSF, dumpnum - 1);
+#else
+       if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0)
+               perror("ioctl MTFSF");
+#endif
+}
+
 extractfile(name)
        char *name;
 {
 extractfile(name)
        char *name;
 {
@@ -308,8 +328,8 @@ extractfile(name)
                        skipfile();
                        return (FAIL);
                }
                        skipfile();
                        return (FAIL);
                }
-               chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
-               chmod(name, mode);
+               (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
+               (void) chmod(name, mode);
                skipfile();
                utime(name, timep);
                return (GOOD);
                skipfile();
                utime(name, timep);
                return (GOOD);
@@ -321,10 +341,10 @@ extractfile(name)
                        skipfile();
                        return (FAIL);
                }
                        skipfile();
                        return (FAIL);
                }
-               fchown(ofile, curfile.dip->di_uid, curfile.dip->di_gid);
-               fchmod(ofile, mode);
+               (void) fchown(ofile, curfile.dip->di_uid, curfile.dip->di_gid);
+               (void) fchmod(ofile, mode);
                getfile(xtrfile, xtrskip);
                getfile(xtrfile, xtrskip);
-               close(ofile);
+               (void) close(ofile);
                utime(name, timep);
                return (GOOD);
        }
                utime(name, timep);
                return (GOOD);
        }
@@ -399,7 +419,7 @@ loop:
        if (readhdr(&spcl) == GOOD && size > 0) {
                if (checktype(&spcl, TS_ADDR) == GOOD)
                        goto loop;
        if (readhdr(&spcl) == GOOD && size > 0) {
                if (checktype(&spcl, TS_ADDR) == GOOD)
                        goto loop;
-               fprintf(stderr, "Missing address (header) block for %s\n",
+               dprintf(stdout, "Missing address (header) block for %s\n",
                        curfile.name);
        }
        if (curblk > 0)
                        curfile.name);
        }
        if (curblk > 0)
@@ -452,7 +472,7 @@ xtrlnkfile(buf, size)
                    curfile.name, lnkbuf, buf, pathlen);
                done(1);
        }
                    curfile.name, lnkbuf, buf, pathlen);
                done(1);
        }
-       strcat(lnkbuf, buf);
+       (void) strcat(lnkbuf, buf);
 }
 
 xtrlnkskip(buf, size)
 }
 
 xtrlnkskip(buf, size)
@@ -474,6 +494,7 @@ xtrmap(buf, size)
 {
 
        bcopy(buf, map, size);
 {
 
        bcopy(buf, map, size);
+       map += size;
 }
 
 xtrmapskip(buf, size)
 }
 
 xtrmapskip(buf, size)
@@ -483,9 +504,9 @@ xtrmapskip(buf, size)
 
 #ifdef lint
        buf = buf;
 
 #ifdef lint
        buf = buf;
-       size = size;
 #endif
        panic("hole in map\n");
 #endif
        panic("hole in map\n");
+       map += size;
 }
 
 null() {;}
 }
 
 null() {;}
@@ -498,7 +519,8 @@ readtape(b)
        char *b;
 {
        register long i;
        char *b;
 {
        register long i;
-       long rd, cnt, newvol;
+       long rd, newvol;
+       int cnt;
 
        if (bct >= NTREC) {
                for (i = 0; i < NTREC; i++)
 
        if (bct >= NTREC) {
                for (i = 0; i < NTREC; i++)
@@ -584,7 +606,7 @@ closemt()
 #ifdef RRESTOR
        rmtclose();
 #else
 #ifdef RRESTOR
        rmtclose();
 #else
-       close(mt);
+       (void) close(mt);
 #endif
 }
 
 #endif
 }
 
@@ -603,7 +625,7 @@ readhdr(b)
 {
 
        if (gethead(b) == FAIL) {
 {
 
        if (gethead(b) == FAIL) {
-               dprintf(stderr, "readhdr fails at %d blocks\n", blksread);
+               dprintf(stdout, "readhdr fails at %d blocks\n", blksread);
                return(FAIL);
        }
        return(GOOD);
                return(FAIL);
        }
        return(GOOD);
@@ -625,14 +647,14 @@ gethead(buf)
                        long    c_ddate;
                        long    c_volume;
                        long    c_tapea;
                        long    c_ddate;
                        long    c_volume;
                        long    c_tapea;
-                       short   c_inumber;
+                       u_short c_inumber;
                        long    c_magic;
                        long    c_checksum;
                        struct odinode {
                                unsigned short odi_mode;
                        long    c_magic;
                        long    c_checksum;
                        struct odinode {
                                unsigned short odi_mode;
-                               short   odi_nlink;
-                               short   odi_uid;
-                               short   odi_gid;
+                               u_short odi_nlink;
+                               u_short odi_uid;
+                               u_short odi_gid;
                                long    odi_size;
                                long    odi_rdev;
                                char    odi_addr[36];
                                long    odi_size;
                                long    odi_rdev;
                                char    odi_addr[36];
@@ -715,7 +737,7 @@ good:
 accthdr(header)
        struct s_spcl *header;
 {
 accthdr(header)
        struct s_spcl *header;
 {
-       static ino_t previno = 0xffffffff;
+       static ino_t previno = 0x7fffffff;
        static int prevtype;
        static long predict;
        long blks, i;
        static int prevtype;
        static long predict;
        long blks, i;
@@ -724,7 +746,7 @@ accthdr(header)
                fprintf(stderr, "Volume header\n");
                return;
        }
                fprintf(stderr, "Volume header\n");
                return;
        }
-       if (previno == 0xffffffff)
+       if (previno == 0x7fffffff)
                goto newcalc;
        switch (prevtype) {
        case TS_BITS:
                goto newcalc;
        switch (prevtype) {
        case TS_BITS:
@@ -800,7 +822,7 @@ findinode(header, complain)
                        skipcnt++;
        }
        if (skipcnt > 0 && complain)
                        skipcnt++;
        }
        if (skipcnt > 0 && complain)
-               fprintf(stderr, "resync restor, skipped %d blocks\n", skipcnt);
+               fprintf(stderr, "resync restore, skipped %d blocks\n", skipcnt);
        skipcnt = 0;
 }
 
        skipcnt = 0;
 }
 
@@ -844,33 +866,6 @@ checksum(b)
        return(GOOD);
 }
 
        return(GOOD);
 }
 
-/*
- * respond to interrupts
- */
-onintr()
-{
-       if (pipein || reply("restore interrupted, continue") == FAIL)
-               done(1);
-       if (signal(SIGINT, onintr) == SIG_IGN)
-               signal(SIGINT, SIG_IGN);
-       if (signal(SIGTERM, onintr) == SIG_IGN)
-               signal(SIGTERM, SIG_IGN);
-}
-
-/*
- * handle unexpected inconsistencies
- */
-/* VARARGS1 */
-panic(msg, d1, d2)
-       char *msg;
-       long d1, d2;
-{
-
-       fprintf(stderr, msg, d1, d2);
-       if (pipein || reply("abort") == GOOD)
-               abort();
-}
-
 #ifdef RRESTOR
 /* VARARGS1 */
 msg(cp, a1, a2, a3)
 #ifdef RRESTOR
 /* VARARGS1 */
 msg(cp, a1, a2, a3)