]> git.wh0rd.org - dump.git/commitdiff
-A archive file implementation
authorStelian Pop <stelian@popies.net>
Fri, 25 Jan 2002 14:59:53 +0000 (14:59 +0000)
committerStelian Pop <stelian@popies.net>
Fri, 25 Jan 2002 14:59:53 +0000 (14:59 +0000)
-Q on remote tape/files.

17 files changed:
CHANGES
THANKS
TODO
compat/include/protocols/dumprestore.h
dump/dump.8.in
dump/dump.h
dump/main.c
dump/tape.c
dump/traverse.c
restore/extern.h
restore/interactive.c
restore/main.c
restore/restore.8.in
restore/restore.c
restore/restore.h
restore/tape.c
restore/utilities.c

diff --git a/CHANGES b/CHANGES
index 55a910a0642492607f0f29631107ef0b6854627a..87d4ba719b1083d0fddbc006fe195bd344332070 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-$Id: CHANGES,v 1.157 2002/01/22 11:12:28 stelian Exp $
+$Id: CHANGES,v 1.158 2002/01/25 14:59:53 stelian Exp $
 
 Changes between versions 0.4b26 and 0.4b27 (released ???????????????)
 =====================================================================
 
 Changes between versions 0.4b26 and 0.4b27 (released ???????????????)
 =====================================================================
@@ -16,10 +16,18 @@ Changes between versions 0.4b26 and 0.4b27 (released ???????????????)
        restores in -i or -x mode (automatically walks through the
        multiple dump volumes).
 
        restores in -i or -x mode (automatically walks through the
        multiple dump volumes).
 
-5.     Extended the QFA mode to work with local files. This way,
-       restore can know in advance the tape number and the offset
-       for the inodes to extract and can minimize the extraction
-       time by seeking directly to the good tape/offset.
+5.     Extended the QFA mode to work with local files and/or
+       remote tapes and files. This way, restore can know in advance
+       the tape number and the offset for the inodes to extract and 
+       can minimize the extraction time by seeking directly to the 
+       good tape/offset.
+
+6.     Added the -A <archive> option to both dump and restore, 
+       which makes dump to archive a dump table-of-contents in
+       the specified file to be used by restore to determine
+       whether a file is in the dump file that is being restored.
+       (the archive file syntax is also compatible with the
+       Solaris ufsdump generated one).
 
 Changes between versions 0.4b25 and 0.4b26 (released January 7, 2002)
 =====================================================================
 
 Changes between versions 0.4b25 and 0.4b26 (released January 7, 2002)
 =====================================================================
diff --git a/THANKS b/THANKS
index 6f75519110d5408a3cb819cec589b073457addcd..385510d5aef1b4f6a4cee775c36cb27448e97acb 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -1,4 +1,4 @@
-$Id: THANKS,v 1.52 2002/01/16 09:32:14 stelian Exp $
+$Id: THANKS,v 1.53 2002/01/25 14:59:53 stelian Exp $
 
 Dump and restore were written by the people of the CSRG at the University
 of California, Berkeley.
 
 Dump and restore were written by the people of the CSRG at the University
 of California, Berkeley.
@@ -43,6 +43,7 @@ Uwe Gohlke            uwe@ugsoft.de
 Ian Gordon             iangordon@users.sourceforge.net
 Andreas Hasenack       andreas@conectiva.com.br
 Christian Haul         haul@informatik.tu-darmstadt.de
 Ian Gordon             iangordon@users.sourceforge.net
 Andreas Hasenack       andreas@conectiva.com.br
 Christian Haul         haul@informatik.tu-darmstadt.de
+Kjetil Torgrim Homme   kjetilho@ifi.uio.no
 Jean-Paul van der Jagt jeanpaul@dutepp0.et.tudelft.nl
 Helmut Jarausch                jarausch@igpm.rwth-aachen.de
 Eric Jergensen         eric@dvns.com
 Jean-Paul van der Jagt jeanpaul@dutepp0.et.tudelft.nl
 Helmut Jarausch                jarausch@igpm.rwth-aachen.de
 Eric Jergensen         eric@dvns.com
diff --git a/TODO b/TODO
index a92865207a6eb1dbf302e5b4b3ff43a86027368a..d3d4102b842328f813ba7ae85fddfff29b79153b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.23 2001/08/16 15:24:21 stelian Exp $
+$Id: TODO,v 1.24 2002/01/25 14:59:53 stelian Exp $
 
 Need to verify:
 ---------------
 
 Need to verify:
 ---------------
@@ -31,18 +31,7 @@ All others:
 
 5.     Make a bootable dump tape? I don't know if it is possible...
 
 
 5.     Make a bootable dump tape? I don't know if it is possible...
 
