diff --git a/sbin/restore/dirs.c b/sbin/restore/dirs.c index bff49fccdafa..f8e56fbf07f0 100644 --- a/sbin/restore/dirs.c +++ b/sbin/restore/dirs.c @@ -1,4 +1,4 @@ -/* $NetBSD: dirs.c,v 1.40 2003/11/05 22:27:16 fvdl Exp $ */ +/* $NetBSD: dirs.c,v 1.41 2004/10/22 22:38:38 bouyer Exp $ */ /* * Copyright (c) 1983, 1993 @@ -39,7 +39,7 @@ #if 0 static char sccsid[] = "@(#)dirs.c 8.7 (Berkeley) 5/1/95"; #else -__RCSID("$NetBSD: dirs.c,v 1.40 2003/11/05 22:27:16 fvdl Exp $"); +__RCSID("$NetBSD: dirs.c,v 1.41 2004/10/22 22:38:38 bouyer Exp $"); #endif #endif /* not lint */ @@ -649,7 +649,12 @@ setdirmodes(flags) (void) utimes(cp, node.mtimep); (void) chown(cp, node.uid, node.gid); (void) chmod(cp, node.mode); - (void) chflags(cp, node.flags); + if (Mtreefile) { + writemtree(cp, "dir", + node.uid, node.gid, node.mode, + node.flags); + } else + (void) chflags(cp, node.flags); } ep->e_flags &= ~NEW; } diff --git a/sbin/restore/extern.h b/sbin/restore/extern.h index 04424105f95b..2470c3a08ea6 100644 --- a/sbin/restore/extern.h +++ b/sbin/restore/extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: extern.h,v 1.10 2004/07/27 02:17:06 enami Exp $ */ +/* $NetBSD: extern.h,v 1.11 2004/10/22 22:38:38 bouyer Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -101,6 +101,8 @@ void swabst __P((u_char *, u_char *)); void treescan __P((char *, ino_t, long (*)(char *, ino_t, int))); ino_t upperbnd __P((ino_t)); long verifyfile __P((char *, ino_t, int)); +void writemtree __P((const char *, const char *, const uid_t, + const gid_t, const mode_t, const u_long)); void xtrnull __P((char *, long)); /* From ../dump/dumprmt.c */ diff --git a/sbin/restore/main.c b/sbin/restore/main.c index 5f79ac700957..46be3e2ddbf4 100644 --- a/sbin/restore/main.c +++ b/sbin/restore/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.26 2004/07/27 14:20:11 wiz Exp $ */ +/* $NetBSD: main.c,v 1.27 2004/10/22 22:38:38 bouyer Exp $ */ /* * Copyright (c) 1983, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\ #if 0 static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/4/95"; #else -__RCSID("$NetBSD: main.c,v 1.26 2004/07/27 14:20:11 wiz Exp $"); +__RCSID("$NetBSD: main.c,v 1.27 2004/10/22 22:38:38 bouyer Exp $"); #endif #endif /* not lint */ @@ -77,6 +77,8 @@ size_t pagesize; FILE *terminal; char *tmpdir; +FILE *Mtreefile = NULL; + int main __P((int, char *[])); static void obsolete __P((int *, char **[])); static void usage __P((void)); @@ -100,7 +102,7 @@ main(argc, argv) if ((tmpdir = getenv("TMPDIR")) == NULL) tmpdir = _PATH_TMP; obsolete(&argc, &argv); - while ((ch = getopt(argc, argv, "b:cD:df:himNRrs:tuvxy")) != -1) + while ((ch = getopt(argc, argv, "b:cD:df:himM:NRrs:tuvxy")) != -1) switch (ch) { case 'b': /* Change default tape blocksize. */ @@ -146,6 +148,11 @@ main(argc, argv) case 'N': Nflag = 1; break; + case 'M': + Mtreefile = fopen(optarg, "a"); + if (Mtreefile == NULL) + err(1, "can't open %s", optarg); + break; case 's': /* Dumpnum (skip to) for multifile dump tapes. */ dumpnum = strtol(optarg, &p, 10); @@ -300,19 +307,19 @@ usage() (void)fprintf(stderr, "usage: %s -i [-cdhmvyN] [-b bsize] [-D algorithm] " - "[-f file] [-s fileno]\n", progname); + "[-f file] [-s fileno] [-M mtreefile]\n", progname); (void)fprintf(stderr, " %s -R [-cdvyN] [-b bsize] [-D algorithm] [-f file] " - "[-s fileno]\n", progname); + "[-s fileno] [-M mtreefile]\n", progname); (void)fprintf(stderr, " %s -r [-cdvyN] [-b bsize] [-D algorithm] [-f file] " - "[-s fileno]\n", progname); + "[-s fileno] [-M mtreefile]\n", progname); (void)fprintf(stderr, " %s -t [-cdhvy] [-b bsize] [-D algorithm] [-f file]\n" " [-s fileno] [file ...]\n", progname); (void)fprintf(stderr, " %s -x [-cdhmvyN] [-b bsize] [-D algorithm] [-f file]\n" - " [-s fileno] [file ...]\n", progname); + " [-s fileno] [-M mtreefile] [file ...]\n", progname); exit(1); } diff --git a/sbin/restore/restore.8 b/sbin/restore/restore.8 index 3b3ed885f0b8..6169ec2f6d4e 100644 --- a/sbin/restore/restore.8 +++ b/sbin/restore/restore.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: restore.8,v 1.43 2004/07/27 14:20:11 wiz Exp $ +.\" $NetBSD: restore.8,v 1.44 2004/10/22 22:38:38 bouyer Exp $ .\" .\" Copyright (c) 1985, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -43,6 +43,7 @@ .Op Fl b Ar bsize .Op Fl D Ar algorithm .Op Fl f Ar file +.Op Fl M Ar mfile .Op Fl s Ar fileno .Nm .Fl R @@ -50,6 +51,7 @@ .Op Fl b Ar bsize .Op Fl D Ar algorithm .Op Fl f Ar file +.Op Fl M Ar mfile .Op Fl s Ar fileno .Nm .Fl r @@ -57,6 +59,7 @@ .Op Fl b Ar bsize .Op Fl D Ar algorithm .Op Fl f Ar file +.Op Fl M Ar mfile .Op Fl s Ar fileno .Nm .Fl t @@ -71,6 +74,7 @@ .Op Fl b Ar bsize .Op Fl D Ar algorithm .Op Fl f Ar file +.Op Fl M Ar mfile .Op Fl s Ar fileno .Op Ar .Pp @@ -341,6 +345,15 @@ Extract by inode numbers rather than by file name. This is useful if only a few files are being extracted, and one wants to avoid regenerating the complete pathname to the file. +.It Fl M Ar mfile +Do not set the file flags on restore, instead append a +.Xr mtree 8 +specification to +.Ar mfile +which can be used later to restore file flags: +.Bd -literal -offset indent +sort mfile | mtree -e -i -u +.Ed .It Fl s Ar fileno Read from the specified .Ar fileno diff --git a/sbin/restore/restore.h b/sbin/restore/restore.h index 21526df7a073..60bdb2ad6b10 100644 --- a/sbin/restore/restore.h +++ b/sbin/restore/restore.h @@ -1,4 +1,4 @@ -/* $NetBSD: restore.h,v 1.15 2004/07/27 02:17:06 enami Exp $ */ +/* $NetBSD: restore.h,v 1.16 2004/10/22 22:38:38 bouyer Exp $ */ /* * Copyright (c) 1983, 1993 @@ -66,6 +66,7 @@ extern FILE *terminal; /* file descriptor for the terminal input */ extern char *tmpdir; /* where to store temporary files */ extern int oldinofmt; /* reading tape with old format inodes */ extern int Bcvt; /* need byte swapping on inodes and dirs */ +extern FILE *Mtreefile; /* file descriptor for the mtree file */ struct digest_desc { const char *dd_name; diff --git a/sbin/restore/tape.c b/sbin/restore/tape.c index 68ac82a23088..bd6015b9c9dd 100644 --- a/sbin/restore/tape.c +++ b/sbin/restore/tape.c @@ -1,4 +1,4 @@ -/* $NetBSD: tape.c,v 1.50 2004/07/27 02:17:06 enami Exp $ */ +/* $NetBSD: tape.c,v 1.51 2004/10/22 22:38:38 bouyer Exp $ */ /* * Copyright (c) 1983, 1993 @@ -39,7 +39,7 @@ #if 0 static char sccsid[] = "@(#)tape.c 8.9 (Berkeley) 5/1/95"; #else -__RCSID("$NetBSD: tape.c,v 1.50 2004/07/27 02:17:06 enami Exp $"); +__RCSID("$NetBSD: tape.c,v 1.51 2004/10/22 22:38:38 bouyer Exp $"); #endif #endif /* not lint */ @@ -52,6 +52,7 @@ __RCSID("$NetBSD: tape.c,v 1.50 2004/07/27 02:17:06 enami Exp $"); #include #include +#include #include #include #include @@ -588,6 +589,21 @@ printdumpinfo() spcl.c_level, spcl.c_filesys, *spcl.c_host? spcl.c_host: "[unknown]", spcl.c_dev); fprintf(stderr, "Label: %s\n", spcl.c_label); + + if (Mtreefile) { + ttime = spcl.c_date; + fprintf(Mtreefile, "#Dump date: %s", ctime(&ttime)); + ttime = spcl.c_ddate; + fprintf(Mtreefile, "#Dumped from: %s", + (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&ttime)); + fprintf(Mtreefile, "#Level %d dump of %s on %s:%s\n", + spcl.c_level, spcl.c_filesys, + *spcl.c_host? spcl.c_host: "[unknown]", spcl.c_dev); + fprintf(Mtreefile, "#Label: %s\n", spcl.c_label); + fprintf(Mtreefile, "/set uname=root gname=wheel\n"); + if (ferror(Mtreefile)) + err(1, "error writing to mtree file"); + } } int @@ -662,7 +678,11 @@ extractfile(name) (void) lutimes(name, mtimep); (void) lchown(name, uid, gid); (void) lchmod(name, mode); - (void) lchflags(name, flags); + if (Mtreefile) { + writemtree(name, "link", + uid, gid, mode, flags); + } else + (void) lchflags(name, flags); return (GOOD); } return (FAIL); @@ -689,7 +709,13 @@ extractfile(name) (void) utimes(name, mtimep); (void) chown(name, uid, gid); (void) chmod(name, mode); - (void) chflags(name, flags); + if (Mtreefile) { + writemtree(name, + ((mode & (S_IFBLK | IFCHR)) == IFBLK) ? + "block" : "char", + uid, gid, mode, flags); + } else + (void) chflags(name, flags); return (GOOD); case IFIFO: @@ -712,7 +738,11 @@ extractfile(name) (void) utimes(name, mtimep); (void) chown(name, uid, gid); (void) chmod(name, mode); - (void) chflags(name, flags); + if (Mtreefile) { + writemtree(name, "fifo", + uid, gid, mode, flags); + } else + (void) chflags(name, flags); return (GOOD); case IFREG: @@ -744,7 +774,11 @@ extractfile(name) (void) futimes(ofile, mtimep); (void) fchown(ofile, uid, gid); (void) fchmod(ofile, mode); - (void) fchflags(ofile, flags); + if (Mtreefile) { + writemtree(name, "file", + uid, gid, mode, flags); + } else + (void) fchflags(ofile, flags); (void) close(ofile); return (GOOD); } diff --git a/sbin/restore/utilities.c b/sbin/restore/utilities.c index a2529ab8a68e..9c664f6aac4b 100644 --- a/sbin/restore/utilities.c +++ b/sbin/restore/utilities.c @@ -1,4 +1,4 @@ -/* $NetBSD: utilities.c,v 1.17 2003/08/07 10:04:38 agc Exp $ */ +/* $NetBSD: utilities.c,v 1.18 2004/10/22 22:38:38 bouyer Exp $ */ /* * Copyright (c) 1983, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)utilities.c 8.5 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: utilities.c,v 1.17 2003/08/07 10:04:38 agc Exp $"); +__RCSID("$NetBSD: utilities.c,v 1.18 2004/10/22 22:38:38 bouyer Exp $"); #endif #endif /* not lint */ @@ -44,6 +44,7 @@ __RCSID("$NetBSD: utilities.c,v 1.17 2003/08/07 10:04:38 agc Exp $"); #include #include +#include #include #include #include @@ -423,3 +424,48 @@ panic(const char *fmt, ...) exit(1); } } + +void +writemtree(const char *name, const char *type, + const uid_t uid, const gid_t gid, const mode_t mode, const u_long flags) +{ + char *sep = ""; + if ((name[0] != '.') || (name[1] != '/' && name[1] != '\0')) + fprintf(Mtreefile, "./"); + fprintf(Mtreefile, "%s type=%s uid=%d gid=%d mode=%#4.4o", + name, type, uid, gid, + mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISTXT)); + if (flags != 0) + fprintf(Mtreefile, " flags="); + if (flags & UF_NODUMP) { + fprintf(Mtreefile, "nodump"); + sep=","; + } + if (flags & UF_IMMUTABLE) { + fprintf(Mtreefile, "%suchg", sep); + sep=","; + } + if (flags & UF_APPEND) { + fprintf(Mtreefile, "%suappnd", sep); + sep=","; + } + if (flags & UF_OPAQUE) { + fprintf(Mtreefile, "%sopaque", sep); + sep=","; + } + if (flags & SF_ARCHIVED) { + fprintf(Mtreefile, "%sarch", sep); + sep=","; + } + if (flags & SF_IMMUTABLE) { + fprintf(Mtreefile, "%sschg", sep); + sep=","; + } + if (flags & SF_APPEND) { + fprintf(Mtreefile, "%ssappnd", sep); + sep=","; + } + fprintf(Mtreefile, "\n"); + if (ferror(Mtreefile)) + err(1, "error writing to mtree file"); +}