dump.c revision fc6d9d519aef67735918bf02c0fa8c9222008f76
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> 1450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_ERRNO_H 1550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <errno.h> 1650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 17f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <sys/types.h> 18f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <sys/stat.h> 19f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <fcntl.h> 20fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#include <utime.h> 21fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#ifdef HAVE_GETOPT_H 22fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#include <getopt.h> 23fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#else 24fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'oextern int optind; 25fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'oextern char *optarg; 26fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#endif 27fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#ifdef HAVE_OPTRESET 28fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'oextern int optreset; /* defined by BSD, but not others */ 29fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#endif 30f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 31f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include "debugfs.h" 32f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 33fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o/* 34fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o * The mode_xlate function translates a linux mode into a native-OS mode_t. 35fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o */ 36fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'ostatic struct { 37fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o __u16 lmask; 38fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o mode_t mask; 39fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o} mode_table[] = { 40fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { LINUX_S_IRUSR, S_IRUSR }, 41fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { LINUX_S_IWUSR, S_IWUSR }, 42fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { LINUX_S_IXUSR, S_IXUSR }, 43fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { LINUX_S_IRGRP, S_IRGRP }, 44fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { LINUX_S_IWGRP, S_IWGRP }, 45fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { LINUX_S_IXGRP, S_IXGRP }, 46fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { LINUX_S_IROTH, S_IROTH }, 47fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { LINUX_S_IWOTH, S_IWOTH }, 48fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { LINUX_S_IXOTH, S_IXOTH }, 49fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o { 0, 0 } 50fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o}; 51fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o 52fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'ostatic mode_t mode_xlate(__u16 lmode) 53fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o{ 54fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o mode_t mode = 0; 55fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o int i; 56fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o 57fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o for (i=0; mode_table[i].lmask; i++) { 58fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (lmode & mode_table[i].lmask) 59fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o mode |= mode_table[i].mask; 60fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o } 61fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o return mode; 62fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o} 63fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o 64f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ostruct dump_block_struct { 65f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o int fd; 66f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o char *buf; 67fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o int left; 68f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o errcode_t errcode; 69f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o}; 70f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 7150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic int dump_block(ext2_filsys fs, blk_t *blocknr, int blockcnt, 7250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o void *private) 73f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 74fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o int nbytes, left; 75fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o off_t ret_off; 76f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 77f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o struct dump_block_struct *rec = (struct dump_block_struct *) private; 78f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 79f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (blockcnt < 0) 80f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return 0; 81f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 82f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (*blocknr) { 83f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o rec->errcode = io_channel_read_blk(fs->io, *blocknr, 84f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 1, rec->buf); 85f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (rec->errcode) 86f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return BLOCK_ABORT; 87fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o } else { 88fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o /* 89fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o * OK, the file has a hole. Let's try to seek past 90fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o * the hole in the destination file, so that the 91fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o * destination file has a hole too. 92fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o */ 93fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o ret_off = lseek(rec->fd, fs->blocksize, SEEK_CUR); 94fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (ret_off >= 0) 95fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o return 0; 96f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o memset(rec->buf, 0, fs->blocksize); 97fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o } 98f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 99fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o left = (rec->left > fs->blocksize) ? fs->blocksize : rec->left; 100fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o rec->left -= left; 101fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o 102fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o while (left > 0) { 103fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o nbytes = write(rec->fd, rec->buf, left); 104fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (nbytes == -1) { 105fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (errno == EINTR) 106fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o continue; 107fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o rec->errcode = errno; 108fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o return BLOCK_ABORT; 109fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o } 110fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o left -= nbytes; 111f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 112fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (rec->left <= 0) 113f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return BLOCK_ABORT; 114f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return 0; 115f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 116f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 117fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'ostatic void dump_file(char *cmdname, ino_t ino, int fd, int preserve, 118fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o char *outname) 119f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 120f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o errcode_t retval; 121f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o struct dump_block_struct rec; 122fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o struct ext2_inode inode; 123fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o struct utimbuf ut; 124fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o 125fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o retval = ext2fs_read_inode(current_fs, ino, &inode); 126fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (retval) { 127fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o com_err(cmdname, retval, 128fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o "while reading inode %u in dump_file", ino); 129fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o return; 130fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o } 131f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 132f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o rec.fd = fd; 133f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o rec.errcode = 0; 134fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o rec.buf = malloc(current_fs->blocksize); 135fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o rec.left = inode.i_size; 136f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 137f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (rec.buf == 0) { 138fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o com_err(cmdname, ENOMEM, 139fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o "while allocating block buffer for dump_inode"); 140f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 141f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 142f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 143fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o retval = ext2fs_block_iterate(current_fs, ino, 144fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o BLOCK_FLAG_HOLE|BLOCK_FLAG_DATA_ONLY, 145fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o NULL, dump_block, &rec); 146f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (retval) { 147f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o com_err(cmdname, retval, "while iterating over blocks in %s", 148f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o outname); 149f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o goto cleanup; 150f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 151f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (rec.errcode) { 152f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o com_err(cmdname, retval, "in dump_block while dumping %s", 153f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o outname); 154f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o goto cleanup; 155f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 156f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 157f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ocleanup: 158fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (preserve) { 159fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#ifdef HAVE_FCHOWN 160fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (fchown(fd, inode.i_uid, inode.i_gid) < 0) 161fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o com_err("dump_file", errno, 162fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o "while changing ownership of %s", outname); 163fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#else 164fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (chown(outname, inode.i_uid, inode.i_gid) < 0) 165fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o com_err("dump_file", errno, 166fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o "while changing ownership of %s", outname); 167fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o 168fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#endif 169fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (fchmod(fd, mode_xlate(inode.i_mode)) < 0) 170fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o com_err("dump_file", errno, 171fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o "while setting permissions of %s", outname); 172fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o ut.actime = inode.i_atime; 173fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o ut.modtime = inode.i_mtime; 174fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o close(fd); 175fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (utime(outname, &ut) < 0) 176fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o com_err("dump_file", errno, 177fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o "while setting times on %s", outname); 178fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o } else if (fd != 1) 179fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o close(fd); 180fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o 181f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o free(rec.buf); 182f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 183f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 184f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 185f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ovoid do_dump(int argc, char **argv) 186f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 187f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o ino_t inode; 188f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o int fd; 189fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o char c; 190fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o int preserve = 0; 191fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o const char *dump_usage = "Usage: dump_inode [-p] <file> <output_file>"; 192fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o char *in_fn, *out_fn; 193fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o 194fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o optind = 0; 195fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#ifdef HAVE_OPTRESET 196fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o optreset = 1; /* Makes BSD getopt happy */ 197fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o#endif 198fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o while ((c = getopt (argc, argv, "p")) != EOF) { 199fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o switch (c) { 200fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o case 'p': 201fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o preserve++; 202fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o break; 203fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o default: 204fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o com_err(argv[0], 0, dump_usage); 205fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o return; 206fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o } 207fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o } 208fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o if (optind != argc-2) { 209fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o com_err(argv[0], 0, dump_usage); 210f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 211f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 212f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 213f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (check_fs_open(argv[0])) 214f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 215f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 216fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o in_fn = argv[optind]; 217fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o out_fn = argv[optind+1]; 218fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o 219fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o inode = string_to_inode(in_fn); 220f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (!inode) 221f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 222f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 223fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o fd = open(out_fn, O_CREAT | O_WRONLY | O_TRUNC, 0666); 224f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (fd < 0) { 225f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o com_err(argv[0], errno, "while opening %s for dump_inode", 226fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o out_fn); 227f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 228f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 229f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 230fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o dump_file(argv[0], inode, fd, preserve, out_fn); 231f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 232f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 233f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 234f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 235f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ovoid do_cat(int argc, char **argv) 236f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 237f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o ino_t inode; 238f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 239f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (argc != 2) { 240f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o com_err(argv[0], 0, "Usage: cat <file>"); 241f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 242f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 243f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 244f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (check_fs_open(argv[0])) 245f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 246f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 247f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o inode = string_to_inode(argv[1]); 248f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (!inode) 249f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 250f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 251fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o fflush(stdout); 252fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o fflush(stderr); 253fc6d9d519aef67735918bf02c0fa8c9222008f76Theodore Ts'o dump_file(argv[0], inode, 1, 0, argv[2]); 254f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 255f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return; 256f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 257f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 258