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