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