X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=dump%2Ftraverse.c;h=0a394aea1c304c3ab4ee66125639fb87ee2341b2;hp=fe5af09c2a839a74abcf76c5fdc3a065c91c42e4;hb=7af2fada292acbfb50d441c4be192690dff40283;hpb=979da669432983d6fedecbd004d6dd20f46486dc diff --git a/dump/traverse.c b/dump/traverse.c index fe5af09..0a394ae 100644 --- a/dump/traverse.c +++ b/dump/traverse.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: traverse.c,v 1.65 2005/01/25 13:33:44 stelian Exp $"; + "$Id: traverse.c,v 1.70 2010/06/10 12:01:30 stelian Exp $"; #endif /* not lint */ #include @@ -99,7 +99,8 @@ static int dirindir __P((dump_ino_t ino, daddr_t blkno, int level, long *size)); static void dmpindir __P((dump_ino_t ino, daddr_t blk, int level, fsizeT *size)); static int searchdir __P((dump_ino_t ino, daddr_t blkno, long size, long filesize)); #endif -static void mapfileino __P((dump_ino_t ino, struct dinode const *dp, long *tapesize, int *dirskipped)); +static void mapfileino __P((dump_ino_t ino, struct dinode const *dp, long long *tapesize, int *dirskipped)); +static void dump_xattr __P((dump_ino_t ino, struct dinode *dp)); #ifdef HAVE_EXT2_JOURNAL_INUM #define ext2_journal_ino(sb) (sb->s_journal_inum) @@ -259,7 +260,7 @@ blockest(struct dinode const *dp) * copy of the given inode, or be NULL (in which case it is fetched.) */ static void -mapfileino(dump_ino_t ino, struct dinode const *dp, long *tapesize, int *dirskipped) +mapfileino(dump_ino_t ino, struct dinode const *dp, long long *tapesize, int *dirskipped) { int mode; @@ -314,7 +315,7 @@ mapfileino(dump_ino_t ino, struct dinode const *dp, long *tapesize, int *dirskip */ #ifdef __linux__ int -mapfiles(UNUSED(dump_ino_t maxino), long *tapesize) +mapfiles(UNUSED(dump_ino_t maxino), long long *tapesize) { ext2_ino_t ino; int anydirskipped = 0; @@ -358,7 +359,7 @@ mapfiles(UNUSED(dump_ino_t maxino), long *tapesize) } #else int -mapfiles(dump_ino_t maxino, long *tapesize) +mapfiles(dump_ino_t maxino, long long *tapesize) { dump_ino_t ino; int anydirskipped = 0; @@ -377,7 +378,7 @@ mapfiles(dump_ino_t maxino, long *tapesize) #ifdef __linux__ int -maponefile(UNUSED(dump_ino_t maxino), long *tapesize, char *directory) +maponefile(UNUSED(dump_ino_t maxino), long long *tapesize, char *directory) { errcode_t retval; ext2_ino_t dir_ino; @@ -425,7 +426,7 @@ maponefile(UNUSED(dump_ino_t maxino), long *tapesize, char *directory) #ifdef __linux__ struct mapfile_context { - long *tapesize; + long long *tapesize; int *anydirskipped; }; @@ -467,7 +468,7 @@ mapfilesindir(struct ext2_dir_entry *dirent, UNUSED(int offset), * the directories in the filesystem. */ int -mapfilesfromdir(UNUSED(dump_ino_t maxino), long *tapesize, char *directory) +mapfilesfromdir(UNUSED(dump_ino_t maxino), long long *tapesize, char *directory) { errcode_t retval; struct mapfile_context mfc; @@ -529,7 +530,7 @@ mapfilesfromdir(UNUSED(dump_ino_t maxino), long *tapesize, char *directory) struct mapdirs_context { int *ret; int nodump; - long *tapesize; + long long *tapesize; }; #endif @@ -546,7 +547,7 @@ struct mapdirs_context { * pass using this algorithm. */ int -mapdirs(dump_ino_t maxino, long *tapesize) +mapdirs(dump_ino_t maxino, long long *tapesize) { struct dinode *dp; int isdir; @@ -573,9 +574,10 @@ mapdirs(dump_ino_t maxino, long *tapesize) * in usedinomap, but we have to go through it anyway * to propagate the nodump attribute. */ + if ((isdir & 1) == 0) + continue; nodump = (TSTINO(ino, usedinomap) == 0); - if ((isdir & 1) == 0 || - (TSTINO(ino, dumpinomap) && nodump == 0)) + if (TSTINO(ino, dumpinomap) && nodump == 0) continue; dp = getino(ino); #ifdef __linux__ @@ -671,7 +673,7 @@ searchdir(struct ext2_dir_entry *dp, UNUSED(int offset), { struct mapdirs_context *mdc; int *ret; - long *tapesize; + long long *tapesize; struct dinode *ip; mdc = (struct mapdirs_context *)private; @@ -776,8 +778,6 @@ dumponeblock(UNUSED(ext2_filsys fs), blk_t *blocknr, e2_blkcnt_t blockcnt, struct block_context *p; e2_blkcnt_t i; - if (blockcnt < NDADDR) - return 0; p = (struct block_context *)private; for (i = p->next_block; i < blockcnt; i++) { p->buf[p->cnt++] = 0; @@ -796,6 +796,70 @@ dumponeblock(UNUSED(ext2_filsys fs), blk_t *blocknr, e2_blkcnt_t blockcnt, } #endif +static void +dump_xattr(dump_ino_t ino, struct dinode *dp) { + + if (dp->di_extraisize != 0) { +#ifdef HAVE_EXT2FS_READ_INODE_FULL + char inode[EXT2_INODE_SIZE(fs->super)]; + errcode_t err; + u_int32_t *magic; + + memset(inode, 0, EXT2_INODE_SIZE(fs->super)); + err = ext2fs_read_inode_full(fs, (ext2_ino_t)ino, + (struct ext2_inode *) inode, + EXT2_INODE_SIZE(fs->super)); + if (err) { + com_err(disk, err, "while reading inode #%ld\n", (long)ino); + exit(X_ABORT); + } + + magic = (void *)inode + EXT2_GOOD_OLD_INODE_SIZE + dp->di_extraisize; + if (*magic == EXT2_XATTR_MAGIC) { + char xattr[EXT2_INODE_SIZE(fs->super)]; + int i; + char *cp; + + if (vflag) + msg("dumping EA (inode) in inode #%ld\n", (long)ino); + memset(xattr, 0, EXT2_INODE_SIZE(fs->super)); + memcpy(xattr, (void *)magic, + EXT2_INODE_SIZE(fs->super) - + (EXT2_GOOD_OLD_INODE_SIZE + dp->di_extraisize)); + magic = (u_int32_t *)xattr; + *magic = EXT2_XATTR_MAGIC2; + + spcl.c_type = TS_INODE; + spcl.c_dinode.di_size = EXT2_INODE_SIZE(fs->super); + spcl.c_flags |= DR_EXTATTRIBUTES; + spcl.c_extattributes = EXT_XATTR; + spcl.c_count = howmany(EXT2_INODE_SIZE(fs->super), TP_BSIZE); + for (i = 0; i < spcl.c_count; i++) + spcl.c_addr[i] = 1; + writeheader(ino); + for (i = 0, cp = xattr; i < spcl.c_count; i++, cp += TP_BSIZE) + writerec(cp, 0); + spcl.c_flags &= ~DR_EXTATTRIBUTES; + spcl.c_extattributes = 0; + } +#endif + } + + if (dp->di_file_acl) { + + if (vflag) + msg("dumping EA (block) in inode #%ld\n", (long)ino); + + spcl.c_type = TS_INODE; + spcl.c_dinode.di_size = sblock->fs_bsize; + spcl.c_flags |= DR_EXTATTRIBUTES; + spcl.c_extattributes = EXT_XATTR; + blksout(&dp->di_file_acl, EXT2_FRAGS_PER_BLOCK(fs->super), ino); + spcl.c_flags &= ~DR_EXTATTRIBUTES; + spcl.c_extattributes = 0; + } +} + /* * Dump passes 3 and 4. * @@ -842,8 +906,6 @@ dumpino(struct dinode *dp, dump_ino_t ino, int metaonly) nbi.di_gen = dp->di_gen; nbi.di_uid = (((int32_t)dp->di_uidhigh) << 16) | dp->di_uid; nbi.di_gid = (((int32_t)dp->di_gidhigh) << 16) | dp->di_gid; - if (dp->di_file_acl) - msg("ACLs in inode #%ld won't be dumped\n", (long)ino); memmove(&spcl.c_dinode, &nbi, sizeof(nbi)); #else /* __linux__ */ spcl.c_dinode = *dp; @@ -856,6 +918,7 @@ dumpino(struct dinode *dp, dump_ino_t ino, int metaonly) spcl.c_count = 0; writeheader(ino); spcl.c_flags &= ~DR_METAONLY; + dump_xattr(ino, dp); return; } @@ -886,6 +949,7 @@ dumpino(struct dinode *dp, dump_ino_t ino, int metaonly) memmove(buf, dp->di_db, (u_long)dp->di_size); buf[dp->di_size] = '\0'; writerec(buf, 0); + dump_xattr(ino, dp); return; } #endif /* __linux__ */ @@ -916,23 +980,13 @@ dumpino(struct dinode *dp, dump_ino_t ino, int metaonly) case S_IFCHR: case S_IFBLK: writeheader(ino); + dump_xattr(ino, dp); return; default: msg("Warning: undefined file type 0%o\n", dp->di_mode & IFMT); return; } - if (i_size > (u_quad_t)NDADDR * sblock->fs_bsize) -#ifdef __linux__ - cnt = NDADDR * EXT2_FRAGS_PER_BLOCK(fs->super); -#else - cnt = NDADDR * sblock->fs_frag; -#endif - else - cnt = howmany(i_size, sblock->fs_fsize); - blksout(&dp->di_db[0], cnt, ino); - if ((quad_t) (size = i_size - NDADDR * sblock->fs_bsize) <= 0) - return; #ifdef __linux__ bc.max = NINDIR(sblock) * EXT2_FRAGS_PER_BLOCK(fs->super); bc.buf = (int *)malloc (bc.max * sizeof (int)); @@ -940,7 +994,7 @@ dumpino(struct dinode *dp, dump_ino_t ino, int metaonly) bc.ino = ino; bc.next_block = NDADDR; - ext2fs_block_iterate2(fs, (ext2_ino_t)ino, 0, NULL, dumponeblock, (void *)&bc); + ext2fs_block_iterate2(fs, (ext2_ino_t)ino, BLOCK_FLAG_DATA_ONLY, NULL, dumponeblock, (void *)&bc); /* deal with holes at the end of the inode */ if (i_size > ((u_quad_t)bc.next_block) * sblock->fs_fsize) { remaining = i_size - ((u_quad_t)bc.next_block) * sblock->fs_fsize; @@ -956,7 +1010,17 @@ dumpino(struct dinode *dp, dump_ino_t ino, int metaonly) blksout (bc.buf, bc.cnt, bc.ino); } free(bc.buf); + dump_xattr(ino, dp); #else + if (i_size > (u_quad_t)NDADDR * sblock->fs_bsize) + cnt = NDADDR * sblock->fs_frag; + else + cnt = howmany(i_size, sblock->fs_fsize); + blksout(&dp->di_db[0], cnt, ino); + if ((quad_t) (size = i_size - NDADDR * sblock->fs_bsize) <= 0) { + dump_xattr(ino, dp); + return; + } for (ind_level = 0; ind_level < NIADDR; ind_level++) { dmpindir(ino, dp->di_ib[ind_level], ind_level, &size); if (size <= 0) @@ -1104,8 +1168,6 @@ dumpdirino(struct dinode *dp, dump_ino_t ino) nbi.di_gen = dp->di_gen; nbi.di_uid = (((int32_t)dp->di_uidhigh) << 16) | dp->di_uid; nbi.di_gid = (((int32_t)dp->di_gidhigh) << 16) | dp->di_gid; - if (dp->di_file_acl) - msg("ACLs in inode #%ld won't be dumped\n", (long)ino); memmove(&spcl.c_dinode, &nbi, sizeof(nbi)); #else /* __linux__ */ spcl.c_dinode = *dp; @@ -1142,6 +1204,7 @@ dumpdirino(struct dinode *dp, dump_ino_t ino) } (void)free(cdc.buf); + dump_xattr(ino, dp); } #endif /* __linux__ */ @@ -1299,7 +1362,11 @@ getino(dump_ino_t inum) errcode_t err; curino = inum; +#ifdef HAVE_EXT2FS_READ_INODE_FULL + err = ext2fs_read_inode_full(fs, (ext2_ino_t)inum, (struct ext2_inode *) &dinode, sizeof(struct dinode)); +#else err = ext2fs_read_inode(fs, (ext2_ino_t)inum, (struct ext2_inode *) &dinode); +#endif if (err) { com_err(disk, err, "while reading inode #%ld\n", (long)inum); exit(X_ABORT);