OSDN Git Service

Merge "e2fsck: read only parameter incorrectly compared"
[android-x86/external-e2fsprogs.git] / tests / progs / test_rel.c
1 /*
2  * test_rel.c
3  *
4  * Copyright (C) 1997 Theodore Ts'o.
5  *
6  * %Begin-Header%
7  * This file may be redistributed under the terms of the GNU Public
8  * License.
9  * %End-Header%
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 #ifdef HAVE_GETOPT_H
17 #include <getopt.h>
18 #endif
19 #include <fcntl.h>
20
21 #include <et/com_err.h>
22 #include <ss/ss.h>
23 #include <ext2fs/ext2_fs.h>
24 #include <ext2fs/ext2fs.h>
25 #include <ext2fs/irel.h>
26 #include <ext2fs/brel.h>
27
28 #include "test_rel.h"
29
30 extern ss_request_table test_cmds;
31
32 ext2_irel irel = NULL;
33 ext2_brel brel = NULL;
34
35 /*
36  * Helper function which parses an inode number.
37  */
38 static int parse_inode(const char *request, const char *desc,
39                        const char *str, ext2_ino_t *ino)
40 {
41         char *tmp;
42
43         *ino = strtoul(str, &tmp, 0);
44         if (*tmp) {
45                 com_err(request, 0, "Bad %s - %s", desc, str);
46                 return 1;
47         }
48         return 0;
49 }
50
51 /*
52  * Helper function which parses a block number.
53  */
54 static int parse_block(const char *request, const char *desc,
55                        const char *str, blk_t *blk)
56 {
57         char *tmp;
58
59         *blk = strtoul(str, &tmp, 0);
60         if (*tmp) {
61                 com_err(request, 0, "Bad %s - %s", desc, str);
62                 return 1;
63         }
64         return 0;
65 }
66
67 /*
68  * Helper function which assures that a brel table is open
69  */
70 static int check_brel(char *request)
71 {
72         if (brel)
73                 return 0;
74         com_err(request, 0, "A block relocation table must be open.");
75         return 1;
76 }
77
78 /*
79  * Helper function which assures that an irel table is open
80  */
81 static int check_irel(char *request)
82 {
83         if (irel)
84                 return 0;
85         com_err(request, 0, "An inode relocation table must be open.");
86         return 1;
87 }
88
89 /*
90  * Helper function which displays a brel entry
91  */
92 static void display_brel_entry(blk_t old,
93                                struct ext2_block_relocate_entry *ent)
94 {
95         printf("Old= %u, New= %u, Owner= %u:%u\n", old, ent->new,
96                ent->owner.block_ref, ent->offset);
97 }
98
99 /*
100  * Helper function which displays an irel entry
101  */
102 static void display_irel_entry(ext2_ino_t old,
103                                struct ext2_inode_relocate_entry *ent,
104                                int do_refs)
105 {
106         struct ext2_inode_reference ref;
107         errcode_t       retval;
108         int             first = 1;
109
110         printf("Old= %lu, New= %lu, Original=%lu, Max_refs=%u\n", old,
111                ent->new, ent->orig, ent->max_refs);
112         if (!do_refs)
113                 return;
114
115         retval = ext2fs_irel_start_iter_ref(irel, old);
116         if (retval) {
117                 printf("\tCouldn't get references: %s\n",
118                        error_message(retval));
119                 return;
120         }
121         while (1) {
122                 retval = ext2fs_irel_next_ref(irel, &ref);
123                 if (retval) {
124                         printf("(%s) ", error_message(retval));
125                         break;
126                 }
127                 if (ref.block == 0)
128                         break;
129                 if (first) {
130                         fputc('\t', stdout);
131                         first = 0;
132                 } else
133                         printf(", ");
134                 printf("%u:%u", ref.block, ref.offset);
135         }
136         if (!first)
137                 fputc('\n', stdout);
138 }
139
140 /*
141  * These are the actual command table procedures
142  */
143 void do_brel_ma_create(int argc, char **argv)
144 {
145         const char *usage = "Usage: %s name max_blocks\n";
146         errcode_t       retval;
147         blk_t           max_blk;
148
149         if (argc < 3) {
150                 printf(usage, argv[0]);
151                 return;
152         }
153         if (parse_block(argv[0], "max_blocks", argv[2], &max_blk))
154                 return;
155         retval = ext2fs_brel_memarray_create(argv[1], max_blk, &brel);
156         if (retval) {
157                 com_err(argv[0], retval, "while opening memarray brel");
158                 return;
159         }
160         return;
161 }
162
163 void do_brel_free(int argc, char **argv)
164 {
165         if (check_brel(argv[0]))
166                 return;
167         ext2fs_brel_free(brel);
168         brel = NULL;
169         return;
170 }
171
172 void do_brel_put(int argc, char **argv)
173 {
174         const char *usage = "usage: %s old_block new_block [owner] [offset]";
175         errcode_t retval;
176         struct ext2_block_relocate_entry ent;
177         blk_t   old, new, offset=0, owner=0;
178
179         if (check_brel(argv[0]))
180                 return;
181
182         if (argc < 3) {
183                 printf(usage, argv[0]);
184                 return;
185         }
186         if (parse_block(argv[0], "old block", argv[1], &old))
187                 return;
188         if (parse_block(argv[0], "new block", argv[2], &new))
189                 return;
190         if (argc > 3 &&
191             parse_block(argv[0], "owner block", argv[3], &owner))
192                 return;
193         if (argc > 4 &&
194             parse_block(argv[0], "offset", argv[4], &offset))
195                 return;
196         if (offset > 65535) {
197                 printf("Offset too large.\n");
198                 return;
199         }
200         ent.new = new;
201         ent.offset = (__u16) offset;
202         ent.flags = 0;
203         ent.owner.block_ref = owner;
204
205         retval = ext2fs_brel_put(brel, old, &ent);
206         if (retval) {
207                 com_err(argv[0], retval, "while calling ext2fs_brel_put");
208                 return;
209         }
210         return;
211 }
212
213 void do_brel_get(int argc, char **argv)
214 {
215         const char *usage = "%s block";
216         errcode_t retval;
217         struct ext2_block_relocate_entry ent;
218         blk_t   blk;
219
220         if (check_brel(argv[0]))
221                 return;
222         if (argc < 2) {
223                 printf(usage, argv[0]);
224                 return;
225         }
226         if (parse_block(argv[0], "block", argv[1], &blk))
227                 return;
228         retval = ext2fs_brel_get(brel, blk, &ent);
229         if (retval) {
230                 com_err(argv[0], retval, "while calling ext2fs_brel_get");
231                 return;
232         }
233         display_brel_entry(blk, &ent);
234         return;
235 }
236
237 void do_brel_start_iter(int argc, char **argv)
238 {
239         errcode_t retval;
240
241         if (check_brel(argv[0]))
242                 return;
243
244         retval = ext2fs_brel_start_iter(brel);
245         if (retval) {
246                 com_err(argv[0], retval, "while calling ext2fs_brel_start_iter");
247                 return;
248         }
249         return;
250 }
251
252 void do_brel_next(int argc, char **argv)
253 {
254         errcode_t retval;
255         struct ext2_block_relocate_entry ent;
256         blk_t   blk;
257
258         if (check_brel(argv[0]))
259                 return;
260
261         retval = ext2fs_brel_next(brel, &blk, &ent);
262         if (retval) {
263                 com_err(argv[0], retval, "while calling ext2fs_brel_next");
264                 return;
265         }
266         if (blk == 0) {
267                 printf("No more entries!\n");
268                 return;
269         }
270         display_brel_entry(blk, &ent);
271         return;
272 }
273
274 void do_brel_dump(int argc, char **argv)
275 {
276         errcode_t retval;
277         struct ext2_block_relocate_entry ent;
278         blk_t   blk;
279
280         if (check_brel(argv[0]))
281                 return;
282
283         retval = ext2fs_brel_start_iter(brel);
284         if (retval) {
285                 com_err(argv[0], retval, "while calling ext2fs_brel_start_iter");
286                 return;
287         }
288
289         while (1) {
290                 retval = ext2fs_brel_next(brel, &blk, &ent);
291                 if (retval) {
292                         com_err(argv[0], retval, "while calling ext2fs_brel_next");
293                         return;
294                 }
295                 if (blk == 0)
296                         break;
297
298                 display_brel_entry(blk, &ent);
299         }
300         return;
301 }
302
303 void do_brel_move(int argc, char **argv)
304 {
305         const char *usage = "%s old_block new_block";
306         errcode_t retval;
307         blk_t   old, new;
308
309         if (check_brel(argv[0]))
310                 return;
311         if (argc < 2) {
312                 printf(usage, argv[0]);
313                 return;
314         }
315         if (parse_block(argv[0], "old block", argv[1], &old))
316                 return;
317         if (parse_block(argv[0], "new block", argv[2], &new))
318                 return;
319
320         retval = ext2fs_brel_move(brel, old, new);
321         if (retval) {
322                 com_err(argv[0], retval, "while calling ext2fs_brel_move");
323                 return;
324         }
325         return;
326 }
327
328 void do_brel_delete(int argc, char **argv)
329 {
330         const char *usage = "%s block";
331         errcode_t retval;
332         blk_t   blk;
333
334         if (check_brel(argv[0]))
335                 return;
336         if (argc < 2) {
337                 printf(usage, argv[0]);
338                 return;
339         }
340         if (parse_block(argv[0], "block", argv[1], &blk))
341                 return;
342
343         retval = ext2fs_brel_delete(brel, blk);
344         if (retval) {
345                 com_err(argv[0], retval, "while calling ext2fs_brel_delete");
346                 return;
347         }
348 }
349
350 void do_irel_ma_create(int argc, char **argv)
351 {
352         const char      *usage = "Usage: %s name max_inode\n";
353         errcode_t       retval;
354         ext2_ino_t      max_ino;
355
356         if (argc < 3) {
357                 printf(usage, argv[0]);
358                 return;
359         }
360         if (parse_inode(argv[0], "max_inodes", argv[2], &max_ino))
361                 return;
362         retval = ext2fs_irel_memarray_create(argv[1], max_ino, &irel);
363         if (retval) {
364                 com_err(argv[0], retval, "while opening memarray irel");
365                 return;
366         }
367         return;
368 }
369
370 void do_irel_free(int argc, char **argv)
371 {
372         if (check_irel(argv[0]))
373                 return;
374
375         ext2fs_irel_free(irel);
376         irel = NULL;
377         return;
378 }
379
380 void do_irel_put(int argc, char **argv)
381 {
382         const char      *usage = "%s old new max_refs";
383         errcode_t       retval;
384         ext2_ino_t      old, new, max_refs;
385         struct ext2_inode_relocate_entry ent;
386
387         if (check_irel(argv[0]))
388                 return;
389
390         if (argc < 4) {
391                 printf(usage, argv[0]);
392                 return;
393         }
394         if (parse_inode(argv[0], "old inode", argv[1], &old))
395                 return;
396         if (parse_inode(argv[0], "new inode", argv[2], &new))
397                 return;
398         if (parse_inode(argv[0], "max_refs", argv[3], &max_refs))
399                 return;
400         if (max_refs > 65535) {
401                 printf("max_refs too big\n");
402                 return;
403         }
404         ent.new = new;
405         ent.max_refs = (__u16) max_refs;
406         ent.flags = 0;
407
408         retval = ext2fs_irel_put(irel, old, &ent);
409         if (retval) {
410                 com_err(argv[0], retval, "while calling ext2fs_irel_put");
411                 return;
412         }
413         return;
414 }
415
416 void do_irel_get(int argc, char **argv)
417 {
418         const char      *usage = "%s inode";
419         errcode_t       retval;
420         ext2_ino_t      old;
421         struct ext2_inode_relocate_entry ent;
422
423         if (check_irel(argv[0]))
424                 return;
425
426         if (argc < 2) {
427                 printf(usage, argv[0]);
428                 return;
429         }
430         if (parse_inode(argv[0], "inode", argv[1], &old))
431                 return;
432
433         retval = ext2fs_irel_get(irel, old, &ent);
434         if (retval) {
435                 com_err(argv[0], retval, "while calling ext2fs_irel_get");
436                 return;
437         }
438         display_irel_entry(old, &ent, 1);
439         return;
440 }
441
442 void do_irel_get_by_orig(int argc, char **argv)
443 {
444         const char      *usage = "%s orig_inode";
445         errcode_t       retval;
446         ext2_ino_t      orig, old;
447         struct ext2_inode_relocate_entry ent;
448
449         if (check_irel(argv[0]))
450                 return;
451
452         if (argc < 2) {
453                 printf(usage, argv[0]);
454                 return;
455         }
456         if (parse_inode(argv[0], "original inode", argv[1], &orig))
457                 return;
458
459         retval = ext2fs_irel_get_by_orig(irel, orig, &old, &ent);
460         if (retval) {
461                 com_err(argv[0], retval, "while calling ext2fs_irel_get_by_orig");
462                 return;
463         }
464         display_irel_entry(old, &ent, 1);
465         return;
466 }
467
468 void do_irel_start_iter(int argc, char **argv)
469 {
470         errcode_t retval;
471
472         if (check_irel(argv[0]))
473                 return;
474
475         retval = ext2fs_irel_start_iter(irel);
476         if (retval) {
477                 com_err(argv[0], retval, "while calling ext2fs_irel_start_iter");
478                 return;
479         }
480         return;
481 }
482
483 void do_irel_next(int argc, char **argv)
484 {
485         errcode_t       retval;
486         ext2_ino_t      old;
487         struct ext2_inode_relocate_entry ent;
488
489         if (check_irel(argv[0]))
490                 return;
491
492         retval = ext2fs_irel_next(irel, &old, &ent);
493         if (retval) {
494                 com_err(argv[0], retval, "while calling ext2fs_irel_next");
495                 return;
496         }
497         if (old == 0) {
498                 printf("No more entries!\n");
499                 return;
500         }
501         display_irel_entry(old, &ent, 1);
502         return;
503 }
504
505 void do_irel_dump(int argc, char **argv)
506 {
507         errcode_t       retval;
508         ext2_ino_t      ino;
509         struct ext2_inode_relocate_entry ent;
510
511         if (check_irel(argv[0]))
512                 return;
513
514         retval = ext2fs_irel_start_iter(irel);
515         if (retval) {
516                 com_err(argv[0], retval, "while calling ext2fs_irel_start_iter");
517                 return;
518         }
519
520         while (1) {
521                 retval = ext2fs_irel_next(irel, &ino, &ent);
522                 if (retval) {
523                         com_err(argv[0], retval, "while calling ext2fs_irel_next");
524                         return;
525                 }
526                 if (ino == 0)
527                         break;
528
529                 display_irel_entry(ino, &ent, 1);
530         }
531         return;
532 }
533
534 void do_irel_add_ref(int argc, char **argv)
535 {
536         const char      *usage = "%s inode block offset";
537         errcode_t       retval;
538         blk_t           block, offset;
539         ext2_ino_t      ino;
540         struct ext2_inode_reference ref;
541
542
543         if (check_irel(argv[0]))
544                 return;
545
546         if (argc < 4) {
547                 printf(usage, argv[0]);
548                 return;
549         }
550         if (parse_inode(argv[0], "inode", argv[1], &ino))
551                 return;
552         if (parse_block(argv[0], "block", argv[2], &block))
553                 return;
554         if (parse_block(argv[0], "offset", argv[3], &offset))
555                 return;
556         if (offset > 65535) {
557                 printf("Offset too big.\n");
558                 return;
559         }
560         ref.block = block;
561         ref.offset = offset;
562
563         retval = ext2fs_irel_add_ref(irel, ino, &ref);
564         if (retval) {
565                 com_err(argv[0], retval, "while calling ext2fs_irel_add_ref");
566                 return;
567         }
568         return;
569 }
570
571 void do_irel_start_iter_ref(int argc, char **argv)
572 {
573         const char      *usage = "%s inode";
574         errcode_t       retval;
575         ext2_ino_t      ino;
576
577         if (check_irel(argv[0]))
578                 return;
579
580         if (argc < 2) {
581                 printf(usage, argv[0]);
582                 return;
583         }
584
585         if (parse_inode(argv[0], "inode", argv[1], &ino))
586                 return;
587         retval = ext2fs_irel_start_iter_ref(irel, ino);
588         if (retval) {
589                 com_err(argv[0], retval, "while calling ext2fs_irel_start_iter_ref");
590                 return;
591         }
592         return;
593 }
594
595 void do_irel_next_ref(int argc, char **argv)
596 {
597         struct ext2_inode_reference ref;
598         errcode_t retval;
599
600         if (check_irel(argv[0]))
601                 return;
602
603         retval = ext2fs_irel_next_ref(irel, &ref);
604         if (retval) {
605                 com_err(argv[0], retval, "while calling ext2fs_irel_next_ref");
606                 return;
607         }
608         printf("Inode reference: %u:%u\n", ref.block, ref.offset);
609         return;
610 }
611
612 void do_irel_move(int argc, char **argv)
613 {
614         const char      *usage = "%s old new";
615         errcode_t       retval;
616         ext2_ino_t      old, new;
617
618         if (check_irel(argv[0]))
619                 return;
620
621         if (argc < 3) {
622                 printf(usage, argv[0]);
623                 return;
624         }
625         if (parse_inode(argv[0], "old inode", argv[1], &old))
626                 return;
627         if (parse_inode(argv[0], "new inode", argv[2], &new))
628                 return;
629
630         retval = ext2fs_irel_move(irel, old, new);
631         if (retval) {
632                 com_err(argv[0], retval, "while calling ext2fs_irel_move");
633                 return;
634         }
635         return;
636 }
637
638 void do_irel_delete(int argc, char **argv)
639 {
640         const char      *usage = "%s inode";
641         errcode_t       retval;
642         ext2_ino_t      ino;
643
644         if (check_irel(argv[0]))
645                 return;
646
647         if (argc < 2) {
648                 printf(usage, argv[0]);
649                 return;
650         }
651         if (parse_inode(argv[0], "inode", argv[1], &ino))
652                 return;
653
654         retval = ext2fs_irel_delete(irel, ino);
655         if (retval) {
656                 com_err(argv[0], retval, "while calling ext2fs_irel_delete");
657                 return;
658         }
659         return;
660 }
661
662 static int source_file(const char *cmd_file, int sci_idx)
663 {
664         FILE            *f;
665         char            buf[256];
666         char            *cp;
667         int             exit_status = 0;
668         int             retval;
669         int             noecho;
670
671         if (strcmp(cmd_file, "-") == 0)
672                 f = stdin;
673         else {
674                 f = fopen(cmd_file, "r");
675                 if (!f) {
676                         perror(cmd_file);
677                         exit(1);
678                 }
679         }
680         fflush(stdout);
681         fflush(stderr);
682         setbuf(stdout, NULL);
683         setbuf(stderr, NULL);
684         while (!feof(f)) {
685                 if (fgets(buf, sizeof(buf), f) == NULL)
686                         break;
687                 if (buf[0] == '#')
688                         continue;
689                 noecho = 0;
690                 if (buf[0] == '-') {
691                         noecho = 1;
692                         buf[0] = ' ';
693                 }
694                 cp = strchr(buf, '\n');
695                 if (cp)
696                         *cp = 0;
697                 cp = strchr(buf, '\r');
698                 if (cp)
699                         *cp = 0;
700                 if (!noecho)
701                         printf("test_rel: %s\n", buf);
702                 retval = ss_execute_line(sci_idx, buf);
703                 if (retval) {
704                         ss_perror(sci_idx, retval, buf);
705                         exit_status++;
706                 }
707         }
708         return exit_status;
709 }
710
711 void main(int argc, char **argv)
712 {
713         int             retval;
714         int             sci_idx;
715         const char      *usage = "Usage: test_rel [-R request] [-f cmd_file]";
716         int             c;
717         char            *request = 0;
718         int             exit_status = 0;
719         char            *cmd_file = 0;
720
721         initialize_ext2_error_table();
722
723         while ((c = getopt (argc, argv, "wR:f:")) != EOF) {
724                 switch (c) {
725                 case 'R':
726                         request = optarg;
727                         break;
728                 case 'f':
729                         cmd_file = optarg;
730                         break;
731                 default:
732                         com_err(argv[0], 0, usage);
733                         return;
734                 }
735         }
736         sci_idx = ss_create_invocation("test_rel", "0.0", (char *) NULL,
737                                        &test_cmds, &retval);
738         if (retval) {
739                 ss_perror(sci_idx, retval, "creating invocation");
740                 exit(1);
741         }
742
743         (void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &retval);
744         if (retval) {
745                 ss_perror(sci_idx, retval, "adding standard requests");
746                 exit (1);
747         }
748         if (request) {
749                 retval = 0;
750                 retval = ss_execute_line(sci_idx, request);
751                 if (retval) {
752                         ss_perror(sci_idx, retval, request);
753                         exit_status++;
754                 }
755         } else if (cmd_file) {
756                 exit_status = source_file(cmd_file, sci_idx);
757         } else {
758                 ss_listen(sci_idx);
759         }
760
761         exit(exit_status);
762 }
763