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