020c38708a4d7be0586418ec33ee442c015fd4b5
[openafs.git] / src / tests / afsdump_dirlist.c
1 /*
2  * CMUCS AFStools
3  * dumpscan - routines for scanning and manipulating AFS volume dumps
4  *
5  * Copyright (c) 1998 Carnegie Mellon University
6  * All Rights Reserved.
7  * 
8  * Permission to use, copy, modify and distribute this software and its
9  * documentation is hereby granted, provided that both the copyright
10  * notice and this permission notice appear in all copies of the
11  * software, derivative works or modified versions, and any portions
12  * thereof, and that both notices appear in supporting documentation.
13  *
14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie Mellon
26  * the rights to redistribute these changes.
27  */
28
29 /* afsdump_dirlist.c - List an AFS directory file */
30
31 #include <sys/fcntl.h>
32 #include <stdlib.h>
33 #include <stdarg.h>
34 #include <string.h>
35
36 #include "dumpscan.h"
37
38 extern int optind;
39 extern char *optarg;
40
41 char *argv0;
42 static char *input_path;
43 static int quiet, verbose, error_count;
44
45 static path_hashinfo phi;
46 static dump_parser dp;
47
48
49 /* Print a usage message and exit */
50 static void
51 usage(int status, char *msg)
52 {
53     if (msg)
54         fprintf(stderr, "%s: %s\n", argv0, msg);
55     fprintf(stderr, "Usage: %s [options] [file]\n", argv0);
56     fprintf(stderr, "  -h     Print this help message\n");
57     fprintf(stderr, "  -q     Quiet mode (don't print errors)\n");
58     fprintf(stderr, "  -v     Verbose mode\n");
59     exit(status);
60 }
61
62
63 /* Parse the command-line options */
64 static void
65 parse_options(int argc, char **argv)
66 {
67     int c;
68
69     /* Set the program name */
70     if (argv0 = strrchr(argv[0], '/'))
71         argv0++;
72     else
73         argv0 = argv[0];
74
75     /* Initialize options */
76     input_path = 0;
77     quiet = verbose = 0;
78
79     /* Initialize other stuff */
80     error_count = 0;
81
82     /* Parse the options */
83     while ((c = getopt(argc, argv, "hqv")) != EOF) {
84         switch (c) {
85         case 'q':
86             quiet = 1;
87             continue;
88         case 'v':
89             verbose = 1;
90             continue;
91         case 'h':
92             usage(0, 0);
93         default:
94             usage(1, "Invalid option!");
95         }
96     }
97
98     if (quiet && verbose)
99         usage(1, "Can't specify both -q and -v");
100
101     /* Parse non-option arguments */
102     if (argc - optind > 1)
103         usage(1, "Too many arguments!");
104     input_path = (argc == optind) ? "-" : argv[optind];
105 }
106
107
108 /* A callback to count and print errors */
109 static afs_uint32
110 my_error_cb(afs_uint32 code, int fatal, void *ref, char *msg, ...)
111 {
112     va_list alist;
113
114     error_count++;
115     if (!quiet) {
116         va_start(alist, msg);
117         com_err_va(argv0, code, msg, alist);
118         va_end(alist);
119     }
120 }
121
122
123 /* Main program */
124 void
125 main(int argc, char **argv)
126 {
127     XFILE input_file;
128     afs_uint32 r;
129
130     parse_options(argc, argv);
131     initialize_acfg_error_table();
132     initialize_AVds_error_table();
133     initialize_rxk_error_table();
134     initialize_u_error_table();
135     initialize_vl_error_table();
136     initialize_vols_error_table();
137     initialize_xFil_error_table();
138     r = xfopen(&input_file, O_RDONLY, input_path);
139     if (r) {
140         com_err(argv0, r, "opening %s", input_path);
141         exit(2);
142     }
143
144     memset(&dp, 0, sizeof(dp));
145     dp.cb_error = my_error_cb;
146     dp.print_flags = DSPRINT_DIR;
147     if (input_file.is_seekable)
148         dp.flags |= DSFLAG_SEEK;
149
150     r = ParseDirectory(&input_file, &dp, 0, 1);
151     xfclose(&input_file);
152
153     if (verbose && error_count)
154         fprintf(stderr, "*** %d errors\n", error_count);
155     if (r && !quiet)
156         fprintf(stderr, "*** FAILED: %s\n", error_message(r));
157     exit(0);
158 }