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