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