Import Upstream version 1.8.5
[hcoop/debian/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
17 usage(int status, char *msg)
18 {
19 if (msg)
20 fprintf(stderr, "%s: %s\n", argv0, msg);
21 fprintf(stderr, "Usage: %s [options] [file]\n", argv0);
22 fprintf(stderr, " -h Print this help message\n");
23 fprintf(stderr, " -p Print paths of bad vnodes\n");
24 fprintf(stderr, " -q Quiet mode (don't print errors)\n");
25 exit(status);
26 }
27
28
29 /* Parse the command-line options */
30 static void
31 parse_options(int argc, char **argv)
32 {
33 int c;
34
35 if (argv0 = strrchr(argv[0], '/'))
36 argv0++;
37 else
38 argv0 = argv[0];
39
40 /* Parse the options */
41 while ((c = getopt(argc, argv, "n:hpq")) != EOF) {
42 switch (c) {
43 case 'n':
44 searchcount = atoi(optarg);
45 continue;
46 case 'p':
47 showpaths = 1;
48 continue;
49 case 'q':
50 quiet = 1;
51 continue;
52 case 'h':
53 usage(0, 0);
54 default:
55 usage(1, "Invalid option!");
56 }
57 }
58
59 if (argc - optind > 1)
60 usage(1, "Too many arguments!");
61 input_path = (argc == optind) ? "-" : argv[optind];
62 }
63
64
65 /* A callback to count and print errors */
66 static afs_uint32
67 my_error_cb(afs_uint32 code, int fatal, void *ref, char *msg, ...)
68 {
69 va_list alist;
70
71 error_count++;
72 if (!quiet) {
73 va_start(alist, msg);
74 afs_com_err_va(argv0, code, msg, alist);
75 va_end(alist);
76 }
77 }
78
79
80 /* A callback to process file vnodes */
81 static afs_uint32
82 my_file_cb(afs_vnode * v, XFILE * X, void *refcon)
83 {
84 static char buf[1024];
85 afs_uint32 size, nulls, cnulls, maxcnulls, n, r;
86 char *name = 0;
87 int i;
88
89 nulls = cnulls = maxcnulls = 0;
90 size = v->size;
91 if ((r = xfseek(X, &v->d_offset)))
92 return r;
93 while (size) {
94 n = (size > 1024) ? 1024 : size;
95 if (r = xfread(X, buf, n))
96 return r;
97 for (i = 0; i < n; i++) {
98 if (buf[i]) {
99 if (cnulls > maxcnulls)
100 maxcnulls = cnulls;
101 cnulls = 0;
102 } else {
103 nulls++;
104 cnulls++;
105 }
106 }
107 size -= n;
108 }
109 if (maxcnulls >= searchcount) {
110 bad_count++;
111 if (showpaths)
112 Path_Build(X, &phi, v->vnode, &name, 0);
113 if (name) {
114 printf("*** BAD %d (%s) - %d nulls, %d consecutive\n", v->vnode,
115 name, nulls, maxcnulls);
116 free(name);
117 } else {
118 printf("*** BAD %d - %d nulls, %d consecutive\n", v->vnode, nulls,
119 maxcnulls);
120 }
121 }
122 return r;
123 }
124
125
126 int
127 main(int argc, char **argv)
128 {
129 XFILE input_file;
130 afs_uint32 r;
131
132 parse_options(argc, argv);
133 initialize_acfg_error_table();
134 initialize_AVds_error_table();
135 initialize_rxk_error_table();
136 initialize_u_error_table();
137 initialize_vl_error_table();
138 initialize_vols_error_table();
139 initialize_xFil_error_table();
140 r = xfopen(&input_file, O_RDONLY, input_path);
141 if (r) {
142 afs_com_err(argv0, r, "opening %s", input_path);
143 exit(2);
144 }
145
146 memset(&dp, 0, sizeof(dp));
147 dp.cb_error = my_error_cb;
148 if (input_file.is_seekable)
149 dp.flags |= DSFLAG_SEEK;
150 if (showpaths) {
151 u_int64 where;
152
153 memset(&phi, 0, sizeof(phi));
154 phi.p = &dp;
155
156 if ((r = xftell(&input_file, &where))
157 || (r = Path_PreScan(&input_file, &phi, 0))
158 || (r = xfseek(&input_file, &where))) {
159 afs_com_err(argv0, r, "- path initialization failed");
160 xfclose(&input_file);
161 exit(2);
162 }
163 }
164
165 dp.cb_vnode_file = my_file_cb;
166 r = ParseDumpFile(&input_file, &dp);
167 xfclose(&input_file);
168
169 if (error_count)
170 printf("*** %d errors\n", error_count);
171 if (bad_count)
172 printf("*** %d bad files\n", bad_count);
173 if (r && !quiet)
174 printf("*** FAILED: %s\n", afs_error_message(r));
175 }