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