sys-prototypes-20090315
[openafs.git] / src / sys / rmtsysnet.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
14     ("$Header$");
15
16 #include <errno.h>
17 #include <sys/param.h>
18 #include <sys/types.h>
19 #include <afs/vice.h>
20 #ifdef AFS_NT40_ENV
21 #include <winsock2.h>
22 #else
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #include <sys/file.h>
26 #endif
27 #include <sys/stat.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <afs/afsint.h>
31 #include <afs/venus.h>
32 #include <rx/xdr.h>
33 #include "rmtsys.h"
34
35
36 /*
37  * We deal with converting pioctl parameters between host and network order.
38  * Painful but somebody has to do this and pioctl is the best place rather than
39  * leaving it to the calling application programs!
40  */
41
42 #define MAXNAME         100
43 #define MAXSIZE         2048
44 #define MAXHOSTS        8       /* XXX HARD Limit limitation XXX */
45 #define MAXGCSIZE       16
46
47 struct Acl {
48     int nplus;
49     int nminus;
50     struct AclEntry *pluslist;
51     struct AclEntry *minuslist;
52 };
53
54 struct AclEntry {
55     struct AclEntry *next;
56     char name[MAXNAME];
57     afs_int32 rights;
58 };
59
60 struct ClearToken {
61     afs_int32 AuthHandle;
62     char HandShakeKey[8];
63     afs_int32 ViceId;
64     afs_int32 BeginTimestamp;
65     afs_int32 EndTimestamp;
66 };
67
68 char *
69 RSkipLine(register char *astr)
70 {
71     while (*astr != '\n')
72         astr++;
73     astr++;
74     return astr;
75 }
76
77
78 struct Acl *
79 RParseAcl(char *astr)
80 {
81     int nplus, nminus, i, trights;
82     char tname[MAXNAME];
83     struct AclEntry *first, *last, *tl;
84     struct Acl *ta;
85     sscanf(astr, "%d", &nplus);
86     astr = RSkipLine(astr);
87     sscanf(astr, "%d", &nminus);
88     astr = RSkipLine(astr);
89
90     ta = (struct Acl *)malloc(sizeof(struct Acl));
91     ta->nplus = nplus;
92     ta->nminus = nminus;
93
94     last = 0;
95     first = 0;
96     for (i = 0; i < nplus; i++) {
97         sscanf(astr, "%100s %d", tname, &trights);
98         astr = RSkipLine(astr);
99         tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
100         if (!first)
101             first = tl;
102         strcpy(tl->name, tname);
103         tl->rights = trights;
104         tl->next = 0;
105         if (last)
106             last->next = tl;
107         last = tl;
108     }
109     ta->pluslist = first;
110
111     last = 0;
112     first = 0;
113     for (i = 0; i < nminus; i++) {
114         sscanf(astr, "%100s %d", tname, &trights);
115         astr = RSkipLine(astr);
116         tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
117         if (!first)
118             first = tl;
119         strcpy(tl->name, tname);
120         tl->rights = trights;
121         tl->next = 0;
122         if (last)
123             last->next = tl;
124         last = tl;
125     }
126     ta->minuslist = first;
127
128     return ta;
129 }
130
131
132 void
133 RAclToString(struct Acl *acl, char *mydata, int ntoh_conv)
134 {
135     char tstring[MAXSIZE];
136     struct AclEntry *tp;
137
138 /* No conversion needed since they're in network order in the first place */
139     sprintf(mydata, "%d\n%d\n", acl->nplus, acl->nminus);
140     for (tp = acl->pluslist; tp; tp = tp->next) {
141         sprintf(tstring, "%s %d\n", tp->name, tp->rights);
142         strcat(mydata, tstring);
143     }
144     for (tp = acl->minuslist; tp; tp = tp->next) {
145         sprintf(tstring, "%s %d\n", tp->name, tp->rights);
146         strcat(mydata, tstring);
147     }
148 }
149
150
151 /* Free all malloced stuff */
152 void
153 RCleanAcl(struct Acl *aa)
154 {
155     register struct AclEntry *te, *ne;
156
157     for (te = aa->pluslist; te; te = ne) {
158         ne = te->next;
159         free(te);
160     }
161     for (te = aa->minuslist; te; te = ne) {
162         ne = te->next;
163         free(te);
164     }
165     free(aa);
166 }
167
168
169 void
170 RFetchVolumeStatus_conversion(char *data, int ntoh_conv)
171 {
172     struct AFSFetchVolumeStatus *status = (AFSFetchVolumeStatus *) data;
173
174     if (ntoh_conv) {            /* Network -> Host */
175         status->Vid = ntohl(status->Vid);
176         status->ParentId = ntohl(status->ParentId);
177 #ifdef  notdef
178 /* save cycles */
179         status->OnLine = status->OnLine;
180         status->InService = status->InService;
181         status->Blessed = status->Blessed;
182         status->NeedsSalvage = status->NeedsSalvage;
183 #endif
184         status->Type = ntohl(status->Type);
185         status->MinQuota = ntohl(status->MinQuota);
186         status->MaxQuota = ntohl(status->MaxQuota);
187         status->BlocksInUse = ntohl(status->BlocksInUse);
188         status->PartBlocksAvail = ntohl(status->PartBlocksAvail);
189         status->PartMaxBlocks = ntohl(status->PartMaxBlocks);
190     } else {                    /* Host -> Network */
191         status->Vid = htonl(status->Vid);
192         status->ParentId = htonl(status->ParentId);
193 #ifdef  notdef
194 /* save cycles */
195         status->OnLine = status->OnLine;
196         status->InService = status->InService;
197         status->Blessed = status->Blessed;
198         status->NeedsSalvage = status->NeedsSalvage;
199 #endif
200         status->Type = htonl(status->Type);
201         status->MinQuota = htonl(status->MinQuota);
202         status->MaxQuota = htonl(status->MaxQuota);
203         status->BlocksInUse = htonl(status->BlocksInUse);
204         status->PartBlocksAvail = htonl(status->PartBlocksAvail);
205         status->PartMaxBlocks = htonl(status->PartMaxBlocks);
206     }
207 }
208
209 void
210 RClearToken_convert(char *ptr, int ntoh_conv)
211 {
212     struct ClearToken *ticket = (struct ClearToken *)ptr;
213
214     if (ntoh_conv) {            /* Network -> host */
215         ticket->AuthHandle = ntohl(ticket->AuthHandle);
216         ticket->ViceId = ntohl(ticket->ViceId);
217         ticket->BeginTimestamp = ntohl(ticket->BeginTimestamp);
218         ticket->EndTimestamp = ntohl(ticket->EndTimestamp);
219     } else {                    /* Host -> Network */
220         ticket->AuthHandle = htonl(ticket->AuthHandle);
221         ticket->ViceId = htonl(ticket->ViceId);
222         ticket->BeginTimestamp = htonl(ticket->BeginTimestamp);
223         ticket->EndTimestamp = htonl(ticket->EndTimestamp);
224     }
225 }
226
227 void
228 inparam_conversion(afs_int32 cmd, char *buffer, afs_int32 ntoh_conv)
229 {
230     struct Acl *acl;
231     afs_int32 *lptr, i;
232     char *ptr;
233
234     switch (cmd & 0xffff) {
235     case VIOCSETAL & 0xffff:
236         acl = RParseAcl(buffer);
237         RAclToString(acl, buffer, ntoh_conv);
238         RCleanAcl(acl);
239         break;
240     case VIOCSETTOK & 0xffff:
241         lptr = (afs_int32 *) buffer;
242         /* i is sizeof of the secret ticket */
243         if (ntoh_conv) {
244             i = ntohl(*lptr);
245             *lptr = i;
246         } else {
247             i = *lptr;
248             *lptr = htonl(i);
249         }
250         lptr++;
251         ptr = (char *)lptr;
252         ptr += i;               /* skip over the ticket */
253         lptr = (afs_int32 *) ptr;
254         /* i is now size of the clear token */
255         if (ntoh_conv) {
256             i = ntohl(*lptr);
257             *lptr = i;
258         } else {
259             i = *lptr;
260             *lptr = htonl(i);
261         }
262         lptr++;
263         ptr = (char *)lptr;
264         RClearToken_convert(ptr, ntoh_conv);
265         ptr += i;               /* sizeof(struct ClearToken) */
266         lptr = (afs_int32 *) ptr;
267         if (ntoh_conv)
268             *lptr = ntohl(*lptr);
269         else
270             *lptr = htonl(*lptr);
271         lptr++;                 /* primary flag */
272         break;
273     case VIOCSETVOLSTAT & 0xffff:
274         RFetchVolumeStatus_conversion(buffer, ntoh_conv);
275         break;
276     case VIOCGETTOK & 0xffff:
277     case VIOCCKSERV & 0xffff:
278     case VIOCACCESS & 0xffff:
279     case VIOCSETCACHESIZE & 0xffff:
280     case VIOCGETCELL & 0xffff:
281     case VIOC_AFS_MARINER_HOST & 0xffff:
282     case VIOC_VENUSLOG & 0xffff:
283     case VIOC_AFS_SYSNAME & 0xffff:
284     case VIOC_EXPORTAFS & 0xffff:
285         lptr = (afs_int32 *) buffer;
286         if (ntoh_conv)
287             *lptr = ntohl(*lptr);
288         else
289             *lptr = htonl(*lptr);
290         break;
291     case VIOC_SETCELLSTATUS & 0xffff:
292         lptr = (afs_int32 *) buffer;
293         if (ntoh_conv)
294             *lptr = ntohl(*lptr);
295         else
296             *lptr = htonl(*lptr);
297         lptr++;
298         if (ntoh_conv)
299             *lptr = ntohl(*lptr);
300         else
301             *lptr = htonl(*lptr);
302         break;
303     case VIOCGETAL & 0xffff:
304     case VIOCGETVOLSTAT & 0xffff:
305     case VIOCGETCACHEPARMS & 0xffff:
306     case VIOCFLUSH & 0xffff:
307     case VIOCSTAT & 0xffff:
308     case VIOCUNLOG & 0xffff:
309     case VIOCCKBACK & 0xffff:
310     case VIOCCKCONN & 0xffff:
311     case VIOCGETTIME & 0xffff:  /* Obsolete */
312     case VIOCWHEREIS & 0xffff:
313     case VIOCPREFETCH & 0xffff:
314     case VIOCNOP & 0xffff:      /* Obsolete */
315     case VIOCENGROUP & 0xffff:  /* Obsolete */
316     case VIOCDISGROUP & 0xffff: /* Obsolete */
317     case VIOCLISTGROUPS & 0xffff:       /* Obsolete */
318     case VIOCUNPAG & 0xffff:
319     case VIOCWAITFOREVER & 0xffff:      /* Obsolete */
320     case VIOCFLUSHCB & 0xffff:
321     case VIOCNEWCELL & 0xffff:
322     case VIOC_AFS_DELETE_MT_PT & 0xffff:
323     case VIOC_AFS_STAT_MT_PT & 0xffff:
324     case VIOC_FILE_CELL_NAME & 0xffff:
325     case VIOC_GET_WS_CELL & 0xffff:
326     case VIOC_GET_PRIMARY_CELL & 0xffff:
327     case VIOC_GETCELLSTATUS & 0xffff:
328     case VIOC_FLUSHVOLUME & 0xffff:
329     case VIOCGETFID & 0xffff:   /* nothing yet */
330         break;
331     default:
332         /* Note that new pioctls are supposed to be in network order! */
333         break;
334     }
335 }
336
337
338 void
339 outparam_conversion(afs_int32 cmd, char *buffer, afs_int32 ntoh_conv)
340 {
341     struct Acl *acl;
342     afs_int32 *lptr, i;
343     char *ptr;
344
345     switch (cmd & 0xffff) {
346     case VIOCGETAL & 0xffff:
347         acl = RParseAcl(buffer);
348         RAclToString(acl, buffer, ntoh_conv);
349         RCleanAcl(acl);
350         break;
351     case VIOCGETVOLSTAT & 0xffff:
352         RFetchVolumeStatus_conversion(buffer, ntoh_conv);
353         break;
354     case VIOCSETVOLSTAT & 0xffff:
355         RFetchVolumeStatus_conversion(buffer, ntoh_conv);
356         break;
357     case VIOCGETTOK & 0xffff:
358         lptr = (afs_int32 *) buffer;
359         /* i is set to sizeof secret ticket */
360         if (ntoh_conv) {
361             i = ntohl(*lptr);
362             *lptr = i;
363         } else {
364             i = *lptr;
365             *lptr = htonl(i);
366         }
367         lptr++;
368         ptr = (char *)lptr;
369         ptr += i;               /* skip over the ticket */
370         lptr = (afs_int32 *) ptr;
371         /* i is set to sizeof clear ticket */
372         if (ntoh_conv) {
373             i = ntohl(*lptr);
374             *lptr = i;
375         } else {
376             i = *lptr;
377             *lptr = htonl(i);
378         }
379         lptr++;
380         ptr = (char *)lptr;
381         RClearToken_convert(ptr, ntoh_conv);
382         ptr += i;               /* sizeof(struct ClearToken) */
383         lptr = (afs_int32 *) ptr;
384         if (ntoh_conv)
385             *lptr = ntohl(*lptr);
386         else
387             *lptr = htonl(*lptr);
388         lptr++;                 /* primary flag */
389         break;
390     case VIOCCKCONN & 0xffff:
391     case VIOC_AFS_MARINER_HOST & 0xffff:
392     case VIOC_VENUSLOG & 0xffff:
393     case VIOC_GETCELLSTATUS & 0xffff:
394     case VIOC_AFS_SYSNAME & 0xffff:
395     case VIOC_EXPORTAFS & 0xffff:
396         lptr = (afs_int32 *) buffer;
397         if (ntoh_conv)
398             *lptr = ntohl(*lptr);
399         else
400             *lptr = htonl(*lptr);
401         break;
402     case VIOCGETCACHEPARMS & 0xffff:
403         lptr = (afs_int32 *) buffer;
404         for (i = 0; i < MAXGCSIZE; i++, lptr++) {
405             if (ntoh_conv)
406                 *lptr = ntohl(*lptr);
407             else
408                 *lptr = htonl(*lptr);
409         }
410         break;
411     case VIOCUNLOG & 0xffff:
412     case VIOCCKSERV & 0xffff:   /* Already in network order */
413     case VIOCCKBACK & 0xffff:
414     case VIOCGETTIME & 0xffff:  /* Obsolete */
415     case VIOCWHEREIS & 0xffff:  /* Already in network order */
416     case VIOCPREFETCH & 0xffff:
417     case VIOCNOP & 0xffff:      /* Obsolete */
418     case VIOCENGROUP & 0xffff:  /* Obsolete */
419     case VIOCDISGROUP & 0xffff: /* Obsolete */
420     case VIOCLISTGROUPS & 0xffff:       /* Obsolete */
421     case VIOCACCESS & 0xffff:
422     case VIOCUNPAG & 0xffff:
423     case VIOCWAITFOREVER & 0xffff:      /* Obsolete */
424     case VIOCSETCACHESIZE & 0xffff:
425     case VIOCFLUSHCB & 0xffff:
426     case VIOCNEWCELL & 0xffff:
427     case VIOCGETCELL & 0xffff:  /* Already in network order */
428     case VIOC_AFS_DELETE_MT_PT & 0xffff:
429     case VIOC_AFS_STAT_MT_PT & 0xffff:
430     case VIOC_FILE_CELL_NAME & 0xffff:  /* no need to convert */
431     case VIOC_GET_WS_CELL & 0xffff:     /* no need to convert */
432     case VIOCGETFID & 0xffff:   /* nothing yet */
433     case VIOCSETAL & 0xffff:
434     case VIOCFLUSH & 0xffff:
435     case VIOCSTAT & 0xffff:
436     case VIOCSETTOK & 0xffff:
437     case VIOC_GET_PRIMARY_CELL & 0xffff:        /* The cell is returned here */
438     case VIOC_SETCELLSTATUS & 0xffff:
439     case VIOC_FLUSHVOLUME & 0xffff:
440         break;
441     default:
442         /* Note that new pioctls are supposed to be in network order! */
443         break;
444     }
445 }