From 72d6b3ce00a5d09ff8a30d649594ff54a7157f97 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Mon, 2 Jan 2006 16:18:56 -0700 Subject: [PATCH] Imported Debian patch 0.4b41-1 --- CHANGES | 21 +++- MCONFIG.in | 4 +- compat/include/compatlfs.h | 6 +- debian/changelog | 6 + debian/compat | 2 +- debian/control | 4 +- dump.lsm | 6 +- dump.spec | 7 +- dump/dump.8.in | 8 +- dump/tape.c | 4 +- restore/dirs.c | 4 +- restore/main.c | 27 +++-- restore/restore.8.in | 24 ++-- restore/restore.c | 8 +- restore/restore.h | 5 +- restore/symtab.c | 38 ++++--- restore/tape.c | 6 +- restore/utilities.c | 6 +- restore/xattr.c | 220 +++++++++++++++++++++++++++++++++++-- 19 files changed, 335 insertions(+), 71 deletions(-) diff --git a/CHANGES b/CHANGES index c4d497d..7309b2a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,23 @@ -$Id: CHANGES,v 1.275 2005/05/02 15:13:40 stelian Exp $ +$Id: CHANGES,v 1.282 2006/01/02 15:24:22 stelian Exp $ + +Changes between versions 0.4b40 and 0.4b41 (released January 2, 2006) +===================================================================== + +1. Fix restore of dumped Access Control Lists. The previous + code for EA works fine, but ACLs needed conversion from the + ext2/3 disk format to posix_acl format before restoring. + +2. Fix some issues with restoration of EA on big endian + platforms. + +3. Fix restore when the symtab is over 2GB in size. + +4. Made the directory hash indexing an optional feature, + accessible by the '-H' option of restore, and disable it + by default. + +5. Fixed dump to not include extended attributes information + in the toc (archive) file which confused restore -t. Changes between versions 0.4b39 and 0.4b40 (released May 2, 2005) ================================================================= diff --git a/MCONFIG.in b/MCONFIG.in index 8bce8b0..e279943 100644 --- a/MCONFIG.in +++ b/MCONFIG.in @@ -1,5 +1,5 @@ -VERSION= 0.4b40 -DATE= May 2, 2005 +VERSION= 0.4b41 +DATE= January 2, 2006 AR= @AR@ CC= @CC@ diff --git a/compat/include/compatlfs.h b/compat/include/compatlfs.h index fe7db5f..b5cb0a7 100644 --- a/compat/include/compatlfs.h +++ b/compat/include/compatlfs.h @@ -3,7 +3,7 @@ * dump and restore backup suit * Stelian Pop - Alcôve , 2000-2002 * - * $Id: compatlfs.h,v 1.5 2004/03/29 13:57:29 stelian Exp $ + * $Id: compatlfs.h,v 1.6 2005/07/07 08:47:16 stelian Exp $ */ /*- @@ -44,8 +44,10 @@ #define _LARGEFILE64_SOURCE #define OPEN open64 +#define FOPEN fopen64 #define LSEEK lseek64 #define STAT stat64 +#define FSTAT fstat64 #define LSTAT lstat64 #define FTRUNCATE ftruncate64 #define OFF_T __off64_t @@ -55,8 +57,10 @@ #else #define OPEN open +#define FOPEN fopen #define LSEEK lseek #define STAT stat +#define FSTAT fstat #define LSTAT lstat #define FTRUNCATE ftruncate #define OFF_T off_t diff --git a/debian/changelog b/debian/changelog index fa233d4..f3f818c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +dump (0.4b41-1) unstable; urgency=low + + * new upstream version + + -- Bdale Garbee Mon, 2 Jan 2006 16:18:56 -0700 + dump (0.4b40-1) unstable; urgency=low * new upstream version, closes: #289210, #291644, #307423 diff --git a/debian/compat b/debian/compat index b8626c4..7ed6ff8 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -4 +5 diff --git a/debian/control b/debian/control index 75dad1a..e530b6d 100644 --- a/debian/control +++ b/debian/control @@ -2,8 +2,8 @@ Source: dump Section: utils Priority: optional Maintainer: Bdale Garbee -Build-Depends: autoconf, comerr-dev, debhelper (>= 4.1.16), e2fslibs-dev, libbz2-dev, libreadline5-dev | libreadline-dev, zlib1g-dev, libblkid-dev, uuid-dev -Standards-Version: 3.6.2.1 +Build-Depends: autoconf, comerr-dev, debhelper (>= 5), e2fslibs-dev, libbz2-dev, libreadline5-dev | libreadline-dev, zlib1g-dev, libblkid-dev, uuid-dev +Standards-Version: 3.6.2.2 Package: dump Architecture: any diff --git a/dump.lsm b/dump.lsm index 043c2e2..835bb0b 100644 --- a/dump.lsm +++ b/dump.lsm @@ -1,13 +1,13 @@ Begin3 Title: dump and restore for Ext2fs -Version: 0.4b40 -Entered-date: 01MAY05 +Version: 0.4b41 +Entered-date: 02JAN06 Description: Port of the 4.4BSD dump and restore backup suite Keywords: backup, filesystem, Ext2fs Author: University of California, Berkeley Maintained-by: stelian@popies.net (Stelian Pop) Primary-site: http://dump.sourceforge.net/ - 0kB dump-0.4b40.tar.gz + 0kB dump-0.4b41.tar.gz 0 dump.lsm Original-site: ftp.freebsd.org /pub/bsd-sources/4.4BSD-Lite2/sbin dump/* diff --git a/dump.spec b/dump.spec index 6d90193..8276ecd 100644 --- a/dump.spec +++ b/dump.spec @@ -4,14 +4,14 @@ Summary: Programs for backing up and restoring ext2/ext3 filesystems. Name: dump -Version: 0.4b40 +Version: 0.4b41 Release: 1 License: BSD URL: http://dump.sourceforge.net Group: Applications/Archiving Source: dump-%{version}.tar.gz BuildPrereq: e2fsprogs-devel >= 1.18 -BuildPrereq: libtermcap-devel, readline-devel +BuildPrereq: libtermcap-devel, readline-devel, ncurses-devel BuildPrereq: zlib-devel, bzip2-devel Requires: rmt BuildRoot: %{_tmppath}/%{name}-root @@ -136,6 +136,9 @@ rm -rf %{buildroot} %{_sbindir}/rrestore.static %changelog +* Mon Jan 2 2006 Stelian Pop +- dump 0.4b41 released, first packaging. + * Fri Jan 21 2005 Stelian Pop - dump 0.4b39 released, first packaging. diff --git a/dump/dump.8.in b/dump/dump.8.in index a6bf3f0..555b7ac 100644 --- a/dump/dump.8.in +++ b/dump/dump.8.in @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dump.8.in,v 1.57 2004/07/13 08:17:32 stelian Exp $ +.\" $Id: dump.8.in,v 1.58 2005/06/01 13:44:35 stelian Exp $ .\" .TH DUMP 8 "version __VERSION__ of __DATE__" BSD "System management commands" .SH NAME @@ -283,6 +283,12 @@ Inodes which are either directories or have been modified since the last dump are saved in a regular way. Uses of this flag must be consistent, meaning that either every dump in an incremental dump set have the flag, or no one has it. .IP +If you use this option, be aware that many programs that unpack +files from archives (e.g. tar, rpm, unzip, dpkg) may set files' +mtimes to dates in the past. Files installed in this way may not be +dumped correctly using "dump -m" if the modified mtime is earlier +than the previous level dump. +.IP Tapes written using such 'metadata only' inodes will not be compatible with the BSD tape format or older versions of .B restore. diff --git a/dump/tape.c b/dump/tape.c index 89f630d..ebee4d8 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.88 2005/03/02 08:46:55 stelian Exp $"; + "$Id: tape.c,v 1.89 2005/08/20 21:00:48 stelian Exp $"; #endif /* not lint */ #include @@ -246,7 +246,7 @@ writerec(const void *dp, int isspcl) /* Need to write it to the archive file */ if (! AfileActive && isspcl && (spcl.c_type == TS_END)) AfileActive = 1; - if (AfileActive && Afile >= 0) { + if (AfileActive && Afile >= 0 && !(spcl.c_flags & DR_EXTATTRIBUTES)) { /* When we dump an inode which is not a directory, * it means we ended the archive contents */ if (isspcl && (spcl.c_type == TS_INODE) && diff --git a/restore/dirs.c b/restore/dirs.c index b049f49..88dfc69 100644 --- a/restore/dirs.c +++ b/restore/dirs.c @@ -42,7 +42,7 @@ #ifndef lint static const char rcsid[] = - "$Id: dirs.c,v 1.32 2005/05/02 15:10:46 stelian Exp $"; + "$Id: dirs.c,v 1.33 2005/05/28 18:34:47 stelian Exp $"; #endif /* not lint */ #include @@ -769,10 +769,10 @@ comparedirmodes(void) if (ep == NULL) { panic("cannot find directory inode %d\n", node.ino); } else { - cp = myname(ep); struct STAT sb; unsigned long newflags; + cp = myname(ep); if (LSTAT(cp, &sb) < 0) { warn("unable to stat %s", cp); do_compare_error; diff --git a/restore/main.c b/restore/main.c index dfbe8c6..496391d 100644 --- a/restore/main.c +++ b/restore/main.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: main.c,v 1.49 2005/01/14 13:04:56 stelian Exp $"; + "$Id: main.c,v 1.50 2005/07/07 09:16:08 stelian Exp $"; #endif /* not lint */ #include @@ -113,6 +113,7 @@ static const char *stdin_opt = NULL; char *bot_script = NULL; dump_ino_t volinfo[TP_NINOS]; int wdfd; +int dirhash_size = 1; #ifdef USE_QFA FILE *gTapeposfp; @@ -177,7 +178,7 @@ main(int argc, char *argv[]) ; obsolete(&argc, &argv); while ((ch = getopt(argc, argv, - "aA:b:CcdD:f:F:hi" + "aA:b:CcdD:f:F:hH:i" #ifdef KERBEROS "k" #endif @@ -227,6 +228,13 @@ main(int argc, char *argv[]) case 'h': hflag = 0; break; + case 'H': + dirhash_size = strtol(optarg, &p, 10); + if (*p) + errx(1, "illegal hash size -- %s", optarg); + if (dirhash_size < 1) + errx(1, "hash size must be greater than 0"); + break; #ifdef KERBEROS case 'k': dokerberos = 1; @@ -679,21 +687,21 @@ usage(void) fprintf(stderr, "usage:" - "\t%s -C [-cd" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file]\n" + "\t%s -C [-cdH" kerbflag "lMvVy] [-b blocksize] [-D filesystem] [-f file]\n" "\t%s [-F script] [-L limit] [-s fileno]\n" - "\t%s -i [-acdh" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n" + "\t%s -i [-acdhH" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n" "\t%s [-F script] " qfaflag "[-s fileno]\n" #ifdef USE_QFA - "\t%s -P file [-acdh" kerbflag "lmMuvVy] [-A file] [-b blocksize]\n" + "\t%s -P file [-acdhH" kerbflag "lmMuvVy] [-A file] [-b blocksize]\n" "\t%s [-f file] [-F script] [-s fileno] [-X filelist] [file ...]\n" #endif - "\t%s -r [-cd" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n" + "\t%s -r [-cdH" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n" "\t%s [-s fileno] [-T directory]\n" - "\t%s -R [-cd" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n" + "\t%s -R [-cdH" kerbflag "lMuvVy] [-b blocksize] [-f file] [-F script]\n" "\t%s [-s fileno] [-T directory]\n" - "\t%s -t [-cdh" kerbflag "lMuvVy] [-A file] [-b blocksize] [-f file]\n" + "\t%s -t [-cdhH" kerbflag "lMuvVy] [-A file] [-b blocksize] [-f file]\n" "\t%s [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n" - "\t%s -x [-acdh" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n" + "\t%s -x [-acdhH" kerbflag "lmMouvVy] [-A file] [-b blocksize] [-f file]\n" "\t%s [-F script] " qfaflag "[-s fileno] [-X filelist] [file ...]\n", __progname, white, __progname, white, @@ -742,6 +750,7 @@ obsolete(int *argcp, char **argvp[]) case 'D': case 'f': case 'F': + case 'H': case 'L': case 'Q': case 's': diff --git a/restore/restore.8.in b/restore/restore.8.in index 1d92342..9f813ca 100644 --- a/restore/restore.8.in +++ b/restore/restore.8.in @@ -25,14 +25,14 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: restore.8.in,v 1.32 2004/07/13 08:17:32 stelian Exp $ +.\" $Id: restore.8.in,v 1.33 2005/07/07 09:16:08 stelian Exp $ .\" .TH RESTORE 8 "version __VERSION__ of __DATE__" BSD "System management commands" .SH NAME restore \- restore files or file systems from backups made with dump .SH SYNOPSIS .B restore \-C -[\fB\-cdklMvVy\fR] +[\fB\-cdHklMvVy\fR] [\fB\-b \fIblocksize\fR] [\fB\-D \fIfilesystem\fR] [\fB\-f \fIfile\fR] @@ -42,7 +42,7 @@ restore \- restore files or file systems from backups made with dump [\fB\-T \fIdirectory\fR] .PP .B restore \-i -[\fB\-acdhklmMNouvVy\fR] +[\fB\-acdhHklmMNouvVy\fR] [\fB\-A \fIfile\fR] [\fB\-b \fIblocksize\fR] [\fB\-f \fIfile\fR] @@ -53,7 +53,7 @@ restore \- restore files or file systems from backups made with dump .PP .B restore \-P .I file -[\fB\-acdhklmMNuvVy\fR] +[\fB\-acdhHklmMNuvVy\fR] [\fB\-A \fIfile\fR] [\fB\-b \fIblocksize\fR] [\fB\-f \fIfile\fR] @@ -64,7 +64,7 @@ restore \- restore files or file systems from backups made with dump [ \fIfile ... \fR] .PP .B restore \-R -[\fB\-cdklMNuvVy\fR] +[\fB\-cdHklMNuvVy\fR] [\fB\-b \fIblocksize\fR] [\fB\-f \fIfile\fR] [\fB\-F \fIscript\fR] @@ -72,7 +72,7 @@ restore \- restore files or file systems from backups made with dump [\fB\-T \fIdirectory\fR] .PP .B restore \-r -[\fB\-cdklMNuvVy\fR] +[\fB\-cdHklMNuvVy\fR] [\fB\-b \fIblocksize\fR] [\fB\-f \fIfile\fR] [\fB\-F \fIscript\fR] @@ -80,7 +80,7 @@ restore \- restore files or file systems from backups made with dump [\fB\-T \fIdirectory\fR] .PP .B restore \-t -[\fB\-cdhklMNuvVy\fR] +[\fB\-cdhHklMNuvVy\fR] [\fB\-A \fIfile\fR] [\fB\-b \fIblocksize\fR] [\fB\-f \fIfile\fR] @@ -92,7 +92,7 @@ restore \- restore files or file systems from backups made with dump [ \fIfile ... \fR] .PP .B restore \-x -[\fB\-adchklmMNouvVy\fR] +[\fB\-adchHklmMNouvVy\fR] [\fB\-A \fIfile\fR] [\fB\-b \fIblocksize\fR] [\fB\-f \fIfile\fR] @@ -375,6 +375,14 @@ script. Extract the actual directory, rather than the files that it references. This prevents hierarchical restoration of complete subtrees from the dump. .TP +.BI \-H " hash_size" +Use a hashtable having the specified number of entries for storing the +directories entries instead of a linked list. This hashtable will +considerably speed up inode lookups (visible especialy in interactive +mode when adding/removing files from the restore list), but at the +price of much more memory usage. The default value is 1, meaning no +hashtable is used. +.TP .B \-k Use Kerberos authentication when contacting the remote tape server. (Only available if this options was enabled when diff --git a/restore/restore.c b/restore/restore.c index 94e0bb6..67a8465 100644 --- a/restore/restore.c +++ b/restore/restore.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: restore.c,v 1.36 2005/03/18 22:12:55 stelian Exp $"; + "$Id: restore.c,v 1.37 2005/07/07 09:16:08 stelian Exp $"; #endif /* not lint */ #include @@ -581,7 +581,7 @@ findunreflinks(void) continue; if (ep->e_entries == NULL) continue; - for (j = 0; j < DIRHASH_SIZE; j++) { + for (j = 0; j < dirhash_size; j++) { for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) { if (np->e_flags == 0) { Dprintf(stdout, @@ -599,7 +599,7 @@ findunreflinks(void) for (ep = removelist; ep != NULL; ep = ep->e_next) { if (ep->e_entries == NULL) continue; - for (j = 0; j < DIRHASH_SIZE; j++) { + for (j = 0; j < dirhash_size; j++) { for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) { if (np->e_type == LEAF) { if (np->e_flags != 0) @@ -638,7 +638,7 @@ removeoldnodes(void) int docont = 0; if (ep->e_entries != NULL) { int i; - for (i = 0; i < DIRHASH_SIZE; i++) { + for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i] != NULL) { prev = &ep->e_next; docont = 1; diff --git a/restore/restore.h b/restore/restore.h index 4f5236f..3d2a5de 100644 --- a/restore/restore.h +++ b/restore/restore.h @@ -5,7 +5,7 @@ * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 2000-2002 * - * $Id: restore.h,v 1.32 2005/05/02 15:10:46 stelian Exp $ + * $Id: restore.h,v 1.33 2005/07/07 09:16:08 stelian Exp $ */ /* @@ -92,8 +92,7 @@ extern int compare_errors; /* did we encounter any compare errors? */ extern char filesys[NAMELEN];/* name of dumped filesystem */ extern dump_ino_t volinfo[]; /* which inode on which volume archive info */ extern int wdfd; /* original working directory */ - -#define DIRHASH_SIZE 1024 +extern int dirhash_size; /* size of the directory hash table */ /* * Each file in the file system is described by one of these entries diff --git a/restore/symtab.c b/restore/symtab.c index b69259a..7e56057 100644 --- a/restore/symtab.c +++ b/restore/symtab.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: symtab.c,v 1.25 2005/03/30 13:34:00 stelian Exp $"; + "$Id: symtab.c,v 1.27 2005/07/07 09:16:08 stelian Exp $"; #endif /* not lint */ /* @@ -50,6 +50,7 @@ static const char rcsid[] = */ #include +#include #include #include @@ -117,7 +118,7 @@ dir_hash(char *name) hash1 = hash0; hash0 = hash; } - return hash0 % DIRHASH_SIZE; + return hash0 % dirhash_size; } /* @@ -219,7 +220,7 @@ lookupname(char *name) /* search all hash lists for renamed inodes */ if (ep == NULL) { int j; - for (j = 0; j < DIRHASH_SIZE; j++) { + for (j = 0; j < dirhash_size; j++) { ep = oldep->e_entries[j]; for ( ; ep != NULL; ep = ep->e_sibling) if (strcmp(ep->e_name, buf) == 0) @@ -306,7 +307,7 @@ addentry(char *name, dump_ino_t inum, int type) } np->e_type = type & ~LINK; if (type & NODE) { - np->e_entries = calloc(1, DIRHASH_SIZE * sizeof(struct entry *)); + np->e_entries = calloc(1, dirhash_size * sizeof(struct entry *)); if (np->e_entries == NULL) panic("unable to allocate directory entries\n"); } @@ -356,7 +357,7 @@ freeentry(struct entry *ep) badentry(ep, "freeing referenced directory"); if (ep->e_entries != NULL) { int i; - for (i = 0; i < DIRHASH_SIZE; i++) { + for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i] != NULL) badentry(ep, "freeing non-empty directory"); } @@ -438,7 +439,7 @@ removeentry(struct entry *ep) /* search all hash lists for renamed inodes */ int j; - for (j = 0; j < DIRHASH_SIZE; j++) { + for (j = 0; j < dirhash_size; j++) { np = ep->e_parent; entry = np->e_entries[j]; if (entry == ep) { @@ -549,12 +550,12 @@ dumpsymtable(char *filename, long checkpt) long mynum = 1, stroff = 0, hashoff = 0; FILE *fd; struct symtableheader hdr; - struct entry *temphash[DIRHASH_SIZE]; + struct entry **temphash; Vprintf(stdout, "Check pointing the restore\n"); if (Nflag) return; - if ((fd = fopen(filename, "w")) == NULL) { + if ((fd = FOPEN(filename, "w")) == NULL) { warn("fopen"); panic("cannot create save file %s for symbol table\n", filename); @@ -574,19 +575,24 @@ dumpsymtable(char *filename, long checkpt) /* * Write out e_entries tables */ + temphash = calloc(1, dirhash_size * sizeof(struct entry *)); + if (temphash == NULL) + errx(1, "no memory for saving hashtable"); for (i = WINO; i <= maxino; i++) { for (ep = lookupino(i); ep != NULL; ep = ep->e_links) { if (ep->e_entries != NULL) { int j; - memcpy(temphash, ep->e_entries, DIRHASH_SIZE * sizeof(struct entry *)); - for (j = 0; j < DIRHASH_SIZE; j++) { + memcpy(temphash, ep->e_entries, dirhash_size * sizeof(struct entry *)); + for (j = 0; j < dirhash_size; j++) { if (temphash[j]) temphash[j] = (struct entry *)ep->e_entries[j]->e_index; } - fwrite(temphash, DIRHASH_SIZE, sizeof(struct entry *), fd); + fwrite(temphash, dirhash_size, sizeof(struct entry *), fd); } } } + free(temphash); + /* * Convert pointers to indexes, and output */ @@ -607,7 +613,7 @@ dumpsymtable(char *filename, long checkpt) (struct entry *)ep->e_sibling->e_index; if (ep->e_entries != NULL) { tep->e_entries = (struct entry **)hashoff; - hashoff += DIRHASH_SIZE * sizeof(struct entry *); + hashoff += dirhash_size * sizeof(struct entry *); } if (ep->e_next != NULL) tep->e_next = @@ -654,7 +660,7 @@ initsymtable(char *filename) struct entry *ep; struct entry *baseep, *lep; struct symtableheader hdr; - struct stat stbuf; + struct STAT stbuf; long i; int fd; @@ -669,11 +675,11 @@ initsymtable(char *filename) ep->e_flags |= NEW; return; } - if ((fd = open(filename, O_RDONLY, 0)) < 0) { + if ((fd = OPEN(filename, O_RDONLY, 0)) < 0) { warn("open"); errx(1, "cannot open symbol table file %s", filename); } - if (fstat(fd, &stbuf) < 0) { + if (FSTAT(fd, &stbuf) < 0) { warn("stat"); errx(1, "cannot stat symbol table file %s", filename); } @@ -736,7 +742,7 @@ initsymtable(char *filename) if (ep->e_type == NODE) { int i; ep->e_entries = (struct entry **)(base + hdr.stringsize + (long)ep->e_entries); - for (i = 0; i < DIRHASH_SIZE; i++) { + for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i]) ep->e_entries[i] = &baseep[(long)ep->e_entries[i]]; } diff --git a/restore/tape.c b/restore/tape.c index e60921b..c74e390 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -42,7 +42,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.89 2005/05/02 15:10:46 stelian Exp $"; + "$Id: tape.c,v 1.90 2005/06/08 13:24:11 stelian Exp $"; #endif /* not lint */ #include @@ -346,6 +346,7 @@ setup(void) #endif FLUSHTAPEBUF(); findtapeblksize(); + cvtflag = 0; if (gethead(&spcl) == FAIL) { blkcnt--; /* push back this block */ blksread--; @@ -2412,6 +2413,7 @@ findtapeblksize(void) errx(1, "Tape read error on first record"); memcpy(&spclpt, tapebuf, TP_BSIZE); + cvtflag = 0; if (converthead(&spclpt) == FAIL) { cvtflag++; if (converthead(&spclpt) == FAIL) { @@ -2622,7 +2624,7 @@ converthead(struct s_spcl *buf) if (checksum((int *)buf) == FAIL) return (FAIL); if (Bcvt) - swabst((u_char *)"8i4s31i528bi192b3i", (u_char *)buf); + swabst((u_char *)"8i4s1l29i528bi192b4i", (u_char *)buf); goto good; } memcpy(&u_ospcl.s_ospcl, buf, TP_BSIZE); diff --git a/restore/utilities.c b/restore/utilities.c index f17bd9c..4dbc13f 100644 --- a/restore/utilities.c +++ b/restore/utilities.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: utilities.c,v 1.28 2005/03/30 13:21:45 stelian Exp $"; + "$Id: utilities.c,v 1.29 2005/07/07 09:16:08 stelian Exp $"; #endif /* not lint */ #include @@ -189,7 +189,7 @@ removenode(struct entry *ep) badentry(ep, "removenode: not a node"); if (ep->e_entries != NULL) { int i; - for (i = 0; i < DIRHASH_SIZE; i++) { + for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i] != NULL) badentry(ep, "removenode: non-empty directory"); } @@ -378,7 +378,7 @@ badentry(struct entry *ep, const char *msg) fprintf(stderr, "sibling name: %s\n", myname(ep->e_sibling)); if (ep->e_entries != NULL) { int i; - for (i = 0; i < DIRHASH_SIZE; i++) { + for (i = 0; i < dirhash_size; i++) { if (ep->e_entries[i] != NULL) { fprintf(stderr, "next entry name: %s\n", myname(ep->e_entries[i])); break; diff --git a/restore/xattr.c b/restore/xattr.c index 6da39eb..290f8b9 100644 --- a/restore/xattr.c +++ b/restore/xattr.c @@ -29,7 +29,7 @@ #ifndef lint static const char rcsid[] = - "$Id: xattr.c,v 1.1 2005/05/02 15:10:47 stelian Exp $"; + "$Id: xattr.c,v 1.3 2005/06/08 13:24:12 stelian Exp $"; #endif /* not lint */ #include @@ -220,6 +220,187 @@ llistxattr(const char *path, char *list, size_t size) return SYSCALL(__NR_llistxattr, path, list, size); } +#define POSIX_ACL_XATTR_VERSION 0x0002 + +#define ACL_UNDEFINED_ID (-1) + +#define ACL_USER_OBJ (0x01) +#define ACL_USER (0x02) +#define ACL_GROUP_OBJ (0x04) +#define ACL_GROUP (0x08) +#define ACL_MASK (0x10) +#define ACL_OTHER (0x20) + +typedef struct { + u_int16_t e_tag; + u_int16_t e_perm; + u_int32_t e_id; +} posix_acl_xattr_entry; + +typedef struct { + u_int32_t a_version; + posix_acl_xattr_entry a_entries[0]; +} posix_acl_xattr_header; + +static inline size_t +posix_acl_xattr_size(int count) +{ + return (sizeof(posix_acl_xattr_header) + + (count * sizeof(posix_acl_xattr_entry))); +} + +struct posix_acl_entry { + short e_tag; + unsigned short e_perm; + unsigned int e_id; +}; + +struct posix_acl { + unsigned int a_count; + struct posix_acl_entry a_entries[0]; +}; + +#define EXT3_ACL_VERSION 0x0001 + +typedef struct { + u_int16_t e_tag; + u_int16_t e_perm; + u_int32_t e_id; +} ext3_acl_entry; + +typedef struct { + u_int16_t e_tag; + u_int16_t e_perm; +} ext3_acl_entry_short; + +typedef struct { + u_int32_t a_version; +} ext3_acl_header; + +static inline int ext3_acl_count(size_t size) +{ + ssize_t s; + size -= sizeof(ext3_acl_header); + s = size - 4 * sizeof(ext3_acl_entry_short); + if (s < 0) { + if (size % sizeof(ext3_acl_entry_short)) + return -1; + return size / sizeof(ext3_acl_entry_short); + } else { + if (s % sizeof(ext3_acl_entry)) + return -1; + return s / sizeof(ext3_acl_entry) + 4; + } +} + +int +posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size) { + posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer; + posix_acl_xattr_entry *ext_entry = ext_acl->a_entries; + int real_size, n; + + real_size = posix_acl_xattr_size(acl->a_count); + if (!buffer) + return real_size; + if (real_size > size) { + fprintf(stderr, "ACL: not enough space to convert (%d %d)\n", real_size, size); + return -1; + } + + ext_acl->a_version = POSIX_ACL_XATTR_VERSION; +#if BYTE_ORDER == BIG_ENDIAN + swabst("1i", (u_char *)ext_acl); +#endif + + for (n=0; n < acl->a_count; n++, ext_entry++) { + ext_entry->e_tag = acl->a_entries[n].e_tag; + ext_entry->e_perm = acl->a_entries[n].e_perm; + ext_entry->e_id = acl->a_entries[n].e_id; +#if BYTE_ORDER == BIG_ENDIAN + swabst("2s1i", (u_char *)ext_entry); +#endif + } + return real_size; +} + +static struct posix_acl * +ext3_acl_from_disk(const void *value, size_t size) +{ + const char *end = (char *)value + size; + int n, count; + struct posix_acl *acl; + + if (!value) + return NULL; + if (size < sizeof(ext3_acl_header)) { + fprintf(stderr, "ACL size too little\n"); + return NULL; + } +#if BYTE_ORDER == BIG_ENDIAN + swabst("1i", (u_char *)value); +#endif + if (((ext3_acl_header *)value)->a_version != EXT3_ACL_VERSION) { + fprintf(stderr, "ACL version unknown\n"); + return NULL; + } + value = (char *)value + sizeof(ext3_acl_header); + count = ext3_acl_count(size); + if (count < 0) { + fprintf(stderr, "ACL bad count\n"); + return NULL; + } + if (count == 0) + return NULL; + acl = malloc(sizeof(struct posix_acl) + count * sizeof(struct posix_acl_entry)); + if (!acl) { + fprintf(stderr, "ACL malloc failed\n"); + return NULL; + } + acl->a_count = count; + + for (n=0; n < count; n++) { + ext3_acl_entry *entry = (ext3_acl_entry *)value; +#if BYTE_ORDER == BIG_ENDIAN + swabst("2s", (u_char *)entry); +#endif + if ((char *)value + sizeof(ext3_acl_entry_short) > end) + goto fail; + acl->a_entries[n].e_tag = entry->e_tag; + acl->a_entries[n].e_perm = entry->e_perm; + switch(acl->a_entries[n].e_tag) { + case ACL_USER_OBJ: + case ACL_GROUP_OBJ: + case ACL_MASK: + case ACL_OTHER: + value = (char *)value + sizeof(ext3_acl_entry_short); + acl->a_entries[n].e_id = ACL_UNDEFINED_ID; + break; + + case ACL_USER: + case ACL_GROUP: +#if BYTE_ORDER == BIG_ENDIAN + swabst("4b1i", (u_char *)entry); +#endif + value = (char *)value + sizeof(ext3_acl_entry); + if ((char *)value > end) + goto fail; + acl->a_entries[n].e_id = entry->e_id; + break; + + default: + goto fail; + } + } + if (value != end) + goto fail; + return acl; + +fail: + fprintf(stderr, "ACL bad entry\n"); + free(acl); + return NULL; +} + /* * Dump code starts here :) */ @@ -279,8 +460,9 @@ xattr_verify(char *buffer) end = buffer + XATTR_MAXSIZE; - if (Bcvt) - swabst("4i", (u_char *)buffer); +#if BYTE_ORDER == BIG_ENDIAN + swabst("4i", (u_char *)buffer); +#endif if (HDR(buffer)->h_magic != EXT2_XATTR_MAGIC && HDR(buffer)->h_magic != EXT2_XATTR_MAGIC2) { @@ -292,8 +474,9 @@ xattr_verify(char *buffer) /* check the on-disk data structure */ entry = FIRST_ENTRY(buffer); - if (Bcvt) - swabst("2b1s3i", (u_char *)entry); +#if BYTE_ORDER == BIG_ENDIAN + swabst("2b1s3i", (u_char *)entry); +#endif while (!IS_LAST_ENTRY(entry)) { struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(entry); @@ -302,8 +485,9 @@ xattr_verify(char *buffer) return FAIL; } entry = next; - if (Bcvt) - swabst("2b1s3i", (u_char *)entry); +#if BYTE_ORDER == BIG_ENDIAN + swabst("2b1s3i", (u_char *)entry); +#endif } return GOOD; } @@ -333,14 +517,19 @@ xattr_walk(char *buffer, int (*xattr_cb)(char *, char *, int, void *), void *pri entry = EXT2_XATTR_NEXT(entry)) { char name[XATTR_MAXSIZE], value[XATTR_MAXSIZE]; int off; + int convertacl = 0; switch (entry->e_name_index) { case EXT2_XATTR_INDEX_USER: strcpy(name, "user."); break; case EXT2_XATTR_INDEX_POSIX_ACL_ACCESS: + strcpy(name, "system.posix_acl_access"); + convertacl = 1; + break; case EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT: - strcpy(name, "system."); + strcpy(name, "system.posix_acl_default"); + convertacl = 1; break; case EXT2_XATTR_INDEX_TRUSTED: strcpy(name, "trusted."); @@ -360,9 +549,22 @@ xattr_walk(char *buffer, int (*xattr_cb)(char *, char *, int, void *), void *pri memcpy(name + off, entry->e_name, entry->e_name_len); name[off + entry->e_name_len] = '\0'; - memcpy(value, buffer + VALUE_OFFSET(buffer, entry), entry->e_value_size); + if (convertacl) { + struct posix_acl *acl; + int size; + + acl = ext3_acl_from_disk(value, entry->e_value_size); + if (!acl) + return FAIL; + size = posix_acl_to_xattr(acl, value, XATTR_MAXSIZE); + if (size < 0) + return FAIL; + entry->e_value_size = size; + free(acl); + } + if (xattr_cb(name, value, entry->e_value_size, private) != GOOD) return FAIL; } -- 2.30.2