e2fsprogs/debugfs/dump.c

144 lines
2.6 KiB
C

/*
* dump.c --- dump the contents of an inode out to a file
*
* Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
* under the terms of the GNU Public License.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "debugfs.h"
struct dump_block_struct {
int fd;
char *buf;
errcode_t errcode;
};
int dump_block(ext2_filsys fs, blk_t *blocknr, int blockcnt, void
*private)
{
ssize_t nbytes;
struct dump_block_struct *rec = (struct dump_block_struct *) private;
if (blockcnt < 0)
return 0;
if (*blocknr) {
rec->errcode = io_channel_read_blk(fs->io, *blocknr,
1, rec->buf);
if (rec->errcode)
return BLOCK_ABORT;
} else
memset(rec->buf, 0, fs->blocksize);
retry_write:
nbytes = write(rec->fd, rec->buf, fs->blocksize);
if (nbytes == -1) {
if (errno == EINTR)
goto retry_write;
rec->errcode = errno;
return BLOCK_ABORT;
}
if (nbytes != fs->blocksize) {
/* XXX not quite right, but good enough */
rec->errcode = EXT2_ET_SHORT_WRITE;
return BLOCK_ABORT;
}
return 0;
}
void dump_file(char *cmdname, ino_t inode, int fd, char *outname)
{
errcode_t retval;
struct dump_block_struct rec;
rec.fd = fd;
rec.errcode = 0;
rec.buf = malloc(fs->blocksize);
if (rec.buf == 0) {
com_err(cmdname, ENOMEM, "while allocating block buffer for dump_inode");
return;
}
retval = ext2fs_block_iterate(fs, inode, 0, NULL,
dump_block, &rec);
if (retval) {
com_err(cmdname, retval, "while iterating over blocks in %s",
outname);
goto cleanup;
}
if (rec.errcode) {
com_err(cmdname, retval, "in dump_block while dumping %s",
outname);
goto cleanup;
}
cleanup:
free(rec.buf);
return;
}
void do_dump(int argc, char **argv)
{
ino_t inode;
int fd;
if (argc != 3) {
com_err(argv[0], 0, "Usage: dump_inode <file> <output_file>");
return;
}
if (check_fs_open(argv[0]))
return;
inode = string_to_inode(argv[1]);
if (!inode)
return;
fd = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fd < 0) {
com_err(argv[0], errno, "while opening %s for dump_inode",
argv[2]);
return;
}
dump_file(argv[0], inode, fd, argv[2]);
close(fd);
return;
}
void do_cat(int argc, char **argv)
{
ino_t inode;
if (argc != 2) {
com_err(argv[0], 0, "Usage: cat <file>");
return;
}
if (check_fs_open(argv[0]))
return;
inode = string_to_inode(argv[1]);
if (!inode)
return;
dump_file(argv[0], inode, 0, argv[2]);
return;
}