-6.     From Kjetil Torgrim Homme <kjetilho@ifi.uio.no>:
-         a archive_file
-            Archive file. Archive a dump table-of-contents  in
-            the   specified   archive_file   to   be  used  by
-            ufsrestore(1M) to determine whether a file  is  in
-            the dump file that is being restored.
-
-7.     EA/ACL support in dump (requested by Michael Ju. Tokarev 
+6.     EA/ACL support in dump (requested by Michael Ju. Tokarev 
        <mjt@tls.msk.ru>.
 
        <mjt@tls.msk.ru>.
 
-8.     Better readline completition in restore (escape spaces etc).
-
-9.     Dump compiled with RedHat's 7.0 gcc seems to hang for some
-       people. When compiled with kgcc all the problems disappear.
-       Will the RedHat's 7.1 gcc resolve this ?
+7.     Better readline completition in restore (escape spaces etc).
index a9f68e0630a83bb8e8ba78d17922c292319f095c..2c3a945fc851ad88c76a0d45724cd6d7b769057e 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: dumprestore.h,v 1.15 2002/01/16 09:32:14 stelian Exp $
+ *     $Id: dumprestore.h,v 1.16 2002/01/25 14:59:53 stelian Exp $
  */
 
 /*
  */
 
 /*
@@ -67,6 +67,7 @@
 #define NTREC          10
 #define HIGHDENSITYTREC        32
 #define TP_NINDIR      (TP_BSIZE/2)
 #define NTREC          10
 #define HIGHDENSITYTREC        32
 #define TP_NINDIR      (TP_BSIZE/2)
+#define TP_NINOS       (TP_NINDIR / sizeof (int32_t))
 #define LBLSIZE                16
 #define NAMELEN                64
 
 #define LBLSIZE                16
 #define NAMELEN                64
 
 
 typedef u_int32_t      dump_ino_t;
 
 
 typedef u_int32_t      dump_ino_t;
 
+union u_data {
+       char    s_addrs[TP_NINDIR];     /* 1 => data; 0 => hole in inode */
+       int32_t s_inos[TP_NINOS];       /* table of first inode on each volume */
+} u_data;
+
 union u_spcl {
        char dummy[TP_BSIZE];
        struct  s_spcl {
 union u_spcl {
        char dummy[TP_BSIZE];
        struct  s_spcl {
@@ -93,7 +99,7 @@ union u_spcl {
                struct  dinode  c_dinode;   /* ownership and mode of inode */
 #endif
                int32_t c_count;            /* number of valid c_addr entries */
                struct  dinode  c_dinode;   /* ownership and mode of inode */
 #endif
                int32_t c_count;            /* number of valid c_addr entries */
-               char    c_addr[TP_NINDIR];  /* 1 => data; 0 => hole in inode */
+               union u_data c_data;        /* see above */
                char    c_label[LBLSIZE];   /* dump label */
                int32_t c_level;            /* level of this dump */
                char    c_filesys[NAMELEN]; /* name of dumpped file system */
                char    c_label[LBLSIZE];   /* dump label */
                int32_t c_level;            /* level of this dump */
                char    c_filesys[NAMELEN]; /* name of dumpped file system */
@@ -106,6 +112,9 @@ union u_spcl {
        } s_spcl;
 } u_spcl;
 #define spcl u_spcl.s_spcl
        } s_spcl;
 } u_spcl;
 #define spcl u_spcl.s_spcl
+#define c_addr c_data.s_addrs
+#define c_inos c_data.s_inos
+
 /*
  * special record types
  */
 /*
  * special record types
  */
@@ -122,6 +131,8 @@ union u_spcl {
 #define DR_NEWHEADER   0x0001  /* new format tape header */
 #define DR_NEWINODEFMT 0x0002  /* new format inodes on tape */
 #define DR_COMPRESSED  0x0080  /* dump tape is compressed */
 #define DR_NEWHEADER   0x0001  /* new format tape header */
 #define DR_NEWINODEFMT 0x0002  /* new format inodes on tape */
 #define DR_COMPRESSED  0x0080  /* dump tape is compressed */
+#define DR_INODEINFO   0x0002  /* TS_END header contains c_inos information */
+
 
 /*
  * compression flags for the tapebuf header.
 
 /*
  * compression flags for the tapebuf header.
index 22ed34036b76f39e42ab77254a50e96930df1084..86548f986763edbc217392ec46e0d551027dd37e 100644 (file)
@@ -30,7 +30,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $Id: dump.8.in,v 1.36 2002/01/22 11:12:28 stelian Exp $
+.\"    $Id: dump.8.in,v 1.37 2002/01/25 14:59:53 stelian Exp $
 .\"
 .Dd __DATE__
 .Dt DUMP 8
 .\"
 .Dd __DATE__
 .Dt DUMP 8
@@ -41,6 +41,7 @@
 .Sh SYNOPSIS
 .Nm dump
 .Op Fl 0123456789ackMnqSu
 .Sh SYNOPSIS
 .Nm dump
 .Op Fl 0123456789ackMnqSu
+.Op Fl A Ar file
 .Op Fl B Ar records
 .Op Fl b Ar blocksize
 .Op Fl d Ar density
 .Op Fl B Ar records
 .Op Fl b Ar blocksize
 .Op Fl d Ar density
@@ -117,11 +118,6 @@ to
 copy all files new or modified since the
 last dump of a lower level.
 The default level is 9.
 copy all files new or modified since the
 last dump of a lower level.
 The default level is 9.
-.It Fl B Ar records
-The number of 1 kB blocks per volume.
-This option overrides the end-of-media detection, and calculation 
-of tape size based on length and density. If compression is on this
-limits the size of the compressed output per volume.
 .It Fl a
 .Dq auto-size .
 Bypass all tape length calculations, and write
 .It Fl a
 .Dq auto-size .
 Bypass all tape length calculations, and write
@@ -130,6 +126,13 @@ for most modern tape drives, and is the default.
 Use of this option is particularly recommended when appending to an 
 existing tape, or using a tape drive with hardware compression 
 (where you can never be sure about the compression ratio).
 Use of this option is particularly recommended when appending to an 
 existing tape, or using a tape drive with hardware compression 
 (where you can never be sure about the compression ratio).
+.It Fl A Ar archive_file
+Archive a dump table-of-contents in the
+specified
+.Ar archive_file
+to be used by 
+.Xr restore 8
+to determine whether a file is in the dump file that is being restored.
 .It Fl b Ar blocksize
 The number of kilobytes per dump record.
 Since the IO system slices all requests into chunks of MAXBSIZE
 .It Fl b Ar blocksize
 The number of kilobytes per dump record.
 Since the IO system slices all requests into chunks of MAXBSIZE
@@ -140,10 +143,20 @@ Therefore
 .Nm dump
 will constrain writes to MAXBSIZE.
 The default blocksize is 10.
 .Nm dump
 will constrain writes to MAXBSIZE.
 The default blocksize is 10.
+.It Fl B Ar records
+The number of 1 kB blocks per volume.
+This option overrides the end-of-media detection, and calculation 
+of tape size based on length and density. If compression is on this
+limits the size of the compressed output per volume.
 .It Fl c
 Change the defaults for use with a cartridge tape drive, with a density
 of 8000 bpi, and a length of 1700 feet. Specifying a cartridge drive
 overrides the end-of-media detection.
 .It Fl c
 Change the defaults for use with a cartridge tape drive, with a density
 of 8000 bpi, and a length of 1700 feet. Specifying a cartridge drive
 overrides the end-of-media detection.
+.It Fl d Ar density
+Set tape density to
+.Ar density .
+The default is 1600BPI. Specifying a tape density overrides the 
+end-of-media detection.
 .It Fl e Ar inodes
 Exclude 
 .Ar inodes
 .It Fl e Ar inodes
 Exclude 
 .Ar inodes
@@ -159,21 +172,6 @@ The file
 .Ar file
 should be an ordinary file containing inode numbers separated by
 newlines.
 .Ar file
 should be an ordinary file containing inode numbers separated by
 newlines.
-.It Fl h Ar level
-Honor the user
-.Dq nodump
-flag
-.Dp Dv UF_NODUMP
-only for dumps at or above the given
-.Ar level .
-The default honor level is 1,
-so that incremental backups omit such files
-but full backups retain them.
-.It Fl d Ar density
-Set tape density to
-.Ar density .
-The default is 1600BPI. Specifying a tape density overrides the 
-end-of-media detection.
 .It Fl f Ar file
 Write the backup to
 .Ar file ;
 .It Fl f Ar file
 Write the backup to
 .Ar file ;
@@ -222,6 +220,16 @@ For security reasons,
 .Nm
 reverts back to the real user ID and the real group ID before 
 running the script.
 .Nm
 reverts back to the real user ID and the real group ID before 
 running the script.
+.It Fl h Ar level
+Honor the user
+.Dq nodump
+flag
+.Dp Dv UF_NODUMP
+only for dumps at or above the given
+.Ar level .
+The default honor level is 1,
+so that incremental backups omit such files
+but full backups retain them.
 .It Fl I Ar nr errors
 By default,
 .Nm
 .It Fl I Ar nr errors
 By default,
 .Nm
index e2c008f016a51134dd163483493374bcac5632ce..2ce50e3c7c8787c7db8567a2293c8963d2c0626c 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: dump.h,v 1.35 2002/01/22 11:12:28 stelian Exp $
+ *     $Id: dump.h,v 1.36 2002/01/25 14:59:53 stelian Exp $
  */
 
 /*-
  */
 
 /*-
@@ -67,12 +67,14 @@ extern char *dumpinomap;    /* map of files to be dumped */
 /*
  *     All calculations done in 0.1" units!
  */
 /*
  *     All calculations done in 0.1" units!
  */
+extern char    *host;          /* name of the remote host */
 extern const char *disk;       /* name of the disk file */
 extern char    tape[MAXPATHLEN];/* name of the tape file */
 extern char    *tapeprefix;    /* prefix of the tape file */
 extern char    *dumpdates;     /* name of the file containing dump date information*/
 extern char    lastlevel;      /* dump level of previous dump */
 extern char    level;          /* dump level of this dump */
 extern const char *disk;       /* name of the disk file */
 extern char    tape[MAXPATHLEN];/* name of the tape file */
 extern char    *tapeprefix;    /* prefix of the tape file */
 extern char    *dumpdates;     /* name of the file containing dump date information*/
 extern char    lastlevel;      /* dump level of previous dump */
 extern char    level;          /* dump level of this dump */
+extern int     Afile;          /* archive file descriptor */
 extern int     bzipflag;       /* compression is done using bzlib */
 extern int     uflag;          /* update flag */
 extern int     Mflag;          /* multi-volume flag */
 extern int     bzipflag;       /* compression is done using bzlib */
 extern int     uflag;          /* update flag */
 extern int     Mflag;          /* multi-volume flag */
@@ -110,6 +112,7 @@ extern long xferrate;       /* averaged transfer rate of all volumes */
 extern long    dev_bsize;      /* block size of underlying disk device */
 extern int     dev_bshift;     /* log2(dev_bsize) */
 extern int     tp_bshift;      /* log2(TP_BSIZE) */
 extern long    dev_bsize;      /* block size of underlying disk device */
 extern int     dev_bshift;     /* log2(dev_bsize) */
 extern int     tp_bshift;      /* log2(TP_BSIZE) */
+extern dump_ino_t volinfo[];   /* which inode on which volume archive info */
 
 #ifdef USE_QFA
 #define        QFA_MAGIC       "495115637697"
 
 #ifdef USE_QFA
 #define        QFA_MAGIC       "495115637697"
@@ -158,6 +161,7 @@ void        dumpdirino __P((struct dinode *dp, dump_ino_t ino));
 #endif
 void   dumpmap __P((char *map, int type, dump_ino_t ino));
 void   writeheader __P((dump_ino_t ino));
 #endif
 void   dumpmap __P((char *map, int type, dump_ino_t ino));
 void   writeheader __P((dump_ino_t ino));
+void   mkchecksum __P((union u_spcl *tmpspcl));
 
 /* tape writing routines */
 int    alloctape __P((void));
 
 /* tape writing routines */
 int    alloctape __P((void));
index a64ad67c0fcc67e0f6a7a8036073458b1010744f..ac6a7a14417f0af477a58220a642b6f7af30592f 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.66 2002/01/22 11:12:28 stelian Exp $";
+       "$Id: main.c,v 1.67 2002/01/25 14:59:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #endif /* not lint */
 
 #include <config.h>
@@ -55,6 +55,7 @@ static const char rcsid[] =
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <sys/param.h>
 #include <sys/time.h>
 
 #include <sys/param.h>
 #include <sys/time.h>
@@ -104,6 +105,7 @@ 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    bzipflag;       /* compression is done using bzlib */
 char   lastlevel;      /* dump level of previous dump */
 char   level;          /* dump level of this dump */
 int    bzipflag;       /* compression is done using bzlib */
+int    Afile = 0;      /* archive file descriptor */
 int    uflag;          /* update flag */
 int    Mflag;          /* multi-volume flag */
 int    qflag;          /* quit on errors flag */
 int    uflag;          /* update flag */
 int    Mflag;          /* multi-volume flag */
 int    qflag;          /* quit on errors flag */
@@ -140,6 +142,7 @@ 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) */
 long   dev_bsize;      /* block size of underlying disk device */
 int    dev_bshift;     /* log2(dev_bsize) */
 int    tp_bshift;      /* log2(TP_BSIZE) */
+dump_ino_t volinfo[TP_NINOS];/* which inode on which volume archive info */
 
 #ifdef USE_QFA
 int    gTapeposfd;
 
 #ifdef USE_QFA
 int    gTapeposfd;
@@ -207,6 +210,7 @@ main(int argc, char *argv[])
 #endif
        time_t tnow;
        char *diskparam;
 #endif
        time_t tnow;
        char *diskparam;
+       char *Apath;
 
        spcl.c_label[0] = '\0';
        spcl.c_date = time(NULL);
 
        spcl.c_label[0] = '\0';
        spcl.c_date = time(NULL);
@@ -237,7 +241,7 @@ main(int argc, char *argv[])
 #endif /* USE_QFA */
 
        while ((ch = getopt(argc, argv,
 #endif /* USE_QFA */
 
        while ((ch = getopt(argc, argv,
-                           "0123456789aB:b:cd:e:E:f:F:h:I:"
+                           "0123456789A:aB:b:cd:e:E:f:F:h:I:"
 #ifdef HAVE_BZLIB
                            "j::"
 #endif
 #ifdef HAVE_BZLIB
                            "j::"
 #endif
@@ -261,6 +265,18 @@ main(int argc, char *argv[])
                        level = ch;
                        break;
 
                        level = ch;
                        break;
 
+               case 'A':               /* archive file */
+                       Apath = optarg;
+                       if ((Afile = open(Apath, O_RDWR|O_CREAT|O_TRUNC,
+                                         S_IRUSR | S_IWUSR)) < 0) {
+                               msg("Cannot open %s for writing: %s\n",
+                                   optarg, strerror(errno));
+                               msg("The ENTIRE dump is aborted.\n");
+                               exit(X_STARTUP);
+                       }
+                       memset(volinfo, 0, TP_NINOS * sizeof(dump_ino_t));
+                       break;
+
                case 'a':               /* `auto-size', Write to EOM. */
                        unlimited = 1;
                        aflag = 1;
                case 'a':               /* `auto-size', Write to EOM. */
                        unlimited = 1;
                        aflag = 1;
@@ -470,13 +486,6 @@ main(int argc, char *argv[])
                tapeprefix = strchr(host, ':');
                *tapeprefix++ = '\0';
 #ifdef RDUMP
                tapeprefix = strchr(host, ':');
                *tapeprefix++ = '\0';
 #ifdef RDUMP
-#ifdef USE_QFA
-               if (tapepos) {
-                       msg("Cannot use -Q option on remote media\n");
-                       msg("The ENTIRE dump is aborted.\n");
-                       exit(X_STARTUP);
-               }
-#endif
                if (index(tapeprefix, '\n')) {
                        msg("invalid characters in tape\n");
                        msg("The ENTIRE dump is aborted.\n");
                if (index(tapeprefix, '\n')) {
                        msg("invalid characters in tape\n");
                        msg("The ENTIRE dump is aborted.\n");
@@ -929,6 +938,13 @@ main(int argc, char *argv[])
 
        tend_writing = time(NULL);
        spcl.c_type = TS_END;
 
        tend_writing = time(NULL);
        spcl.c_type = TS_END;
+
+       if (Afile) {
+               volinfo[1] = ROOTINO;
+               memcpy(spcl.c_inos, volinfo, TP_NINOS * sizeof(dump_ino_t));
+               spcl.c_flags |= DR_INODEINFO;
+       }
+
        /*
         * Finish off the current tape record with trailer blocks, to ensure
         * at least the data in the last partial record makes it to tape.
        /*
         * Finish off the current tape record with trailer blocks, to ensure
         * at least the data in the last partial record makes it to tape.
@@ -969,6 +985,9 @@ main(int argc, char *argv[])
                        spcl.c_tapea, tapekb, rate);
        }
 
                        spcl.c_tapea, tapekb, rate);
        }
 
+       if (Afile)
+               msg("Archiving dump to %s\n", Apath);
+
        broadcast("DUMP IS DONE!\7\7\n");
        msg("DUMP IS DONE\n");
        Exit(X_FINOK);
        broadcast("DUMP IS DONE!\7\7\n");
        msg("DUMP IS DONE\n");
        Exit(X_FINOK);
@@ -998,22 +1017,23 @@ usage(void)
                "k"
 #endif
                "MnqSu"
                "k"
 #endif
                "MnqSu"
-               "] [-B records] [-b blocksize] [-d density]\n"
-               "\t%s [-e inode#,inode#,...] [-E file] [-f file] [-h level]\n"
-               "\t%s [-I nr errors] "
+               "] [-A file] [-B records] [-b blocksize]\n"
+               "\t%s [-d density] [-e inode#,inode#,...] [-E file] [-f file]\n"
+               "\t%s [-h level] [-I nr errors] "
 #ifdef HAVE_BZLIB
                "[-j zlevel] "
 #endif
 #ifdef USE_QFA
                "[-Q file] "
 #endif
 #ifdef HAVE_BZLIB
                "[-j zlevel] "
 #endif
 #ifdef USE_QFA
                "[-Q file] "
 #endif
-               "[-s feet] [-T date] "
+               "[-s feet]\n"
+               "\t%s [-T date] "
 #ifdef HAVE_ZLIB
                "[-z zlevel] "
 #endif
                "filesystem\n"
                "\t%s [-W | -w]\n", 
 #ifdef HAVE_ZLIB
                "[-z zlevel] "
 #endif
                "filesystem\n"
                "\t%s [-W | -w]\n", 
-               __progname, white, white, __progname);
+               __progname, white, white, white, __progname);
        exit(X_STARTUP);
 }
 
        exit(X_STARTUP);
 }
 
@@ -1110,6 +1130,7 @@ obsolete(int *argcp, char **argvp[])
 
        for (flags = 0; *ap; ++ap) {
                switch (*ap) {
 
        for (flags = 0; *ap; ++ap) {
                switch (*ap) {
+               case 'A':
                case 'B':
                case 'b':
                case 'd':
                case 'B':
                case 'b':
                case 'd':
index df8676362d65c5bbab59772eb0c0c77bcbef02ee..66fc821cdaaab154898d8eb21f64233b47e935a9 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.60 2002/01/22 11:12:28 stelian Exp $";
+       "$Id: tape.c,v 1.61 2002/01/25 14:59:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #endif /* not lint */
 
 #include <config.h>
@@ -80,6 +80,7 @@ int    write(), read();
 #include <linux/ext2_fs.h>
 #endif
 #include <ext2fs/ext2fs.h>
 #include <linux/ext2_fs.h>
 #endif
 #include <ext2fs/ext2fs.h>
+#include <sys/stat.h>
 #include <bsdcompat.h>
 #elif defined sunos
 #include <sys/vnode.h>
 #include <bsdcompat.h>
 #elif defined sunos
 #include <sys/vnode.h>
@@ -110,7 +111,6 @@ extern      long blocksperfile;     /* number of blocks per output file */
 long   blocksthisvol;          /* number of blocks on current output file */
 extern int ntrec;              /* blocking factor on tape */
 extern int cartridge;
 long   blocksthisvol;          /* number of blocks on current output file */
 extern int ntrec;              /* blocking factor on tape */
 extern int cartridge;
-extern char *host;
 char   *nexttape;
 extern  pid_t rshpid;
 int    eot_code = 1;
 char   *nexttape;
 extern  pid_t rshpid;
 int    eot_code = 1;
@@ -125,8 +125,8 @@ static      void flushtape __P((void));
 static void killall __P((void));
 static void rollforward __P((void));
 #ifdef USE_QFA
 static void killall __P((void));
 static void rollforward __P((void));
 #ifdef USE_QFA
-static int GetTapePos __P((long *));
-static void MkTapeString __P((struct s_spcl *, long));
+static int GetTapePos __P((long long *));
+static void MkTapeString __P((struct s_spcl *, long long));
 #endif
 
 /*
 #endif
 
 /*
@@ -234,6 +234,30 @@ writerec(const void *dp, int isspcl)
        slp->req[trecno].count = 1;
        /* XXX post increment triggers an egcs-1.1.2-12 bug on alpha/sparc */
        *(union u_spcl *)(*(nextblock)) = *(union u_spcl *)dp;
        slp->req[trecno].count = 1;
        /* XXX post increment triggers an egcs-1.1.2-12 bug on alpha/sparc */
        *(union u_spcl *)(*(nextblock)) = *(union u_spcl *)dp;
+
+       /* Need to write it to the archive file */
+       if (Afile < 0 && isspcl && (spcl.c_type == TS_END))
+               Afile = -Afile;
+       if (Afile > 0) {
+               /* When we dump an inode which is not a directory,
+                * it means we ended the archive contents */
+               if (isspcl && (spcl.c_type == TS_INODE) &&
+                   ((spcl.c_dinode.di_mode & S_IFMT) != IFDIR))
+                       Afile = -Afile;
+               else {
+                       union u_spcl tmp;
+                       tmp = *(union u_spcl *)dp;
+                       /* Write the record, _uncompressed_ */
+                       if (isspcl) {
+                               tmp.s_spcl.c_flags &= ~DR_COMPRESSED;
+                               mkchecksum(&tmp);
+                       }
+                       if (write(Afile, &tmp, TP_BSIZE) != TP_BSIZE)
+                               msg("error writing archive file: %s\n", 
+                               strerror(errno));
+               }
+       }
+
        nextblock++;
        if (isspcl)
                lastspclrec = spcl.c_tapea;
        nextblock++;
        if (isspcl)
                lastspclrec = spcl.c_tapea;
@@ -892,6 +916,8 @@ restore_check_point:
                if (tapeno > 1)
                        msg("Volume %d begins with blocks from inode %d\n",
                                tapeno, slp->inode);
                if (tapeno > 1)
                        msg("Volume %d begins with blocks from inode %d\n",
                                tapeno, slp->inode);
+               if (tapeno < TP_NINOS)
+                       volinfo[tapeno] = slp->inode;
        }
 }
 
        }
 }
 
@@ -1052,7 +1078,7 @@ doslave(int cmd, int slave_number, int first)
        errcode_t retval;
 #endif
 #ifdef USE_QFA
        errcode_t retval;
 #endif
 #ifdef USE_QFA
-       long curtapepos;
+       long long curtapepos;
        union u_spcl *uspclptr;
        struct s_spcl *spclptr;
 #endif /* USE_QFA */
        union u_spcl *uspclptr;
        struct s_spcl *spclptr;
 #endif /* USE_QFA */
@@ -1320,21 +1346,32 @@ atomic_write(int fd, const void *buf, size_t count)
  * read the current tape position
  */
 static int
  * read the current tape position
  */
 static int
-GetTapePos(long *pos)
+GetTapePos(long long *pos)
 {
        int err = 0;
 
 {
        int err = 0;
 
+#ifdef RDUMP
+       if (host) {
+               *pos = (long long) rmtseek(0, SEEK_CUR);
+               err = *pos < 0;
+       }
+       else 
+#endif
+       {
        if (magtapeout) {
        if (magtapeout) {
+               long mtpos;
                *pos = 0;
                *pos = 0;
-               err = (ioctl(tapefd, MTIOCPOS, pos) < 0);
+               err = (ioctl(tapefd, MTIOCPOS, &mtpos) < 0);
+               *pos = (long long)mtpos;
        }
        else {
        }
        else {
-               *pos = lseek(tapefd, 0, SEEK_CUR);
+               *pos = LSEEK(tapefd, 0, SEEK_CUR);
                err = (*pos < 0);
        }
                err = (*pos < 0);
        }
+       }
        if (err) {
                err = errno;
        if (err) {
                err = errno;
-               msg("[%ld] error: %d (getting tapepos: %ld)\n", getpid(), 
+               msg("[%ld] error: %d (getting tapepos: %lld)\n", getpid(), 
                        err, *pos);
                return err;
        }
                        err, *pos);
                return err;
        }
@@ -1342,13 +1379,13 @@ GetTapePos(long *pos)
 }
 
 static void 
 }
 
 static void 
-MkTapeString(struct s_spcl *spclptr, long curtapepos) {
+MkTapeString(struct s_spcl *spclptr, long long curtapepos) {
 
 #ifdef DEBUG_QFA
 
 #ifdef DEBUG_QFA
-       msg("inode %ld at tapepos %ld\n", spclptr->c_inumber, curtapepos);
+       msg("inode %ld at tapepos %lld\n", spclptr->c_inumber, curtapepos);
 #endif
 
 #endif
 
-       snprintf(gTps, sizeof(gTps), "%ld\t%d\t%ld\n", 
+       snprintf(gTps, sizeof(gTps), "%ld\t%d\t%lld\n", 
                 (unsigned long)spclptr->c_inumber, 
                 tapeno, 
                 curtapepos);
                 (unsigned long)spclptr->c_inumber, 
                 tapeno, 
                 curtapepos);
index 06eeb7373cb0954cf3512c3191aedded1f859265..80d7e86bf17e18441bb28cf38ac708f59d5d516b 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: traverse.c,v 1.40 2002/01/16 09:32:14 stelian Exp $";
+       "$Id: traverse.c,v 1.41 2002/01/25 14:59:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #endif /* not lint */
 
 #include <config.h>
@@ -1176,21 +1176,20 @@ dumpmap(char *map, int type, dump_ino_t ino)
                writerec(cp, 0);
 }
 
                writerec(cp, 0);
 }
 
-/*
- * Write a header record to the dump tape.
- */
 #if defined __linux__ && !defined(int32_t)
 #define int32_t __s32
 #endif
 #if defined __linux__ && !defined(int32_t)
 #define int32_t __s32
 #endif
+
+/* 
+ * Compute and fill in checksum information.
+ */
 void
 void
-writeheader(dump_ino_t ino)
+mkchecksum(union u_spcl *tmpspcl) 
 {
 {
-       register int32_t sum, cnt, *lp;
+       int32_t sum, cnt, *lp;
 
 
-       spcl.c_inumber = ino;
-       spcl.c_magic = NFS_MAGIC;
-       spcl.c_checksum = 0;
-       lp = (int32_t *)&spcl;
+       tmpspcl->s_spcl.c_checksum = 0;
+       lp = (int32_t *)&tmpspcl->s_spcl;
        sum = 0;
        cnt = sizeof(union u_spcl) / (4 * sizeof(int32_t));
        while (--cnt >= 0) {
        sum = 0;
        cnt = sizeof(union u_spcl) / (4 * sizeof(int32_t));
        while (--cnt >= 0) {
@@ -1199,7 +1198,18 @@ writeheader(dump_ino_t ino)
                sum += *lp++;
                sum += *lp++;
        }
                sum += *lp++;
                sum += *lp++;
        }
-       spcl.c_checksum = CHECKSUM - sum;
+       tmpspcl->s_spcl.c_checksum = CHECKSUM - sum;
+}
+
+/*
+ * Write a header record to the dump tape.
+ */
+void
+writeheader(dump_ino_t ino)
+{
+       spcl.c_inumber = ino;
+       spcl.c_magic = NFS_MAGIC;
+       mkchecksum((union u_spcl *)&spcl);
        writerec((char *)&spcl, 1);
 }
 
        writerec((char *)&spcl, 1);
 }
 
index babafea8bf51a3976c145dd96935524d1e9673d4..7cc98044c46e85fad8ba3e7b819b2baf68e9a220 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: extern.h,v 1.14 2002/01/16 09:32:14 stelian Exp $
+ *     $Id: extern.h,v 1.15 2002/01/25 14:59:53 stelian Exp $
  */
 
 /*-
  */
 
 /*-
@@ -90,6 +90,7 @@ void           panic __P((const char *, ...));
 void            pathcheck __P((char *));
 struct direct  *pathsearch __P((const char *));
 void            printdumpinfo __P((void));
 void            pathcheck __P((char *));
 struct direct  *pathsearch __P((const char *));
 void            printdumpinfo __P((void));
+void            printvolinfo __P((void));
 void            removeleaf __P((struct entry *));
 void            removenode __P((struct entry *));
 void            removeoldleaves __P((void));
 void            removeleaf __P((struct entry *));
 void            removenode __P((struct entry *));
 void            removeoldleaves __P((void));
@@ -127,9 +128,9 @@ int fgetflags __P((const char *, unsigned long *));
 int setflags __P((int, unsigned long));
 
 #ifdef USE_QFA
 int setflags __P((int, unsigned long));
 
 #ifdef USE_QFA
-int    Inode2Tapepos __P((dump_ino_t, long *, long *, int));
-int    GetTapePos __P((long *));
-int    GotoTapePos __P((long));
+int    Inode2Tapepos __P((dump_ino_t, long *, long long *, int));
+int    GetTapePos __P((long long *));
+int    GotoTapePos __P((long long));
 void   ReReadFromTape __P((void));
 void   ReReadFromTape __P((void));
-void   RequestVol __P((long));
 #endif
 #endif
+void   RequestVol __P((long));
index 10cc5bfac6a1c7412fbae1c5190fdc1f2b0d8f36..fb29a4fd51e232ca22b2539754c4c7d1469cd471 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: interactive.c,v 1.19 2002/01/16 10:53:28 stelian Exp $";
+       "$Id: interactive.c,v 1.20 2002/01/25 14:59:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #endif /* not lint */
 
 #include <config.h>
@@ -316,6 +316,7 @@ loop:
                if (strncmp(cmd, "what", strlen(cmd)) != 0)
                        goto bad;
                printdumpinfo();
                if (strncmp(cmd, "what", strlen(cmd)) != 0)
                        goto bad;
                printdumpinfo();
+               printvolinfo();
                break;
        /*
         * Turn on debugging.
                break;
        /*
         * Turn on debugging.
index ab058abcdaf74eb3d2f94344f35e95e3e5750a9b..fb51380cf600c92078c0f584ce675a2b224f312a 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.36 2002/01/22 11:12:28 stelian Exp $";
+       "$Id: main.c,v 1.37 2002/01/25 14:59:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #endif /* not lint */
 
 #include <config.h>
@@ -83,6 +83,7 @@ static const char rcsid[] =
 int    aflag = 0, bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
 int    hflag = 1, mflag = 1, Mflag = 0, Nflag = 0, Vflag = 0, zflag = 0;
 int    uflag = 0, lflag = 0, Lflag = 0;
 int    aflag = 0, bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
 int    hflag = 1, mflag = 1, Mflag = 0, Nflag = 0, Vflag = 0, zflag = 0;
 int    uflag = 0, lflag = 0, Lflag = 0;
+char   *Afile = NULL;
 int    dokerberos = 0;
 char   command = '\0';
 long   dumpnum = 1;
 int    dokerberos = 0;
 char   command = '\0';
 long   dumpnum = 1;
@@ -100,6 +101,7 @@ int compare_errors;
 char   filesys[NAMELEN];
 static const char *stdin_opt = NULL;
 char   *bot_script = NULL;
 char   filesys[NAMELEN];
 static const char *stdin_opt = NULL;
 char   *bot_script = NULL;
+dump_ino_t volinfo[TP_NINOS];
 
 #ifdef USE_QFA
 FILE   *gTapeposfp;
 
 #ifdef USE_QFA
 FILE   *gTapeposfp;
@@ -154,7 +156,7 @@ main(int argc, char *argv[])
                ;                                                               
        obsolete(&argc, &argv);
        while ((ch = getopt(argc, argv, 
                ;                                                               
        obsolete(&argc, &argv);
        while ((ch = getopt(argc, argv, 
-               "ab:CcdD:f:F:hi"
+               "aA:b:CcdD:f:F:hi"
 #ifdef KERBEROS
                "k"
 #endif
 #ifdef KERBEROS
                "k"
 #endif
@@ -167,6 +169,10 @@ main(int argc, char *argv[])
                case 'a':
                        aflag = 1;
                        break;
                case 'a':
                        aflag = 1;
                        break;
+               case 'A':
+                       Afile = optarg;
+                       aflag = 1;
+                       break;
                case 'b':
                        /* Change default tape blocksize. */
                        bflag = 1;
                case 'b':
                        /* Change default tape blocksize. */
                        bflag = 1;
@@ -284,7 +290,13 @@ main(int argc, char *argv[])
 #ifdef USE_QFA
        if (!mflag && tapeposflag)
                errx(1, "m and Q options are mutually exclusive");
 #ifdef USE_QFA
        if (!mflag && tapeposflag)
                errx(1, "m and Q options are mutually exclusive");
+
+       if (tapeposflag && command != 'i' && command != 'x' && command != 't')
+               errx(1, "Q option is not valid for %c command", command);
 #endif
 #endif
+       
+       if (Afile && command != 'i' && command != 'x' && command != 't')
+               errx(1, "A option is not valid for %c command", command);
 
        if (signal(SIGINT, onintr) == SIG_IGN)
                (void) signal(SIGINT, SIG_IGN);
 
        if (signal(SIGINT, onintr) == SIG_IGN)
                (void) signal(SIGINT, SIG_IGN);
@@ -469,6 +481,7 @@ main(int argc, char *argv[])
                setup();
                extractdirs(0);
                initsymtable((char *)0);
                setup();
                extractdirs(0);
                initsymtable((char *)0);
+               printvolinfo();
                for (;;) {
                        NEXTFILE(p);
                        if (!p)
                for (;;) {
                        NEXTFILE(p);
                        if (!p)
@@ -523,9 +536,13 @@ main(int argc, char *argv[])
 static void
 usage(void)
 {
 static void
 usage(void)
 {
-#ifdef __linux__
+       char white[MAXPATHLEN];
        const char *ext2ver, *ext2date;
 
        const char *ext2ver, *ext2date;
 
+       memset(white, ' ', MAXPATHLEN);
+       white[MIN(strlen(__progname), MAXPATHLEN - 1)] = '\0';
+
+#ifdef __linux__
        ext2fs_get_library_version(&ext2ver, &ext2date);
        (void)fprintf(stderr, "%s %s (using libext2fs %s of %s)\n", 
                      __progname, _DUMP_VERSION, ext2ver, ext2date);
        ext2fs_get_library_version(&ext2ver, &ext2date);
        (void)fprintf(stderr, "%s %s (using libext2fs %s of %s)\n", 
                      __progname, _DUMP_VERSION, ext2ver, ext2date);
@@ -545,14 +562,26 @@ usage(void)
 #define qfaflag
 #endif
 
 #define qfaflag
 #endif
 
-       (void)fprintf(stderr,
-         "usage:\t%s%s\n\t%s%s\n\t%s%s\n\t%s%s\n\t%s%s\n\t%s%s\n",
-         __progname, " -C [-c" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file] [-F script] [-L limit] [-s fileno]",
-         __progname, " -i [-ach" kerbflag "lmMuvVy] [-b blocksize] [-f file] [-F script] " qfaflag "[-s fileno]",
-         __progname, " -r [-c" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script] [-s fileno] [-T directory]",
-         __progname, " -R [-c" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script] [-s fileno] [-T directory]",
-         __progname, " -t [-ch" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]",
-         __progname, " -x [-ach" kerbflag "lmMuvVy] [-b blocksize] [-f file] [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]");
+       fprintf(stderr,
+               "usage:"
+               "\t%s -C [-c" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file]\n"
+               "\t%s    [-F script] [-L limit] [-s fileno]\n"
+               "\t%s -i [-ach" kerbflag "lmMuvVy] [-A file] [-b blocksize] [-f file]\n"
+               "\t%s    [-F script] " qfaflag "[-s fileno]\n"
+               "\t%s -r [-c" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
+               "\t%s    [-s fileno] [-T directory]\n"
+               "\t%s -R [-c" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n"
+               "\t%s    [-s fileno] [-T directory]\n"
+               "\t%s -t [-ch" kerbflag "lMuvVy] [-A file] [-b blocksize] [-f file]\n"
+               "\t%s    [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n"
+               "\t%s -x [-ach" kerbflag "lmMuvVy] [-A file] [-b blocksize] [-f file]\n"
+               "\t%s    [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n",
+               __progname, white, 
+               __progname, white, 
+               __progname, white,
+               __progname, white, 
+               __progname, white, 
+               __progname, white);
        exit(1);
 }
 
        exit(1);
 }
 
@@ -586,6 +615,7 @@ obsolete(int *argcp, char **argvp[])
 
        for (flags = 0; *ap; ++ap) {
                switch (*ap) {
 
        for (flags = 0; *ap; ++ap) {
                switch (*ap) {
+               case 'A':
                case 'b':
                case 'D':
                case 'f':
                case 'b':
                case 'D':
                case 'f':
index 90fb1e323427e7f92cbae1db99173a8672f04e08..54f289e4fa4e77bd32d9b160b47f1b4c3c11a07a 100644 (file)
@@ -29,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $Id: restore.8.in,v 1.23 2002/01/22 11:12:28 stelian Exp $
+.\"    $Id: restore.8.in,v 1.24 2002/01/25 14:59:53 stelian Exp $
 .\"
 .Dd __DATE__
 .Dt RESTORE 8
 .\"
 .Dd __DATE__
 .Dt RESTORE 8
@@ -51,6 +51,7 @@
 .Nm restore
 .Fl i
 .Op Fl achklmMNuvVy
 .Nm restore
 .Fl i
 .Op Fl achklmMNuvVy
+.Op Fl A Ar file
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
 .Op Fl F Ar script
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
 .Op Fl F Ar script
@@ -76,6 +77,7 @@
 .Nm restore
 .Fl t
 .Op Fl chklMNuvVy
 .Nm restore
 .Fl t
 .Op Fl chklMNuvVy
+.Op Fl A Ar file
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
 .Op Fl F Ar script
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
 .Op Fl F Ar script
@@ -87,6 +89,7 @@
 .Nm restore
 .Fl x
 .Op Fl achklmMNuvVy
 .Nm restore
 .Fl x
 .Op Fl achklmMNuvVy
+.Op Fl A Ar file
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
 .Op Fl F Ar script
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
 .Op Fl F Ar script
@@ -316,6 +319,16 @@ option disables this behaviour and reads all the volumes starting
 with 1. This option is useful when the operator does not know on which
 volume the files to be extracted are and/or when he prefers the
 longer unattended mode rather than the shorter interactive mode.
 with 1. This option is useful when the operator does not know on which
 volume the files to be extracted are and/or when he prefers the
 longer unattended mode rather than the shorter interactive mode.
+.It Fl A Ar archive_file
+Read the table of contents from
+.Ar archive_file
+instead of the media. This option can be used in combination with the 
+.Fl t, 
+.Fl i, 
+or 
+.Fl x 
+options, making it possible to check whether files are on the media 
+without having to mount the media. 
 .It Fl b Ar blocksize
 The number of kilobytes per dump record.
 If the
 .It Fl b Ar blocksize
 The number of kilobytes per dump record.
 If the
@@ -376,17 +389,16 @@ For security reasons,
 .Nm
 reverts back to the real user ID and the real group ID before 
 running the script.
 .Nm
 reverts back to the real user ID and the real group ID before 
 running the script.
-.It Fl k
-Use Kerberos authentication when contacting the remote tape server.
-(Only available if this options was enabled when
-.Nm restore
-was compiled.)
-.Pp
 .It Fl h
 Extract the actual directory, 
 rather than the files that it references.
 This prevents hierarchical restoration of complete subtrees
 from the dump.
 .It Fl h
 Extract the actual directory, 
 rather than the files that it references.
 This prevents hierarchical restoration of complete subtrees
 from the dump.
+.It Fl k
+Use Kerberos authentication when contacting the remote tape server.
+(Only available if this options was enabled when
+.Nm restore
+was compiled.)
 .It Fl l
 When doing remote restores, assume the remote file is a
 regular file (instead of a tape device). If you're restoring
 .It Fl l
 When doing remote restores, assume the remote file is a
 regular file (instead of a tape device). If you're restoring
@@ -437,7 +449,12 @@ command without actually writing any file on disk.
 Use the file
 .Ar file
 in order to read tape position as stored using the dump Quick File
 Use the file
 .Ar file
 in order to read tape position as stored using the dump Quick File
-Access mode.
+Access mode, in one of 
+.Fl i,
+.Fl x
+or
+.Fl t
+mode.
 .Pp
 It is recommended to set up the st driver to return logical tape 
 positions rather than physical before calling dump/restore with 
 .Pp
 It is recommended to set up the st driver to return logical tape 
 positions rather than physical before calling dump/restore with 
@@ -451,8 +468,8 @@ Before calling restore with parameter Q, always make sure the st
 driver is set to return the same type of tape position used during the 
 call to dump. Otherwise restore may be confused.
 .Pp
 driver is set to return the same type of tape position used during the 
 call to dump. Otherwise restore may be confused.
 .Pp
-This option can be used when restoring from local tapes (see above)
-or from local files.
+This option can be used when restoring from local or remote tapes 
+(see above) or from local or remote files.
 .It Fl s Ar fileno
 Read from the specified
 .Ar fileno
 .It Fl s Ar fileno
 Read from the specified
 .Ar fileno
index 3cc2badf9654143be991a5102c5f8ad599960ba6..a44f50dddf5dc022a41d2636f2e221b1481b7524 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: restore.c,v 1.24 2002/01/22 11:12:28 stelian Exp $";
+       "$Id: restore.c,v 1.25 2002/01/25 14:59:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #endif /* not lint */
 
 #include <config.h>
@@ -83,7 +83,7 @@ listfile(char *name, dump_ino_t ino, int type)
        long descend = hflag ? GOOD : FAIL;
 #ifdef USE_QFA
        long tnum;
        long descend = hflag ? GOOD : FAIL;
 #ifdef USE_QFA
        long tnum;
-       long tpos;
+       long long tpos;
 #endif
 
        if (TSTINO(ino, dumpmap) == 0)
 #endif
 
        if (TSTINO(ino, dumpmap) == 0)
@@ -92,7 +92,7 @@ listfile(char *name, dump_ino_t ino, int type)
 #ifdef USE_QFA
        if (tapeposflag) {      /* add QFA positions to output */
                (void)Inode2Tapepos(ino, &tnum, &tpos, 1);
 #ifdef USE_QFA
        if (tapeposflag) {      /* add QFA positions to output */
                (void)Inode2Tapepos(ino, &tnum, &tpos, 1);
-               fprintf(stdout, "%10lu\t%ld\t%ld\t%s\n", (unsigned long)ino, 
+               fprintf(stdout, "%10lu\t%ld\t%lld\t%s\n", (unsigned long)ino, 
                        tnum, tpos, name);
        }
        else
                        tnum, tpos, name);
        }
        else
@@ -839,16 +839,22 @@ createfiles(void)
        register struct entry *ep;
        long curvol;
 #ifdef USE_QFA
        register struct entry *ep;
        long curvol;
 #ifdef USE_QFA
-       long tnum, tpos, curtpos, tmpcnt;
+       long tnum, tmpcnt;
+       long long tpos, curtpos;
        time_t tistart, tiend, titaken;
 #endif
 
        Vprintf(stdout, "Extract requested files\n");
        curfile.action = SKIP;
 #ifdef USE_QFA
        time_t tistart, tiend, titaken;
 #endif
 
        Vprintf(stdout, "Extract requested files\n");
        curfile.action = SKIP;
 #ifdef USE_QFA
-       if (!tapeposflag)
+       if (tapeposflag)
+               curfile.ino = 0;
+       else
 #endif
 #endif
-               getvol((long)1);
+               if (volinfo[1] == ROOTINO)
+                       curfile.ino = 0;
+               else
+                       getvol((long)1);
        skipmaps();
        skipdirs();
        first = lowerbnd(ROOTINO);
        skipmaps();
        skipdirs();
        first = lowerbnd(ROOTINO);
@@ -911,7 +917,7 @@ createfiles(void)
                                         *  might be too slow */
                                        if (tpos > curtpos) {
 #ifdef DEBUG_QFA
                                         *  might be too slow */
                                        if (tpos > curtpos) {
 #ifdef DEBUG_QFA
-                                               msg("positioning tape %ld from %ld to %ld for inode %10lu ...\n", volno, curtpos, tpos, (unsigned long)next);
+                                               msg("positioning tape %ld from %lld to %lld for inode %10lu ...\n", volno, curtpos, tpos, (unsigned long)next);
 #endif
                                                if (GotoTapePos(tpos) == 0) {
 #ifdef DEBUG_QFA
 #endif
                                                if (GotoTapePos(tpos) == 0) {
 #ifdef DEBUG_QFA
@@ -928,7 +934,18 @@ createfiles(void)
                                }
                        }
                }
                                }
                        }
                }
+               else
 #endif /* USA_QFA */
 #endif /* USA_QFA */
+                       if (volinfo[1] == ROOTINO) {
+                               int i, goodvol = 1;
+
+                               for (i = 1; i < TP_NINOS && volinfo[i] != 0; ++i)
+                                       if (volinfo[i] < next)
+                                               goodvol = i;
+
+                               if (goodvol != volno)
+                                       RequestVol(goodvol);
+                       }
 
                do      {
                        curvol = volno;
 
                do      {
                        curvol = volno;
index ba6af080534c1a93cd696c89af5a9a07a1d9428a..a9dba7bfb539530da14453bd4513882459faf5fa 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: restore.h,v 1.23 2002/01/16 10:29:26 stelian Exp $
+ *     $Id: restore.h,v 1.24 2002/01/25 14:59:53 stelian Exp $
  */
 
 /*
  */
 
 /*
@@ -52,6 +52,7 @@
  * Flags
  */
 extern int     aflag;          /* automatic volume increment */
  * Flags
  */
 extern int     aflag;          /* automatic volume increment */
+extern char    *Afile;         /* archive file */
 extern int     cvtflag;        /* convert from old to new tape format */
 extern int     bflag;          /* set input block size */
 extern int     dflag;          /* print out debugging info */
 extern int     cvtflag;        /* convert from old to new tape format */
 extern int     bflag;          /* set input block size */
 extern int     dflag;          /* print out debugging info */
@@ -70,6 +71,7 @@ extern char*  bot_script;     /* beginning of tape script */
 /*
  * Global variables
  */
 /*
  * Global variables
  */
+extern char    *host;          /* name of the remote host */
 extern char    *dumpmap;       /* map of inodes on this dump tape */
 extern char    *usedinomap;    /* map of inodes that are in use on this fs */
 extern dump_ino_t maxino;      /* highest numbered inode in this file system */
 extern char    *dumpmap;       /* map of inodes on this dump tape */
 extern char    *usedinomap;    /* map of inodes that are in use on this fs */
 extern dump_ino_t maxino;      /* highest numbered inode in this file system */
@@ -90,6 +92,7 @@ extern int    compare_ignore_not_found;
                                /* isn't seen. */
 extern int     compare_errors; /* did we encounter any compare errors? */
 extern char    filesys[NAMELEN];/* name of dumped filesystem */
                                /* isn't seen. */
 extern int     compare_errors; /* did we encounter any compare errors? */
 extern char    filesys[NAMELEN];/* name of dumped filesystem */
+extern dump_ino_t volinfo[];   /* which inode on which volume archive info */
 
 /*
  * Each file in the file system is described by one of these entries
 
 /*
  * Each file in the file system is described by one of these entries
index cf024713643ab76e53dca89f0142f14279196b65..ff524ce0c1c3efbe202e978eb83bcd5326828a8d 100644 (file)
@@ -46,7 +46,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.54 2002/01/22 11:12:28 stelian Exp $";
+       "$Id: tape.c,v 1.55 2002/01/25 14:59:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #endif /* not lint */
 
 #include <config.h>
@@ -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 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;
 
 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));
 
 #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 *));
 static void    readtape_set __P((char *));
 static void    readtape_uncompr __P((char *));
 static void    readtape_comprfile __P((char *));
@@ -190,10 +191,6 @@ setinput(char *source)
 
 #ifdef RRESTORE
        if (strchr(source, ':')) {
 
 #ifdef RRESTORE
        if (strchr(source, ':')) {
-#ifdef USE_QFA
-               if (tapeposflag)
-                       errx(1, "cannot use -Q option on remote media");
-#endif
                host = source;
                source = strchr(host, ':');
                *source++ = '\0';
                host = source;
                source = strchr(host, ':');
                *source++ = '\0';
@@ -268,9 +265,10 @@ setup(void)
 {
        int i, j, *ip, bot_code;
        struct STAT stbuf;
 {
        int i, j, *ip, bot_code;
        struct STAT stbuf;
+       char *temptape;
 
        Vprintf(stdout, "Verify tape and initialize maps\n");
 
        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) {
                msg("Launching %s\n", bot_script);
                bot_code = system_command(bot_script, magtape, 1);
                if (bot_code != 0 && bot_code != 1) {
@@ -278,20 +276,31 @@ setup(void)
                        exit(1);
                }
        }
                        exit(1);
                }
        }
+
+       if (Afile)
+               temptape = Afile;
+       else
+               temptape = magtape;
+
 #ifdef RRESTORE
        if (host)
 #ifdef RRESTORE
        if (host)
-               mt = rmtopen(magtape, 0);
+               mt = rmtopen(temptape, 0);
        else
 #endif
        if (pipein)
                mt = 0;
        else
        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);
        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) {
        FLUSHTAPEBUF();
        findtapeblksize();
        if (gethead(&spcl) == FAIL) {
@@ -306,11 +315,9 @@ setup(void)
 
        if (zflag) {
                fprintf(stderr, "Dump tape is compressed.\n");
 
        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");
                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;
        }
        if (pipein) {
                endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : NFS_MAGIC;
@@ -505,6 +512,9 @@ again:
        }
 gethdr:
        setmagtapein();
        }
 gethdr:
        setmagtapein();
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB)
+       readtape_func = readtape_set;
+#endif
        volno = newvol;
        setdumpnum();
        FLUSHTAPEBUF();
        volno = newvol;
        setdumpnum();
        FLUSHTAPEBUF();
@@ -546,6 +556,12 @@ gethdr:
         * If coming to this volume at random, skip to the beginning
         * of the next record.
         */
         * 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)) {
        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)) {
@@ -642,6 +658,18 @@ printdumpinfo(void)
        fprintf(stdout, "Label: %s\n", spcl.c_label);
 }
 
        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)
 {
 int
 extractfile(char *name)
 {
@@ -1986,7 +2014,7 @@ gethead(struct s_spcl *buf)
                                int32_t odi_ctime;
                        } c_dinode;
                        int32_t c_count;
                                int32_t odi_ctime;
                        } c_dinode;
                        int32_t c_count;
-                       char    c_addr[256];
+                       char    c_fill[256];
                } s_ospcl;
        } u_ospcl;
 
                } s_ospcl;
        } u_ospcl;
 
@@ -2032,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;
        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);
        if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
            checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
                return(FAIL);
@@ -2078,6 +2106,11 @@ good:
                /* fall through */
        case TS_END:
                buf->c_inumber = 0;
                /* 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:
                break;
 
        case TS_INODE:
@@ -2385,21 +2418,32 @@ swabl(u_long x)
  * get the current position of the tape
  */
 int
  * get the current position of the tape
  */
 int
-GetTapePos(long *pos)
+GetTapePos(long long *pos)
 {
        int err = 0;
 
 {
        int err = 0;
 
+#ifdef RDUMP
+       if (host) {
+               *pos = (long long) rmtseek(0, SEEK_CUR);
+               err = *pos < 0;
+       }
+       else
+#endif
+       {
        if (magtapein) {
        if (magtapein) {
+               long mtpos;
                *pos = 0;
                *pos = 0;
-               err = (ioctl(mt, MTIOCPOS, pos) < 0);
+               err = (ioctl(mt, MTIOCPOS, &mtpos) < 0);
+               *pos = (long long)mtpos;
        }
        else {
        }
        else {
-               *pos = lseek(mt, 0, SEEK_CUR);
+               *pos = LSEEK(mt, 0, SEEK_CUR);
                err = (*pos < 0);
        }
                err = (*pos < 0);
        }
+       }
        if (err) {
                err = errno;
        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;
        }
                        (unsigned long)getpid(), err, *pos);
                return err;
        }
@@ -2415,23 +2459,30 @@ typedef struct mt_pos {
  * go to specified position on tape
  */
 int
  * go to specified position on tape
  */
 int
-GotoTapePos(long pos)
+GotoTapePos(long long pos)
 {
        int err = 0;
 
 {
        int err = 0;
 
+#ifdef RDUMP
+       if (host)
+               err = (rmtseek((long)pos, SEEK_SET) < 0);
+       else
+#endif
+       {
        if (magtapein) {
                struct mt_pos buf;
                buf.mt_op = MTSEEK;
        if (magtapein) {
                struct mt_pos buf;
                buf.mt_op = MTSEEK;
-               buf.mt_count = pos;
+               buf.mt_count = (int) pos;
                err = (ioctl(mt, MTIOCTOP, &buf) < 0);
        }
        else {
                err = (ioctl(mt, MTIOCTOP, &buf) < 0);
        }
        else {
-               pos = lseek(mt, pos, SEEK_SET);
+               pos = LSEEK(mt, pos, SEEK_SET);
                err = (pos < 0);
        }
                err = (pos < 0);
        }
+       }
        if (err) {
                err = errno;
        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;
        }
                        (unsigned long)getpid(), err, pos);
                return err;
        }
@@ -2454,6 +2505,7 @@ ReReadFromTape(void)
        findinode(&spcl);
        noresyncmesg = 0;
 }
        findinode(&spcl);
        noresyncmesg = 0;
 }
+#endif /* USE_QFA */
 
 void
 RequestVol(long tnum)
 
 void
 RequestVol(long tnum)
@@ -2461,4 +2513,3 @@ RequestVol(long tnum)
        FLUSHTAPEBUF();
        getvol(tnum);
 }
        FLUSHTAPEBUF();
        getvol(tnum);
 }
