X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=dump%2Ftraverse.c;h=a8ca3a4f08cba32c08b0b418be65712bc516d410;hp=4bf70d5ddf8565d819ab4bfd7a05ff0438e1280a;hb=54ec08c6ea42e9189423def508c5119f33466db2;hpb=a4f547cdfcac72c75d5e147fa4592652229fd0a1 diff --git a/dump/traverse.c b/dump/traverse.c index 4bf70d5..a8ca3a4 100644 --- a/dump/traverse.c +++ b/dump/traverse.c @@ -41,7 +41,7 @@ #ifndef lint static const char rcsid[] = - "$Id: traverse.c,v 1.29 2001/03/21 09:37:13 stelian Exp $"; + "$Id: traverse.c,v 1.37 2001/07/19 09:49:35 stelian Exp $"; #endif /* not lint */ #include @@ -55,7 +55,11 @@ static const char rcsid[] = #include #include #ifdef __linux__ +#ifdef HAVE_EXT2FS_EXT2_FS_H +#include +#else #include +#endif #include #include #include @@ -98,9 +102,6 @@ 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 int exclude_ino __P((dump_ino_t ino)); -extern dump_ino_t iexclude_list[IEXCLUDE_MAXNUM]; /* the inode exclude list */ -extern int iexclude_num; /* number of elements in list */ #ifdef HAVE_EXT2_JOURNAL_INUM #define ext2_journal_ino(sb) (sb->s_journal_inum) @@ -108,7 +109,7 @@ extern int iexclude_num; /* number of elements in list */ #define ext2_journal_ino(sb) (*((__u32 *)sb + 0x38)) #endif #ifndef HAVE_EXT2_INO_T -#define ext2_ino_t __u32 +typedef ino_t ext2_ino_t; #endif #ifndef EXT3_FEATURE_COMPAT_HAS_JOURNAL @@ -128,6 +129,9 @@ extern int iexclude_num; /* number of elements in list */ #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_RECOVER | \ EXT2_FEATURE_INCOMPAT_FILETYPE) #endif +#ifndef EXT2_RESIZE_INO +#define EXT2_RESIZE_INO 7 +#endif int dump_fs_open(const char *disk, ext2_filsys *fs) { @@ -136,7 +140,7 @@ int dump_fs_open(const char *disk, ext2_filsys *fs) retval = ext2fs_open(disk, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, fs); if (!retval) { struct ext2_super_block *es = (*fs)->super; - ext2_ino_t journal_ino = ext2_journal_ino(es); + dump_ino_t journal_ino = ext2_journal_ino(es); if (es->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV){ fprintf(stderr, "This an journal, not a filesystem!\n"); @@ -152,13 +156,12 @@ int dump_fs_open(const char *disk, ext2_filsys *fs) retval = EXT2_ET_UNSUPP_FEATURE; ext2fs_close(*fs); } - else if (es->s_feature_compat & + else { + if (es->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL && - journal_ino && - !exclude_ino((dump_ino_t)journal_ino)) { - iexclude_list[iexclude_num++] = (dump_ino_t)journal_ino; - msg("Added ext3 journal inode %d to exclude list\n", - journal_ino); + journal_ino) + do_exclude_ino(journal_ino, "journal inode"); + do_exclude_ino(EXT2_RESIZE_INO, "resize inode"); } } return retval; @@ -214,22 +217,6 @@ blockest(struct dinode const *dp) return (blkest + 1); } -/* - * This tests whether an inode is in the exclude list - */ -int -exclude_ino(dump_ino_t ino) -{ - /* 04-Feb-00 ILC */ - if (iexclude_num) { /* if there are inodes in the exclude list */ - int idx; /* then check this inode against it */ - for (idx = 0; idx < iexclude_num; idx++) - if (ino == iexclude_list[idx]) - return 1; - } - return 0; -} - /* Auxiliary macro to pick up files changed since previous dump. */ #define CHANGEDSINCE(dp, t) \ ((dp)->di_mtime >= (t) || (dp)->di_ctime >= (t)) @@ -363,6 +350,54 @@ mapfiles(dump_ino_t maxino, long *tapesize) } #endif /* __linux__ */ +#ifdef __linux__ +int +maponefile(dump_ino_t maxino, long *tapesize, char *directory) +{ + errcode_t retval; + ext2_ino_t dir_ino; + char dir_name [MAXPATHLEN]; + int i, anydirskipped = 0; + + /* + * Mark every directory in the path as being dumped + */ + for (i = 0; i < strlen (directory); i++) { + if (directory[i] == '/') { + strncpy (dir_name, directory, i); + dir_name[i] = '\0'; + retval = ext2fs_namei(fs, ROOTINO, ROOTINO, + dir_name, &dir_ino); + if (retval) { + com_err(disk, retval, + "while translating %s", dir_name); + exit(X_ABORT); + } + mapfileino((dump_ino_t) dir_ino, 0, + tapesize, &anydirskipped); + } + } + /* + * Mark the final directory + */ + retval = ext2fs_namei(fs, ROOTINO, ROOTINO, directory, &dir_ino); + if (retval) { + com_err(disk, retval, "while translating %s", directory); + exit(X_ABORT); + } + mapfileino((dump_ino_t)dir_ino, 0, tapesize, &anydirskipped); + + mapfileino(ROOTINO, 0, tapesize, &anydirskipped); + + /* + * Restore gets very upset if the root is not dumped, + * so ensure that it always is dumped. + */ + SETINO(ROOTINO, dumpdirmap); + return anydirskipped; +} +#endif /* __linux__ */ + #ifdef __linux__ struct mapfile_context { long *tapesize; @@ -742,9 +777,10 @@ void dumpino(struct dinode *dp, dump_ino_t ino) { unsigned long cnt; - fsizeT size; + fsizeT size, remaining; char buf[TP_BSIZE]; struct old_bsd_inode obi; + int i; #ifdef __linux__ struct block_context bc; #else @@ -861,6 +897,17 @@ dumpino(struct dinode *dp, dump_ino_t ino) bc.next_block = NDADDR; ext2fs_block_iterate2(fs, (ext2_ino_t)ino, 0, NULL, dumponeblock, (void *)&bc); + /* deal with holes at the end of the inode */ + if (i_size > bc.next_block*sblock->fs_fsize) { + remaining = i_size - bc.next_block*sblock->fs_fsize; + for (i = 0; i < howmany(remaining, sblock->fs_fsize); i++) { + bc.buf[bc.cnt++] = 0; + if (bc.cnt == bc.max) { + blksout (bc.buf, bc.cnt, bc.ino); + bc.cnt = 0; + } + } + } if (bc.cnt > 0) { blksout (bc.buf, bc.cnt, bc.ino); }