13f19f367cb2b9e26eb2099ce7eb7b7a74792bc4
[openafs.git] / src / dir / test / dtest.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #define PAGESIZE 2048
11 #include <afsconfig.h>
12 #include <afs/param.h>
13
14 #include <roken.h>
15
16 #include <stdarg.h>
17
18 #include <afs/dir.h>
19
20 long fidCounter = 0;
21
22 typedef struct dirhandle {
23     int fd;
24     int uniq;
25 } dirhandle;
26 int Uniq;
27
28 static void OpenDir(char *name, dirhandle *dir);
29 static void CreateDir(char *name, dirhandle *dir);
30
31 static void
32 Usage(void)
33 {
34     printf("Usage: dtest <command [args]>, where command is one of:\n");
35     printf("-l file - lists directory in file\n");
36     printf("-c file - checks directory in file\n");
37     printf("-s ifile ofile - salvages directory in ifile, places in ofile\n");
38     printf
39         ("-f file name count - creates count names based on \"name\" in directory in file\n");
40     printf("-d file name - delete name from directory in file\n");
41     printf("-r file name - lookup name in directory\n");
42     printf("-a file name - add name to directory in file\n");
43     exit(1);
44 }
45
46 static void
47 LookupDir(char *dname, char *ename)
48 {
49     dirhandle dir;
50     long fid[3];
51     int code;
52
53     OpenDir(dname, &dir);
54     code = Lookup(&dir, ename, fid);
55     if (code)
56         printf("lookup code %d\n", code);
57     else {
58         printf("Found fid %ld.%ld for file '%s'\n", fid[1], fid[2], ename);
59     }
60     DFlush();
61 }
62
63 static void
64 AddEntry(char *dname, char *ename)
65 {
66     dirhandle dir;
67     long fid[3];
68     int code;
69
70     fid[1] = fidCounter++;
71     fid[2] = 3;
72     OpenDir(dname, &dir);
73     code = Create(&dir, ename, fid);
74     if (code)
75         printf("create code %d\n", code);
76     DFlush();
77 }
78
79 static int
80 ListEntry(void * handle, char *name, afs_int32 vnode, afs_int32 unique)
81 {
82     printf("%s\t%ld\t%ld\n", name, afs_printable_int32_ld(vnode),
83            afs_printable_int32_ld(unique));
84
85     return 0;
86 }
87
88 static void
89 ListDir(char *name)
90 {
91     dirhandle dir;
92     OpenDir(name, &dir);
93     EnumerateDir(&dir, ListEntry, 0);
94 }
95
96 static void
97 CheckDir(char *name)
98 {
99     dirhandle dir;
100     OpenDir(name, &dir);
101     if (DirOK(&dir))
102         printf("Directory ok.\n");
103     else
104         printf("Directory bad\n");
105 }
106
107 static void
108 SalvageDir(char *iname, char *oname)
109 {
110     dirhandle in, out;
111     afs_int32 myFid[3], parentFid[3];
112
113     OpenDir(iname, &in);
114     if (Lookup(&in, ".", myFid) || Lookup(&in, "..", parentFid)) {
115         printf("Lookup of \".\" and/or \"..\" failed: ");
116         printf("%d %d %d %d\n", myFid[1], myFid[2], parentFid[1],
117                parentFid[2]);
118         printf("Directory cannnot be salvaged\n");
119     }
120     CreateDir(oname, &out);
121     DirSalvage(&in, &out, myFid[1], myFid[2], parentFid[1], parentFid[2]);
122     DFlush();
123 }
124
125 static void
126 DelTest(char *dname, char *ename)
127 {
128     dirhandle dir;
129     int code;
130
131     OpenDir(dname, &dir);
132     code = Delete(&dir, ename);
133     if (code)
134         printf("delete code is %d\n", code);
135     DFlush();
136 }
137
138 static void
139 CRTest(char *dname, char *ename, int count)
140 {
141     char tbuffer[200];
142     int i;
143     afs_int32 fid[3];
144     dirhandle dir;
145     int code;
146
147     CreateDir(dname, &dir);
148     memset(fid, 0, sizeof(fid));
149     MakeDir(&dir, fid, fid);
150     for (i = 0; i < count; i++) {
151         sprintf(tbuffer, "%s%d", ename, i);
152         fid[1] = fidCounter++;
153         fid[2] = count;
154         code = Create(&dir, tbuffer, &fid);
155         if (i % 100 == 0) {
156             printf("#");
157             fflush(stdout);
158         }
159         if (code) {
160             printf("code for '%s' is %d\n", tbuffer, code);
161             return;
162         }
163     }
164     DFlush();
165 }
166
167 static void
168 OpenDir(char *name, dirhandle *dir)
169 {
170     dir->fd = open(name, O_RDWR, 0666);
171     if (dir->fd == -1) {
172         printf("Couldn't open %s\n", name);
173         exit(1);
174     }
175     dir->uniq = ++Uniq;
176 }
177
178 static void
179 CreateDir(char *name, dirhandle *dir)
180 {
181     dir->fd = open(name, O_CREAT | O_RDWR | O_TRUNC, 0666);
182     dir->uniq = ++Uniq;
183     if (dir->fd == -1) {
184         printf("Couldn't create %s\n", name);
185         exit(1);
186     }
187 }
188
189 int
190 ReallyRead(dirhandle *dir, int block, char *data)
191 {
192     int code;
193     if (lseek(dir->fd, block * PAGESIZE, 0) == -1)
194         return errno;
195     code = read(dir->fd, data, PAGESIZE);
196     if (code < 0)
197         return errno;
198     if (code != PAGESIZE)
199         return EIO;
200     return 0;
201 }
202
203 int
204 ReallyWrite(dirhandle *dir, int block, char *data)
205 {
206     int code;
207     if (lseek(dir->fd, block * PAGESIZE, 0) == -1)
208         return errno;
209     code = write(dir->fd, data, PAGESIZE);
210     if (code < 0)
211         return errno;
212     if (code != PAGESIZE)
213         return EIO;
214     return 0;
215 }
216
217 void
218 FidZap(dirhandle *dir)
219 {
220     dir->fd = -1;
221 }
222
223 void
224 FidZero(long *afid)
225 {
226     *afid = 0;
227 }
228
229 int
230 FidEq(dirhandle *dir1, dirhandle *dir2)
231 {
232     return (dir1->uniq == dir2->uniq);
233 }
234
235 int
236 FidVolEq(long *afid, long *bfid)
237 {
238     return 1;
239 }
240
241 void
242 FidCpy(dirhandle *todir, dirhandle *fromdir)
243 {
244     *todir = *fromdir;
245 }
246
247 void
248 Die(char *msg)
249 {
250     printf("Something died with this message:  %s\n", msg);
251 }
252
253 void
254 Log(const char *fmt, ...)
255 {
256     va_list ap;
257
258     va_start(ap, fmt);
259     vprintf(fmt, ap);
260     va_end(ap);
261 }
262
263 int
264 main(int argc, char **argv)
265 {
266     DInit(600);
267     argc--;
268     argv++;
269
270     if (argc == 0)
271         Usage();
272
273     switch ((*argv++)[1]) {
274     case 'l':
275         ListDir(*argv);
276         break;
277     case 'c':
278         CheckDir(*argv);
279         break;
280     case 's':
281         SalvageDir(*argv, argv[1]);
282         break;
283     case 'f':
284         CRTest(*argv, argv[1], atoi(argv[2]));
285         break;
286     case 'd':
287         DelTest(*argv, argv[1]);
288         break;
289     case 'r':
290         LookupDir(*argv, argv[1]);
291         break;
292     case 'a':
293         AddEntry(*argv, argv[1]);
294         break;
295     default:
296         Usage();
297     }
298     exit(0);
299 }