This patch is just a load of minor fixes. Wietse Prereq: 1.02 diff -bcr /tmp/tct-1.02/patchlevel ./patchlevel *** /tmp/tct-1.02/patchlevel Tue Aug 8 21:16:32 2000 --- ./patchlevel Tue Sep 26 14:33:42 2000 *************** *** 1 **** ! 1.02 --- 1 ---- ! 1.03 diff -bcr /tmp/tct-1.02/CHANGES ./CHANGES *** /tmp/tct-1.02/CHANGES Tue Aug 8 20:03:39 2000 --- ./CHANGES Tue Sep 26 14:22:18 2000 *************** *** 1,3 **** --- 1,18 ---- + Tue Sep 26 10:55:24 EDT 2000 + + o Fixed a bug in fs_read_block() that caused icat etc. to + remember the wrong file seek position, so that icat etc. + would call lseek() too often. The other possibility, not + calling lseek() when it should be called, did not happen + due to an implementation artefact of the TCT utilities. + Reported by Brian Carrier, Purdue University. + + Updated help-recovering-file document by Dan. + + Sat Aug 12 10:51:16 EDT 2000 + + o Added -V option to direct icat/ils/unrm for verbose output + to stdout. The -v option now sends verbose logging to stderr. Tue Aug 8 11:46:19 PDT 2000 diff -bcr /tmp/tct-1.02/help-recovering-file ./help-recovering-file *** /tmp/tct-1.02/help-recovering-file Tue Aug 8 21:15:28 2000 --- ./help-recovering-file Wed Aug 9 10:12:59 2000 *************** *** 115,121 **** and: ! % bin/unrm /dev/sda1 > /path/to/TCT/unrm_ouput You'll probably need to wait several minutes, depending on how big the disk is that you're unrm'ing from. --- 115,121 ---- and: ! # bin/unrm /dev/sda1 > /path/to/TCT/unrm_ouput You'll probably need to wait several minutes, depending on how big the disk is that you're unrm'ing from. *************** *** 123,129 **** That's it, you've recovered your file! Well, if it was on the disk it's in that big file you just created ("/path/to/TCT/unrm_ouput"). You can, if you wish, try to scrounge through that binary thing to ! recover your data. Or you can move on to #3. #3. Run Lazarus on the output of unrm. Typically this is done like: --- 123,131 ---- That's it, you've recovered your file! Well, if it was on the disk it's in that big file you just created ("/path/to/TCT/unrm_ouput"). You can, if you wish, try to scrounge through that binary thing to ! recover your data. Or you can move on to #3. (Sometimes the former ! is what you want to do; it really depends on your experience and the ! situation. If unsure, proceed onwards.) #3. Run Lazarus on the output of unrm. Typically this is done like: *************** *** 133,139 **** The -h flag generates HTML output, which we can view with a browser. Lazarus splits that big binary file into many smaller chunks. It creates two directories, one of which is called "blocks" and has *lots* of files ! in it. Hopefully your data is in there. #4. Now the hard part. If you know what your file looks like, and it --- 135,142 ---- The -h flag generates HTML output, which we can view with a browser. Lazarus splits that big binary file into many smaller chunks. It creates two directories, one of which is called "blocks" and has *lots* of files ! in it. Hopefully your data is in there (if it was on the disk and unrm ! recovered it, it's there.) #4. Now the hard part. If you know what your file looks like, and it *************** *** 143,149 **** Method A --------- ! Let's say you lost a the last letter that your Dad wrote to you before he died, and all you really remember is that he wrote something about a Studebaker automobile he had as a kid. "Studebaker" is a great word to search for because the odds are that not a lot of files have that word --- 146,152 ---- Method A --------- ! Let's say you lost the last letter that your Dad wrote to you before he died, and all you really remember is that he wrote something about a Studebaker automobile he had as a kid. "Studebaker" is a great word to search for because the odds are that not a lot of files have that word *************** *** 203,211 **** Will find any files that have rpcsvc/sm_inter.h in them (not a lot, probably! ;-)) This sort of brute force approach can be quite useful. ! Again, beware of concatenating lots of recovered blocks/files ! together and performing text based searches or operations on them ! (sort, grep, uniq, etc.) Method B --- 206,215 ---- Will find any files that have rpcsvc/sm_inter.h in them (not a lot, probably! ;-)) This sort of brute force approach can be quite useful. ! Beware of concatenating lots of recovered blocks/files together and ! performing text based searches or operations on them (sort, grep, ! uniq, etc.), because text tools will often perform badly when ! encountering binary data that is often in the lazarus output. Method B diff -bcr /tmp/tct-1.02/lib/command.pl ./lib/command.pl *** /tmp/tct-1.02/lib/command.pl Sun Jul 30 19:39:20 2000 --- ./lib/command.pl Sat Aug 26 17:22:08 2000 *************** *** 63,69 **** # AUTHOR(S) # Wietse Venema # IBM T.J. Watson Research ! # P.O. Box 704Yorktown Heights, NY 10598, USA #-- require "logger.pl"; --- 63,69 ---- # AUTHOR(S) # Wietse Venema # IBM T.J. Watson Research ! # P.O. Box 704, Yorktown Heights, NY 10598, USA #-- require "logger.pl"; Only in /tmp/tct-1.02/lib: logfs.pl diff -bcr /tmp/tct-1.02/lib/logger.pl ./lib/logger.pl *** /tmp/tct-1.02/lib/logger.pl Sun Jul 30 19:39:20 2000 --- ./lib/logger.pl Sat Aug 26 17:23:30 2000 *************** *** 29,35 **** # AUTHOR(S) # Wietse Venema # IBM T.J. Watson Research ! # P.O. Box 704Yorktown Heights, NY 10598, USA #-- # log_init_path($path) - open logfile for append mode --- 29,35 ---- # AUTHOR(S) # Wietse Venema # IBM T.J. Watson Research ! # P.O. Box 704, Yorktown Heights, NY 10598, USA #-- # log_init_path($path) - open logfile for append mode diff -bcr /tmp/tct-1.02/src/fstools/ext2fs.c ./src/fstools/ext2fs.c *** /tmp/tct-1.02/src/fstools/ext2fs.c Sun Jul 30 19:39:20 2000 --- ./src/fstools/ext2fs.c Sat Aug 12 11:11:10 2000 *************** *** 62,71 **** * reads instead of cacheing group descriptors in a large buffer. */ offs = ext2fs->group_offset + grpnum * sizeof(*gd); ! fs_read_random(ext2fs->fs_info.fd, (char *) gd, sizeof(*gd), offs); ext2fs->grpnum = grpnum; if (verbose) ! printf("\tgroup %lu: %lu/%lu free blocks/inodes\n", (ULONG) grpnum, (ULONG) gd->bg_free_blocks_count, (ULONG) gd->bg_free_inodes_count); --- 62,73 ---- * reads instead of cacheing group descriptors in a large buffer. */ offs = ext2fs->group_offset + grpnum * sizeof(*gd); ! fs_read_random(ext2fs->fs_info.fd, (char *) gd, sizeof(*gd), offs, ! "group descriptor"); ext2fs->grpnum = grpnum; if (verbose) ! fprintf(logfp, ! "\tgroup %lu: %lu/%lu free blocks/inodes\n", (ULONG) grpnum, (ULONG) gd->bg_free_blocks_count, (ULONG) gd->bg_free_inodes_count); *************** *** 80,89 **** for (i = 0; i < len; i++) { if (i > 0 && i % 10 == 0) ! putchar('|'); ! putchar(isset(map, i) ? '1' : '.'); } ! putchar('\n'); } /* ext2fs_bmap_lookup - look up block bitmap */ --- 82,91 ---- for (i = 0; i < len; i++) { if (i > 0 && i % 10 == 0) ! putc('|', logfp); ! putc(isset(map, i) ? '1' : '.', logfp); } ! putc('\n', logfp); } /* ext2fs_bmap_lookup - look up block bitmap */ *************** *** 104,112 **** fs_read_random(ext2fs->fs_info.fd, (char *) ext2fs->block_map, ext2fs->fs_info.block_size, ! (OFF_T) gd->bg_block_bitmap * ext2fs->fs_info.block_size); ext2fs->bmap_num = grpnum; ! if (verbose) ext2fs_print_map(ext2fs->block_map, ext2fs->fs.s_blocks_per_group); return (ext2fs->block_map); --- 106,115 ---- fs_read_random(ext2fs->fs_info.fd, (char *) ext2fs->block_map, ext2fs->fs_info.block_size, ! (OFF_T) gd->bg_block_bitmap * ext2fs->fs_info.block_size, ! "block bitmap"); ext2fs->bmap_num = grpnum; ! if (verbose > 1) ext2fs_print_map(ext2fs->block_map, ext2fs->fs.s_blocks_per_group); return (ext2fs->block_map); *************** *** 130,138 **** fs_read_random(ext2fs->fs_info.fd, (char *) ext2fs->inode_map, ext2fs->fs_info.block_size, ! (OFF_T) gd->bg_inode_bitmap * ext2fs->fs_info.block_size); ext2fs->imap_num = grpnum; ! if (verbose) ext2fs_print_map(ext2fs->inode_map, ext2fs->fs.s_inodes_per_group); return (ext2fs->inode_map); --- 133,142 ---- fs_read_random(ext2fs->fs_info.fd, (char *) ext2fs->inode_map, ext2fs->fs_info.block_size, ! (OFF_T) gd->bg_inode_bitmap * ext2fs->fs_info.block_size, ! "inode bitmap"); ext2fs->imap_num = grpnum; ! if (verbose > 1) ext2fs_print_map(ext2fs->inode_map, ext2fs->fs.s_inodes_per_group); return (ext2fs->inode_map); *************** *** 168,177 **** offs = (inum - 1) - ext2fs->fs.s_inodes_per_group * grpnum; addr = (OFF_T) gd->bg_inode_table * ext2fs->fs_info.block_size + offs * sizeof(struct ext2_inode); ! fs_read_random(ext2fs->fs_info.fd, (char *) dino, sizeof(*dino), addr); ext2fs->inum = inum; if (verbose) ! printf("%lu m/l/s=%o/%d/%lu u/g=%d/%d macd=%lu/%lu/%lu/%lu\n", (ULONG) inum, dino->i_mode, dino->i_links_count, (ULONG) dino->i_size, dino->i_uid, dino->i_gid, (ULONG) dino->i_mtime, (ULONG) dino->i_atime, --- 172,183 ---- offs = (inum - 1) - ext2fs->fs.s_inodes_per_group * grpnum; addr = (OFF_T) gd->bg_inode_table * ext2fs->fs_info.block_size + offs * sizeof(struct ext2_inode); ! fs_read_random(ext2fs->fs_info.fd, (char *) dino, sizeof(*dino), addr, ! "inode block"); ext2fs->inum = inum; if (verbose) ! fprintf(logfp, ! "%lu m/l/s=%o/%d/%lu u/g=%d/%d macd=%lu/%lu/%lu/%lu\n", (ULONG) inum, dino->i_mode, dino->i_links_count, (ULONG) dino->i_size, dino->i_uid, dino->i_gid, (ULONG) dino->i_mtime, (ULONG) dino->i_atime, *************** *** 339,345 **** myflags = (isset(bmap, addr - dbase) ? FS_FLAG_ALLOC : FS_FLAG_UNALLOC); if (flags & myflags) { ! fs_read_block(fs, fs_buf, fs->block_size, addr); action(addr, fs_buf->data, myflags, ptr); } } --- 345,351 ---- myflags = (isset(bmap, addr - dbase) ? FS_FLAG_ALLOC : FS_FLAG_UNALLOC); if (flags & myflags) { ! fs_read_block(fs, fs_buf, fs->block_size, addr, "data block"); action(addr, fs_buf->data, myflags, ptr); } } *************** *** 427,433 **** * Print some stats. */ if (verbose) ! printf("inodes %lu root ino %lu blocks %lu blocks/group %lu\n", (ULONG) ext2fs->fs.s_inodes_count, (ULONG) EXT2_ROOT_INO, (ULONG) ext2fs->fs.s_blocks_count, --- 433,440 ---- * Print some stats. */ if (verbose) ! fprintf(logfp, ! "inodes %lu root ino %lu blocks %lu blocks/group %lu\n", (ULONG) ext2fs->fs.s_inodes_count, (ULONG) EXT2_ROOT_INO, (ULONG) ext2fs->fs.s_blocks_count, diff -bcr /tmp/tct-1.02/src/fstools/ffs.c ./src/fstools/ffs.c *** /tmp/tct-1.02/src/fstools/ffs.c Sun Jul 30 19:39:20 2000 --- ./src/fstools/ffs.c Sat Aug 12 10:50:15 2000 *************** *** 62,70 **** ffs->cg_buf = fs_buf_alloc(ffs->fs->fs_bsize); cg = (struct cg *) ffs->cg_buf->data; if (ffs->cg_buf->addr != addr) { ! fs_read_block(&ffs->fs_info, ffs->cg_buf, ffs->cg_buf->size, addr); if (verbose) ! printf("\tcyl group %lu: %lu/%lu/%lu free blocks/inodes/frags\n", (ULONG) cgnum, (ULONG) cg->cg_cs.cs_nbfree, (ULONG) cg->cg_cs.cs_nifree, (ULONG) cg->cg_cs.cs_nffree); --- 62,72 ---- ffs->cg_buf = fs_buf_alloc(ffs->fs->fs_bsize); cg = (struct cg *) ffs->cg_buf->data; if (ffs->cg_buf->addr != addr) { ! fs_read_block(&ffs->fs_info, ffs->cg_buf, ffs->cg_buf->size, addr, ! "cylinder block"); if (verbose) ! fprintf(logfp, ! "\tcyl group %lu: %lu/%lu/%lu free blocks/inodes/frags\n", (ULONG) cgnum, (ULONG) cg->cg_cs.cs_nbfree, (ULONG) cg->cg_cs.cs_nifree, (ULONG) cg->cg_cs.cs_nffree); *************** *** 100,106 **** ffs->dino_buf = fs_buf_alloc(ffs->fs->fs_bsize); addr = itod(ffs->fs, inum); if (ffs->dino_buf->addr != addr) ! fs_read_block(&ffs->fs_info, ffs->dino_buf, ffs->dino_buf->size, addr); /* * Copy the inode, in order to avoid alignment problems when accessing --- 102,109 ---- ffs->dino_buf = fs_buf_alloc(ffs->fs->fs_bsize); addr = itod(ffs->fs, inum); if (ffs->dino_buf->addr != addr) ! fs_read_block(&ffs->fs_info, ffs->dino_buf, ffs->dino_buf->size, addr, ! "inode block"); /* * Copy the inode, in order to avoid alignment problems when accessing *************** *** 319,325 **** } else { if (fs_buf->addr < 0 || faddr >= fs_buf->addr + fs->block_frags) ! fs_read_block(fs, fs_buf, fs->block_size * frags, addr); action(faddr, fs_buf->data + fs->block_size * (faddr - fs_buf->addr), myflags, ptr); --- 322,329 ---- } else { if (fs_buf->addr < 0 || faddr >= fs_buf->addr + fs->block_frags) ! fs_read_block(fs, fs_buf, fs->block_size * frags, addr, ! "data block"); action(faddr, fs_buf->data + fs->block_size * (faddr - fs_buf->addr), myflags, ptr); *************** *** 406,412 **** * Print some stats. */ if (verbose) ! printf("inodes %lu root ino %lu cyl groups %lu blocks %lu\n", (ULONG) ffs->fs->fs_ncg * ffs->fs->fs_ipg, (ULONG) ROOTINO, (ULONG) ffs->fs->fs_ncg, --- 410,417 ---- * Print some stats. */ if (verbose) ! fprintf(logfp, ! "inodes %lu root ino %lu cyl groups %lu blocks %lu\n", (ULONG) ffs->fs->fs_ncg * ffs->fs->fs_ipg, (ULONG) ROOTINO, (ULONG) ffs->fs->fs_ncg, diff -bcr /tmp/tct-1.02/src/fstools/fs_copy_file.c ./src/fstools/fs_copy_file.c *** /tmp/tct-1.02/src/fstools/fs_copy_file.c Sun Jul 30 19:39:20 2000 --- ./src/fstools/fs_copy_file.c Fri Aug 11 21:50:39 2000 *************** *** 46,52 **** } } else { if (flags & FS_FLAG_ALLOC) { ! fs_read_block(fs, buf[0], roundup(read_count, DEV_BSIZE), addr); if (fwrite(buf[0]->data, read_count, 1, stdout) != 1) error("write: %m"); } --- 46,53 ---- } } else { if (flags & FS_FLAG_ALLOC) { ! fs_read_block(fs, buf[0], roundup(read_count, DEV_BSIZE), addr, ! "data block"); if (fwrite(buf[0]->data, read_count, 1, stdout) != 1) error("write: %m"); } *************** *** 65,71 **** int n; if (verbose) ! printf("%s: level %d block %lu\n", myname, level, (ULONG) addr); /* * Read a block of disk addresses. --- 66,72 ---- int n; if (verbose) ! fprintf(logfp, "%s: level %d block %lu\n", myname, level, (ULONG) addr); /* * Read a block of disk addresses. *************** *** 73,79 **** if (addr == 0) memset(buf[level]->data, 0, buf[level]->size); else ! fs_read_block(fs, buf[level], buf[level]->size, addr); /* * For each disk address, copy a direct block or process an indirect --- 74,81 ---- if (addr == 0) memset(buf[level]->data, 0, buf[level]->size); else ! fs_read_block(fs, buf[level], buf[level]->size, addr, ! "disk address block"); /* * For each disk address, copy a direct block or process an indirect diff -bcr /tmp/tct-1.02/src/fstools/fs_io.c ./src/fstools/fs_io.c *** /tmp/tct-1.02/src/fstools/fs_io.c Sun Jul 30 19:39:20 2000 --- ./src/fstools/fs_io.c Tue Sep 26 10:15:41 2000 *************** *** 6,22 **** /* SYNOPSIS /* #include "fstools.h" /* ! /* void fs_read_block(fs, buf, len, addr) /* FS_INFO *fs; /* FS_BUF *buf; /* int len; /* DADDR_T addr; /* ! /* void fs_read_random(fd, buf, len, offs) /* int fd; /* char *buf; /* int len; /* OFF_T offs; /* DESCRIPTION /* fs_read_block() reads a block of data from the named file system. /* --- 6,24 ---- /* SYNOPSIS /* #include "fstools.h" /* ! /* void fs_read_block(fs, buf, len, addr, comment) /* FS_INFO *fs; /* FS_BUF *buf; /* int len; /* DADDR_T addr; + /* const char *comment; /* ! /* void fs_read_random(fd, buf, len, offs, comment) /* int fd; /* char *buf; /* int len; /* OFF_T offs; + /* const char *comment; /* DESCRIPTION /* fs_read_block() reads a block of data from the named file system. /* *************** *** 35,40 **** --- 37,44 ---- /* Open device file. /* .IP offs /* Byte offset. + /* .IP comment + /* Text logged with verbose logging. /* LICENSE /* This software is distributed under the IBM Public License. /* AUTHOR(S) *************** *** 50,58 **** /* fs_read_block - read a block from a file system */ ! void fs_read_block(FS_INFO *fs, FS_BUF *buf, int len, DADDR_T addr) { ! char *myname = "read_ffs"; OFF_T offs; /* --- 54,63 ---- /* fs_read_block - read a block from a file system */ ! void fs_read_block(FS_INFO *fs, FS_BUF *buf, int len, DADDR_T addr, ! const char *comment) { ! char *myname = "fs_read_block"; OFF_T offs; /* *************** *** 73,100 **** offs = (OFF_T) addr *fs->block_size; if (verbose) ! printf("%s: read block %lu %.0f\n", myname, (ULONG) addr, (double) offs); #ifdef USE_PREAD if (pread(fs->fd, buf->data, len, offs) != len) error("read (%d@%.0f): %m", len, (double) offs); - fs->seek_pos = addr; #else ! if (fs->seek_pos != addr) if (LSEEK(fs->fd, offs, SEEK_SET) != offs) error("lseek (%.0f): %m", (double) offs); if (read(fs->fd, buf->data, len) != len) error("read (%d@%.0f): %m", len, (double) offs); - fs->seek_pos = addr + len; #endif buf->used = len; } /* fs_read_random - random-access read */ ! void fs_read_random(int fd, char *buf, int len, OFF_T offs) { int count; if (LSEEK(fd, offs, SEEK_SET) != offs) error("seek offset %lu: %m", (ULONG) offs); if ((count = read(fd, buf, len)) != len) --- 78,110 ---- offs = (OFF_T) addr *fs->block_size; if (verbose) ! fprintf(logfp, "%s: read block %lu offs %.0f len %d (%s)\n", ! myname, (ULONG) addr, (double) offs, len, comment); #ifdef USE_PREAD if (pread(fs->fd, buf->data, len, offs) != len) error("read (%d@%.0f): %m", len, (double) offs); #else ! if (fs->seek_pos != offs) if (LSEEK(fs->fd, offs, SEEK_SET) != offs) error("lseek (%.0f): %m", (double) offs); if (read(fs->fd, buf->data, len) != len) error("read (%d@%.0f): %m", len, (double) offs); #endif + fs->seek_pos = offs + len; buf->used = len; } /* fs_read_random - random-access read */ ! void fs_read_random(int fd, char *buf, int len, OFF_T offs, ! const char *comment) { + char *myname = "fs_read_random"; int count; + if (verbose) + fprintf(logfp, "%s: read offs %.0f len %d (%s)\n", + myname, (double) offs, len, comment); if (LSEEK(fd, offs, SEEK_SET) != offs) error("seek offset %lu: %m", (ULONG) offs); if ((count = read(fd, buf, len)) != len) diff -bcr /tmp/tct-1.02/src/fstools/fs_tools.h ./src/fstools/fs_tools.h *** /tmp/tct-1.02/src/fstools/fs_tools.h Sun Jul 30 19:39:20 2000 --- ./src/fstools/fs_tools.h Fri Aug 11 21:49:20 2000 *************** *** 23,28 **** --- 23,33 ---- #include /* + * Verbose logging. + */ + extern FILE *logfp; + + /* * Solaris 2.x. Build for large files when dealing with filesystems > 2GB. * With the 32-bit file model, needs pread() to access filesystems > 2GB. */ *************** *** 287,294 **** * Generic routines. */ extern FS_INFO *fs_open(const char *, const char *); ! extern void fs_read_block(FS_INFO *, FS_BUF *, int, DADDR_T); ! extern void fs_read_random(int, char *, int, OFF_T); extern void fs_copy_file(FS_INFO *, INUM_T, int); /* --- 292,299 ---- * Generic routines. */ extern FS_INFO *fs_open(const char *, const char *); ! extern void fs_read_block(FS_INFO *, FS_BUF *, int, DADDR_T, const char *); ! extern void fs_read_random(int, char *, int, OFF_T, const char *); extern void fs_copy_file(FS_INFO *, INUM_T, int); /* diff -bcr /tmp/tct-1.02/src/fstools/icat.c ./src/fstools/icat.c *** /tmp/tct-1.02/src/fstools/icat.c Sun Jul 30 19:39:20 2000 --- ./src/fstools/icat.c Fri Aug 11 21:35:50 2000 *************** *** 6,12 **** /* SYNOPSIS /* .ad /* .fi ! /* \fBicat\fR [\fB-hHv\fR] [\fB-f \fIfstype\fR] /* \fIdevice\fR \fIinode\fR ... /* DESCRIPTION /* \fBicat\fR opens the named \fIdevice\fR and copies the files --- 6,12 ---- /* SYNOPSIS /* .ad /* .fi ! /* \fBicat\fR [\fB-hHvV\fR] [\fB-f \fIfstype\fR] /* \fIdevice\fR \fIinode\fR ... /* DESCRIPTION /* \fBicat\fR opens the named \fIdevice\fR and copies the files *************** *** 26,32 **** /* information is preserved. This option wastes space when copying /* sparse files. /* .IP \fB-v\fR ! /* Enable verbose mode, for debugging purposes. /* .IP \fIdevice\fR /* Disk special file, or regular file containing a disk image. /* On UNIX systems, raw mode disk access may give better performance --- 26,34 ---- /* information is preserved. This option wastes space when copying /* sparse files. /* .IP \fB-v\fR ! /* Enable verbose mode, output to stderr. ! /* .IP \fB-V\fR ! /* Enable verbose mode, output to stdout. /* .IP \fIdevice\fR /* Disk special file, or regular file containing a disk image. /* On UNIX systems, raw mode disk access may give better performance *************** *** 51,61 **** #include "fs_tools.h" #include "error.h" /* usage - explain and terminate */ static void usage() { ! error("usage: %s [-f fstype] [-h (no holes)] [-H (keep holes)] device inum...", progname); } int main(int argc, char **argv) --- 53,65 ---- #include "fs_tools.h" #include "error.h" + FILE *logfp; + /* usage - explain and terminate */ static void usage() { ! error("usage: %s [-f fstype] [-h (no holes)] [-H (keep holes)] [-vV] device inum...", progname); } int main(int argc, char **argv) *************** *** 69,75 **** progname = argv[0]; ! while ((ch = getopt(argc, argv, "f:hHv")) > 0) { switch (ch) { default: usage(); --- 73,79 ---- progname = argv[0]; ! while ((ch = getopt(argc, argv, "f:hHvV")) > 0) { switch (ch) { default: usage(); *************** *** 84,89 **** --- 88,98 ---- break; case 'v': verbose++; + logfp = stderr; + break; + case 'V': + verbose++; + logfp = stdout; break; } } diff -bcr /tmp/tct-1.02/src/fstools/ils.c ./src/fstools/ils.c *** /tmp/tct-1.02/src/fstools/ils.c Fri Aug 4 10:52:58 2000 --- ./src/fstools/ils.c Fri Aug 11 21:35:31 2000 *************** *** 6,15 **** /* SYNOPSIS /* .ad /* .fi ! /* \fBils\fR [\fB-eorv\fR] [\fB-f \fIfstype\fR] /* \fIdevice\fR [\fIstart-stop\fR ...] /* ! /* \fBils\fR [\fB-aAlLvzZ\fR] [\fB-f \fIfstype\fR] /* \fIdevice\fR [\fIstart-stop\fR ...] /* DESCRIPTION /* \fBils\fR opens the named \fIdevice\fR and lists inode information. --- 6,15 ---- /* SYNOPSIS /* .ad /* .fi ! /* \fBils\fR [\fB-eorvV\fR] [\fB-f \fIfstype\fR] /* \fIdevice\fR [\fIstart-stop\fR ...] /* ! /* \fBils\fR [\fB-aAlLvVzZ\fR] [\fB-f \fIfstype\fR] /* \fIdevice\fR [\fIstart-stop\fR ...] /* DESCRIPTION /* \fBils\fR opens the named \fIdevice\fR and lists inode information. *************** *** 32,38 **** /* for \fB-LZ\fR /* (see the \fBfine controls\fR section below). /* .IP \fB-v\fR ! /* Turn on verbose mode. /* .IP \fIdevice\fR /* Disk special file, or regular file containing a disk image. /* On UNIX systems, raw mode disk access may give better performance --- 32,40 ---- /* for \fB-LZ\fR /* (see the \fBfine controls\fR section below). /* .IP \fB-v\fR ! /* Turn on verbose mode, output to stderr. ! /* .IP \fB-V\fR ! /* Turn on verbose mode, output to stdout. /* .IP \fIdevice\fR /* Disk special file, or regular file containing a disk image. /* On UNIX systems, raw mode disk access may give better performance *************** *** 112,117 **** --- 114,121 ---- #include "error.h" #include "split_at.h" + FILE *logfp; + #define DEF_FLAGS (FS_FLAG_USED | FS_FLAG_UNLINK) /* atoinum - convert string to inode number */ *************** *** 133,139 **** static void usage() { ! error("usage: %s [-e (everything)] [-f fstype] [-o (removed but still open)] [-r (removed)] [-v] device [inum... ]", progname); } --- 137,143 ---- static void usage() { ! error("usage: %s [-e (everything)] [-f fstype] [-o (removed but still open)] [-r (removed)] [-vV] device [inum... ]", progname); } *************** *** 203,209 **** * Provide convenience options for the most commonly selected feature * combinations. */ ! while ((ch = getopt(argc, argv, "aAef:lLorvzZ")) > 0) { switch (ch) { default: usage(); --- 207,213 ---- * Provide convenience options for the most commonly selected feature * combinations. */ ! while ((ch = getopt(argc, argv, "aAef:lLorvVzZ")) > 0) { switch (ch) { default: usage(); *************** *** 221,226 **** --- 225,235 ---- break; case 'v': verbose++; + logfp = stderr; + break; + case 'V': + verbose++; + logfp = stdout; break; /* diff -bcr /tmp/tct-1.02/src/fstools/unrm.c ./src/fstools/unrm.c *** /tmp/tct-1.02/src/fstools/unrm.c Sun Jul 30 19:39:20 2000 --- ./src/fstools/unrm.c Fri Aug 11 21:38:40 2000 *************** *** 6,12 **** /* SYNOPSIS /* .ad /* .fi ! /* \fBunrm\fR [\fB-bev\fR] [\fB-f \fIfstype\fR] /* \fIdevice\fR [\fIstart-stop\fR ...] /* DESCRIPTION /* \fBunrm\fR opens the named \fIdevice\fR and copies data blocks. --- 6,12 ---- /* SYNOPSIS /* .ad /* .fi ! /* \fBunrm\fR [\fB-bevV\fR] [\fB-f \fIfstype\fR] /* \fIdevice\fR [\fIstart-stop\fR ...] /* DESCRIPTION /* \fBunrm\fR opens the named \fIdevice\fR and copies data blocks. *************** *** 27,33 **** /* is \fBufs\fR (Berkeley fast file system). With Linux the default /* type is \fBext2fs\fR (second extended file system). /* .IP \fB-v\fR ! /* Turn on verbose mode. /* .IP \fIdevice\fR /* Disk special file, or regular file containing a disk image. /* On UNIX systems, raw mode disk access may give better performance --- 27,35 ---- /* is \fBufs\fR (Berkeley fast file system). With Linux the default /* type is \fBext2fs\fR (second extended file system). /* .IP \fB-v\fR ! /* Turn on verbose mode, output to stderr. ! /* .IP \fB-V\fR ! /* Turn on verbose mode, output to stdout. /* .IP \fIdevice\fR /* Disk special file, or regular file containing a disk image. /* On UNIX systems, raw mode disk access may give better performance *************** *** 57,62 **** --- 59,66 ---- #include "error.h" #include "split_at.h" + FILE *logfp; + /* atoblock - convert string to block number */ DADDR_T atoblock(const char *str) *************** *** 76,82 **** static void usage() { ! error("usage: %s [-b (no block padding)] [-e (every block)] [-f fstype] [-v] device [block... ]", progname); } --- 80,86 ---- static void usage() { ! error("usage: %s [-b (no block padding)] [-e (every block)] [-f fstype] [-vV] device [block... ]", progname); } *************** *** 87,93 **** FS_INFO *fs = (FS_INFO *) ptr; if (verbose) ! printf("write block %lu\n", (ULONG) addr); if (fwrite(buf, fs->block_size, 1, stdout) != 1) error("write stdout: %m"); } --- 91,97 ---- FS_INFO *fs = (FS_INFO *) ptr; if (verbose) ! fprintf(logfp, "write block %lu\n", (ULONG) addr); if (fwrite(buf, fs->block_size, 1, stdout) != 1) error("write stdout: %m"); } *************** *** 107,113 **** progname = argv[0]; ! while ((ch = getopt(argc, argv, "bef:v")) > 0) { switch (ch) { default: usage(); --- 111,117 ---- progname = argv[0]; ! while ((ch = getopt(argc, argv, "bef:vV")) > 0) { switch (ch) { default: usage(); *************** *** 122,127 **** --- 126,136 ---- break; case 'v': verbose++; + logfp = stderr; + break; + case 'V': + verbose++; + logfp = stdout; break; } } diff -bcr /tmp/tct-1.02/src/misc/timeout.c ./src/misc/timeout.c *** /tmp/tct-1.02/src/misc/timeout.c Sun Jul 30 19:39:20 2000 --- ./src/misc/timeout.c Tue Aug 22 09:52:47 2000 *************** *** 79,85 **** /* * Run the command and its watchdog in a separate process group so that ! * both can be killed of with one signal. */ setsid(); switch (child_pid = fork()) { --- 79,85 ---- /* * Run the command and its watchdog in a separate process group so that ! * both can be killed off with one signal. */ setsid(); switch (child_pid = fork()) {