-#endif /* USE_QFA */
index c94d36f2e1c02e311d3618d96ba2c535249b66c7..4960b9ab4e3a5e8d9757c9d546e4b3de99df5ef0 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: utilities.c,v 1.17 2002/01/16 09:32:14 stelian Exp $";
+       "$Id: utilities.c,v 1.18 2002/01/25 14:59:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #endif /* not lint */
 
 #include <config.h>
@@ -485,13 +485,13 @@ panic(fmt, va_alist)
  * if no smaller inode found return tnum=0 and tpos=0
  */
 int
  * if no smaller inode found return tnum=0 and tpos=0
  */
 int
-Inode2Tapepos(dump_ino_t ino, long *tnum, long *tpos, int exactmatch)
+Inode2Tapepos(dump_ino_t ino, long *tnum, long long *tpos, int exactmatch)
 {
        char *p, *pp;
        char numbuff[32];
        unsigned long tmpino;
        long tmptnum;
 {
        char *p, *pp;
        char numbuff[32];
        unsigned long tmpino;
        long tmptnum;
-       long tmptpos;
+       long long tmptpos;
 
        *tpos = 0;
        *tnum = 0;
 
        *tpos = 0;
        *tnum = 0;
@@ -523,7 +523,7 @@ Inode2Tapepos(dump_ino_t ino, long *tnum, long *tpos, int exactmatch)
                /* read tapepos */
                while ((*p != 0) && (*p != '\t'))
                        *pp++ = *p++;
                /* read tapepos */
                while ((*p != 0) && (*p != '\t'))
                        *pp++ = *p++;
-               tmptpos = atol(numbuff);
+               tmptpos = atoll(numbuff);
 
                if (exactmatch) {
                        if (tmpino == ino)  {
 
                if (exactmatch) {
                        if (tmpino == ino)  {