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