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