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