dump.c revision 50e1e10fa0ac12a3e2a9d20a75ee9041873cda96
1/* 2 * dump.c --- dump the contents of an inode out to a file 3 * 4 * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed 5 * under the terms of the GNU Public License. 6 */ 7 8#include <stdio.h> 9#include <unistd.h> 10#include <stdlib.h> 11#include <ctype.h> 12#include <string.h> 13#include <time.h> 14#ifdef HAVE_ERRNO_H 15#include <errno.h> 16#endif 17#include <sys/types.h> 18#include <sys/stat.h> 19#include <fcntl.h> 20 21#include "debugfs.h" 22 23struct dump_block_struct { 24 int fd; 25 char *buf; 26 errcode_t errcode; 27}; 28 29static int dump_block(ext2_filsys fs, blk_t *blocknr, int blockcnt, 30 void *private) 31{ 32 ssize_t nbytes; 33 34 struct dump_block_struct *rec = (struct dump_block_struct *) private; 35 36 if (blockcnt < 0) 37 return 0; 38 39 if (*blocknr) { 40 rec->errcode = io_channel_read_blk(fs->io, *blocknr, 41 1, rec->buf); 42 if (rec->errcode) 43 return BLOCK_ABORT; 44 } else 45 memset(rec->buf, 0, fs->blocksize); 46 47retry_write: 48 nbytes = write(rec->fd, rec->buf, fs->blocksize); 49 if (nbytes == -1) { 50 if (errno == EINTR) 51 goto retry_write; 52 rec->errcode = errno; 53 return BLOCK_ABORT; 54 } 55 if (nbytes != fs->blocksize) { 56 /* XXX not quite right, but good enough */ 57 rec->errcode = EXT2_ET_SHORT_WRITE; 58 return BLOCK_ABORT; 59 } 60 return 0; 61} 62 63static void dump_file(char *cmdname, ino_t inode, int fd, char *outname) 64{ 65 errcode_t retval; 66 struct dump_block_struct rec; 67 68 rec.fd = fd; 69 rec.errcode = 0; 70 rec.buf = malloc(fs->blocksize); 71 72 if (rec.buf == 0) { 73 com_err(cmdname, ENOMEM, "while allocating block buffer for dump_inode"); 74 return; 75 } 76 77 retval = ext2fs_block_iterate(fs, inode, 0, NULL, 78 dump_block, &rec); 79 if (retval) { 80 com_err(cmdname, retval, "while iterating over blocks in %s", 81 outname); 82 goto cleanup; 83 } 84 if (rec.errcode) { 85 com_err(cmdname, retval, "in dump_block while dumping %s", 86 outname); 87 goto cleanup; 88 } 89 90cleanup: 91 free(rec.buf); 92 return; 93} 94 95void do_dump(int argc, char **argv) 96{ 97 ino_t inode; 98 int fd; 99 100 if (argc != 3) { 101 com_err(argv[0], 0, "Usage: dump_inode <file> <output_file>"); 102 return; 103 } 104 105 if (check_fs_open(argv[0])) 106 return; 107 108 inode = string_to_inode(argv[1]); 109 if (!inode) 110 return; 111 112 fd = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0666); 113 if (fd < 0) { 114 com_err(argv[0], errno, "while opening %s for dump_inode", 115 argv[2]); 116 return; 117 } 118 119 dump_file(argv[0], inode, fd, argv[2]); 120 121 close(fd); 122 return; 123} 124 125void do_cat(int argc, char **argv) 126{ 127 ino_t inode; 128 129 if (argc != 2) { 130 com_err(argv[0], 0, "Usage: cat <file>"); 131 return; 132 } 133 134 if (check_fs_open(argv[0])) 135 return; 136 137 inode = string_to_inode(argv[1]); 138 if (!inode) 139 return; 140 141 dump_file(argv[0], inode, 0, argv[2]); 142 143 return; 144} 145 146