-$Id: CHANGES,v 1.160 2002/01/31 10:49:16 stelian Exp $
+$Id: CHANGES,v 1.161 2002/02/04 11:18:45 stelian Exp $
Changes between versions 0.4b26 and 0.4b27 (released ???????????????)
=====================================================================
ext2 disk labels (LABEL=/). Thanks to John Yu <jky@it.bu.edu>
for reporting this bug.
+9. Added the -P <file> option to restore to create a
+ Quick File Access file from an already made dump. Patch
+ contributed by Uwe Gohlke <uwe@ugsoft.de>.
+
+10. Made restore compile and run on Solaris, making it a
+ possible replacement for the standard ufsrestore. Port was
+ contributed by Uwe Gohlke <uwe@ugsoft.de>.
+
Changes between versions 0.4b25 and 0.4b26 (released January 7, 2002)
=====================================================================
#ifndef lint
static const char rcsid[] =
- "$Id: optr.c,v 1.30 2002/01/25 15:08:59 stelian Exp $";
+ "$Id: optr.c,v 1.31 2002/02/04 11:18:45 stelian Exp $";
#endif /* not lint */
#include <config.h>
strcmp(fs->fs_type, FSTAB_RQ))
continue;
fs = allocfsent(fs);
+ fs->fs_passno = 0;
if ((pf = (struct pfstab *)malloc(sizeof (*pf))) == NULL)
quit("%s\n", strerror(errno));
pf->pf_fstab = fs;
#ifndef lint
static const char rcsid[] =
- "$Id: traverse.c,v 1.42 2002/01/25 15:08:59 stelian Exp $";
+ "$Id: traverse.c,v 1.43 2002/02/04 11:18:46 stelian Exp $";
#endif /* not lint */
#include <config.h>
dump_ino_t journal_ino = ext2_journal_ino(es);
if (es->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV){
- fprintf(stderr, "This an journal, not a filesystem!\n");
+ msg("This is a journal, not a filesystem!\n");
retval = EXT2_ET_UNSUPP_FEATURE;
ext2fs_close(*fs);
}
else if ((retval = es->s_feature_incompat &
~(EXT2_LIB_FEATURE_INCOMPAT_SUPP |
EXT3_FEATURE_INCOMPAT_RECOVER))) {
- fprintf(stderr,
- "Unsupported feature(s) 0x%x in filesystem\n",
+ msg("Unsupported feature(s) 0x%x in filesystem\n",
retval);
retval = EXT2_ET_UNSUPP_FEATURE;
ext2fs_close(*fs);
#ifndef lint
static const char rcsid[] =
- "$Id: dirs.c,v 1.17 2002/01/25 15:08:59 stelian Exp $";
+ "$Id: dirs.c,v 1.18 2002/02/04 11:18:46 stelian Exp $";
#endif /* not lint */
#include <config.h>
char d_name[ODIRSIZ];
};
-#ifdef __linux__
+#if defined(__linux__) || defined(sunos)
static struct inotab *allocinotab __P((dump_ino_t, struct new_bsd_inode *, long));
#else
static struct inotab *allocinotab __P((dump_ino_t, struct dinode *, long));
extractdirs(int genmode)
{
int i;
-#ifdef __linux__
+#if defined(__linux__) || defined(sunos)
struct new_bsd_inode *ip;
#else
struct dinode *ip;
while (*path == '/')
path++;
dp = NULL;
+#ifdef __linux__
while ((name = strsep(&path, "/")) != NULL && *name /* != NULL */) {
+#else
+ while ((name = strtok_r(NULL, "/", &path)) != NULL && *name /* != NULL */) {
+#endif
if ((dp = searchdir(ino, name)) == NULL)
return (NULL);
ino = dp->d_ino;
/*
* These variables are "local" to the following two functions.
*/
-char dirbuf[DIRBLKSIZ];
-long dirloc = 0;
-long prev = 0;
+static char dirbuf[DIRBLKSIZ];
+static long dirloc = 0;
+static long prev = 0;
/*
* add a new directory entry to a file.
* Stelian Pop <stelian@popies.net>, 1999-2000
* Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
*
- * $Id: extern.h,v 1.15 2002/01/25 14:59:53 stelian Exp $
+ * $Id: extern.h,v 1.16 2002/02/04 11:18:46 stelian Exp $
*/
/*-
int GetTapePos __P((long long *));
int GotoTapePos __P((long long));
void ReReadFromTape __P((void));
+void ReReadInodeFromTape __P((dump_ino_t));
#endif
void RequestVol __P((long));
#ifndef lint
static const char rcsid[] =
- "$Id: main.c,v 1.37 2002/01/25 14:59:53 stelian Exp $";
+ "$Id: main.c,v 1.38 2002/02/04 11:18:46 stelian Exp $";
#endif /* not lint */
#include <config.h>
#include <compatlfs.h>
+#include <fcntl.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <errno.h>
char gTps[255];
long gSeekstart;
int tapeposflag;
+int gTapeposfd;
+int createtapeposflag;
+unsigned long qfadumpdate;
+long long curtapepos;
#endif /* USE_QFA */
-#ifdef __linux__
+#if defined(__linux__) || defined(sunos)
char *__progname;
#endif
char *p, name[MAXPATHLEN];
FILE *filelist = NULL;
char fname[MAXPATHLEN];
-#ifdef USE_QFA
- tapeposflag = 0;
-#endif
-#ifdef USE_QFADEBUG
+#ifdef DEBUG_QFA
time_t tistart, tiend, titaken;
#endif
+#ifdef USE_QFA
+ tapeposflag = 0;
+ createtapeposflag = 0;
+#endif /* USE_QFA */
/* Temp files should *not* be readable. We set permissions later. */
(void) umask(077);
filesys[0] = '\0';
-#ifdef __linux__
+#if defined(__linux__) || defined(sunos)
__progname = argv[0];
#endif
#endif
"lL:mMN"
#ifdef USE_QFA
- "Q:"
+ "P:Q:"
#endif
"Rrs:tT:uvVxX:y")) != -1)
switch(ch) {
#endif
case 'C':
case 'i':
+#ifdef USE_QFA
+ case 'P':
+#endif
case 'R':
case 'r':
case 't':
"%c and %c options are mutually exclusive",
ch, command);
command = ch;
+#ifdef USE_QFA
+ if (ch == 'P') {
+ gTapeposfile = optarg;
+ createtapeposflag = 1;
+ }
+#endif
+
break;
case 'l':
lflag = 1;
if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
errx(1, "not requested format of -- %s", gTapeposfile);
gTps[strlen(gTps) - 1] = 0;
- /* TODO: check dumpdate from QFA file with current dump file's
- * dump date */
- /* if not equal either output warning and continue without QFA
- * or abort */
+ qfadumpdate = atol(gTps);
/* read empty line */
if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
errx(1, "not requested format of -- %s", gTapeposfile);
/* end reading header info */
/* tape position table starts here */
gSeekstart = ftell(gTapeposfp); /* remember for later use */
-}
+ }
#endif /* USE_QFA */
switch (command) {
* Batch extraction of tape contents.
*/
case 'x':
-#ifdef USE_QFADEBUG
+#ifdef DEBUG_QFA
tistart = time(NULL);
#endif
setup();
setdirmodes(0);
if (dflag)
checkrestore();
-#ifdef USE_QFADEBUG
+#ifdef DEBUG_QFA
tiend = time(NULL);
titaken = tiend - tistart;
msg("restore took %d:%02d:%02d\n", titaken / 3600,
(titaken % 3600) / 60, titaken % 60);
-#endif /* USE_QFADEBUG */
+#endif /* DEBUG_QFA */
+ break;
+#ifdef USE_QFA
+ case 'P':
+#ifdef DEBUG_QFA
+ tistart = time(NULL);
+#endif
+ setup();
+ msg("writing QFA positions to %s\n", gTapeposfile);
+ if ((gTapeposfd = open(gTapeposfile, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0)
+ errx(1, "can't create tapeposfile\n");
+ /* print QFA-file header */
+ sprintf(gTps, "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION,(unsigned long)spcl.c_date);
+ if (write(gTapeposfd, gTps, strlen(gTps)) != strlen(gTps))
+ errx(1, "can't write tapeposfile\n");
+ sprintf(gTps, "ino\ttapeno\ttapepos\n");
+ if (write(gTapeposfd, gTps, strlen(gTps)) != strlen(gTps))
+ errx(1, "can't write tapeposfile\n");
+
+ extractdirs(1);
+ initsymtable((char *)0);
+ for (;;) {
+ NEXTFILE(p);
+ if (!p)
+ break;
+ canon(p, name, sizeof(name));
+ ino = dirlookup(name);
+ if (ino == 0)
+ continue;
+ if (mflag)
+ pathcheck(name);
+ treescan(name, ino, addfile);
+ }
+ createfiles();
+#ifdef DEBUG_QFA
+ tiend = time(NULL);
+ titaken = tiend - tistart;
+ msg("writing QFA positions took %d:%02d:%02d\n", titaken / 3600,
+ (titaken % 3600) / 60, titaken % 60);
+#endif /* DEBUG_QFA */
break;
+#endif /* USE_QFA */
}
exit(0);
/* NOTREACHED */
"\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"
+#ifdef USE_QFA
+ "\t%s -P file [-ach" kerbflag "lmMuvVy] [-A file] [-b blocksize]\n"
+ "\t%s [-f file] [-F script] [-s fileno] [-X filelist] [file ...]\n"
+#endif
"\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 [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n",
__progname, white,
__progname, white,
+#ifdef USE_QFA
+ __progname, white,
+#endif
__progname, white,
__progname, white,
__progname, white,
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: restore.8.in,v 1.24 2002/01/25 14:59:53 stelian Exp $
+.\" $Id: restore.8.in,v 1.25 2002/02/04 11:18:46 stelian Exp $
.\"
.Dd __DATE__
.Dt RESTORE 8
.Op Fl s Ar fileno
.Op Fl T Ar directory
.Nm restore
+.Fl P Ar file
+.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 s Ar fileno
+.Op Fl T Ar directory
+.Op Fl X Ar filelist
+.Op file ...
+.Nm restore
.Fl R
.Op Fl cklMNuvVy
.Op Fl b Ar blocksize
.Nm restore
to print out information about each file as it is extracted.
.El
+.It Fl P Ar file
+.Nm Restore
+creates a new Quick File Access file
+.Ar file
+from an existing dump file without restoring its contents.
.It Fl R
.Nm Restore
requests a particular tape of a multi-volume set on which to restart
#ifndef lint
static const char rcsid[] =
- "$Id: restore.c,v 1.26 2002/01/25 15:08:59 stelian Exp $";
+ "$Id: restore.c,v 1.27 2002/02/04 11:18:46 stelian Exp $";
#endif /* not lint */
#include <config.h>
#else /* __linux__ */
#include <ufs/ufs/dinode.h>
#endif /* __linux__ */
+#include <protocols/dumprestore.h>
+#include <compaterr.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#ifdef __linux__
#include <ext2fs/ext2fs.h>
}
}
ep = addentry(name, ino, type);
+#ifdef USE_QFA
+ if ((type == NODE) && (!createtapeposflag))
+#else
if (type == NODE)
+#endif
newnode(ep);
ep->e_flags |= NEW;
return (descend);
if (GetTapePos(&curtpos) == 0) {
/* curtpos +1000 ???, some drives
* might be too slow */
- if (tpos > curtpos) {
+ if (tpos != curtpos) {
#ifdef DEBUG_QFA
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
if (GetTapePos(&curtpos) == 0)
- msg("before resnyc at tape position %ld\n", curtpos);
+ msg("before resync at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name);
#endif
- (void)ReReadFromTape();
+msg("bobo1\n");
+ ReReadInodeFromTape(next);
#ifdef DEBUG_QFA
- if (GetTapePos(&curtpos) == 0)
- msg("after resync at tape position %ld\n", curtpos);
+msg("bobo2\n");
+ if (GetTapePos(&curtpos) == 0) {
+msg("bobo3\n");
+ msg("after resync at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name);
+msg("bobo4\n");
+ }
#endif
}
}
+#ifdef DEBUG_QFA
+ else
+ msg("already at tape %ld position %ld for inode %10lu ...\n", volno, tpos, (unsigned long)next);
+#endif
}
}
}
ep = lookupino(next);
if (ep == NULL)
panic("corrupted symbol table\n");
- fprintf(stderr, "%s: (inode %lu) not found on tape\n",
- myname(ep), (unsigned long)next);
+#ifdef USE_QFA
+ if (!createtapeposflag)
+ fprintf(stderr, "%s: (inode %lu) not found on tape\n",
+ myname(ep), (unsigned long)next);
+#endif
ep->e_flags &= ~NEW;
next = lowerbnd(next);
}
ep = lookupino(next);
if (ep == NULL)
panic("corrupted symbol table\n");
- (void) extractfile(myname(ep));
+#ifdef USE_QFA
+ if (createtapeposflag) {
+#ifdef DEBUG_QFA
+ msg("inode %ld at tapepos %ld\n", curfile.ino, curtapepos);
+#endif
+ sprintf(gTps, "%ld\t%ld\t%lld\n", (unsigned long)curfile.ino, volno, curtapepos);
+ if (write(gTapeposfd, gTps, strlen(gTps)) != strlen(gTps))
+ warn("error writing tapepos file.\n");
+ skipfile();
+ }
+ else {
+ msg("restoring %s\n", myname(ep));
+#endif /* USE_QFA */
+ (void) extractfile(myname(ep));
+#ifdef USE_QFA
+ }
+#endif /* USE_QFA */
ep->e_flags &= ~NEW;
if (volno != curvol)
skipmaps();
* Stelian Pop <stelian@popies.net>, 1999-2000
* Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
*
- * $Id: restore.h,v 1.24 2002/01/25 14:59:53 stelian Exp $
+ * $Id: restore.h,v 1.25 2002/02/04 11:18:46 stelian Exp $
*/
/*
struct context {
char *name; /* name of file */
dump_ino_t ino; /* inumber of file */
-#ifdef __linux__
+#if defined(__linux__) || defined(sunos)
struct new_bsd_inode *dip; /* pointer to inode */
#else
struct dinode *dip; /* pointer to inode */
extern char gTps[255];
extern long gSeekstart;
extern int tapeposflag;
+extern int gTapeposfd;
+extern int createtapeposflag;
+extern unsigned long qfadumpdate;
+extern long long curtapepos;
#endif /* USE_QFA */
#define do_compare_error \
#ifndef lint
static const char rcsid[] =
- "$Id: tape.c,v 1.57 2002/01/31 10:25:55 stelian Exp $";
+ "$Id: tape.c,v 1.58 2002/02/04 11:18:46 stelian Exp $";
#endif /* not lint */
#include <config.h>
}
if (vflag || command == 't' || command == 'C')
printdumpinfo();
+#ifdef USE_QFA
+ if (tapeposflag && spcl.c_date != qfadumpdate)
+ errx(1, "different QFA/dumpdates detected\n");
+#endif
if (filesys[0] == '\0') {
char *dirptr;
strncpy(filesys, spcl.c_filesys, NAMELEN);
}
saved_blksread = blksread;
saved_tpblksread = tpblksread;
+#if defined(USE_QFA) && defined(sunos)
+ if (createtapeposflag || tapeposflag)
+ close(fdsmtc);
+#endif
again:
if (pipein)
exit(1); /* pipes do not get a second chance */
while (newvol <= 0) {
if (tapesread == 0) {
fprintf(stderr, "%s%s%s%s%s",
- "You have not read any tapes yet.\n",
+ "You have not read any volumes yet.\n",
"Unless you know which volume your",
" file(s) are on you should start\n",
"with the last volume and work",
}
if (newvol == volno) {
tapesread |= 1 << volno;
+#if defined(USE_QFA) && defined(sunos)
+ if (createtapeposflag || tapeposflag) {
+ if (OpenSMTCmt(magtape) < 0) {
+ volno = -1;
+ haderror = 1;
+ goto again;
+ }
+ }
+#endif
return;
}
closemt();
}
if (haderror || (bot_code && !Mflag)) {
haderror = 0;
- fprintf(stderr, "Mount tape volume %ld\n", (long)newvol);
- fprintf(stderr, "Enter ``none'' if there are no more tapes\n");
- fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape);
+ fprintf(stderr, "Mount volume %ld\n", (long)newvol);
+ fprintf(stderr, "Enter ``none'' if there are no more volumes\n");
+ fprintf(stderr, "otherwise enter volume name (default: %s) ", magtape);
(void) fflush(stderr);
(void) fgets(buf, TP_BSIZE, terminal);
if (feof(terminal))
}
}
+#ifdef sunos
+struct timeval
+ time_t tv_sec; /* seconds */
+ suseconds_t tv_usec; /* and microseconds */
+};
+#endif
+
int
extractfile(char *name)
{
curfile.name = name;
curfile.action = USING;
-#ifdef __linux__
+#if defined(__linux__) || defined(sunos)
timep[0].tv_sec = curfile.dip->di_atime.tv_sec;
timep[0].tv_usec = curfile.dip->di_atime.tv_usec;
timep[1].tv_sec = curfile.dip->di_mtime.tv_sec;
timep[1].tv_usec = curfile.dip->di_mtime.tv_usec;
-#else /* __linux__ */
+#else /* __linux__ || sunos */
timep[0].tv_sec = curfile.dip->di_atime;
timep[0].tv_usec = curfile.dip->di_atimensec / 1000;
timep[1].tv_sec = curfile.dip->di_mtime;
curfile.name, (long)blksread);
}
if (curblk > 0) {
- (*fill)((char *)buf, (size_t)(curblk * TP_BSIZE) + size);
+ (*fill)((char *)buf, (size_t)((curblk * TP_BSIZE) + size));
last_write_was_hole = 0;
}
if (size > 0) {
numtrec = ntrec;
cnt = ntrec * TP_BSIZE;
rd = 0;
+#ifdef USE_QFA
+ if (createtapeposflag)
+ (void)GetTapePos(&curtapepos);
+#endif
getmore:
#ifdef RRESTORE
if (host)
buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid;
buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size;
buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev;
-#ifdef __linux__
+#if defined(__linux__) || defined(sunos)
buf->c_dinode.di_atime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_atime;
buf->c_dinode.di_mtime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_mtime;
buf->c_dinode.di_ctime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_ctime;
-#else /* __linux__ */
+#else /* __linux__ || sunos */
buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime;
buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime;
buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
-#endif /* __linux__ */
+#endif /* __linux__ || sunos */
buf->c_count = u_ospcl.s_ospcl.c_count;
memmove(buf->c_addr, u_ospcl.s_ospcl.c_fill, (long)256);
if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
(buf->c_dinode.di_mode & IFMT) == IFDIR && Qcvt == 0) {
qcvt.qval = buf->c_dinode.di_size;
if (qcvt.val[0] || qcvt.val[1]) {
- printf("Note: Doing Quad swapping\n");
+ Vprintf(stdout, "Note: Doing Quad swapping\n");
Qcvt = 1;
}
}
findinode(&spcl);
noresyncmesg = 0;
}
+
+void
+ReReadInodeFromTape(dump_ino_t theino)
+{
+ long cntloop = 0;
+
+ FLUSHTAPEBUF();
+ noresyncmesg = 1;
+ do {
+ cntloop++;
+ gethead(&spcl);
+ } while (!(spcl.c_inumber == theino && spcl.c_type == TS_INODE && spcl.c_date == dumpdate) && (cntloop < 32));
+#ifdef DEBUG_QFA
+ fprintf(stderr, "%ld reads\n", cntloop);
+ if (cntloop == 32) {
+ fprintf(stderr, "DEBUG: bufsize %d\n", bufsize);
+ fprintf(stderr, "DEBUG: ntrec %ld\n", ntrec);
+ fprintf(stderr, "DEBUG: %ld reads\n", cntloop);
+ }
+#endif
+ findinode(&spcl);
+ noresyncmesg = 0;
+}
#endif /* USE_QFA */
void
#ifndef lint
static const char rcsid[] =
- "$Id: utilities.c,v 1.19 2002/01/25 15:09:00 stelian Exp $";
+ "$Id: utilities.c,v 1.20 2002/02/04 11:18:46 stelian Exp $";
#endif /* not lint */
#include <config.h>
if (!Nflag && (ret = link(existing, new)) < 0) {
-#ifndef __linux__
+#if !defined(__linux__) && !defined(sunos)
struct stat s;
/*
return (GOOD);
}
-#ifndef __linux__
+#if !defined(__linux__) && !defined(sunos)
/*
* Create a whiteout.
*/