]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - debugfs/dump.c
ChangeLog, Makefile.in, bmap.c, bmove.c, ext2fs.h, jump.funcs:
[thirdparty/e2fsprogs.git] / debugfs / dump.c
CommitLineData
f3db3566
TT
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>
50e1e10f
TT
14#ifdef HAVE_ERRNO_H
15#include <errno.h>
16#endif
f3db3566
TT
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <fcntl.h>
fc6d9d51
TT
20#include <utime.h>
21#ifdef HAVE_GETOPT_H
22#include <getopt.h>
23#else
24extern int optind;
25extern char *optarg;
26#endif
27#ifdef HAVE_OPTRESET
28extern int optreset; /* defined by BSD, but not others */
29#endif
f3db3566
TT
30
31#include "debugfs.h"
32
fc6d9d51
TT
33/*
34 * The mode_xlate function translates a linux mode into a native-OS mode_t.
35 */
36static struct {
37 __u16 lmask;
38 mode_t mask;
39} mode_table[] = {
40 { LINUX_S_IRUSR, S_IRUSR },
41 { LINUX_S_IWUSR, S_IWUSR },
42 { LINUX_S_IXUSR, S_IXUSR },
43 { LINUX_S_IRGRP, S_IRGRP },
44 { LINUX_S_IWGRP, S_IWGRP },
45 { LINUX_S_IXGRP, S_IXGRP },
46 { LINUX_S_IROTH, S_IROTH },
47 { LINUX_S_IWOTH, S_IWOTH },
48 { LINUX_S_IXOTH, S_IXOTH },
49 { 0, 0 }
50};
51
52static mode_t mode_xlate(__u16 lmode)
53{
54 mode_t mode = 0;
55 int i;
56
57 for (i=0; mode_table[i].lmask; i++) {
58 if (lmode & mode_table[i].lmask)
59 mode |= mode_table[i].mask;
60 }
61 return mode;
62}
63
fc6d9d51
TT
64static void dump_file(char *cmdname, ino_t ino, int fd, int preserve,
65 char *outname)
f3db3566
TT
66{
67 errcode_t retval;
fc6d9d51
TT
68 struct ext2_inode inode;
69 struct utimbuf ut;
5a51384e
TT
70 char buf[8192];
71 ext2_file_t e2_file;
4a31c48b
TT
72 int nbytes;
73 unsigned int got;
5a51384e 74
fc6d9d51
TT
75 retval = ext2fs_read_inode(current_fs, ino, &inode);
76 if (retval) {
77 com_err(cmdname, retval,
78 "while reading inode %u in dump_file", ino);
79 return;
80 }
f3db3566 81
5a51384e
TT
82 retval = ext2fs_file_open(current_fs, ino, 0, &e2_file);
83 if (retval) {
84 com_err(cmdname, retval, "while opening ext2 file");
f3db3566
TT
85 return;
86 }
5a51384e
TT
87 while (1) {
88 retval = ext2fs_file_read(e2_file, buf, sizeof(buf), &got);
89 if (retval)
90 com_err(cmdname, retval, "while reading ext2 file");
91 if (got == 0)
92 break;
93 nbytes = write(fd, buf, got);
94 if (nbytes != got)
95 com_err(cmdname, errno, "while writing file");
f3db3566 96 }
5a51384e
TT
97 retval = ext2fs_file_close(e2_file);
98 if (retval) {
99 com_err(cmdname, retval, "while closing ext2 file");
100 return;
f3db3566 101 }
5a51384e 102
fc6d9d51
TT
103 if (preserve) {
104#ifdef HAVE_FCHOWN
105 if (fchown(fd, inode.i_uid, inode.i_gid) < 0)
106 com_err("dump_file", errno,
107 "while changing ownership of %s", outname);
108#else
109 if (chown(outname, inode.i_uid, inode.i_gid) < 0)
110 com_err("dump_file", errno,
111 "while changing ownership of %s", outname);
112
113#endif
114 if (fchmod(fd, mode_xlate(inode.i_mode)) < 0)
115 com_err("dump_file", errno,
116 "while setting permissions of %s", outname);
117 ut.actime = inode.i_atime;
118 ut.modtime = inode.i_mtime;
119 close(fd);
120 if (utime(outname, &ut) < 0)
121 com_err("dump_file", errno,
122 "while setting times on %s", outname);
123 } else if (fd != 1)
124 close(fd);
125
f3db3566
TT
126 return;
127}
128
129void do_dump(int argc, char **argv)
130{
131 ino_t inode;
132 int fd;
f1304811 133 int c;
fc6d9d51
TT
134 int preserve = 0;
135 const char *dump_usage = "Usage: dump_inode [-p] <file> <output_file>";
136 char *in_fn, *out_fn;
137
138 optind = 0;
139#ifdef HAVE_OPTRESET
140 optreset = 1; /* Makes BSD getopt happy */
141#endif
142 while ((c = getopt (argc, argv, "p")) != EOF) {
143 switch (c) {
144 case 'p':
145 preserve++;
146 break;
147 default:
148 com_err(argv[0], 0, dump_usage);
149 return;
150 }
151 }
152 if (optind != argc-2) {
153 com_err(argv[0], 0, dump_usage);
f3db3566
TT
154 return;
155 }
156
157 if (check_fs_open(argv[0]))
158 return;
159
fc6d9d51
TT
160 in_fn = argv[optind];
161 out_fn = argv[optind+1];
162
163 inode = string_to_inode(in_fn);
f3db3566
TT
164 if (!inode)
165 return;
166
fc6d9d51 167 fd = open(out_fn, O_CREAT | O_WRONLY | O_TRUNC, 0666);
f3db3566
TT
168 if (fd < 0) {
169 com_err(argv[0], errno, "while opening %s for dump_inode",
fc6d9d51 170 out_fn);
f3db3566
TT
171 return;
172 }
173
fc6d9d51 174 dump_file(argv[0], inode, fd, preserve, out_fn);
f3db3566 175
f3db3566
TT
176 return;
177}
178
179void do_cat(int argc, char **argv)
180{
181 ino_t inode;
182
183 if (argc != 2) {
184 com_err(argv[0], 0, "Usage: cat <file>");
185 return;
186 }
187
188 if (check_fs_open(argv[0]))
189 return;
190
191 inode = string_to_inode(argv[1]);
192 if (!inode)
193 return;
194
fc6d9d51
TT
195 fflush(stdout);
196 fflush(stderr);
197 dump_file(argv[0], inode, 1, 0, argv[2]);
f3db3566
TT
198
199 return;
200}
201