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