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