OSDN Git Service

am f65354a9: Merge "Add bare-bones encryption support to e2fsck"
[android-x86/external-e2fsprogs.git] / debugfs / zap.c
1 /*
2  * zap.c --- zap block
3  *
4  * Copyright (C) 2012 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 #ifdef HAVE_ERRNO_H
15 #include <errno.h>
16 #endif
17 #include <sys/types.h>
18 #ifdef HAVE_GETOPT_H
19 #include <getopt.h>
20 #else
21 extern int optind;
22 extern char *optarg;
23 #endif
24
25 #include "debugfs.h"
26
27 void do_zap_block(int argc, char *argv[])
28 {
29         unsigned long   pattern = 0;
30         unsigned char   *buf;
31         ext2_ino_t      inode;
32         errcode_t       errcode;
33         blk64_t         block;
34         char            *file = NULL;
35         int             c, err;
36         int             offset = -1;
37         int             length = -1;
38         int             bit = -1;
39
40         if (check_fs_open(argv[0]))
41                 return;
42         if (check_fs_read_write(argv[0]))
43                 return;
44
45         reset_getopt();
46         while ((c = getopt (argc, argv, "b:f:l:o:p:")) != EOF) {
47                 switch (c) {
48                 case 'f':
49                         file = optarg;
50                         break;
51                 case 'b':
52                         bit = parse_ulong(optarg, argv[0],
53                                           "bit", &err);
54                         if (err)
55                                 return;
56                         if (bit >= (int) current_fs->blocksize * 8) {
57                                 com_err(argv[0], 0, "The bit to flip "
58                                         "must be within a %d block\n",
59                                         current_fs->blocksize);
60                                 return;
61                         }
62                         break;
63                 case 'p':
64                         pattern = parse_ulong(optarg, argv[0],
65                                               "pattern", &err);
66                         if (err)
67                                 return;
68                         if (pattern >= 256) {
69                                 com_err(argv[0], 0, "The fill pattern must "
70                                         "be an 8-bit value\n");
71                                 return;
72                         }
73                         break;
74                 case 'o':
75                         offset = parse_ulong(optarg, argv[0],
76                                              "offset", &err);
77                         if (err)
78                                 return;
79                         if (offset >= (int) current_fs->blocksize) {
80                                 com_err(argv[0], 0, "The offset must be "
81                                         "within a %d block\n",
82                                         current_fs->blocksize);
83                                 return;
84                         }
85                         break;
86
87                         break;
88                 case 'l':
89                         length = parse_ulong(optarg, argv[0],
90                                              "length", &err);
91                         if (err)
92                                 return;
93                         break;
94                 default:
95                         goto print_usage;
96                 }
97         }
98
99         if (bit > 0 && offset > 0) {
100                 com_err(argv[0], 0, "The -o and -b options can not be mixed.");
101                 return;
102         }
103
104         if (offset < 0)
105                 offset = 0;
106         if (length < 0)
107                 length = current_fs->blocksize - offset;
108         if ((offset + length) > (int) current_fs->blocksize) {
109                 com_err(argv[0], 0, "The specified length is too bug\n");
110                 return;
111         }
112
113         if (argc != optind+1) {
114         print_usage:
115                 com_err(0, 0, "Usage:\tzap_block [-f file] [-o offset] "
116                         "[-l length] [-p pattern] block_num");
117                 com_err(0, 0, "\tzap_block [-f file] [-b bit] "
118                         "block_num");
119                 return;
120         }
121
122         block = parse_ulonglong(argv[optind], argv[0], "block", &err);
123         if (err)
124                 return;
125
126         if (file) {
127                 inode = string_to_inode(file);
128                 if (!inode)
129                         return;
130                 errcode = ext2fs_bmap2(current_fs, inode, 0, 0, 0,
131                                        block, 0, &block);
132                 if (errcode) {
133                         com_err(argv[0], errcode,
134                                 "while mapping logical block %llu\n", block);
135                         return;
136                 }
137         }
138
139         buf = malloc(current_fs->blocksize);
140         if (!buf) {
141                 com_err(argv[0], 0, "Couldn't allocate block buffer");
142                 return;
143         }
144
145         errcode = io_channel_read_blk64(current_fs->io, block, 1, buf);
146         if (errcode) {
147                 com_err(argv[0], errcode,
148                         "while reading block %llu\n", block);
149                 goto errout;
150         }
151
152         if (bit >= 0)
153                 buf[bit >> 3] ^= 1 << (bit & 7);
154         else
155                 memset(buf+offset, pattern, length);
156
157         errcode = io_channel_write_blk64(current_fs->io, block, 1, buf);
158         if (errcode) {
159                 com_err(argv[0], errcode,
160                         "while write block %llu\n", block);
161                 goto errout;
162         }
163
164 errout:
165         free(buf);
166         return;
167 }
168
169 void do_block_dump(int argc, char *argv[])
170 {
171         unsigned char   *buf;
172         ext2_ino_t      inode;
173         errcode_t       errcode;
174         blk64_t         block;
175         char            *file = NULL;
176         unsigned int    i, j;
177         int             c, err;
178         int             suppress = -1;
179
180         if (check_fs_open(argv[0]))
181                 return;
182
183         reset_getopt();
184         while ((c = getopt (argc, argv, "f:")) != EOF) {
185                 switch (c) {
186                 case 'f':
187                         file = optarg;
188                         break;
189
190                 default:
191                         goto print_usage;
192                 }
193         }
194
195         if (argc != optind + 1) {
196         print_usage:
197                 com_err(0, 0, "Usage: block_dump [-f inode] block_num");
198                 return;
199         }
200
201         block = parse_ulonglong(argv[optind], argv[0], "block", &err);
202         if (err)
203                 return;
204
205         if (file) {
206                 inode = string_to_inode(file);
207                 if (!inode)
208                         return;
209                 errcode = ext2fs_bmap2(current_fs, inode, 0, 0, 0,
210                                        block, 0, &block);
211                 if (errcode) {
212                         com_err(argv[0], errcode,
213                                 "while mapping logical block %llu\n", block);
214                         return;
215                 }
216         }
217
218         buf = malloc(current_fs->blocksize);
219         if (!buf) {
220                 com_err(argv[0], 0, "Couldn't allocate block buffer");
221                 return;
222         }
223
224         errcode = io_channel_read_blk64(current_fs->io, block, 1, buf);
225         if (errcode) {
226                 com_err(argv[0], errcode,
227                         "while reading block %llu\n", block);
228                 goto errout;
229         }
230
231         for (i=0; i < current_fs->blocksize; i += 16) {
232                 if (suppress < 0) {
233                         if (i && memcmp(buf + i, buf + i - 16, 16) == 0) {
234                                 suppress = i;
235                                 printf("*\n");
236                                 continue;
237                         }
238                 } else {
239                         if (memcmp(buf + i, buf + suppress, 16) == 0)
240                                 continue;
241                         suppress = -1;
242                 }
243                 printf("%04o  ", i);
244                 for (j = 0; j < 16; j++) {
245                         printf("%02x", buf[i+j]);
246                         if ((j % 2) == 1)
247                                 putchar(' ');
248                 }
249                 putchar(' ');
250                 for (j = 0; j < 16; j++)
251                         printf("%c", isprint(buf[i+j]) ? buf[i+j] : '.');
252                 putchar('\n');
253         }
254         putchar('\n');
255
256 errout:
257         free(buf);
258         return;
259 }