summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2007-06-03 20:16:09 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2007-06-03 20:16:09 +0000
commit0ff9cbbdef89eed7cbcda58dbc021f8035a2dbad (patch)
tree00e07c12b1495418158af273fdd672ed76ea4754 /sbin
parentad936b34df484977c12aee44475ade8d8d010a16 (diff)
Add ffs2 support to dump/restore. From FreeBSD with some NetBSD changes.
With help from otto@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/dump/dump.h26
-rw-r--r--sbin/dump/itime.c18
-rw-r--r--sbin/dump/main.c74
-rw-r--r--sbin/dump/optr.c6
-rw-r--r--sbin/dump/tape.c40
-rw-r--r--sbin/dump/traverse.c318
-rw-r--r--sbin/restore/dirs.c62
-rw-r--r--sbin/restore/restore.h19
-rw-r--r--sbin/restore/tape.c331
9 files changed, 585 insertions, 309 deletions
diff --git a/sbin/dump/dump.h b/sbin/dump/dump.h
index b15835dcab8..3ca64744f8a 100644
--- a/sbin/dump/dump.h
+++ b/sbin/dump/dump.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dump.h,v 1.15 2007/04/10 04:45:37 moritz Exp $ */
+/* $OpenBSD: dump.h,v 1.16 2007/06/03 20:16:08 millert Exp $ */
/* $NetBSD: dump.h,v 1.11 1997/06/05 11:13:20 lukem Exp $ */
/*-
@@ -32,9 +32,6 @@
* @(#)dump.h 8.1 (Berkeley) 6/5/93
*/
-#define MAXINOPB (MAXBSIZE / sizeof(struct ufs1_dinode))
-#define MAXNINDIR (MAXBSIZE / sizeof(daddr_t))
-
/*
* Dump maps used to describe what is to be dumped.
*/
@@ -90,31 +87,34 @@ int tp_bshift; /* log2(TP_BSIZE) */
void broadcast(char *message);
time_t do_stats(void);
void lastdump(int arg); /* int should be char */
-void msg(const char *fmt, ...);
-void msgtail(const char *fmt, ...);
+void msg(const char *fmt, ...)
+ __attribute__((__format__ (printf, 1, 2)));
+void msgtail(const char *fmt, ...)
+ __attribute__((__format__ (printf, 1, 2)));
int query(char *question);
void quit(const char *fmt, ...);
void statussig(int);
void timeest(void);
/* mapping routines */
-struct ufs1_dinode;
-off_t blockest(struct ufs1_dinode *dp);
+union dinode;
+off_t blockest(union dinode *dp);
void mapfileino(ino_t, off_t *, int *);
int mapfiles(ino_t maxino, off_t *tapesize, char *disk, char * const *dirv);
int mapdirs(ino_t maxino, off_t *tapesize);
/* file dumping routines */
-void blksout(daddr_t *blkp, int frags, ino_t ino);
-void bread(daddr_t blkno, char *buf, int size);
-void dumpino(struct ufs1_dinode *dp, ino_t ino);
+void ufs1_blksout(int32_t *blkp, int frags, ino_t ino);
+void ufs2_blksout(daddr64_t *blkp, int frags, ino_t ino);
+void bread(daddr64_t blkno, char *buf, int size);
+void dumpino(union dinode *dp, ino_t ino);
void dumpmap(char *map, int type, ino_t ino);
void writeheader(ino_t ino);
/* tape writing routines */
int alloctape(void);
void close_rewind(void);
-void dumpblock(daddr_t blkno, int size);
+void dumpblock(daddr64_t blkno, int size);
void startnewtape(int top);
void trewind(void);
void writerec(char *dp, int isspcl);
@@ -124,7 +124,7 @@ void dumpabort(int signo);
void getfstab(void);
char *rawname(char *cp);
-struct ufs1_dinode *getino(ino_t inum);
+union dinode *getino(ino_t inum, int *mode);
/* rdump routines */
#ifdef RDUMP
diff --git a/sbin/dump/itime.c b/sbin/dump/itime.c
index 5f56537495a..eb5f5be36ff 100644
--- a/sbin/dump/itime.c
+++ b/sbin/dump/itime.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: itime.c,v 1.14 2007/03/04 22:37:18 deraadt Exp $ */
+/* $OpenBSD: itime.c,v 1.15 2007/06/03 20:16:08 millert Exp $ */
/* $NetBSD: itime.c,v 1.4 1997/04/15 01:09:50 lukem Exp $ */
/*-
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)itime.c 8.1 (Berkeley) 6/5/93";
#else
-static const char rcsid[] = "$OpenBSD: itime.c,v 1.14 2007/03/04 22:37:18 deraadt Exp $";
+static const char rcsid[] = "$OpenBSD: itime.c,v 1.15 2007/06/03 20:16:08 millert Exp $";
#endif
#endif /* not lint */
@@ -150,9 +150,9 @@ getdumptime(void)
continue;
if (ddp->dd_level >= level)
continue;
- if (ddp->dd_ddate <= spcl.c_ddate)
+ if (ddp->dd_ddate <= (time_t)spcl.c_ddate)
continue;
- spcl.c_ddate = ddp->dd_ddate;
+ spcl.c_ddate = (int64_t)ddp->dd_ddate;
lastlevel = ddp->dd_level;
}
}
@@ -162,9 +162,9 @@ putdumptime(void)
{
FILE *df;
struct dumpdates *dtwalk;
- int i;
- int fd;
+ int fd, i;
char *fname;
+ time_t t;
if(uflag == 0)
return;
@@ -200,7 +200,7 @@ putdumptime(void)
found:
(void) strlcpy(dtwalk->dd_name, fname, sizeof(dtwalk->dd_name));
dtwalk->dd_level = level;
- dtwalk->dd_ddate = spcl.c_date;
+ dtwalk->dd_ddate = (time_t)spcl.c_date;
ITITERATE(i, dtwalk) {
dumprecout(df, dtwalk);
@@ -210,8 +210,8 @@ putdumptime(void)
if (ftruncate(fd, ftello(df)))
quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
(void) fclose(df);
- msg("level %c dump on %s", level,
- spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
+ t = (time_t)spcl.c_date;
+ msg("level %c dump on %s", level, t == 0 ? "the epoch\n" : ctime(&t));
}
static void
diff --git a/sbin/dump/main.c b/sbin/dump/main.c
index 327f0c64e3f..ce24fd1224c 100644
--- a/sbin/dump/main.c
+++ b/sbin/dump/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.40 2007/03/04 22:36:54 deraadt Exp $ */
+/* $OpenBSD: main.c,v 1.41 2007/06/03 20:16:08 millert Exp $ */
/* $NetBSD: main.c,v 1.14 1997/06/05 11:13:24 lukem Exp $ */
/*-
@@ -40,7 +40,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 4/15/94";
#else
-static const char rcsid[] = "$OpenBSD: main.c,v 1.40 2007/03/04 22:36:54 deraadt Exp $";
+static const char rcsid[] = "$OpenBSD: main.c,v 1.41 2007/06/03 20:16:08 millert Exp $";
#endif
#endif /* not lint */
@@ -69,10 +69,6 @@ static const char rcsid[] = "$OpenBSD: main.c,v 1.40 2007/03/04 22:36:54 deraadt
#include "dump.h"
#include "pathnames.h"
-#ifndef SBOFF
-#define SBOFF (SBLOCK * DEV_BSIZE)
-#endif
-
int notify = 0; /* notify operator flag */
int blockswritten = 0; /* number of blocks written on current tape */
int tapeno = 0; /* current tape number */
@@ -84,6 +80,11 @@ long blocksperfile; /* output blocks per file */
char *host = NULL; /* remote host (if any) */
int maxbsize = 64*1024; /* XXX MAXBSIZE from sys/param.h */
+/*
+ * Possible superblock locations ordered from most to least likely.
+ */
+static int sblock_try[] = SBLOCKSEARCH;
+
static long numarg(char *, long, long);
static void obsolete(int *, char **[]);
static void usage(void);
@@ -93,20 +94,19 @@ main(int argc, char *argv[])
{
ino_t ino;
int dirty;
- struct ufs1_dinode *dp;
+ union dinode *dp;
struct fstab *dt;
char *map;
- int ch;
+ int ch, mode;
struct tm then;
struct statfs fsbuf;
int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
ino_t maxino;
- time_t tnow;
+ time_t t;
int dirlist;
char *toplevel, *str, *mount_point = NULL;
- spcl.c_date = 0;
- (void)time((time_t *)&spcl.c_date);
+ spcl.c_date = (int64_t)time(NULL);
tsize = 0; /* Default later, based on 'c' option for cart tapes */
if ((tape = getenv("TAPE")) == NULL)
@@ -173,9 +173,9 @@ main(int argc, char *argv[])
str = strptime(optarg, "%a %b %e %H:%M:%S %Y", &then);
then.tm_isdst = -1;
if (str == NULL || (*str != '\n' && *str != '\0'))
- spcl.c_ddate = (time_t) -1;
+ spcl.c_ddate = -1;
else
- spcl.c_ddate = mktime(&then);
+ spcl.c_ddate = (int64_t)mktime(&then);
if (spcl.c_ddate < 0) {
(void)fprintf(stderr, "bad time \"%s\"\n",
optarg);
@@ -378,10 +378,12 @@ main(int argc, char *argv[])
if (!Tflag)
getdumptime(); /* /etc/dumpdates snarfed */
+ t = (time_t)spcl.c_date;
msg("Date of this level %c dump: %s", level,
- spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
+ t == 0 ? "the epoch\n" : ctime(&t));
+ t = (time_t)spcl.c_ddate;
msg("Date of last level %c dump: %s", lastlevel,
- spcl.c_ddate == 0 ? "the epoch\n" : ctime(&spcl.c_ddate));
+ t == 0 ? "the epoch\n" : ctime(&t));
msg("Dumping %s ", disk);
if (mount_point != NULL)
msgtail("(%s) ", mount_point);
@@ -396,9 +398,18 @@ main(int argc, char *argv[])
}
sync();
sblock = (struct fs *)sblock_buf;
- bread(SBOFF, (char *) sblock, SBSIZE);
- if (sblock->fs_magic != FS_MAGIC)
- quit("bad sblock magic number\n");
+ for (i = 0; sblock_try[i] != -1; i++) {
+ ssize_t n = pread(diskfd, sblock, SBLOCKSIZE,
+ (off_t)sblock_try[i]);
+ if (n == SBLOCKSIZE && (sblock->fs_magic == FS_UFS1_MAGIC ||
+ (sblock->fs_magic == FS_UFS2_MAGIC &&
+ sblock->fs_sblockloc == sblock_try[i])) &&
+ sblock->fs_bsize <= MAXBSIZE &&
+ sblock->fs_bsize >= sizeof(struct fs))
+ break;
+ }
+ if (sblock_try[i] == -1)
+ quit("Cannot find filesystem superblock\n");
dev_bsize = sblock->fs_fsize / fsbtodb(sblock, 1);
dev_bshift = ffs(dev_bsize) - 1;
if (dev_bsize != (1 << dev_bshift))
@@ -407,7 +418,8 @@ main(int argc, char *argv[])
if (TP_BSIZE != (1 << tp_bshift))
quit("TP_BSIZE (%d) is not a power of 2\n", TP_BSIZE);
#ifdef FS_44INODEFMT
- if (sblock->fs_inodefmt >= FS_44INODEFMT)
+ if (sblock->fs_magic == FS_UFS2_MAGIC ||
+ sblock->fs_inodefmt >= FS_44INODEFMT)
spcl.c_flags |= DR_NEWINODEFMT;
#endif
maxino = sblock->fs_ipg * sblock->fs_ncg;
@@ -432,7 +444,7 @@ main(int argc, char *argv[])
if (pipeout || unlimited) {
tapesize += 10; /* 10 trailer blocks */
- msg("estimated %qd tape blocks.\n", tapesize);
+ msg("estimated %lld tape blocks.\n", tapesize);
} else {
double fetapes;
@@ -472,7 +484,7 @@ main(int argc, char *argv[])
tapesize += (etapes - 1) *
(howmany(mapsize * sizeof(char), TP_BSIZE) + 1);
tapesize += etapes + 10; /* headers + 10 trailer blks */
- msg("estimated %qd tape blocks on %3.2f tape(s).\n",
+ msg("estimated %lld tape blocks on %3.2f tape(s).\n",
tapesize, fetapes);
}
@@ -499,16 +511,14 @@ main(int argc, char *argv[])
/*
* Skip directory inodes deleted and maybe reallocated
*/
- dp = getino(ino);
- if ((dp->di_mode & IFMT) != IFDIR)
+ dp = getino(ino, &mode);
+ if (mode != IFDIR)
continue;
(void)dumpino(dp, ino);
}
msg("dumping (Pass IV) [regular files]\n");
for (map = dumpinomap, ino = 1; ino < maxino; ino++) {
- int mode;
-
if (((ino - 1) % NBBY) == 0) /* map is offset by 1 */
dirty = *map++;
else
@@ -518,8 +528,7 @@ main(int argc, char *argv[])
/*
* Skip inodes deleted and reallocated as directories.
*/
- dp = getino(ino);
- mode = dp->di_mode & IFMT;
+ dp = getino(ino, &mode);
if (mode == IFDIR)
continue;
(void)dumpino(dp, ino);
@@ -529,15 +538,16 @@ main(int argc, char *argv[])
for (i = 0; i < ntrec; i++)
writeheader(maxino - 1);
if (pipeout)
- msg("%ld tape blocks\n", spcl.c_tapea);
+ msg("%lld tape blocks\n", spcl.c_tapea);
else
- msg("%ld tape blocks on %d volume%s\n",
+ msg("%lld tape blocks on %d volume%s\n",
spcl.c_tapea, spcl.c_volume,
(spcl.c_volume == 1) ? "" : "s");
- tnow = do_stats();
+ t = (time_t)spcl.c_date;
msg("Date of this level %c dump: %s", level,
- spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
- msg("Date this dump completed: %s", ctime(&tnow));
+ t == 0 ? "the epoch\n" : ctime(&t));
+ t = do_stats();
+ msg("Date this dump completed: %s", ctime(&t));
msg("Average transfer rate: %ld KB/s\n", xferrate / tapeno);
putdumptime();
trewind();
diff --git a/sbin/dump/optr.c b/sbin/dump/optr.c
index 6d3dd331445..815183d8fdd 100644
--- a/sbin/dump/optr.c
+++ b/sbin/dump/optr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: optr.c,v 1.29 2007/02/20 01:44:16 ray Exp $ */
+/* $OpenBSD: optr.c,v 1.30 2007/06/03 20:16:08 millert Exp $ */
/* $NetBSD: optr.c,v 1.11 1997/05/27 08:34:36 mrg Exp $ */
/*-
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)optr.c 8.2 (Berkeley) 1/6/94";
#else
-static const char rcsid[] = "$OpenBSD: optr.c,v 1.29 2007/02/20 01:44:16 ray Exp $";
+static const char rcsid[] = "$OpenBSD: optr.c,v 1.30 2007/06/03 20:16:08 millert Exp $";
#endif
#endif /* not lint */
@@ -42,6 +42,8 @@ static const char rcsid[] = "$OpenBSD: optr.c,v 1.29 2007/02/20 01:44:16 ray Exp
#include <sys/wait.h>
#include <sys/time.h>
+#include <ufs/ufs/dinode.h>
+
#include <errno.h>
#include <fstab.h>
#include <grp.h>
diff --git a/sbin/dump/tape.c b/sbin/dump/tape.c
index 062b8ad2bfd..4ba27079678 100644
--- a/sbin/dump/tape.c
+++ b/sbin/dump/tape.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tape.c,v 1.28 2007/03/04 22:36:54 deraadt Exp $ */
+/* $OpenBSD: tape.c,v 1.29 2007/06/03 20:16:08 millert Exp $ */
/* $NetBSD: tape.c,v 1.11 1997/06/05 11:13:26 lukem Exp $ */
/*-
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)tape.c 8.2 (Berkeley) 3/17/94";
#else
-static const char rcsid[] = "$OpenBSD: tape.c,v 1.28 2007/03/04 22:36:54 deraadt Exp $";
+static const char rcsid[] = "$OpenBSD: tape.c,v 1.29 2007/06/03 20:16:08 millert Exp $";
#endif
#endif /* not lint */
@@ -62,7 +62,7 @@ static const char rcsid[] = "$OpenBSD: tape.c,v 1.28 2007/03/04 22:36:54 deraadt
#include "pathnames.h"
int writesize; /* size of malloc()ed buffer for tape */
-long lastspclrec = -1; /* tape block number of last written header */
+int64_t lastspclrec = -1; /* tape block number of last written header */
int trecno = 0; /* next record to write in current block */
extern long blocksperfile; /* number of blocks per output file */
long blocksthisvol; /* number of blocks on current output file */
@@ -87,21 +87,21 @@ static void rollforward(void);
* The following structure defines the instruction packets sent to slaves.
*/
struct req {
- daddr_t dblk;
+ daddr64_t dblk;
int count;
};
int reqsiz;
#define SLAVES 3 /* 1 slave writing, 1 reading, 1 for slack */
struct slave {
- int tapea; /* header number at start of this chunk */
+ int64_t tapea; /* header number at start of this chunk */
+ int64_t firstrec; /* record number of this block */
int count; /* count to next header (used for TS_TAPE */
/* after EOT) */
int inode; /* inode that we are currently dealing with */
int fd; /* FD for this slave */
pid_t pid; /* PID for this slave */
int sent; /* 1 == we've sent this slave requests */
- int firstrec; /* record number of this block */
char (*tblock)[TP_BSIZE]; /* buffer for data blocks */
struct req *req; /* buffer for requests */
} slaves[SLAVES+1];
@@ -110,7 +110,7 @@ struct slave *slp;
char (*nextblock)[TP_BSIZE];
static time_t tstart_volume; /* time of volume start */
-static int tapea_volume; /* value of spcl.c_tapea at volume start */
+static int64_t tapea_volume; /* value of spcl.c_tapea at volume start */
pid_t master; /* pid of master, for sending error signals */
int tenths; /* length of tape used per block written */
@@ -160,7 +160,7 @@ void
writerec(char *dp, int isspcl)
{
- slp->req[trecno].dblk = (daddr_t)0;
+ slp->req[trecno].dblk = (daddr64_t)0;
slp->req[trecno].count = 1;
*(union u_spcl *)(*(nextblock)++) = *(union u_spcl *)dp;
if (isspcl)
@@ -172,9 +172,10 @@ writerec(char *dp, int isspcl)
}
void
-dumpblock(daddr_t blkno, int size)
+dumpblock(daddr64_t blkno, int size)
{
- int avail, tpblks, dblkno;
+ int avail, tpblks;
+ daddr64_t dblkno;
dblkno = fsbtodb(sblock, blkno);
tpblks = size >> tp_bshift;
@@ -203,7 +204,7 @@ tperror(int signo)
quit("Cannot recover\n");
/* NOTREACHED */
}
- msg("write error %d blocks into volume %d\n", blocksthisvol, tapeno);
+ msg("write error %ld blocks into volume %d\n", blocksthisvol, tapeno);
broadcast("DUMP WRITE ERROR!\n");
if (!query("Do you want to restart?"))
dumpabort(0);
@@ -240,7 +241,7 @@ do_stats(void)
if (ttaken > 0) {
msg("Volume %d took %d:%02d:%02d\n", tapeno,
ttaken / 3600, (ttaken % 3600) / 60, ttaken % 60);
- msg("Volume %d transfer rate: %ld KB/s\n", tapeno,
+ msg("Volume %d transfer rate: %d KB/s\n", tapeno,
blocks / ttaken);
xferrate += blocks / ttaken;
}
@@ -267,7 +268,7 @@ statussig(int signo)
deltat = tstart_writing - tnow + (1.0 * (tnow - tstart_writing))
/ blockswritten * tapesize;
(void)snprintf(msgbuf, sizeof(msgbuf),
- "dump: %s %3.2f%% done at %d KB/s, finished in %d:%02d\n",
+ "dump: %s %3.2f%% done at %lld KB/s, finished in %d:%02d\n",
tape, (blockswritten * 100.0) / tapesize,
(spcl.c_tapea - tapea_volume) / (tnow - tstart_volume),
(int)(deltat / 3600), (int)((deltat % 3600) / 60));
@@ -279,7 +280,7 @@ static void
flushtape(void)
{
int i, blks, got;
- long lastfirstrec;
+ int64_t lastfirstrec;
int siz = (char *)nextblock - (char *)slp->req;
@@ -445,7 +446,8 @@ rollforward(void)
{
struct req *p, *q, *prev;
struct slave *tslp;
- int i, size, savedtapea, got;
+ int i, size, got;
+ int64_t savedtapea;
union u_spcl *ntb, *otb;
tslp = &slaves[SLAVES];
ntb = (union u_spcl *)tslp->tblock[1];
@@ -681,9 +683,11 @@ restore_check_point:
spcl.c_firstrec = slp->firstrec;
spcl.c_volume++;
spcl.c_type = TS_TAPE;
- spcl.c_flags |= DR_NEWHEADER;
+ if (sblock->fs_magic != FS_UFS2_MAGIC)
+ spcl.c_flags |= DR_NEWHEADER;
writeheader((ino_t)slp->inode);
- spcl.c_flags &=~ DR_NEWHEADER;
+ if (sblock->fs_magic != FS_UFS2_MAGIC)
+ spcl.c_flags &=~ DR_NEWHEADER;
msg("Volume %d started at: %s", tapeno, ctime(&tstart_volume));
if (tapeno > 1)
msg("Volume %d begins with blocks from inode %d\n",
@@ -795,7 +799,7 @@ killall(void)
static void
doslave(int cmd, int slave_number)
{
- int nread, nextslave, size, wrote, eot_count;
+ int nread, nextslave, size, wrote = 0, eot_count;
sigset_t nsigset, osigset;
/*
diff --git a/sbin/dump/traverse.c b/sbin/dump/traverse.c
index f37bdfa6089..d7f6e851c42 100644
--- a/sbin/dump/traverse.c
+++ b/sbin/dump/traverse.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: traverse.c,v 1.20 2007/03/19 13:27:47 pedro Exp $ */
+/* $OpenBSD: traverse.c,v 1.21 2007/06/03 20:16:08 millert Exp $ */
/* $NetBSD: traverse.c,v 1.17 1997/06/05 11:13:27 lukem Exp $ */
/*-
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)traverse.c 8.2 (Berkeley) 9/23/93";
#else
-static const char rcsid[] = "$OpenBSD: traverse.c,v 1.20 2007/03/19 13:27:47 pedro Exp $";
+static const char rcsid[] = "$OpenBSD: traverse.c,v 1.21 2007/06/03 20:16:08 millert Exp $";
#endif
#endif /* not lint */
@@ -51,17 +51,26 @@ static const char rcsid[] = "$OpenBSD: traverse.c,v 1.20 2007/03/19 13:27:47 ped
#include <errno.h>
#include <fts.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "dump.h"
+union dinode {
+ struct ufs1_dinode dp1;
+ struct ufs2_dinode dp2;
+};
+#define DIP(dp, field) \
+ ((sblock->fs_magic == FS_UFS1_MAGIC) ? \
+ (dp)->dp1.field : (dp)->dp2.field)
+
#define HASDUMPEDFILE 0x1
#define HASSUBDIRS 0x2
-static int dirindir(ino_t ino, daddr_t blkno, int level, off_t *size);
-static void dmpindir(ino_t ino, daddr_t blk, int level, off_t *size);
-static int searchdir(ino_t ino, daddr_t blkno, long size, off_t filesize);
+static int dirindir(ino_t ino, daddr64_t blkno, int level, off_t *size);
+static void dmpindir(ino_t ino, daddr64_t blk, int level, off_t *size);
+static int searchdir(ino_t ino, daddr64_t blkno, long size, off_t filesize);
/*
* This is an estimation of the number of TP_BSIZE blocks in the file.
@@ -71,7 +80,7 @@ static int searchdir(ino_t ino, daddr_t blkno, long size, off_t filesize);
* hence the estimate may be high.
*/
off_t
-blockest(struct ufs1_dinode *dp)
+blockest(union dinode *dp)
{
off_t blkest, sizeest;
@@ -89,11 +98,11 @@ blockest(struct ufs1_dinode *dp)
* dump blocks (sizeest vs. blkest in the indirect block
* calculation).
*/
- blkest = howmany(dbtob((off_t)dp->di_blocks), TP_BSIZE);
- sizeest = howmany(dp->di_size, TP_BSIZE);
+ blkest = howmany(dbtob((off_t)DIP(dp, di_blocks)), TP_BSIZE);
+ sizeest = howmany((off_t)DIP(dp, di_size), TP_BSIZE);
if (blkest > sizeest)
blkest = sizeest;
- if (dp->di_size > sblock->fs_bsize * NDADDR) {
+ if (DIP(dp, di_size) > sblock->fs_bsize * NDADDR) {
/* calculate the number of indirect blocks on the dump tape */
blkest +=
howmany(sizeest - NDADDR * sblock->fs_bsize / TP_BSIZE,
@@ -104,13 +113,13 @@ blockest(struct ufs1_dinode *dp)
/* Auxiliary macro to pick up files changed since previous dump. */
#define CHANGEDSINCE(dp, t) \
- ((dp)->di_mtime >= (t) || (dp)->di_ctime >= (t))
+ (DIP(dp, di_mtime) >= (t) || DIP(dp, di_ctime) >= (t))
/* The WANTTODUMP macro decides whether a file should be dumped. */
#ifdef UF_NODUMP
#define WANTTODUMP(dp) \
(CHANGEDSINCE(dp, spcl.c_ddate) && \
- (nonodump || ((dp)->di_flags & UF_NODUMP) != UF_NODUMP))
+ (nonodump || (DIP(dp, di_flags) & UF_NODUMP) != UF_NODUMP))
#else
#define WANTTODUMP(dp) CHANGEDSINCE(dp, spcl.c_ddate)
#endif
@@ -122,10 +131,10 @@ void
mapfileino(ino_t ino, off_t *tapesize, int *dirskipped)
{
int mode;
- struct ufs1_dinode *dp;
+ union dinode *dp;
- dp = getino(ino);
- if ((mode = (dp->di_mode & IFMT)) == 0)
+ dp = getino(ino, &mode);
+ if (mode == 0)
return;
SETINO(ino, usedinomap);
if (mode == IFDIR)
@@ -142,6 +151,59 @@ mapfileino(ino_t ino, off_t *tapesize, int *dirskipped)
*dirskipped = 1;
}
+void
+fs_mapinodes(ino_t maxino, off_t *tapesize, int *anydirskipped)
+{
+ int i, cg, inosused;
+ struct cg *cgp;
+ ino_t ino;
+ char *cp;
+
+ if ((cgp = malloc(sblock->fs_cgsize)) == NULL)
+ quit("fs_mapinodes: cannot allocate memory.\n");
+
+ for (cg = 0; cg < sblock->fs_ncg; cg++) {
+ ino = cg * sblock->fs_ipg;
+ bread(fsbtodb(sblock, cgtod(sblock, cg)), (char *)cgp,
+ sblock->fs_cgsize);
+ if (sblock->fs_magic == FS_UFS2_MAGIC)
+ inosused = cgp->cg_initediblk;
+ else
+ inosused = sblock->fs_ipg;
+ /*
+ * If we are using soft updates, then we can trust the
+ * cylinder group inode allocation maps to tell us which
+ * inodes are allocated. We will scan the used inode map
+ * to find the inodes that are really in use, and then
+ * read only those inodes in from disk.
+ */
+ if (sblock->fs_flags & FS_DOSOFTDEP) {
+ if (!cg_chkmagic(cgp))
+ quit("mapfiles: cg %d: bad magic number\n", cg);
+ cp = &cg_inosused(cgp)[(inosused - 1) / CHAR_BIT];
+ for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) {
+ if (*cp == 0)
+ continue;
+ for (i = 1 << (CHAR_BIT - 1); i > 0; i >>= 1) {
+ if (*cp & i)
+ break;
+ inosused--;
+ }
+ break;
+ }
+ if (inosused <= 0)
+ continue;
+ }
+ for (i = 0; i < inosused; i++, ino++) {
+ if (ino < ROOTINO)
+ continue;
+ mapfileino(ino, tapesize, anydirskipped);
+ }
+ }
+
+ free(cgp);
+}
+
/*
* Dump pass 1.
*
@@ -227,11 +289,7 @@ mapfiles(ino_t maxino, off_t *tapesize, char *disk, char * const *dirv)
*/
mapfileino(ROOTINO, tapesize, &anydirskipped);
} else {
- ino_t ino;
-
- for (ino = ROOTINO; ino < maxino; ino++) {
- mapfileino(ino, tapesize, &anydirskipped);
- }
+ fs_mapinodes(maxino, tapesize, &anydirskipped);
}
/*
* Restore gets very upset if the root is not dumped,
@@ -256,10 +314,11 @@ mapfiles(ino_t maxino, off_t *tapesize, char *disk, char * const *dirv)
int
mapdirs(ino_t maxino, off_t *tapesize)
{
- struct ufs1_dinode *dp;
+ union dinode *dp;
int i, isdir;
char *map;
ino_t ino;
+ union dinode di;
off_t filesize;
int ret, change = 0;
@@ -271,21 +330,29 @@ mapdirs(ino_t maxino, off_t *tapesize)
isdir >>= 1;
if ((isdir & 1) == 0 || TSTINO(ino, dumpinomap))
continue;
- dp = getino(ino);
- filesize = dp->di_size;
+ dp = getino(ino, &i);
+ /*
+ * inode buf may change in searchdir().
+ */
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ di.dp1 = dp->dp1;
+ else
+ di.dp2 = dp->dp2;
+ filesize = (off_t)DIP(dp, di_size);
for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) {
- if (dp->di_db[i] != 0)
- ret |= searchdir(ino, dp->di_db[i],
- dblksize(sblock, dp, i), filesize);
+ if (DIP(&di, di_db[i]) != 0)
+ ret |= searchdir(ino, DIP(&di, di_db[i]),
+ sblksize(sblock, DIP(dp, di_size), i),
+ filesize);
if (ret & HASDUMPEDFILE)
filesize = 0;
else
filesize -= sblock->fs_bsize;
}
for (i = 0; filesize > 0 && i < NIADDR; i++) {
- if (dp->di_ib[i] == 0)
+ if (DIP(&di, di_ib[i]) == 0)
continue;
- ret |= dirindir(ino, dp->di_ib[i], i, &filesize);
+ ret |= dirindir(ino, DIP(&di, di_ib[i]), i, &filesize);
}
if (ret & HASDUMPEDFILE) {
SETINO(ino, dumpinomap);
@@ -309,16 +376,21 @@ mapdirs(ino_t maxino, off_t *tapesize)
* require the directory to be dumped.
*/
static int
-dirindir(ino_t ino, daddr_t blkno, int ind_level, off_t *filesize)
+dirindir(ino_t ino, daddr64_t blkno, int ind_level, off_t *filesize)
{
int ret = 0;
int i;
- daddr_t idblk[MAXNINDIR];
+ static void *idblk;
- bread(fsbtodb(sblock, blkno), (char *)idblk, (int)sblock->fs_bsize);
+ if (idblk == NULL && (idblk = malloc(sblock->fs_bsize)) == NULL)
+ quit("dirindir: cannot allocate indirect memory.\n");
+ bread(fsbtodb(sblock, blkno), idblk, (int)sblock->fs_bsize);
if (ind_level <= 0) {
for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
- blkno = idblk[i];
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ blkno = ((int32_t *)idblk)[i];
+ else
+ blkno = ((int64_t *)idblk)[i];
if (blkno != 0)
ret |= searchdir(ino, blkno, sblock->fs_bsize,
*filesize);
@@ -331,7 +403,10 @@ dirindir(ino_t ino, daddr_t blkno, int ind_level, off_t *filesize)
}
ind_level--;
for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
- blkno = idblk[i];
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ blkno = ((int32_t *)idblk)[i];
+ else
+ blkno = ((int64_t *)idblk)[i];
if (blkno != 0)
ret |= dirindir(ino, blkno, ind_level, filesize);
}
@@ -344,13 +419,15 @@ dirindir(ino_t ino, daddr_t blkno, int ind_level, off_t *filesize)
* contains any subdirectories.
*/
static int
-searchdir(ino_t ino, daddr_t blkno, long size, off_t filesize)
+searchdir(ino_t ino, daddr64_t blkno, long size, off_t filesize)
{
struct direct *dp;
long loc;
- char dblk[MAXBSIZE];
+ static caddr_t dblk;
int ret = 0;
+ if (dblk == NULL && (dblk = malloc(sblock->fs_bsize)) == NULL)
+ quit("searchdir: cannot allocate indirect memory.\n");
bread(fsbtodb(sblock, blkno), dblk, (int)size);
if (filesize < size)
size = filesize;
@@ -389,7 +466,7 @@ searchdir(ino_t ino, daddr_t blkno, long size, off_t filesize)
* Dump the contents of an inode to tape.
*/
void
-dumpino(struct ufs1_dinode *dp, ino_t ino)
+dumpino(union dinode *dp, ino_t ino)
{
int ind_level, cnt;
off_t size;
@@ -400,10 +477,36 @@ dumpino(struct ufs1_dinode *dp, ino_t ino)
dumpmap(dumpinomap, TS_BITS, ino);
}
CLRINO(ino, dumpinomap);
- spcl.c_dinode = *dp;
+ if (sblock->fs_magic == FS_UFS1_MAGIC) {
+ spcl.c_mode = dp->dp1.di_mode;
+ spcl.c_size = dp->dp1.di_size;
+ spcl.c_atime = (time_t)dp->dp1.di_atime;
+ spcl.c_atimensec = dp->dp1.di_atimensec;
+ spcl.c_mtime = (time_t)dp->dp1.di_mtime;
+ spcl.c_mtimensec = dp->dp1.di_mtimensec;
+ spcl.c_birthtime = 0;
+ spcl.c_birthtimensec = 0;
+ spcl.c_rdev = dp->dp1.di_rdev;
+ spcl.c_file_flags = dp->dp1.di_flags;
+ spcl.c_uid = dp->dp1.di_uid;
+ spcl.c_gid = dp->dp1.di_gid;
+ } else {
+ spcl.c_mode = dp->dp2.di_mode;
+ spcl.c_size = dp->dp2.di_size;
+ spcl.c_atime = (time_t)dp->dp2.di_atime;
+ spcl.c_atimensec = dp->dp2.di_atimensec;
+ spcl.c_mtime = (time_t)dp->dp2.di_mtime;
+ spcl.c_mtimensec = dp->dp2.di_mtimensec;
+ spcl.c_birthtime = (time_t)dp->dp2.di_birthtime;
+ spcl.c_birthtimensec = dp->dp2.di_birthnsec;
+ spcl.c_rdev = dp->dp2.di_rdev;
+ spcl.c_file_flags = dp->dp2.di_flags;
+ spcl.c_uid = dp->dp2.di_uid;
+ spcl.c_gid = dp->dp2.di_gid;
+ }
spcl.c_type = TS_INODE;
spcl.c_count = 0;
- switch (dp->di_mode & IFMT) {
+ switch (DIP(dp, di_mode) & S_IFMT) {
case 0:
/*
@@ -415,18 +518,24 @@ dumpino(struct ufs1_dinode *dp, ino_t ino)
/*
* Check for short symbolic link.
*/
- if (dp->di_size > 0 &&
+ if (DIP(dp, di_size) > 0 &&
#ifdef FS_44INODEFMT
- (dp->di_size < sblock->fs_maxsymlinklen ||
- (sblock->fs_maxsymlinklen == 0 && dp->di_blocks == 0))) {
+ (DIP(dp, di_size) < sblock->fs_maxsymlinklen ||
+ (sblock->fs_maxsymlinklen == 0 && DIP(dp, di_blocks) == 0))) {
#else
- dp->di_blocks == 0) {
+ DIP(dp, di_blocks) == 0) {
#endif
+ void *shortlink;
+
spcl.c_addr[0] = 1;
spcl.c_count = 1;
writeheader(ino);
- memcpy(buf, dp->di_shortlink, (u_long)dp->di_size);
- buf[dp->di_size] = '\0';
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ shortlink = dp->dp1.di_shortlink;
+ else
+ shortlink = dp->dp2.di_shortlink;
+ memcpy(buf, shortlink, DIP(dp, di_size));
+ buf[DIP(dp, di_size)] = '\0';
writerec(buf, 0);
return;
}
@@ -434,7 +543,7 @@ dumpino(struct ufs1_dinode *dp, ino_t ino)
case IFDIR:
case IFREG:
- if (dp->di_size > 0)
+ if (DIP(dp, di_size) > 0)
break;
/* FALLTHROUGH */
@@ -446,18 +555,22 @@ dumpino(struct ufs1_dinode *dp, ino_t ino)
return;
default:
- msg("Warning: undefined file type 0%o\n", dp->di_mode & IFMT);
+ msg("Warning: undefined file type 0%o\n",
+ DIP(dp, di_mode) & IFMT);
return;
}
- if (dp->di_size > NDADDR * sblock->fs_bsize)
+ if (DIP(dp, di_size) > NDADDR * sblock->fs_bsize)
cnt = NDADDR * sblock->fs_frag;
else
- cnt = howmany(dp->di_size, sblock->fs_fsize);
- blksout(&dp->di_db[0], cnt, ino);
- if ((size = dp->di_size - NDADDR * sblock->fs_bsize) <= 0)
+ cnt = howmany(DIP(dp, di_size), sblock->fs_fsize);
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ ufs1_blksout(&dp->dp1.di_db[0], cnt, ino);
+ else
+ ufs2_blksout(&dp->dp2.di_db[0], cnt, ino);
+ if ((size = DIP(dp, di_size) - NDADDR * sblock->fs_bsize) <= 0)
return;
for (ind_level = 0; ind_level < NIADDR; ind_level++) {
- dmpindir(ino, dp->di_ib[ind_level], ind_level, &size);
+ dmpindir(ino, DIP(dp, di_ib[ind_level]), ind_level, &size);
if (size <= 0)
return;
}
@@ -467,13 +580,15 @@ dumpino(struct ufs1_dinode *dp, ino_t ino)
* Read indirect blocks, and pass the data blocks to be dumped.
*/
static void
-dmpindir(ino_t ino, daddr_t blk, int ind_level, off_t *size)
+dmpindir(ino_t ino, daddr64_t blk, int ind_level, off_t *size)
{
int i, cnt;
- daddr_t idblk[MAXNINDIR];
+ static void *idblk;
+ if (idblk == NULL && (idblk = malloc(sblock->fs_bsize)) == NULL)
+ quit("dmpindir: cannot allocate indirect memory.\n");
if (blk != 0)
- bread(fsbtodb(sblock, blk), (char *)idblk, (int) sblock->fs_bsize);
+ bread(fsbtodb(sblock, blk), idblk, (int) sblock->fs_bsize);
else
memset(idblk, 0, (int)sblock->fs_bsize);
if (ind_level <= 0) {
@@ -482,12 +597,20 @@ dmpindir(ino_t ino, daddr_t blk, int ind_level, off_t *size)
else
cnt = NINDIR(sblock) * sblock->fs_frag;
*size -= NINDIR(sblock) * sblock->fs_bsize;
- blksout(&idblk[0], cnt, ino);
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ ufs1_blksout((int32_t *)idblk, cnt, ino);
+ else
+ ufs2_blksout((int64_t *)idblk, cnt, ino);
return;
}
ind_level--;
for (i = 0; i < NINDIR(sblock); i++) {
- dmpindir(ino, idblk[i], ind_level, size);
+ if (sblock->fs_magic == FS_UFS1_MAGIC)
+ dmpindir(ino, ((int32_t *)idblk)[i], ind_level,
+ size);
+ else
+ dmpindir(ino, ((int64_t *)idblk)[i], ind_level,
+ size);
if (*size <= 0)
return;
}
@@ -497,9 +620,44 @@ dmpindir(ino_t ino, daddr_t blk, int ind_level, off_t *size)
* Collect up the data into tape record sized buffers and output them.
*/
void
-blksout(daddr_t *blkp, int frags, ino_t ino)
+ufs1_blksout(int32_t *blkp, int frags, ino_t ino)
{
- daddr_t *bp;
+ int32_t *bp;
+ int i, j, count, blks, tbperdb;
+
+ blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
+ tbperdb = sblock->fs_bsize >> tp_bshift;
+ for (i = 0; i < blks; i += TP_NINDIR) {
+ if (i + TP_NINDIR > blks)
+ count = blks;
+ else
+ count = i + TP_NINDIR;
+ for (j = i; j < count; j++)
+ if (blkp[j / tbperdb] != 0)
+ spcl.c_addr[j - i] = 1;
+ else
+ spcl.c_addr[j - i] = 0;
+ spcl.c_count = count - i;
+ writeheader(ino);
+ bp = &blkp[i / tbperdb];
+ for (j = i; j < count; j += tbperdb, bp++)
+ if (*bp != 0) {
+ if (j + tbperdb <= count)
+ dumpblock(*bp, (int)sblock->fs_bsize);
+ else
+ dumpblock(*bp, (count - j) * TP_BSIZE);
+ }
+ spcl.c_type = TS_ADDR;
+ }
+}
+
+/*
+ * Collect up the data into tape record sized buffers and output them.
+ */
+void
+ufs2_blksout(daddr64_t *blkp, int frags, ino_t ino)
+{
+ daddr64_t *bp;
int i, j, count, blks, tbperdb;
blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
@@ -557,7 +715,15 @@ writeheader(ino)
int32_t sum, cnt, *lp;
spcl.c_inumber = ino;
- spcl.c_magic = NFS_MAGIC;
+ if (sblock->fs_magic == FS_UFS2_MAGIC) {
+ spcl.c_magic = FS_UFS2_MAGIC;
+ } else {
+ spcl.c_magic = NFS_MAGIC;
+ spcl.c_old_date = (int32_t)spcl.c_date;
+ spcl.c_old_ddate = (int32_t)spcl.c_ddate;
+ spcl.c_old_tapea = (int32_t)spcl.c_tapea;
+ spcl.c_old_firstrec = (int32_t)spcl.c_firstrec;
+ }
spcl.c_checksum = 0;
lp = (int32_t *)&spcl;
sum = 0;
@@ -572,20 +738,32 @@ writeheader(ino)
writerec((char *)&spcl, 1);
}
-struct ufs1_dinode *
-getino(ino_t inum)
+union dinode *
+getino(ino_t inum, int *modep)
{
- static daddr_t minino, maxino;
- static struct ufs1_dinode inoblock[MAXINOPB];
+ static ino_t minino, maxino;
+ static void *inoblock;
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+ if (inoblock == NULL && (inoblock = malloc(sblock->fs_bsize)) == NULL)
+ quit("cannot allocate inode memory.\n");
curino = inum;
if (inum >= minino && inum < maxino)
- return (&inoblock[inum - minino]);
- bread(fsbtodb(sblock, ino_to_fsba(sblock, inum)), (char *)inoblock,
+ goto gotit;
+ bread(fsbtodb(sblock, ino_to_fsba(sblock, inum)), inoblock,
(int)sblock->fs_bsize);
minino = inum - (inum % INOPB(sblock));
maxino = minino + INOPB(sblock);
- return (&inoblock[inum - minino]);
+gotit:
+ if (sblock->fs_magic == FS_UFS1_MAGIC) {
+ dp1 = &((struct ufs1_dinode *)inoblock)[inum - minino];
+ *modep = (dp1->di_mode & IFMT);
+ return ((union dinode *)dp1);
+ }
+ dp2 = &((struct ufs2_dinode *)inoblock)[inum - minino];
+ *modep = (dp2->di_mode & IFMT);
+ return ((union dinode *)dp2);
}
/*
@@ -598,7 +776,7 @@ int breaderrors = 0;
#define BREADEMAX 32
void
-bread(daddr_t blkno, char *buf, int size)
+bread(daddr64_t blkno, char *buf, int size)
{
int cnt, i;
@@ -622,10 +800,10 @@ loop:
goto loop;
}
if (cnt == -1)
- msg("read error from %s: %s: [block %d]: count=%d\n",
+ msg("read error from %s: %s: [block %lld]: count=%d\n",
disk, strerror(errno), blkno, size);
else
- msg("short read error from %s: [block %d]: count=%d, got=%d\n",
+ msg("short read error from %s: [block %lld]: count=%d, got=%d\n",
disk, blkno, size, cnt);
if (++breaderrors > BREADEMAX) {
msg("More than %d block read errors from %s\n",
@@ -648,11 +826,11 @@ loop:
if ((cnt = read(diskfd, buf, (int)dev_bsize)) == dev_bsize)
continue;
if (cnt == -1) {
- msg("read error from %s: %s: [sector %d]: count=%d\n",
+ msg("read error from %s: %s: [sector %lld]: count=%ld\n",
disk, strerror(errno), blkno, dev_bsize);
continue;
}
- msg("short read error from %s: [sector %d]: count=%d, got=%d\n",
+ msg("short read error from %s: [sector %lld]: count=%ld, got=%d\n",
disk, blkno, dev_bsize, cnt);
}
}
diff --git a/sbin/restore/dirs.c b/sbin/restore/dirs.c
index ee7b71634d6..fd8edee7b7c 100644
--- a/sbin/restore/dirs.c
+++ b/sbin/restore/dirs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dirs.c,v 1.30 2005/04/28 16:15:45 millert Exp $ */
+/* $OpenBSD: dirs.c,v 1.31 2007/06/03 20:16:08 millert Exp $ */
/* $NetBSD: dirs.c,v 1.26 1997/07/01 05:37:49 lukem Exp $ */
/*
@@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "@(#)dirs.c 8.5 (Berkeley) 8/31/94";
#else
-static const char rcsid[] = "$OpenBSD: dirs.c,v 1.30 2005/04/28 16:15:45 millert Exp $";
+static const char rcsid[] = "$OpenBSD: dirs.c,v 1.31 2007/06/03 20:16:08 millert Exp $";
#endif
#endif /* not lint */
@@ -83,7 +83,8 @@ static struct inotab *inotab[HASHSIZE];
*/
struct modeinfo {
ino_t ino;
- struct timeval timep[2];
+ struct timeval ctimep[2];
+ struct timeval mtimep[2];
mode_t mode;
uid_t uid;
gid_t gid;
@@ -121,7 +122,7 @@ struct odirect {
char d_name[ODIRSIZ];
};
-static struct inotab *allocinotab(ino_t, struct ufs1_dinode *, long);
+static struct inotab *allocinotab(FILE *, struct context *, long);
static void dcvt(struct odirect *, struct direct *);
static void flushent(void);
static struct inotab *inotablookup(ino_t);
@@ -142,7 +143,6 @@ void
extractdirs(int genmode)
{
int i;
- struct ufs1_dinode *ip;
struct inotab *itp;
struct direct nulldir;
int fd;
@@ -183,8 +183,7 @@ extractdirs(int genmode)
for (;;) {
curfile.name = "<directory file - name unknown>";
curfile.action = USING;
- ip = curfile.dip;
- if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) {
+ if (curfile.mode == 0 || (curfile.mode & IFMT) != IFDIR) {
(void)fclose(df);
dirp = opendirfile(dirfile);
if (dirp == NULL)
@@ -196,7 +195,7 @@ extractdirs(int genmode)
panic("Root directory is not on tape\n");
return;
}
- itp = allocinotab(curfile.ino, ip, seekpt);
+ itp = allocinotab(mf, &curfile, seekpt);
getfile(putdir, xtrnull);
putent(&nulldir);
flushent();
@@ -211,7 +210,7 @@ void
skipdirs(void)
{
- while (curfile.dip && (curfile.dip->di_mode & IFMT) == IFDIR) {
+ while (curfile.ino && (curfile.mode & IFMT) == IFDIR) {
skipfile();
}
}
@@ -270,7 +269,7 @@ treescan(char *pname, ino_t ino, long (*todo)(char *, ino_t, int))
while (dp != NULL) {
locname[namelen] = '\0';
if (namelen + dp->d_namlen >= sizeof(locname)) {
- fprintf(stderr, "%s%s: name exceeds %d char\n",
+ fprintf(stderr, "%s%s: name exceeds %zd char\n",
locname, dp->d_name, sizeof(locname) - 1);
} else {
(void)strlcat(locname, dp->d_name, sizeof(locname));
@@ -617,11 +616,14 @@ setdirmodes(int flags)
if (ep == NULL) {
panic("cannot find directory inode %d\n", node.ino);
} else {
- cp = myname(ep);
- (void)chown(cp, node.uid, node.gid);
- (void)chmod(cp, node.mode);
- (void)chflags(cp, node.flags);
- utimes(cp, node.timep);
+ if (!Nflag) {
+ cp = myname(ep);
+ (void)chown(cp, node.uid, node.gid);
+ (void)chmod(cp, node.mode);
+ (void)chflags(cp, node.flags);
+ (void)utimes(cp, node.ctimep);
+ (void)utimes(cp, node.mtimep);
+ }
ep->e_flags &= ~NEW;
}
}
@@ -687,7 +689,7 @@ inodetype(ino_t ino)
* If requested, save its pertinent mode, owner, and time info.
*/
static struct inotab *
-allocinotab(ino_t ino, struct ufs1_dinode *dip, long seekpt)
+allocinotab(FILE *mf, struct context *ctxp, long seekpt)
{
struct inotab *itp;
struct modeinfo node;
@@ -695,21 +697,25 @@ allocinotab(ino_t ino, struct ufs1_dinode *dip, long seekpt)
itp = calloc(1, sizeof(struct inotab));
if (itp == NULL)
panic("no memory directory table\n");
- itp->t_next = inotab[INOHASH(ino)];
- inotab[INOHASH(ino)] = itp;
- itp->t_ino = ino;
+ itp->t_next = inotab[INOHASH(ctxp->ino)];
+ inotab[INOHASH(ctxp->ino)] = itp;
+ itp->t_ino = ctxp->ino;
itp->t_seekpt = seekpt;
if (mf == NULL)
return (itp);
- node.ino = ino;
- node.timep[0].tv_sec = dip->di_atime;
- node.timep[0].tv_usec = dip->di_atimensec / 1000;
- node.timep[1].tv_sec = dip->di_mtime;
- node.timep[1].tv_usec = dip->di_mtimensec / 1000;
- node.mode = dip->di_mode;
- node.flags = dip->di_flags;
- node.uid = dip->di_uid;
- node.gid = dip->di_gid;
+ node.ino = ctxp->ino;
+ node.mtimep[0].tv_sec = ctxp->atime_sec;
+ node.mtimep[0].tv_usec = ctxp->atime_nsec / 1000;
+ node.mtimep[1].tv_sec = ctxp->mtime_sec;
+ node.mtimep[1].tv_usec = ctxp->mtime_nsec / 1000;
+ node.ctimep[0].tv_sec = ctxp->atime_sec;
+ node.ctimep[0].tv_usec = ctxp->atime_nsec / 1000;
+ node.ctimep[1].tv_sec = ctxp->birthtime_sec;
+ node.ctimep[1].tv_usec = ctxp->birthtime_nsec / 1000;
+ node.mode = ctxp->mode;
+ node.flags = ctxp->file_flags;
+ node.uid = ctxp->uid;
+ node.gid = ctxp->gid;
(void)fwrite((char *)&node, 1, sizeof(struct modeinfo), mf);
return (itp);
}
diff --git a/sbin/restore/restore.h b/sbin/restore/restore.h
index e88ec7d44d5..891ce558f9e 100644
--- a/sbin/restore/restore.h
+++ b/sbin/restore/restore.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: restore.h,v 1.6 2004/03/31 22:08:32 henning Exp $ */
+/* $OpenBSD: restore.h,v 1.7 2007/06/03 20:16:08 millert Exp $ */
/* $NetBSD: restore.h,v 1.8 1997/07/01 05:37:54 lukem Exp $ */
/*
@@ -105,10 +105,21 @@ struct entry {
* The entry describes the next file available on the tape
*/
struct context {
- char *name; /* name of file */
+ short action; /* action being taken on this file */
+ mode_t mode; /* mode of file */
ino_t ino; /* inumber of file */
- struct ufs1_dinode *dip; /* pointer to inode */
- char action; /* action being taken on this file */
+ uid_t uid; /* file owner */
+ gid_t gid; /* file group */
+ int file_flags; /* status flags (chflags) */
+ int rdev; /* device number of file */
+ time_t atime_sec; /* access time seconds */
+ time_t mtime_sec; /* modified time seconds */
+ time_t birthtime_sec; /* creation time seconds */
+ int atime_nsec; /* access time nanoseconds */
+ int mtime_nsec; /* modified time nanoseconds */
+ int birthtime_nsec; /* creation time nanoseconds */
+ off_t size; /* size of file */
+ char *name; /* name of file */
} curfile;
/* actions */
#define USING 1 /* extracting from the tape */
diff --git a/sbin/restore/tape.c b/sbin/restore/tape.c
index fa6e7b36dee..0ea205899bc 100644
--- a/sbin/restore/tape.c
+++ b/sbin/restore/tape.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tape.c,v 1.31 2005/06/14 19:46:05 millert Exp $ */
+/* $OpenBSD: tape.c,v 1.32 2007/06/03 20:16:08 millert Exp $ */
/* $NetBSD: tape.c,v 1.26 1997/04/15 07:12:25 lukem Exp $ */
/*
@@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "@(#)tape.c 8.6 (Berkeley) 9/13/94";
#else
-static const char rcsid[] = "$OpenBSD: tape.c,v 1.31 2005/06/14 19:46:05 millert Exp $";
+static const char rcsid[] = "$OpenBSD: tape.c,v 1.32 2007/06/03 20:16:08 millert Exp $";
#endif
#endif /* not lint */
@@ -86,10 +86,37 @@ static size_t pathlen;
int oldinofmt; /* old inode format conversion required */
int Bcvt; /* Swap Bytes (for CCI or sun) */
-static int Qcvt; /* Swap quads (for sun) */
#define FLUSHTAPEBUF() blkcnt = ntrec + 1
+union u_ospcl {
+ char dummy[TP_BSIZE];
+ struct s_ospcl {
+ int32_t c_type;
+ int32_t c_date;
+ int32_t c_ddate;
+ int32_t c_volume;
+ int32_t c_tapea;
+ u_int16_t c_inumber;
+ int32_t c_magic;
+ int32_t c_checksum;
+ struct odinode {
+ unsigned short odi_mode;
+ u_int16_t odi_nlink;
+ u_int16_t odi_uid;
+ u_int16_t odi_gid;
+ int32_t odi_size;
+ int32_t odi_rdev;
+ char odi_addr[36];
+ int32_t odi_atime;
+ int32_t odi_mtime;
+ int32_t odi_ctime;
+ } c_odinode;
+ int32_t c_count;
+ char c_addr[256];
+ } s_ospcl;
+};
+
static void accthdr(struct s_spcl *);
static int checksum(int *);
static void findinode(struct s_spcl *);
@@ -98,6 +125,7 @@ static int gethead(struct s_spcl *);
static void readtape(char *);
static void setdumpnum(void);
static void swap_header(struct s_spcl *);
+static void swap_old_header(struct s_ospcl *);
static void terminateinput(void);
static void xtrfile(char *, size_t);
static void xtrlnkfile(char *, size_t);
@@ -198,7 +226,8 @@ setup(void)
(void)fputs("Converting to new file system format.\n", stderr);
}
if (pipein) {
- endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : NFS_MAGIC;
+ endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC :
+ FS_UFS2_MAGIC;
endoftapemark.s_spcl.c_type = TS_END;
ip = (int *)&endoftapemark;
j = sizeof(union u_spcl) / sizeof(int);
@@ -210,8 +239,8 @@ setup(void)
}
if (vflag || command == 't')
printdumpinfo();
- dumptime = spcl.c_ddate;
- dumpdate = spcl.c_date;
+ dumptime = (time_t)spcl.c_ddate;
+ dumpdate = (time_t)spcl.c_date;
if (stat(".", &stbuf) < 0)
err(1, "cannot stat .");
if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE )
@@ -257,7 +286,7 @@ setup(void)
void
getvol(long nextvol)
{
- long newvol = 0, savecnt, wantnext, i;
+ long newvol = 0, savecnt = 0, wantnext = 0, i;
union u_spcl tmpspcl;
# define tmpbuf tmpspcl.s_spcl
char buf[TP_BSIZE];
@@ -364,8 +393,8 @@ gethdr:
goto again;
}
if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) {
- fprintf(stderr, "Wrong dump date\n\tgot: %s",
- ctime(&tmpbuf.c_date));
+ time_t t = (time_t)tmpbuf.c_date;
+ fprintf(stderr, "Wrong dump date\n\tgot: %s", ctime(&t));
fprintf(stderr, "\twanted: %s", ctime(&dumpdate));
volno = 0;
goto again;
@@ -379,7 +408,7 @@ gethdr:
* If coming to this volume at random, skip to the beginning
* of the next record.
*/
- Dprintf(stdout, "read %ld recs, tape starts with %d\n",
+ Dprintf(stdout, "read %ld recs, tape starts with %lld\n",
tpblksread, tmpbuf.c_firstrec);
if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
if (!wantnext) {
@@ -430,7 +459,7 @@ terminateinput(void)
}
curfile.name = "<name unknown>";
curfile.action = UNKNOWN;
- curfile.dip = NULL;
+ curfile.mode = 0;
curfile.ino = maxino;
if (gettingfile) {
gettingfile = 0;
@@ -465,9 +494,13 @@ setdumpnum(void)
void
printdumpinfo(void)
{
- fprintf(stdout, "Dump date: %s", ctime(&spcl.c_date));
+ time_t t;
+
+ t = (time_t)spcl.c_date;
+ fprintf(stdout, "Dump date: %s", ctime(&t));
+ t = (time_t)spcl.c_ddate;
fprintf(stdout, "Dumped from: %s",
- (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&spcl.c_ddate));
+ (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&t));
if (spcl.c_host[0] == '\0')
return;
fprintf(stderr, "Level %d dump of %s on %s:%s\n",
@@ -479,18 +512,31 @@ int
extractfile(char *name)
{
u_int flags;
+ uid_t uid;
+ gid_t gid;
mode_t mode;
- struct timeval timep[2];
+ struct timeval mtimep[2], ctimep[2];
struct entry *ep;
+ int setbirth;
curfile.name = name;
curfile.action = USING;
- 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;
- timep[1].tv_usec = curfile.dip->di_mtimensec / 1000;
- mode = curfile.dip->di_mode;
- flags = curfile.dip->di_flags;
+ mtimep[0].tv_sec = curfile.atime_sec;
+ mtimep[0].tv_usec = curfile.atime_nsec / 1000;
+ mtimep[1].tv_sec = curfile.mtime_sec;
+ mtimep[1].tv_usec = curfile.mtime_nsec / 1000;
+
+ setbirth = curfile.birthtime_sec != 0;
+ if (setbirth) {
+ ctimep[0].tv_sec = curfile.atime_sec;
+ ctimep[0].tv_usec = curfile.atime_nsec / 1000;
+ ctimep[1].tv_sec = curfile.birthtime_sec;
+ ctimep[1].tv_usec = curfile.birthtime_nsec / 1000;
+ }
+ uid = curfile.uid;
+ gid = curfile.gid;
+ mode = curfile.mode;
+ flags = curfile.file_flags;
switch (mode & IFMT) {
default:
@@ -515,10 +561,6 @@ extractfile(char *name)
return (genliteraldir(name, curfile.ino));
case IFLNK: {
- /* Gotta save these, linkit() changes curfile. */
- uid_t luid = curfile.dip->di_uid;
- gid_t lgid = curfile.dip->di_gid;
-
lnkbuf[0] = '\0';
pathlen = 0;
getfile(xtrlnkfile, xtrlnkskip);
@@ -530,7 +572,7 @@ extractfile(char *name)
}
if (linkit(lnkbuf, name, SYMLINK) == FAIL)
return (FAIL);
- (void)lchown(name, luid, lgid);
+ (void)lchown(name, uid, gid);
return (GOOD);
}
@@ -541,16 +583,18 @@ extractfile(char *name)
skipfile();
return (GOOD);
}
- if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) {
+ if (mknod(name, mode, (int)curfile.rdev) < 0) {
warn("%s: cannot create special file", name);
skipfile();
return (FAIL);
}
- (void)chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
+ (void)chown(name, uid, gid);
(void)chmod(name, mode);
(void)chflags(name, flags);
skipfile();
- utimes(name, timep);
+ if (setbirth)
+ (void)utimes(name, ctimep);
+ (void)utimes(name, mtimep);
return (GOOD);
case IFIFO:
@@ -564,11 +608,13 @@ extractfile(char *name)
skipfile();
return (FAIL);
}
- (void)chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
+ (void)chown(name, uid, gid);
(void)chmod(name, mode);
(void)chflags(name, flags);
skipfile();
- utimes(name, timep);
+ if (setbirth)
+ (void)utimes(name, ctimep);
+ (void)utimes(name, mtimep);
return (GOOD);
case IFREG:
@@ -583,12 +629,14 @@ extractfile(char *name)
skipfile();
return (FAIL);
}
- (void)fchown(ofile, curfile.dip->di_uid, curfile.dip->di_gid);
+ (void)fchown(ofile, curfile.uid, curfile.gid);
(void)fchmod(ofile, mode);
(void)fchflags(ofile, flags);
getfile(xtrfile, xtrskip);
(void)close(ofile);
- utimes(name, timep);
+ if (setbirth)
+ (void)utimes(name, ctimep);
+ (void)utimes(name, mtimep);
return (GOOD);
}
/* NOTREACHED */
@@ -630,7 +678,7 @@ getfile(void (*fill)(char *, size_t), void (*skip)(char *, size_t))
{
int i;
volatile int curblk = 0;
- volatile off_t size = spcl.c_dinode.di_size;
+ volatile off_t size = spcl.c_size;
static char clearedbuf[MAXBSIZE];
char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
char junk[TP_BSIZE];
@@ -638,7 +686,7 @@ getfile(void (*fill)(char *, size_t), void (*skip)(char *, size_t))
if (spcl.c_type == TS_END)
panic("ran off end of tape\n");
- if (spcl.c_magic != NFS_MAGIC)
+ if (spcl.c_magic != FS_UFS2_MAGIC)
panic("not at beginning of a file\n");
if (!gettingfile && setjmp(restart) != 0)
return;
@@ -938,43 +986,14 @@ closemt(void)
static int
gethead(struct s_spcl *buf)
{
- long i;
- union {
- quad_t qval;
- int32_t val[2];
- } qcvt;
- union u_ospcl {
- char dummy[TP_BSIZE];
- struct s_ospcl {
- int32_t c_type;
- int32_t c_date;
- int32_t c_ddate;
- int32_t c_volume;
- int32_t c_tapea;
- u_int16_t c_inumber;
- int32_t c_magic;
- int32_t c_checksum;
- struct odinode {
- unsigned short odi_mode;
- u_int16_t odi_nlink;
- u_int16_t odi_uid;
- u_int16_t odi_gid;
- int32_t odi_size;
- int32_t odi_rdev;
- char odi_addr[36];
- int32_t odi_atime;
- int32_t odi_mtime;
- int32_t odi_ctime;
- } c_dinode;
- int32_t c_count;
- char c_addr[256];
- } s_ospcl;
- } u_ospcl;
+ union u_ospcl u_ospcl;
if (!cvtflag) {
readtape((char *)buf);
- if (buf->c_magic != NFS_MAGIC) {
- if (swap32(buf->c_magic) != NFS_MAGIC)
+ if (buf->c_magic != NFS_MAGIC &&
+ buf->c_magic != FS_UFS2_MAGIC) {
+ if (swap32(buf->c_magic) != NFS_MAGIC &&
+ swap32(buf->c_magic) != FS_UFS2_MAGIC)
return (FAIL);
if (!Bcvt) {
Vprintf(stdout, "Note: Doing Byte swapping\n");
@@ -987,7 +1006,20 @@ gethead(struct s_spcl *buf)
swap_header(buf);
goto good;
}
+
readtape((char *)(&u_ospcl.s_ospcl));
+ if (checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
+ return (FAIL);
+ if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC) {
+ if (swap32(u_ospcl.s_ospcl.c_magic) != OFS_MAGIC)
+ return (FAIL);
+ if (!Bcvt) {
+ fprintf(stdout, "Note: Doing Byte swapping\n");
+ Bcvt = 1;
+ }
+ swap_old_header(&u_ospcl.s_ospcl);
+ }
+
memset(buf, 0, (long)TP_BSIZE);
buf->c_type = u_ospcl.s_ospcl.c_type;
buf->c_date = u_ospcl.s_ospcl.c_date;
@@ -996,40 +1028,17 @@ gethead(struct s_spcl *buf)
buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
- buf->c_magic = u_ospcl.s_ospcl.c_magic;
- buf->c_dinode.di_mode = u_ospcl.s_ospcl.c_dinode.odi_mode;
- buf->c_dinode.di_nlink = u_ospcl.s_ospcl.c_dinode.odi_nlink;
- buf->c_dinode.di_uid = u_ospcl.s_ospcl.c_dinode.odi_uid;
- 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;
- 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;
+ buf->c_mode = u_ospcl.s_ospcl.c_odinode.odi_mode;
+ buf->c_uid = u_ospcl.s_ospcl.c_odinode.odi_uid;
+ buf->c_gid = u_ospcl.s_ospcl.c_odinode.odi_gid;
+ buf->c_size = u_ospcl.s_ospcl.c_odinode.odi_size;
+ buf->c_rdev = u_ospcl.s_ospcl.c_odinode.odi_rdev;
+ buf->c_atime = u_ospcl.s_ospcl.c_odinode.odi_atime;
+ buf->c_mtime = u_ospcl.s_ospcl.c_odinode.odi_mtime;
buf->c_count = u_ospcl.s_ospcl.c_count;
memcpy(buf->c_addr, u_ospcl.s_ospcl.c_addr, (long)256);
- if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
- checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
- return(FAIL);
- buf->c_magic = NFS_MAGIC;
-
+ buf->c_magic = FS_UFS2_MAGIC;
good:
- if ((buf->c_dinode.di_size == 0 || buf->c_dinode.di_size > 0xfffffff) &&
- (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");
- Qcvt = 1;
- }
- }
- if (Qcvt) {
- qcvt.qval = buf->c_dinode.di_size;
- i = qcvt.val[1];
- qcvt.val[1] = qcvt.val[0];
- qcvt.val[0] = i;
- buf->c_dinode.di_size = qcvt.qval;
- }
-
switch (buf->c_type) {
case TS_CLRI:
@@ -1038,7 +1047,7 @@ good:
* Have to patch up missing information in bit map headers
*/
buf->c_inumber = 0;
- buf->c_dinode.di_size = buf->c_count * TP_BSIZE;
+ buf->c_size = buf->c_count * TP_BSIZE;
break;
case TS_TAPE:
@@ -1050,6 +1059,18 @@ good:
break;
case TS_INODE:
+ if (buf->c_magic == NFS_MAGIC) {
+ buf->c_tapea = buf->c_old_tapea;
+ buf->c_firstrec = buf->c_old_firstrec;
+ buf->c_date = buf->c_old_date;
+ buf->c_ddate = buf->c_old_ddate;
+ buf->c_atime = buf->c_old_atime;
+ buf->c_mtime = buf->c_old_mtime;
+ buf->c_birthtime = 0;
+ buf->c_birthtimensec = 0;
+ buf->c_atimensec = buf->c_mtimensec = 0;
+ }
+
case TS_ADDR:
break;
@@ -1057,13 +1078,16 @@ good:
panic("gethead: unknown inode type %d\n", buf->c_type);
break;
}
+
+ buf->c_magic = FS_UFS2_MAGIC;
+
/*
- * If we are restoring a filesystem with old format inodes,
+ * If we are restoring a filesystem with old format inodes,
* copy the uid/gid to the new location.
*/
if (oldinofmt) {
- buf->c_dinode.di_uid = buf->c_dinode.di_ouid;
- buf->c_dinode.di_gid = buf->c_dinode.di_ogid;
+ buf->c_uid = buf->c_spare1[1];
+ buf->c_gid = buf->c_spare1[2];
}
if (dflag)
accthdr(buf);
@@ -1085,8 +1109,8 @@ accthdr(struct s_spcl *header)
fprintf(stderr, "Volume header (%s inode format) ",
oldinofmt ? "old" : "new");
if (header->c_firstrec)
- fprintf(stderr, "begins with record %d",
- header->c_firstrec);
+ fprintf(stderr, "begins with record %lld",
+ (long long)header->c_firstrec);
fprintf(stderr, "\n");
previno = 0x7fffffff;
return;
@@ -1150,10 +1174,10 @@ findinode(struct s_spcl *header)
curfile.name = "<name unknown>";
curfile.action = UNKNOWN;
- curfile.dip = NULL;
+ curfile.mode = 0;
curfile.ino = 0;
do {
- if (header->c_magic != NFS_MAGIC) {
+ if (header->c_magic != FS_UFS2_MAGIC) {
skipcnt++;
while (gethead(header) == FAIL ||
header->c_date != dumpdate)
@@ -1174,7 +1198,18 @@ findinode(struct s_spcl *header)
break;
case TS_INODE:
- curfile.dip = &header->c_dinode;
+ curfile.mode = header->c_mode;
+ curfile.uid = header->c_uid;
+ curfile.gid = header->c_gid;
+ curfile.file_flags = header->c_file_flags;
+ curfile.rdev = header->c_rdev;
+ curfile.atime_sec = header->c_atime;
+ curfile.atime_nsec = header->c_atimensec;
+ curfile.mtime_sec = header->c_mtime;
+ curfile.mtime_nsec = header->c_mtimensec;
+ curfile.birthtime_sec = header->c_birthtime;
+ curfile.birthtime_nsec = header->c_birthtimensec;
+ curfile.size = header->c_size;
curfile.ino = header->c_inumber;
break;
@@ -1217,8 +1252,6 @@ checksum(int *buf)
i += *buf++;
while (--j);
} else {
- /* What happens if we want to read restore tapes
- for a 16bit int machine??? */
do
i += swap32(*buf++);
while (--j);
@@ -1250,36 +1283,68 @@ static void
swap_header(struct s_spcl *s)
{
s->c_type = swap32(s->c_type);
- s->c_date = swap32(s->c_date);
- s->c_ddate = swap32(s->c_ddate);
+ s->c_old_date = swap32(s->c_old_date);
+ s->c_old_ddate = swap32(s->c_old_ddate);
s->c_volume = swap32(s->c_volume);
- s->c_tapea = swap32(s->c_tapea);
+ s->c_old_tapea = swap32(s->c_old_tapea);
s->c_inumber = swap32(s->c_inumber);
s->c_magic = swap32(s->c_magic);
s->c_checksum = swap32(s->c_checksum);
- s->c_dinode.di_mode = swap16(s->c_dinode.di_mode);
- s->c_dinode.di_nlink = swap16(s->c_dinode.di_nlink);
- s->c_dinode.di_ouid = swap16(s->c_dinode.di_ouid);
- s->c_dinode.di_ogid = swap16(s->c_dinode.di_ogid);
-
- s->c_dinode.di_size = swap64(s->c_dinode.di_size);
-
- s->c_dinode.di_atime = swap32(s->c_dinode.di_atime);
- s->c_dinode.di_atimensec = swap32(s->c_dinode.di_atimensec);
- s->c_dinode.di_mtime = swap32(s->c_dinode.di_mtime);
- s->c_dinode.di_mtimensec = swap32(s->c_dinode.di_mtimensec);
- s->c_dinode.di_ctime = swap32(s->c_dinode.di_ctime);
- s->c_dinode.di_ctimensec = swap32(s->c_dinode.di_ctimensec);
-
- s->c_dinode.di_flags = swap32(s->c_dinode.di_flags);
- s->c_dinode.di_blocks = swap32(s->c_dinode.di_blocks);
- s->c_dinode.di_gen = swap32(s->c_dinode.di_gen);
- s->c_dinode.di_uid = swap32(s->c_dinode.di_uid);
- s->c_dinode.di_gid = swap32(s->c_dinode.di_gid);
+ s->c_mode = swap16(s->c_mode);
+ s->c_size = swap64(s->c_size);
+ s->c_old_atime = swap32(s->c_old_atime);
+ s->c_atimensec = swap32(s->c_atimensec);
+ s->c_old_mtime = swap32(s->c_old_mtime);
+ s->c_mtimensec = swap32(s->c_mtimensec);
+ s->c_rdev = swap32(s->c_rdev);
+ s->c_birthtimensec = swap32(s->c_birthtimensec);
+ s->c_birthtime = swap64(s->c_birthtime);
+ s->c_atime = swap64(s->c_atime);
+ s->c_mtime = swap64(s->c_mtime);
+ s->c_file_flags = swap32(s->c_file_flags);
+ s->c_uid = swap32(s->c_uid);
+ s->c_gid = swap32(s->c_gid);
s->c_count = swap32(s->c_count);
s->c_level = swap32(s->c_level);
s->c_flags = swap32(s->c_flags);
- s->c_firstrec = swap32(s->c_firstrec);
+ s->c_old_firstrec = swap32(s->c_old_firstrec);
+
+ s->c_date = swap64(s->c_date);
+ s->c_ddate = swap64(s->c_ddate);
+ s->c_tapea = swap64(s->c_tapea);
+ s->c_firstrec = swap64(s->c_firstrec);
+
+ /*
+ * These are ouid and ogid.
+ */
+ s->c_spare1[1] = swap16(s->c_spare1[1]);
+ s->c_spare1[2] = swap16(s->c_spare1[2]);
+}
+
+static void
+swap_old_header(struct s_ospcl *os)
+{
+ os->c_type = swap32(os->c_type);
+ os->c_date = swap32(os->c_date);
+ os->c_ddate = swap32(os->c_ddate);
+ os->c_volume = swap32(os->c_volume);
+ os->c_tapea = swap32(os->c_tapea);
+ os->c_inumber = swap16(os->c_inumber);
+ os->c_magic = swap32(os->c_magic);
+ os->c_checksum = swap32(os->c_checksum);
+
+ os->c_odinode.odi_mode = swap16(os->c_odinode.odi_mode);
+ os->c_odinode.odi_nlink = swap16(os->c_odinode.odi_nlink);
+ os->c_odinode.odi_uid = swap16(os->c_odinode.odi_uid);
+ os->c_odinode.odi_gid = swap16(os->c_odinode.odi_gid);
+
+ os->c_odinode.odi_size = swap32(os->c_odinode.odi_size);
+ os->c_odinode.odi_rdev = swap32(os->c_odinode.odi_rdev);
+ os->c_odinode.odi_atime = swap32(os->c_odinode.odi_atime);
+ os->c_odinode.odi_mtime = swap32(os->c_odinode.odi_mtime);
+ os->c_odinode.odi_ctime = swap32(os->c_odinode.odi_ctime);
+
+ os->c_count = swap32(os->c_count);
}