diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2007-06-03 20:16:09 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2007-06-03 20:16:09 +0000 |
commit | 0ff9cbbdef89eed7cbcda58dbc021f8035a2dbad (patch) | |
tree | 00e07c12b1495418158af273fdd672ed76ea4754 /sbin | |
parent | ad936b34df484977c12aee44475ade8d8d010a16 (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.h | 26 | ||||
-rw-r--r-- | sbin/dump/itime.c | 18 | ||||
-rw-r--r-- | sbin/dump/main.c | 74 | ||||
-rw-r--r-- | sbin/dump/optr.c | 6 | ||||
-rw-r--r-- | sbin/dump/tape.c | 40 | ||||
-rw-r--r-- | sbin/dump/traverse.c | 318 | ||||
-rw-r--r-- | sbin/restore/dirs.c | 62 | ||||
-rw-r--r-- | sbin/restore/restore.h | 19 | ||||
-rw-r--r-- | sbin/restore/tape.c | 331 |
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); } |