|
|
1.1 root 1: /*
2: * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3: * unrestricted use provided that this legend is included on all tape
4: * media and as a part of the software program in whole or part. Users
5: * may copy or modify Sun RPC without charge, but are not authorized
6: * to license or distribute it to anyone else except as part of a product or
7: * program developed by the user.
8: *
9: * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10: * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11: * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12: *
13: * Sun RPC is provided with no support and without any obligation on the
14: * part of Sun Microsystems, Inc. to assist in its use, correction,
15: * modification or enhancement.
16: *
17: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19: * OR ANY PART THEREOF.
20: *
21: * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22: * or profits or other special, indirect and consequential damages, even if
23: * Sun has been advised of the possibility of such damages.
24: *
25: * Sun Microsystems, Inc.
26: * 2550 Garcia Avenue
27: * Mountain View, California 94043
28: */
29: #ifndef lint
30: static char sccsid[] = "@(#)xdr.c 1.3 85/02/26 Copyr 1984 Sun Micro";
31: #endif
32:
33: /*
34: * xdr.c, Generic XDR routines impelmentation.
35: *
36: * Copyright (C) 1984, Sun Microsystems, Inc.
37: *
38: * These are the "generic" xdr routines used to serialize and de-serialize
39: * most common data items. See xdr.h for more info on the interface to
40: * xdr.
41: */
42:
43: #include "types.h"
44: #include "xdr.h"
45: #include <stdio.h>
46:
47: char *mem_alloc();
48:
49: /*
50: * constants specific to the xdr "protocol"
51: */
52: #define XDR_FALSE ((long) 0)
53: #define XDR_TRUE ((long) 1)
54: #define LASTUNSIGNED ((u_int) 0-1)
55:
56: /*
57: * for unit alignment
58: */
59: static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
60:
61:
62: /*
63: * XDR nothing
64: */
65: bool_t
66: xdr_void(/* xdrs, addr */)
67: /* XDR *xdrs; */
68: /* caddr_t addr; */
69: {
70:
71: return (TRUE);
72: }
73:
74: /*
75: * XDR integers
76: */
77: bool_t
78: xdr_int(xdrs, ip)
79: XDR *xdrs;
80: int *ip;
81: {
82:
83: if (sizeof(int) == sizeof(long)) {
84: return (xdr_long(xdrs, (long *)ip));
85: } else {
86: return (xdr_short(xdrs, (short *)ip));
87: }
88: }
89:
90: /*
91: * XDR unsigned integers
92: */
93: bool_t
94: xdr_u_int(xdrs, up)
95: XDR *xdrs;
96: u_int *up;
97: {
98:
99: if (sizeof(u_int) == sizeof(u_long)) {
100: return (xdr_u_long(xdrs, (u_long *)up));
101: } else {
102: return (xdr_short(xdrs, (short *)up));
103: }
104: }
105:
106: /*
107: * XDR long integers
108: * same as xdr_u_long - open coded to save a proc call!
109: */
110: bool_t
111: xdr_long(xdrs, lp)
112: register XDR *xdrs;
113: long *lp;
114: {
115:
116: if (xdrs->x_op == XDR_ENCODE)
117: return (XDR_PUTLONG(xdrs, lp));
118:
119: if (xdrs->x_op == XDR_DECODE)
120: return (XDR_GETLONG(xdrs, lp));
121:
122: if (xdrs->x_op == XDR_FREE)
123: return (TRUE);
124:
125: return (FALSE);
126: }
127:
128: /*
129: * XDR unsigned long integers
130: * same as xdr_long - open coded to save a proc call!
131: */
132: bool_t
133: xdr_u_long(xdrs, ulp)
134: register XDR *xdrs;
135: u_long *ulp;
136: {
137:
138: if (xdrs->x_op == XDR_DECODE)
139: return (XDR_GETLONG(xdrs, (long *)ulp));
140: if (xdrs->x_op == XDR_ENCODE)
141: return (XDR_PUTLONG(xdrs, (long *)ulp));
142: if (xdrs->x_op == XDR_FREE)
143: return (TRUE);
144: return (FALSE);
145: }
146:
147: /*
148: * XDR short integers
149: */
150: bool_t
151: xdr_short(xdrs, sp)
152: register XDR *xdrs;
153: short *sp;
154: {
155: long l;
156:
157: switch (xdrs->x_op) {
158:
159: case XDR_ENCODE:
160: l = (long) *sp;
161: return (XDR_PUTLONG(xdrs, &l));
162:
163: case XDR_DECODE:
164: if (!XDR_GETLONG(xdrs, &l)) {
165: return (FALSE);
166: }
167: *sp = (short) l;
168: return (TRUE);
169:
170: case XDR_FREE:
171: return (TRUE);
172: }
173: return (FALSE);
174: }
175:
176: /*
177: * XDR unsigned short integers
178: */
179: bool_t
180: xdr_u_short(xdrs, usp)
181: register XDR *xdrs;
182: u_short *usp;
183: {
184: u_long l;
185:
186: switch (xdrs->x_op) {
187:
188: case XDR_ENCODE:
189: l = (u_long) *usp;
190: return (XDR_PUTLONG(xdrs, &l));
191:
192: case XDR_DECODE:
193: if (!XDR_GETLONG(xdrs, &l)) {
194: return (FALSE);
195: }
196: *usp = (u_short) l;
197: return (TRUE);
198:
199: case XDR_FREE:
200: return (TRUE);
201: }
202: return (FALSE);
203: }
204:
205:
206: /*
207: * XDR booleans
208: */
209: bool_t
210: xdr_bool(xdrs, bp)
211: register XDR *xdrs;
212: bool_t *bp;
213: {
214: long lb;
215:
216: switch (xdrs->x_op) {
217:
218: case XDR_ENCODE:
219: lb = *bp ? XDR_TRUE : XDR_FALSE;
220: return (XDR_PUTLONG(xdrs, &lb));
221:
222: case XDR_DECODE:
223: if (!XDR_GETLONG(xdrs, &lb)) {
224: return (FALSE);
225: }
226: *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
227: return (TRUE);
228:
229: case XDR_FREE:
230: return (TRUE);
231: }
232: return (FALSE);
233: }
234:
235: /*
236: * XDR enumerations
237: */
238: bool_t
239: xdr_enum(xdrs, ep)
240: XDR *xdrs;
241: enum_t *ep;
242: {
243:
244: /*
245: * enums are treated as ints
246: */
247: if (sizeof(enum_t) == sizeof(long)) {
248: return (xdr_long(xdrs, (long *)ep));
249: } else {
250: return (xdr_short(xdrs, (short *)ep));
251: }
252: }
253:
254: /*
255: * XDR opaque data
256: * Allows the specification of a fixed size sequence of opaque bytes.
257: * cp points to the opaque object and cnt gives the byte length.
258: */
259: bool_t
260: xdr_opaque(xdrs, cp, cnt)
261: register XDR *xdrs;
262: caddr_t cp;
263: register u_int cnt;
264: {
265: register u_int rndup;
266: static crud[BYTES_PER_XDR_UNIT];
267:
268: /*
269: * if no data we are done
270: */
271: if (cnt == 0)
272: return (TRUE);
273:
274: /*
275: * round byte count to full xdr units
276: */
277: rndup = cnt % BYTES_PER_XDR_UNIT;
278: if (rndup > 0)
279: rndup = BYTES_PER_XDR_UNIT - rndup;
280:
281: if (xdrs->x_op == XDR_DECODE) {
282: if (!XDR_GETBYTES(xdrs, cp, cnt)) {
283: return (FALSE);
284: }
285: if (rndup == 0)
286: return (TRUE);
287: return (XDR_GETBYTES(xdrs, crud, rndup));
288: }
289:
290: if (xdrs->x_op == XDR_ENCODE) {
291: if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
292: return (FALSE);
293: }
294: if (rndup == 0)
295: return (TRUE);
296: return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
297: }
298:
299: if (xdrs->x_op == XDR_FREE) {
300: return (TRUE);
301: }
302:
303: return (FALSE);
304: }
305:
306: /*
307: * XDR counted bytes
308: * *cpp is a pointer to the bytes, *sizep is the count.
309: * If *cpp is NULL maxsize bytes are allocated
310: */
311: bool_t
312: xdr_bytes(xdrs, cpp, sizep, maxsize)
313: register XDR *xdrs;
314: char **cpp;
315: register u_int *sizep;
316: u_int maxsize;
317: {
318: register char *sp = *cpp; /* sp is the actual string pointer */
319: register u_int nodesize;
320:
321: /*
322: * first deal with the length since xdr bytes are counted
323: */
324: if (! xdr_u_int(xdrs, sizep)) {
325: return (FALSE);
326: }
327: nodesize = *sizep;
328: if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
329: return (FALSE);
330: }
331:
332: /*
333: * now deal with the actual bytes
334: */
335: switch (xdrs->x_op) {
336:
337: case XDR_DECODE:
338: if (sp == NULL) {
339: *cpp = sp = mem_alloc(nodesize);
340: }
341: if (sp == NULL) {
342: fprintf(stderr, "xdr_bytes: out of memory\n");
343: return (FALSE);
344: }
345: /* fall into ... */
346:
347: case XDR_ENCODE:
348: return (xdr_opaque(xdrs, sp, nodesize));
349:
350: case XDR_FREE:
351: if (sp != NULL) {
352: mem_free(sp, nodesize);
353: *cpp = NULL;
354: }
355: return (TRUE);
356: }
357: return (FALSE);
358: }
359:
360: /*
361: * XDR a descriminated union
362: * Support routine for discriminated unions.
363: * You create an array of xdrdiscrim structures, terminated with
364: * an entry with a null procedure pointer. The routine gets
365: * the discriminant value and then searches the array of xdrdiscrims
366: * looking for that value. It calls the procedure given in the xdrdiscrim
367: * to handle the discriminant. If there is no specific routine a default
368: * routine may be called.
369: * If there is no specific or default routine an error is returned.
370: */
371: bool_t
372: xdr_union(xdrs, dscmp, unp, choices, dfault)
373: register XDR *xdrs;
374: enum_t *dscmp; /* enum to decide which arm to work on */
375: caddr_t unp; /* the union itself */
376: struct xdr_discrim *choices; /* [value, xdr proc] for each arm */
377: xdrproc_t dfault; /* default xdr routine */
378: {
379: register enum_t dscm;
380:
381: /*
382: * we deal with the discriminator; it's an enum
383: */
384: if (! xdr_enum(xdrs, dscmp)) {
385: return (FALSE);
386: }
387: dscm = *dscmp;
388:
389: /*
390: * search choices for a value that matches the discriminator.
391: * if we find one, execute the xdr routine for that value.
392: */
393: for (; choices->proc != NULL_xdrproc_t; choices++) {
394: if (choices->value == dscm)
395: return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
396: }
397:
398: /*
399: * no match - execute the default xdr routine if there is one
400: */
401: return ((dfault == NULL_xdrproc_t) ? FALSE :
402: (*dfault)(xdrs, unp, LASTUNSIGNED));
403: }
404:
405:
406: /*
407: * Non-portable xdr primitives.
408: * Care should be taken when moving these routines to new architectures.
409: */
410:
411:
412: /*
413: * XDR null terminated ASCII strings
414: * xdr_string deals with "C strings" - arrays of bytes that are
415: * terminated by a NULL character. The parameter cpp references a
416: * pointer to storage; If the pointer is null, then the necessary
417: * storage is allocated. The last parameter is the max allowed length
418: * of the string as specified by a protocol.
419: */
420: bool_t
421: xdr_string(xdrs, cpp, maxsize)
422: register XDR *xdrs;
423: char **cpp;
424: u_int maxsize;
425: {
426: register char *sp = *cpp; /* sp is the actual string pointer */
427: u_int size;
428: u_int nodesize;
429:
430: /*
431: * first deal with the length since xdr strings are counted-strings
432: */
433: if ((xdrs->x_op) != XDR_DECODE)
434: size = strlen(sp);
435: if (! xdr_u_int(xdrs, &size)) {
436: return (FALSE);
437: }
438: if (size > maxsize) {
439: return (FALSE);
440: }
441: nodesize = size + 1;
442:
443: /*
444: * now deal with the actual bytes
445: */
446: switch (xdrs->x_op) {
447:
448: case XDR_DECODE:
449: if (sp == NULL)
450: *cpp = sp = mem_alloc(nodesize);
451: if (sp == NULL) {
452: fprintf(stderr, "xdr_string: out of memory\n");
453: return (FALSE);
454: }
455: sp[size] = 0;
456: /* fall into ... */
457:
458: case XDR_ENCODE:
459: return (xdr_opaque(xdrs, sp, size));
460:
461: case XDR_FREE:
462: if (sp != NULL) {
463: mem_free(sp, nodesize);
464: *cpp = NULL;
465: }
466: return (TRUE);
467: }
468: return (FALSE);
469: }
470:
471: /*
472: * Wrapper for xdr_string that can be called directly from
473: * routines like clnt_call
474: */
475:
476: bool_t
477: xdr_wrapstring(xdrs, cpp)
478: XDR *xdrs;
479: char **cpp;
480: {
481: if (xdr_string(xdrs, cpp, BUFSIZ)) {
482: return(TRUE);
483: }
484: return(FALSE);
485: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.