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