dir: dtest should flush on error when creating directories
[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 <afs/dir.h>
17 #include <afs/opr.h>
18
19 long fidCounter = 0;
20
21 typedef struct DirHandle {
22     int fd;
23     int uniq;
24 } dirhandle;
25 int Uniq;
26
27 static void OpenDir(char *name, dirhandle *dir);
28 static void CreateDir(char *name, dirhandle *dir);
29
30 static void
31 Usage(void)
32 {
33     printf("Usage: dtest <command [args]>, where command is one of:\n");
34     printf("-l file - lists directory in file\n");
35     printf("-c file - checks directory in file\n");
36     printf("-s ifile ofile - salvages directory in ifile, places in ofile\n");
37     printf
38         ("-f file name count - creates count names based on \"name\" in directory in file\n");
39     printf("-d file name - delete name from directory in file\n");
40     printf("-r file name - lookup name in directory\n");
41     printf("-a file name - add name to directory in file\n");
42     exit(1);
43 }
44
45 static void
46 LookupDir(char *dname, char *ename)
47 {
48     dirhandle dir;
49     afs_int32 fid[3];
50     int code;
51
52     OpenDir(dname, &dir);
53     code = afs_dir_Lookup(&dir, ename, fid);
54     if (code)
55         printf("lookup code %d\n", code);
56     else {
57         printf("Found fid %d.%d for file '%s'\n", fid[1], fid[2], ename);
58     }
59     DFlush();
60 }
61
62 static void
63 AddEntry(char *dname, char *ename)
64 {
65     dirhandle dir;
66     afs_int32 fid[3];
67     int code;
68
69     fid[1] = fidCounter++;
70     fid[2] = 3;
71     OpenDir(dname, &dir);
72     code = afs_dir_Create(&dir, ename, fid);
73     if (code)
74         printf("create code %d\n", code);
75     DFlush();
76 }
77
78 static int
79 ListEntry(void * handle, char *name, afs_int32 vnode, afs_int32 unique)
80 {
81     printf("%s\t%ld\t%ld\n", name, afs_printable_int32_ld(vnode),
82            afs_printable_int32_ld(unique));
83
84     return 0;
85 }
86
87 static void
88 ListDir(char *name)
89 {
90     dirhandle dir;
91     OpenDir(name, &dir);
92     afs_dir_EnumerateDir(&dir, ListEntry, 0);
93 }
94
95 static void
96 CheckDir(char *name)
97 {
98     dirhandle dir;
99     OpenDir(name, &dir);
100     if (DirOK(&dir))
101         printf("Directory ok.\n");
102     else
103         printf("Directory bad\n");
104 }
105
106 static void
107 SalvageDir(char *iname, char *oname)
108 {
109     dirhandle in, out;
110     afs_int32 myFid[3], parentFid[3];
111
112     OpenDir(iname, &in);
113     if (afs_dir_Lookup(&in, ".", myFid) || 
114         afs_dir_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 = afs_dir_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     afs_dir_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 = afs_dir_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             break;
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(afs_int32 *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(afs_int32 *afid, afs_int32 *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(const char *msg)
249 {
250     printf("Something died with this message:  %s\n", msg);
251     opr_abort();
252 }
253
254 void
255 Log(const char *fmt, ...)
256 {
257     va_list ap;
258
259     va_start(ap, fmt);
260     vprintf(fmt, ap);
261     va_end(ap);
262 }
263
264 int
265 main(int argc, char **argv)
266 {
267     DInit(600);
268     argc--;
269     argv++;
270
271     if (argc == 0)
272         Usage();
273
274     switch ((*argv++)[1]) {
275     case 'l':
276         ListDir(*argv);
277         break;
278     case 'c':
279         CheckDir(*argv);
280         break;
281     case 's':
282         SalvageDir(*argv, argv[1]);
283         break;
284     case 'f':
285         CRTest(*argv, argv[1], atoi(argv[2]));
286         break;
287     case 'd':
288         DelTest(*argv, argv[1]);
289         break;
290     case 'r':
291         LookupDir(*argv, argv[1]);
292         break;
293     case 'a':
294         AddEntry(*argv, argv[1]);
295         break;
296     default:
297         Usage();
298     }
299     exit(0);
300 }