X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Fdirs.c;h=b049f49007801c6caa8c70d755b38ecce9dbc860;hp=423fe6ea9e428fbe286b173dd34215a12530514b;hb=cca7148b36e60b4671518602ff9a7c2d0c22a7b2;hpb=a55ce9149e3f4a5f848a20b7593dbe8cd7b0bbd1 diff --git a/restore/dirs.c b/restore/dirs.c index 423fe6e..b049f49 100644 --- a/restore/dirs.c +++ b/restore/dirs.c @@ -42,7 +42,7 @@ #ifndef lint static const char rcsid[] = - "$Id: dirs.c,v 1.29 2004/12/15 11:00:01 stelian Exp $"; + "$Id: dirs.c,v 1.32 2005/05/02 15:10:46 stelian Exp $"; #endif /* not lint */ #include @@ -114,6 +114,7 @@ struct modeinfo { uid_t uid; gid_t gid; unsigned int flags; + char xattr; }; /* @@ -149,10 +150,10 @@ struct odirect { #if defined(__linux__) || defined(sunos) static struct inotab *allocinotab __P((dump_ino_t, OFF_T)); -static void savemodeinfo __P((dump_ino_t, struct new_bsd_inode *)); +static void savemodeinfo __P((dump_ino_t, struct new_bsd_inode *, char *)); #else static struct inotab *allocinotab __P((dump_ino_t, OFF_T)); -static void savemodeinfo __P((dump_ino_t, struct dinode *)); +static void savemodeinfo __P((dump_ino_t, struct dinode *, char *)); #endif static void dcvt __P((struct odirect *, struct direct *)); static void flushent __P((void)); @@ -186,6 +187,8 @@ extractdirs(int genmode) struct inotab *itp; struct direct nulldir; int fd; + char xattr[XATTR_MAXSIZE]; + int xattr_found = 0; dump_ino_t ino; Vprintf(stdout, "Extract directories from tape\n"); @@ -242,6 +245,7 @@ extractdirs(int genmode) memcpy(&ip, curfile.dip, sizeof(ip)); itp = allocinotab(ino, seekpt); getfile(putdir, xtrnull); + xattr_found = 0; while (spcl.c_flags & DR_EXTATTRIBUTES) { switch (spcl.c_extattributes) { case EXT_MACOSFNDRINFO: @@ -253,12 +257,15 @@ extractdirs(int genmode) skipfile(); break; case EXT_XATTR: - msg("EA/ACLs attributes not supported, skipping\n"); - skipfile(); + if (readxattr(xattr) == GOOD) + xattr_found = 1; break; } } - savemodeinfo(ino, &ip); + if (xattr_found) + savemodeinfo(ino, &ip, xattr); + else + savemodeinfo(ino, &ip, NULL); putent(&nulldir); flushent(); itp->t_size = seekpt - itp->t_seekpt; @@ -675,9 +682,15 @@ setdirmodes(int flags) } clearerr(mf); for (;;) { + char xattr[XATTR_MAXSIZE]; (void) fread((char *)&node, 1, sizeof(struct modeinfo), mf); if (feof(mf)) break; + if (node.xattr) { + (void) fread(xattr, 1, XATTR_MAXSIZE, mf); + if (feof(mf)) + break; + } ep = lookupino(node.ino); if (command == 'i' || command == 'x') { if (ep == NULL) @@ -707,6 +720,8 @@ setdirmodes(int flags) #endif #endif utimes(cp, node.timep); + if (node.xattr) + xattr_extract(cp, xattr); ep->e_flags &= ~NEW; } } @@ -741,9 +756,15 @@ comparedirmodes(void) } clearerr(mf); for (;;) { + char xattr[XATTR_MAXSIZE]; (void) fread((char *)&node, 1, sizeof(struct modeinfo), mf); if (feof(mf)) break; + if (node.xattr) { + (void) fread(xattr, 1, XATTR_MAXSIZE, mf); + if (feof(mf)) + break; + } ep = lookupino(node.ino); if (ep == NULL) { panic("cannot find directory inode %d\n", node.ino); @@ -753,7 +774,7 @@ comparedirmodes(void) unsigned long newflags; if (LSTAT(cp, &sb) < 0) { - warn("%s: does not exist", cp); + warn("unable to stat %s", cp); do_compare_error; continue; } @@ -777,8 +798,10 @@ comparedirmodes(void) } #ifdef __linux__ if (lgetflags(cp, &newflags) < 0) { - warn("%s: lgetflags failed", cp); - do_compare_error; + if (node.flags != 0) { + warn("%s: lgetflags failed", cp); + do_compare_error; + } } else { if (newflags != node.flags) { @@ -788,6 +811,14 @@ comparedirmodes(void) } } #endif + if (node.xattr) { + if (xattr_compare(cp, xattr) == FAIL) + do_compare_error; + } + else { + if (xattr_compare(cp, NULL) == FAIL) + do_compare_error; + } ep->e_flags &= ~NEW; } } @@ -872,9 +903,9 @@ allocinotab(dump_ino_t ino, OFF_T seekpt) static void #if defined(__linux__) || defined(sunos) -savemodeinfo(dump_ino_t ino, struct new_bsd_inode *dip) { +savemodeinfo(dump_ino_t ino, struct new_bsd_inode *dip, char *xattr) { #else -savemodeinfo(dump_ino_t ino, struct dinode *dip) { +savemodeinfo(dump_ino_t ino, struct dinode *dip, char *xattr) { #endif struct modeinfo node; @@ -896,8 +927,12 @@ savemodeinfo(dump_ino_t ino, struct dinode *dip) { node.flags = dip->di_flags; node.uid = dip->di_uid; node.gid = dip->di_gid; + node.xattr = xattr ? 1 : 0; if ( fwrite((char *)&node, 1, sizeof(struct modeinfo), mf) != sizeof(struct modeinfo) ) err(1,"cannot write to file %s", modefile); + if (xattr) + if ( fwrite(xattr, 1, XATTR_MAXSIZE, mf) != XATTR_MAXSIZE) + err(1,"cannot write to file %s", modefile); } /*