X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Fdirs.c;h=2717f9421dc0b2588132e3682a9c9358299df867;hp=26c637bffb69bebb46a58df6bf5c0869d6da8bc9;hb=4a9a33ef6c2f09149c5ab3f89e42572ef38801e1;hpb=f30c53e5aacd10d449f01703b31a927c8a7a3134 diff --git a/restore/dirs.c b/restore/dirs.c index 26c637b..2717f94 100644 --- a/restore/dirs.c +++ b/restore/dirs.c @@ -42,7 +42,7 @@ #ifndef lint static const char rcsid[] = - "$Id: dirs.c,v 1.31 2005/01/24 10:32:14 stelian Exp $"; + "$Id: dirs.c,v 1.35 2008/04/17 15:16:47 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; @@ -666,7 +673,7 @@ setdirmodes(int flags) fprintf(stderr, "directory mode, owner, and times not set\n"); return; } - mf = fopen(modefile, "r"); + mf = FOPEN(modefile, "r"); if (mf == NULL) { warn("fopen"); fprintf(stderr, "cannot open mode file %s\n", modefile); @@ -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) @@ -697,6 +710,10 @@ setdirmodes(int flags) cp = myname(ep); (void) chown(cp, node.uid, node.gid); (void) chmod(cp, node.mode); + utimes(cp, node.timep); + if (node.xattr) + xattr_extract(cp, xattr); + ep->e_flags &= ~NEW; if (node.flags) #ifdef __linux__ (void) lsetflags(cp, node.flags); @@ -706,8 +723,6 @@ setdirmodes(int flags) (void) chflags(cp, node.flags); #endif #endif - utimes(cp, node.timep); - ep->e_flags &= ~NEW; } } if (ferror(mf)) @@ -732,7 +747,7 @@ comparedirmodes(void) fprintf(stderr, "directory mode, owner, and times not set\n"); return; } - mf = fopen(modefile, "r"); + mf = FOPEN(modefile, "r"); if (mf == NULL) { warn("fopen"); fprintf(stderr, "cannot open mode file %s\n", modefile); @@ -741,17 +756,23 @@ 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); } 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; @@ -790,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; } } @@ -874,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; @@ -898,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); } /*