Add printf format checks to the cache manager
[openafs.git] / src / viced / fsprobe.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 #include <afsconfig.h>
11 #include <afs/param.h>
12
13
14 #include <afs/stds.h>
15 #include <afs/afsint.h>
16 #include <sys/socket.h>
17 #include <rx/rx_globals.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #include <netdb.h>
21 #include <ubik.h>
22 #include <string.h>
23
24 struct ubik_client *cstruct;
25 struct rx_connection *serverconns[MAXSERVERS];
26 char *(args[50]);
27
28 afs_int32
29 pxclient_Initialize(int auth, afs_int32 serverAddr)
30 {
31     afs_int32 code;
32     afs_int32 scIndex;
33     struct rx_securityClass *sc;
34
35     code = rx_Init(htons(2115) /*0 */ );
36     if (code) {
37         fprintf(stderr, "pxclient_Initialize:  Could not initialize rx.\n");
38         return code;
39     }
40     scIndex = 0;
41     rx_SetRxDeadTime(50);
42     switch (scIndex) {
43     case 0:
44         sc = rxnull_NewClientSecurityObject();
45         break;
46
47 #ifdef notdef                   /* security */
48     case 1:
49         sc = rxvab_NewClientSecurityObject(&ttoken.sessionKey, ttoken.ticket,
50                                            0);
51         break;
52
53     case 2:
54         sc = rxkad_NewClientSecurityObject(rxkad_clear, &ttoken.sessionKey,
55                                            ttoken.kvno, ttoken.ticketLen,
56                                            ttoken.ticket);
57 #endif /* notdef */
58     }
59     serverconns[0] =
60         rx_NewConnection(serverAddr, htons(7000), 1, sc, scIndex);
61
62     code = ubik_ClientInit(serverconns, &cstruct);
63
64     if (code) {
65         fprintf(stderr, "pxclient_Initialize: ubik client init failed.\n");
66         return code;
67     }
68     return 0;
69 }
70
71 /* main program */
72
73 #include "AFS_component_version_number.c"
74
75 int
76 main(int argc, char **argv)
77 {
78     char **av = argv;
79     struct sockaddr_in host;
80     register afs_int32 code;
81     struct hostent *hp;
82     char *hostname;
83     char hnamebuf[200];
84     struct timeval tv;
85     int noAuth = 1;             /* Default is authenticated connections */
86
87     argc--, av++;
88     if (argc < 1) {
89         printf("usage: pxclient <serverHost>\n");
90         exit(1);
91     }
92     memset(&host, 0, sizeof(struct sockaddr_in));
93     host.sin_family = AF_INET;
94     host.sin_addr.s_addr = inet_addr(av[0]);
95 #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
96     host.sin_len = sizeof(struct sockaddr_in);
97 #endif
98     if (host.sin_addr.s_addr != -1) {
99         strcpy(hnamebuf, av[0]);
100         hostname = hnamebuf;
101     } else {
102         hp = gethostbyname(av[0]);
103         if (hp) {
104             host.sin_family = hp->h_addrtype;
105             memcpy((caddr_t) & host.sin_addr, hp->h_addr, hp->h_length);
106             hostname = hp->h_name;
107         } else {
108             printf("unknown server host %s\n", av[0]);
109             exit(1);
110         }
111     }
112     if ((code = pxclient_Initialize(noAuth, host.sin_addr.s_addr)) != 0) {
113         printf("Couldn't initialize fs library (code=%d).\n", code);
114         exit(1);
115     }
116
117     code = ubik_Call(RXAFS_GetTime, cstruct, 0, &tv.tv_sec, &tv.tv_usec);
118     if (!code)
119         printf("AFS_GetTime on %s sec=%ld, usec=%ld\n", av[0], tv.tv_sec,
120                (long int)tv.tv_usec);
121     else
122         printf("return code is %d\n", code);
123
124 #ifdef notdef
125     while (1) {
126         char line[500];
127         int nargs;
128
129         printf("fs> ");
130         if (fgets(line, 499, stdin) != NULL) {
131             char *oper;
132             register char **argp = args;
133             GetArgs(line, argp, &nargs);
134             oper = &argp[0][0];
135             ++argp, --nargs;
136             if (!strcmp(oper, "probe")) {
137                 code =
138                     ubik_Call(RXAFS_GetTime, cstruct, 0, &tv.tv_sec,
139                               &tv.tv_usec);
140                 printf("return code is %d\n", code);
141                 if (!code)
142                     printf("sec=%d\n", tv.tv_sec);
143             } else if (!strcmp(oper, "fsstats")) {
144                 struct afsStatistics stats;
145
146                 code = ubik_AFS_GetStatistics(cstruct, 0, &stats);
147                 printf("return code is %d\n", code);
148             } else if (!strcmp(oper, "fd")) {
149                 code = FetchData(argp);
150                 printf("return code is %d\n", code);
151             } else if (!strcmp(oper, "fs")) {
152                 code = FetchStatus(argp);
153                 printf("return code is %d\n", code);
154             } else if (!strcmp(oper, "fa")) {
155                 code = FetchACL(argp);
156                 printf("return code is %d\n", code);
157             } else if (!strcmp(oper, "sd")) {
158                 code = StoreData(argp);
159                 printf("return code is %d\n", code);
160             } else if (!strcmp(oper, "ss")) {
161                 code = StoreStatus(argp);
162                 printf("return code is %d\n", code);
163             } else if (!strcmp(oper, "sa")) {
164                 code = StoreACL(argp);
165                 printf("return code is %d\n", code);
166             } else if (!strcmp(oper, "cf")) {
167                 code = CreateFile(argp);
168                 printf("return code is %d\n", code);
169             } else if (!strcmp(oper, "rf")) {
170                 code = RemoveFile(argp);
171                 printf("return code is %d\n", code);
172             } else if (!strcmp(oper, "rn")) {
173                 code = Rename(argp);
174                 printf("return code is %d\n", code);
175             } else if (!strcmp(oper, "sl")) {
176                 code = Symlink(argp);
177                 printf("return code is %d\n", code);
178             } else if (!strcmp(oper, "hl")) {
179                 code = HardLink(argp);
180                 printf("return code is %d\n", code);
181             } else if (!strcmp(oper, "md")) {
182                 code = MakeDir(argp);
183                 printf("return code is %d\n", code);
184             } else if (!strcmp(oper, "rd")) {
185                 code = RemoveDir(argp);
186                 printf("return code is %d\n", code);
187             } else if (!strcmp(oper, "rdd")) {
188                 code = Readdir(argp);
189                 printf("return code is %d\n", code);
190             } else if (!strcmp(oper, "mm")) {
191                 code = MakeMountPoint(argp);
192                 printf("return code is %d\n", code);
193             } else if (!strcmp(oper, "rt")) {
194                 code = ReleaseTokens(argp);
195                 printf("return code is %d\n", code);
196             } else if (!strcmp(oper, "bs")) {
197                 code = BulkStatus(argp);
198                 printf("return code is %d\n", code);
199             } else if (!strcmp(oper, "lk")) {
200                 code = Lookup(argp);
201                 printf("return code is %d\n", code);
202             } else if (!strcmp(oper, "gt")) {
203                 code = GetToken(argp);
204                 printf("return code is %d\n", code);
205             } else if (!strcmp(oper, "ka")) {
206                 code = KeepAlive(argp);
207                 printf("return code is %d\n", code);
208             } else if ((!strcmp(oper, "q")) || !strcmp(oper, "quit"))
209                 exit(0);
210             else {
211                 printf("Unknown oper! Available operations: \n\n");
212                 printf("fd <vnode> <unique> <pos> <len>\n");
213                 printf("fs <vnode> <unique>\n");
214                 printf("fa <vnode> <unique>\n");
215                 printf
216                     ("sd <vnode> <unique> <pos> <len> <flen> [<mode>|-1] [<owner>|-1] [<length>|-1] <string>\n");
217                 printf
218                     ("ss <vnode> <unique> [<mode>|-1] [<owner>|-1] [<length>|-1]\n");
219                 printf("sa <vnode> <unique> <string>\n");
220                 printf("rf <vnode> <unique> <name>\n");
221                 printf
222                     ("cf <vnode> <unique> <name> [<mode>|-1] [<owner>|-1] [<length>|-1]\n");
223                 printf
224                     ("rn <ovnode> <ounique> <oname> <nvnode> <nunique> <nname>\n");
225                 printf
226                     ("sl <vnode> <unique> <name> <contents> [<mode>|-1] [<owner>|-1] [<length>|-1]\n");
227                 printf("hl <dvnode> <dunique> <name> <evnode> <eunique>\n");
228                 printf
229                     ("md <vnode> <unique> <name> [<mode>|-1] [<owner>|-1] [<length>|-1]\n");
230                 printf("rd <vnode> <unique> <name>\n");
231                 printf("rdd <vnode> <unique> <pos> <len>\n");
232                 printf("lk <vnode> <unique> <name>\n");
233                 printf("gt <vnode> <unique> <tokenID>\n");
234                 printf("ka <vol.l> <vnode> <unique> <isExec> <kaTime>\n");
235             }
236         }
237     }
238 #endif
239     return 0;
240 }
241
242
243 void
244 GetArgs(register char *line, register char **args, register int *nargs)
245 {
246     *nargs = 0;
247     while (*line) {
248         register char *last = line;
249         while (*line == ' ')
250             line++;
251         if (*last == ' ')
252             *last = 0;
253         if (!*line)
254             break;
255         *args++ = line, (*nargs)++;
256         while (*line && *line != ' ')
257             line++;
258     }
259 }
260
261 #ifdef notdef
262 afs_int32
263 FetchData(char **argp)
264 {
265     struct afsFetchStatus OutStatus;
266     struct afsToken Token;
267     struct afsVolSync tsync;
268     struct afsFid fid;
269     int vnode, unique, position, length;
270     int code;
271     struct rx_call *tcall;
272
273     sscanf(&(*argp)[0], "%d", &vnode);
274     ++argp;
275     sscanf(&(*argp)[0], "%d", &unique);
276     ++argp;
277     memset(&fid, 0, sizeof(struct afsFid));
278     fid.Volume.low = 10;        /* XXX */
279     fid.Vnode = vnode;
280     fid.Unique = unique;
281     sscanf(&(*argp)[0], "%d", &position);
282     ++argp;
283     sscanf(&(*argp)[0], "%d", &length);
284     ++argp;
285     tcall = rx_NewCall(cstruct->conns[0]);
286     code = StartAFS_FetchData(tcall, &fid, &hyp0, position, length, 0);
287     if (!code) {
288         code = FetchProc(tcall);
289     }
290     if (!code) {
291         code = EndAFS_FetchData(tcall, &OutStatus, &Token, &tsync);
292     }
293     code = rx_EndCall(tcall, code);
294     return code;
295 }
296
297
298 static afs_int32
299 FetchProc(register struct rx_call *acall)
300 {
301     extern char *malloc();
302     register char *tbuffer;
303     afs_int32 tlen, length, code;
304
305     code = rx_Read(acall, &length, sizeof(afs_int32));
306     length = ntohl(length);
307     if (code != sizeof(afs_int32))
308         return -1;
309     tbuffer = malloc(256);
310     while (length > 0) {
311         tlen = (length > 256 ? 256 : length);
312         code = rx_Read(acall, tbuffer, tlen);
313         if (code != tlen) {
314             free(tbuffer);
315             return -1;
316         }
317         length -= tlen;
318     }
319     free(tbuffer);
320     return 0;
321 }
322
323
324 afs_int32
325 FetchStatus(char **argp)
326 {
327     struct afsFetchStatus OutStatus;
328     struct afsToken Token;
329     struct afsVolSync tsync;
330     struct afsFid fid;
331     int vnode, unique;
332     int code;
333
334     sscanf(&(*argp)[0], "%d", &vnode);
335     ++argp;
336     sscanf(&(*argp)[0], "%d", &unique);
337     ++argp;
338     memset(&fid, 0, sizeof(struct afsFid));
339     fid.Volume.low = 10;        /* XXX */
340     fid.Vnode = vnode;
341     fid.Unique = unique;
342     code =
343         ubik_AFS_FetchStatus(cstruct, 0, &fid, &hyp0, 0, &OutStatus,
344                   &Token, &tsync);
345     return (code);
346 }
347
348
349 afs_int32
350 FetchACL(char **argp)
351 {
352     struct afsFetchStatus OutStatus;
353     struct afsACL AccessList;
354     struct afsToken Token;
355     struct afsVolSync tsync;
356     struct afsFid fid;
357     int vnode, unique;
358     int code;
359
360     sscanf(&(*argp)[0], "%d", &vnode);
361     ++argp;
362     sscanf(&(*argp)[0], "%d", &unique);
363     ++argp;
364     memset(&fid, 0, sizeof(struct afsFid));
365     fid.Volume.low = 10;        /* XXX */
366     fid.Vnode = vnode;
367     fid.Unique = unique;
368     code =
369         ubik_AFS_FetchACL(cstruct, 0, &fid, &hyp0, 0, &AccessList,
370                   &OutStatus, &tsync);
371     return (code);
372 }
373
374
375 afs_int32
376 StoreData(char **argp)
377 {
378     struct afsStoreStatus InStatus;
379     struct afsFetchStatus OutStatus;
380     struct afsVolSync tsync;
381     struct afsFid fid;
382     int vnode, unique, position, length, filelength;
383     int mode, owner, len;
384     int code;
385     char *string;
386     struct rx_call *tcall;
387
388     sscanf(&(*argp)[0], "%d", &vnode);
389     ++argp;
390     sscanf(&(*argp)[0], "%d", &unique);
391     ++argp;
392     memset(&fid, 0, sizeof(struct afsFid));
393     fid.Volume.low = 10;        /* XXX */
394     fid.Vnode = vnode;
395     fid.Unique = unique;
396     sscanf(&(*argp)[0], "%d", &position);
397     ++argp;
398     sscanf(&(*argp)[0], "%d", &length);
399     ++argp;
400     sscanf(&(*argp)[0], "%d", &filelength);
401     ++argp;
402     memset(&InStatus, 0, sizeof(struct afsStoreStatus));
403     sscanf(&(*argp)[0], "%d", &mode);
404     ++argp;
405     sscanf(&(*argp)[0], "%d", &owner);
406     ++argp;
407     sscanf(&(*argp)[0], "%d", &len);
408     ++argp;
409     if (mode != -1) {
410         InStatus.mode = mode;
411         InStatus.mask |= AFS_SETMODE;
412     }
413     if (owner != -1) {
414         InStatus.owner = owner;
415         InStatus.mask |= AFS_SETOWNER;
416     }
417     if (length != -1) {
418         InStatus.length = length;
419         InStatus.mask |= AFS_SETLENGTH;
420     }
421     string = &argp[0][0];
422     ++argp;
423
424     tcall = rx_NewCall(cstruct->conns[0]);
425     code =
426         StartAFS_StoreData(tcall, &fid, &InStatus, position, length,
427                            filelength, &hyp0, 0);
428     if (!code) {
429         code = StoreProc(tcall, string, length);
430     }
431     if (!code) {
432         code = EndAFS_StoreData(tcall, &OutStatus, &tsync);
433     }
434     code = rx_EndCall(tcall, code);
435     return (code);
436 }
437
438
439 static afs_int32
440 StoreProc(register struct rx_call *acall, char *string, int length)
441 {
442     afs_int32 tlen, code;
443
444     while (length > 0) {
445         tlen = (length > 256 ? 256 : length);
446         code = rx_Write(acall, string, tlen);
447         if (code != tlen) {
448             return -1;
449         }
450         length -= tlen;
451     }
452     return 0;
453 }
454
455
456 afs_int32
457 StoreStatus(char **argp)
458 {
459     struct afsStoreStatus InStatus;
460     struct afsFetchStatus OutStatus;
461     struct afsVolSync tsync;
462     struct afsFid fid;
463     int vnode, unique, mode, owner, length;
464     int code;
465
466     sscanf(&(*argp)[0], "%d", &vnode);
467     ++argp;
468     sscanf(&(*argp)[0], "%d", &unique);
469     ++argp;
470     memset(&fid, 0, sizeof(struct afsFid));
471     fid.Volume.low = 10;        /* XXX */
472     fid.Vnode = vnode;
473     fid.Unique = unique;
474     memset(&InStatus, 0, sizeof(struct afsStoreStatus));
475     sscanf(&(*argp)[0], "%d", &mode);
476     ++argp;
477     sscanf(&(*argp)[0], "%d", &owner);
478     ++argp;
479     sscanf(&(*argp)[0], "%d", &length);
480     ++argp;
481     if (mode != -1) {
482         InStatus.mode = mode;
483         InStatus.mask |= AFS_SETMODE;
484     }
485     if (owner != -1) {
486         InStatus.owner = owner;
487         InStatus.mask |= AFS_SETOWNER;
488     }
489     if (length != -1) {
490         InStatus.length = length;
491         InStatus.mask |= AFS_SETLENGTH;
492     }
493     code =
494         ubik_AFS_StoreStatus(cstruct, 0, &fid, &InStatus, &hyp0, 0,
495                   &OutStatus, &tsync);
496     return (code);
497 }
498
499
500 afs_int32
501 StoreACL(char **argp)
502 {
503     struct afsFetchStatus OutStatus;
504     struct afsACL AccessList;
505     struct afsToken Token;
506     struct afsVolSync tsync;
507     struct afsFid fid;
508     char *string;
509     int vnode, unique;
510     int code;
511
512     sscanf(&(*argp)[0], "%d", &vnode);
513     ++argp;
514     sscanf(&(*argp)[0], "%d", &unique);
515     ++argp;
516     memset(&fid, 0, sizeof(struct afsFid));
517     fid.Volume.low = 10;        /* XXX */
518     fid.Vnode = vnode;
519     fid.Unique = unique;
520     string = &argp[0][0];
521     ++argp;
522     AccessList.afsACL_len = strlen(string) + 1;
523     AccessList.afsACL_val = string;
524     code =
525         ubik_AFS_StoreACL(cstruct, 0, &fid, &AccessList, &hyp0, 0,
526                   &OutStatus, &tsync);
527     return (code);
528 }
529
530
531 afs_int32
532 RemoveFile(char **argp)
533 {
534     struct afsFetchStatus OutDirStatus, OutFidStatus;
535     struct afsVolSync tsync;
536     struct afsFidName nameFid;
537     struct afsFid fid, outFid;
538     char *name;
539     int vnode, unique;
540     int code;
541
542     sscanf(&(*argp)[0], "%d", &vnode);
543     ++argp;
544     sscanf(&(*argp)[0], "%d", &unique);
545     ++argp;
546     memset(&fid, 0, sizeof(struct afsFid));
547     fid.Volume.low = 10;        /* XXX */
548     fid.Vnode = vnode;
549     fid.Unique = unique;
550     name = &argp[0][0];
551     ++argp;
552     memset(&nameFid, 0, sizeof(struct afsFidName));
553     strcpy(nameFid.name, name);
554     code =
555         ubik_AFS_RemoveFile(cstruct, 0, &fid, &nameFid, &hyp0, 0,
556                   &OutDirStatus, &OutFidStatus, &outFid, &tsync);
557     return (code);
558 }
559
560
561 afs_int32
562 CreateFile(char **argp)
563 {
564     struct afsFetchStatus OutDirStatus, OutFidStatus;
565     struct afsStoreStatus InStatus;
566     struct afsVolSync tsync;
567     struct afsFid fid, outFid;
568     struct afsToken Token;
569     char *name;
570     int vnode, unique, mode, owner, length;
571     int code;
572
573     sscanf(&(*argp)[0], "%d", &vnode);
574     ++argp;
575     sscanf(&(*argp)[0], "%d", &unique);
576     ++argp;
577     memset(&fid, 0, sizeof(struct afsFid));
578     fid.Volume.low = 10;        /* XXX */
579     fid.Vnode = vnode;
580     fid.Unique = unique;
581     name = &argp[0][0];
582     ++argp;
583     memset(&InStatus, 0, sizeof(struct afsStoreStatus));
584     sscanf(&(*argp)[0], "%d", &mode);
585     ++argp;
586     sscanf(&(*argp)[0], "%d", &owner);
587     ++argp;
588     sscanf(&(*argp)[0], "%d", &length);
589     ++argp;
590     if (mode != -1) {
591         InStatus.mode = mode;
592         InStatus.mask |= AFS_SETMODE;
593     }
594     if (owner != -1) {
595         InStatus.owner = owner;
596         InStatus.mask |= AFS_SETOWNER;
597     }
598     if (length != -1) {
599         InStatus.length = length;
600         InStatus.mask |= AFS_SETLENGTH;
601     }
602     code =
603         ubik_AFS_CreateFile(cstruct, 0, &fid, name, &InStatus, &hyp0, 0,
604                   &outFid, &OutFidStatus, &OutDirStatus, &Token, &tsync);
605     return (code);
606 }
607
608
609 afs_int32
610 Rename(char **argp)
611 {
612     struct afsFetchStatus OutOldDirStatus, OutNewDirStatus;
613     struct afsFetchStatus OutOldFileStatus, OutNewFileStatus;
614     struct afsVolSync tsync;
615     struct afsFid OldDirFid, NewDirFid, OutOldFileFid, OutNewFileFid;
616     struct afsFidName OldName, NewName;
617     char *oname, *nname;
618     int ovnode, ounique, nvnode, nunique;
619     int code;
620
621     sscanf(&(*argp)[0], "%d", &ovnode);
622     ++argp;
623     sscanf(&(*argp)[0], "%d", &ounique);
624     ++argp;
625     memset(&OldDirFid, 0, sizeof(struct afsFid));
626     OldDirFid.Volume.low = 10;  /* XXX */
627     OldDirFid.Vnode = ovnode;
628     OldDirFid.Unique = ounique;
629     oname = &argp[0][0];
630     ++argp;
631     memset(&OldName, 0, sizeof(struct afsFidName));
632     strcpy(OldName.name, oname);
633     sscanf(&(*argp)[0], "%d", &nvnode);
634     ++argp;
635     sscanf(&(*argp)[0], "%d", &nunique);
636     ++argp;
637     memset(&NewDirFid, 0, sizeof(struct afsFid));
638     NewDirFid.Volume.low = 10;  /* XXX */
639     NewDirFid.Vnode = nvnode;
640     NewDirFid.Unique = nunique;
641     nname = &argp[0][0];
642     ++argp;
643     memset(&NewName, 0, sizeof(struct afsFidName));
644     strcpy(NewName.name, nname);
645     code =
646         ubik_AFS_Rename(cstruct, 0, &OldDirFid, &OldName, &NewDirFid,
647                   &NewName, &hyp0, 0, &OutOldDirStatus, &OutNewDirStatus,
648                   &OutOldFileFid, &OutOldFileStatus, &OutNewFileFid,
649                   &OutNewFileStatus, &tsync);
650     return (code);
651 }
652
653
654 afs_int32
655 Symlink(char **argp)
656 {
657     struct afsFetchStatus OutDirStatus, OutFidStatus;
658     struct afsStoreStatus InStatus;
659     struct afsVolSync tsync;
660     struct afsFid fid, outFid;
661     struct afsToken Token;
662     char *name, *linkcontents;
663     int vnode, unique, mode, owner, length;
664     int code;
665
666     sscanf(&(*argp)[0], "%d", &vnode);
667     ++argp;
668     sscanf(&(*argp)[0], "%d", &unique);
669     ++argp;
670     memset(&fid, 0, sizeof(struct afsFid));
671     fid.Volume.low = 10;        /* XXX */
672     fid.Vnode = vnode;
673     fid.Unique = unique;
674     name = &argp[0][0];
675     ++argp;
676     linkcontents = &argp[0][0];
677     ++argp;
678     memset(&InStatus, 0, sizeof(struct afsStoreStatus));
679     sscanf(&(*argp)[0], "%d", &mode);
680     ++argp;
681     sscanf(&(*argp)[0], "%d", &owner);
682     ++argp;
683     sscanf(&(*argp)[0], "%d", &length);
684     ++argp;
685     if (mode != -1) {
686         InStatus.mode = mode;
687         InStatus.mask |= AFS_SETMODE;
688     }
689     if (owner != -1) {
690         InStatus.owner = owner;
691         InStatus.mask |= AFS_SETOWNER;
692     }
693     if (length != -1) {
694         InStatus.length = length;
695         InStatus.mask |= AFS_SETLENGTH;
696     }
697     code =
698         ubik_AFS_Symlink(cstruct, 0, &fid, name, linkcontents,
699                   &InStatus, &hyp0, 0, &outFid, &OutFidStatus, &OutDirStatus,
700                   &Token, &tsync);
701     return (code);
702 }
703
704
705 afs_int32
706 HardLink(char **argp)
707 {
708     struct afsFetchStatus OutDirStatus, OutFidStatus;
709     struct afsVolSync tsync;
710     struct afsFid fid, existingFid;
711     char *name;
712     int vnode, unique;
713     int code;
714
715     sscanf(&(*argp)[0], "%d", &vnode);
716     ++argp;
717     sscanf(&(*argp)[0], "%d", &unique);
718     ++argp;
719     memset(&fid, 0, sizeof(struct afsFid));
720     fid.Volume.low = 10;        /* XXX */
721     fid.Vnode = vnode;
722     fid.Unique = unique;
723     name = &argp[0][0];
724     ++argp;
725     sscanf(&(*argp)[0], "%d", &vnode);
726     ++argp;
727     sscanf(&(*argp)[0], "%d", &unique);
728     ++argp;
729     memset(&existingFid, 0, sizeof(struct afsFid));
730     existingFid.Volume.low = 10;        /* XXX */
731     existingFid.Vnode = vnode;
732     existingFid.Unique = unique;
733     code =
734         ubik_AFS_HardLink(cstruct, 0, &fid, name, &existingFid, &hyp0,
735                   0, &OutFidStatus, &OutDirStatus, &tsync);
736     return (code);
737 }
738
739
740 afs_int32
741 MakeDir(char **argp)
742 {
743     struct afsFetchStatus OutDirStatus, OutFidStatus;
744     struct afsStoreStatus InStatus;
745     struct afsVolSync tsync;
746     struct afsFid fid, outFid;
747     struct afsToken Token;
748     char *name;
749     int vnode, unique, mode, owner, length;
750     int code;
751
752     sscanf(&(*argp)[0], "%d", &vnode);
753     ++argp;
754     sscanf(&(*argp)[0], "%d", &unique);
755     ++argp;
756     memset(&fid, 0, sizeof(struct afsFid));
757     fid.Volume.low = 10;        /* XXX */
758     fid.Vnode = vnode;
759     fid.Unique = unique;
760     name = &argp[0][0];
761     ++argp;
762     memset(&InStatus, 0, sizeof(struct afsStoreStatus));
763     sscanf(&(*argp)[0], "%d", &mode);
764     ++argp;
765     sscanf(&(*argp)[0], "%d", &owner);
766     ++argp;
767     sscanf(&(*argp)[0], "%d", &length);
768     ++argp;
769     if (mode != -1) {
770         InStatus.mode = mode;
771         InStatus.mask |= AFS_SETMODE;
772     }
773     if (owner != -1) {
774         InStatus.owner = owner;
775         InStatus.mask |= AFS_SETOWNER;
776     }
777     if (length != -1) {
778         InStatus.length = length;
779         InStatus.mask |= AFS_SETLENGTH;
780     }
781     code =
782         ubik_AFS_MakeDir(cstruct, 0, &fid, name, &InStatus, &hyp0, 0,
783                   &outFid, &OutFidStatus, &OutDirStatus, &Token, &tsync);
784     return (code);
785 }
786
787
788 afs_int32
789 RemoveDir(char **argp)
790 {
791     struct afsFetchStatus OutDirStatus;
792     struct afsVolSync tsync;
793     struct afsFid fid, outFid;
794     struct afsFidName nameFid;
795     char *name;
796     int vnode, unique;
797     int code;
798
799     sscanf(&(*argp)[0], "%d", &vnode);
800     ++argp;
801     sscanf(&(*argp)[0], "%d", &unique);
802     ++argp;
803     memset(&fid, 0, sizeof(struct afsFid));
804     fid.Volume.low = 10;        /* XXX */
805     fid.Vnode = vnode;
806     fid.Unique = unique;
807     name = &argp[0][0];
808     ++argp;
809     memset(&nameFid, 0, sizeof(struct afsFidName));
810     strcpy(nameFid.name, name);
811     code =
812         ubik_AFS_RemoveDir(cstruct, 0, &fid, &nameFid, &hyp0, 0,
813                   &OutDirStatus, &outFid, &tsync);
814     return (code);
815 }
816
817
818 afs_int32
819 Readdir(char **argp)
820 {
821     struct afsFetchStatus OutDirStatus;
822     struct afsVolSync tsync;
823     struct afsFid fid;
824     struct afsToken Token;
825     char *name;
826     struct rx_call *tcall;
827     int vnode, unique, offset, length, NextOffset;
828     int code;
829
830     sscanf(&(*argp)[0], "%d", &vnode);
831     ++argp;
832     sscanf(&(*argp)[0], "%d", &unique);
833     ++argp;
834     sscanf(&(*argp)[0], "%d", &offset);
835     ++argp;
836     sscanf(&(*argp)[0], "%d", &length);
837     ++argp;
838     memset(&fid, 0, sizeof(struct afsFid));
839     fid.Volume.low = 10;        /* XXX */
840     fid.Vnode = vnode;
841     fid.Unique = unique;
842     tcall = rx_NewCall(cstruct->conns[0]);
843     code = StartAFS_Readdir(tcall, &fid, offset, length, &hyp0, 0);
844     if (!code) {
845         code = FetchDir(tcall);
846     }
847     if (!code) {
848         code =
849             EndAFS_FetchData(tcall, &NextOffset, &OutDirStatus, &Token,
850                              &tsync);
851     }
852     code = rx_EndCall(tcall, code);
853     return (code);
854 }
855
856
857 static afs_int32
858 FetchDir(register struct rx_call *acall)
859 {
860     extern char *malloc();
861     register char *tbuffer;
862     afs_int32 tlen, length, code;
863     struct dirent *dp;
864
865
866     tbuffer = malloc(256);
867     while (1) {
868         code = rx_Read(acall, &length, sizeof(afs_int32));
869         length = ntohl(length);
870         if (code != sizeof(afs_int32))
871             return -1;
872         if (length == 0)
873             break;
874         tlen = (length > 8192 ? 8192 : length);
875         code = rx_Read(acall, tbuffer, tlen);
876         if (code != tlen) {
877             free(tbuffer);
878             return -1;
879         }
880         length -= tlen;
881     }
882     dp = (struct dirent *)dp;
883     free(tbuffer);
884     return 0;
885 }
886
887
888 afs_int32
889 Lookup(char **argp)
890 {
891     struct afsFetchStatus OutDirStatus, OutFidStatus;
892     struct afsVolSync tsync;
893     struct afsFid fid, outFid;
894     char *name;
895     int vnode, unique;
896     int code;
897
898     sscanf(&(*argp)[0], "%d", &vnode);
899     ++argp;
900     sscanf(&(*argp)[0], "%d", &unique);
901     ++argp;
902     memset(&fid, 0, sizeof(struct afsFid));
903     fid.Volume.low = 10;        /* XXX */
904     fid.Vnode = vnode;
905     fid.Unique = unique;
906     name = &argp[0][0];
907     ++argp;
908     code =
909         ubik_AFS_Lookup(cstruct, 0, &fid, name, &hyp0, 0, &outFid,
910                   &OutFidStatus, &OutDirStatus, &tsync);
911     return (code);
912 }
913
914
915 afs_int32
916 GetToken(char **argp)
917 {
918     struct afsFetchStatus OutStatus;
919     struct afsVolSync tsync;
920     struct afsToken MinToken, RealToken;
921     struct afsFid fid;
922     int vnode, unique, tokenId;
923     int code;
924
925     sscanf(&(*argp)[0], "%d", &vnode);
926     ++argp;
927     sscanf(&(*argp)[0], "%d", &unique);
928     ++argp;
929     memset(&fid, 0, sizeof(struct afsFid));
930     fid.Volume.low = 10;        /* XXX */
931     fid.Vnode = vnode;
932     fid.Unique = unique;
933     sscanf(&(*argp)[0], "%d", &tokenId);
934     ++argp;
935     memset(&MinToken, 0, sizeof(struct afsToken));
936     MinToken.tokenID.low = tokenId;     /* XXX */
937     code =
938         ubik_AFS_GetToken(cstruct, 0, &fid, &MinToken, &hyp0, 0,
939                   &RealToken, &OutStatus, &tsync);
940     return (code);
941 }
942
943
944 afs_int32
945 MakeMountPoint(char **argp)
946 {
947 }
948
949
950 afs_int32
951 ReleaseTokens(char **argp)
952 {
953 }
954
955
956 afs_int32
957 BulkStatus(char **argp)
958 {
959 }
960
961 /*  printf("ka <vol.l> <vnode> <unique> <isExec> <kaTime>\n"); */
962 afs_int32
963 KeepAlive(char **argp)
964 {
965     struct afsBulkFEX fex;
966     afs_uint32 numExec, spare4;
967     struct afsFidExp fx;
968     int code;
969
970     memset(&fx, 0, sizeof(struct afsFidExp));
971     sscanf(&(*argp)[0], "%d", &fx.fid.Volume.low);
972     ++argp;
973     sscanf(&(*argp)[0], "%d", &fx.fid.Vnode);
974     ++argp;
975     sscanf(&(*argp)[0], "%d", &fx.fid.Unique);
976     ++argp;
977     sscanf(&(*argp)[0], "%d", &numExec);
978     ++argp;
979     sscanf(&(*argp)[0], "%d", &fx.keepAliveTime);
980     memset(&fex, 0, sizeof(struct afsBulkFEX));
981     fex.afsBulkFEX_val = &fx;
982     fex.afsBulkFEX_len = 1;
983     code =
984         ubik_AFS_BulkKeepAlive(cstruct, 0, &fex, numExec, 0, 0, 0,
985                   &spare4);
986     return (code);
987 }
988 #endif /* notdef */