test-suite-pull-tools-directly-in-20020114
[openafs.git] / src / tests / null-search.c
1 #include <sys/fcntl.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <string.h>
5
6 #include "dumpscan.h"
7
8 char *argv0;
9 static char *input_path = 0;
10 static int quiet = 0, showpaths = 0, searchcount = 1;
11 static int error_count = 0, bad_count = 0;
12 static path_hashinfo phi;
13 static dump_parser dp;
14
15 /* Print a usage message and exit */
16 static void usage(int status, char *msg)
17 {
18   if (msg) fprintf(stderr, "%s: %s\n", argv0, msg);
19   fprintf(stderr, "Usage: %s [options] [file]\n", argv0);
20   fprintf(stderr, "  -h     Print this help message\n");
21   fprintf(stderr, "  -p     Print paths of bad vnodes\n");
22   fprintf(stderr, "  -q     Quiet mode (don't print errors)\n");
23   exit(status);
24 }
25
26
27 /* Parse the command-line options */
28 static void parse_options(int argc, char **argv)
29 {
30   int c;
31
32   if (argv0 = strrchr(argv[0], '/')) argv0++;
33   else argv0 = argv[0];
34
35   /* Parse the options */
36   while ((c = getopt(argc, argv, "n:hpq")) != EOF) {
37     switch (c) {
38       case 'n': searchcount  = atoi(optarg); continue;
39       case 'p': showpaths    = 1;            continue;
40       case 'q': quiet        = 1;            continue;
41       case 'h': usage(0, 0);
42       default:  usage(1, "Invalid option!");
43     }
44   }
45
46   if (argc - optind > 1) usage(1, "Too many arguments!");
47   input_path = (argc == optind) ? "-" : argv[optind];
48 }
49
50
51 /* A callback to count and print errors */
52 static afs_uint32 my_error_cb(afs_uint32 code, int fatal, void *ref, char *msg, ...)
53 {
54   va_list alist;
55
56   error_count++;
57   if (!quiet) {
58     va_start(alist, msg);
59     com_err_va(argv0, code, msg, alist);
60     va_end(alist);
61   }
62 }
63
64
65 /* A callback to process file vnodes */
66 static afs_uint32 my_file_cb(afs_vnode *v, XFILE *X, void *refcon)
67 {
68   static char buf[1024];
69   afs_uint32 size, nulls, cnulls, maxcnulls, n, r;
70   char *name = 0;
71   int i;
72
73   nulls = cnulls = maxcnulls = 0;
74   size = v->size;
75   if ((r = xfseek(X, &v->d_offset))) return r;
76   while (size) {
77     n = (size > 1024) ? 1024 : size;
78     if (r = xfread(X, buf, n)) return r;
79     for (i = 0; i < n; i++) {
80       if (buf[i]) {
81         if (cnulls > maxcnulls) maxcnulls = cnulls;
82         cnulls = 0;
83       } else {
84         nulls++;
85         cnulls++;
86       }
87     }
88     size -= n;
89   }
90   if (maxcnulls >= searchcount) {
91     bad_count++;
92     if (showpaths) Path_Build(X, &phi, v->vnode, &name, 0);
93     if (name) {
94       printf("*** BAD %d (%s) - %d nulls, %d consecutive\n",
95              v->vnode, name, nulls, maxcnulls);
96       free(name);
97     } else {
98       printf("*** BAD %d - %d nulls, %d consecutive\n",
99              v->vnode, nulls, maxcnulls);
100     }
101   }
102   return r;
103 }
104
105
106 int main(int argc, char **argv)
107 {
108   XFILE input_file;
109   afs_uint32 r;
110
111   parse_options(argc, argv);
112   initialize_acfg_error_table();
113   initialize_AVds_error_table();
114   initialize_rxk_error_table();
115   initialize_u_error_table();
116   initialize_vl_error_table();
117   initialize_vols_error_table();
118   initialize_xFil_error_table();
119   r = xfopen(&input_file, O_RDONLY, input_path);
120   if (r) {
121     com_err(argv0, r, "opening %s", input_path);
122     exit(2);
123   }
124
125   memset(&dp, 0, sizeof(dp));
126   dp.cb_error      = my_error_cb;
127   if (input_file.is_seekable) dp.flags |= DSFLAG_SEEK;
128   if (showpaths) {
129     u_int64 where;
130
131     memset(&phi, 0, sizeof(phi));
132     phi.p = &dp;
133
134     if ((r = xftell(&input_file, &where))
135     ||  (r = Path_PreScan(&input_file, &phi, 0))
136     ||  (r = xfseek(&input_file, &where))) {
137       com_err(argv0, r, "- path initialization failed");
138       xfclose(&input_file);
139       exit(2);
140     }
141   }
142
143   dp.cb_vnode_file = my_file_cb;
144   r = ParseDumpFile(&input_file, &dp);
145   xfclose(&input_file);
146
147   if (error_count) printf("*** %d errors\n", error_count);
148   if (bad_count)   printf("*** %d bad files\n", bad_count);
149   if (r && !quiet) printf("*** FAILED: %s\n", error_message(r));
150 }