Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

xdr.c

Go to the documentation of this file.
00001 /*********************************************************************
00002  * RPC for the Windows NT Operating System
00003  * 1993 by Martin F. Gergeleit
00004  * Users may use, copy or modify Sun RPC for the Windows NT Operating
00005  * System according to the Sun copyright below.
00006  *
00007  * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO
00008  * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE
00009  * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
00010  *********************************************************************/
00011 
00012 /* @(#)xdr.c    2.1 88/07/29 4.0 RPCSRC */
00013 /*
00014  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00015  * unrestricted use provided that this legend is included on all tape
00016  * media and as a part of the software program in whole or part.  Users
00017  * may copy or modify Sun RPC without charge, but are not authorized
00018  * to license or distribute it to anyone else except as part of a product or
00019  * program developed by the user.
00020  *
00021  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00022  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00023  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00024  *
00025  * Sun RPC is provided with no support and without any obligation on the
00026  * part of Sun Microsystems, Inc. to assist in its use, correction,
00027  * modification or enhancement.
00028  *
00029  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00030  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00031  * OR ANY PART THEREOF.
00032  *
00033  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00034  * or profits or other special, indirect and consequential damages, even if
00035  * Sun has been advised of the possibility of such damages.
00036  *
00037  * Sun Microsystems, Inc.
00038  * 2550 Garcia Avenue
00039  * Mountain View, California  94043
00040  */
00041 #if !defined(lint) && defined(SCCSIDS)
00042 static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
00043 #endif
00044 
00045 /*
00046  * xdr.c, Generic XDR routines implementation.
00047  *
00048  * Copyright (C) 1986, Sun Microsystems, Inc.
00049  *
00050  * These are the "generic" xdr routines used to serialize and de-serialize
00051  * most common data items.  See xdr.h for more info on the interface to
00052  * xdr.
00053  */
00054 
00055 #if !defined(UNDER_CE) && !defined(WINDOWS_CE)
00056 #include <stdio.h>
00057 #endif
00058 #include <stdlib.h>             /* malloc,free */
00059 #include <string.h>             /* strlen() */
00060 
00061 #include "xdr.h"
00062 
00063 /*
00064  * constants specific to the xdr "protocol"
00065  */
00066 #define XDR_FALSE       ((long) 0)
00067 #define XDR_TRUE        ((long) 1)
00068 #define LASTUNSIGNED    ((u_int) 0-1)
00069 
00070 /*
00071  * for unit alignment
00072  */
00073 static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
00074 
00075 /*
00076  * Free a data structure using XDR
00077  * Not a filter, but a convenient utility nonetheless
00078  */
00079 void
00080 xdr_free(proc, objp)
00081         xdrproc_t proc;
00082         char *objp;
00083 {
00084         XDR x;
00085 
00086         x.x_op = XDR_FREE;
00087         (*proc)(&x, objp);
00088 }
00089 
00090 /*
00091  * XDR nothing
00092  */
00093 bool_t
00094 xdr_void(/* xdrs, addr */)
00095         /* XDR *xdrs; */
00096         /* caddr_t addr; */
00097 {
00098 
00099         return (TRUE);
00100 }
00101 
00102 /*
00103  * XDR integers
00104  */
00105 bool_t
00106 xdr_int(xdrs, ip)
00107         XDR *xdrs;
00108         int *ip;
00109 {
00110 
00111 #ifdef lint
00112         (void) (xdr_short(xdrs, (short *)ip));
00113         return (xdr_long(xdrs, (long *)ip));
00114 #else
00115         if (sizeof (int) == sizeof (long)) {
00116                 return (xdr_long(xdrs, (long *)ip));
00117         } else {
00118                 return (xdr_short(xdrs, (short *)ip));
00119         }
00120 #endif
00121 }
00122 
00123 /*
00124  * XDR unsigned integers
00125  */
00126 bool_t
00127 xdr_u_int(xdrs, up)
00128         XDR *xdrs;
00129         u_int *up;
00130 {
00131 
00132 #ifdef lint
00133         (void) (xdr_short(xdrs, (short *)up));
00134         return (xdr_u_long(xdrs, (u_long *)up));
00135 #else
00136         if (sizeof (u_int) == sizeof (u_long)) {
00137                 return (xdr_u_long(xdrs, (u_long *)up));
00138         } else {
00139                 return (xdr_short(xdrs, (short *)up));
00140         }
00141 #endif
00142 }
00143 
00144 /*
00145  * XDR long integers
00146  * same as xdr_u_long - open coded to save a proc call!
00147  */
00148 bool_t
00149 xdr_long(xdrs, lp)
00150         register XDR *xdrs;
00151         long *lp;
00152 {
00153 
00154         if (xdrs->x_op == XDR_ENCODE)
00155                 return (XDR_PUTLONG(xdrs, lp));
00156 
00157         if (xdrs->x_op == XDR_DECODE)
00158                 return (XDR_GETLONG(xdrs, lp));
00159 
00160         if (xdrs->x_op == XDR_FREE)
00161                 return (TRUE);
00162 
00163         return (FALSE);
00164 }
00165 
00166 /*
00167  * XDR unsigned long integers
00168  * same as xdr_long - open coded to save a proc call!
00169  */
00170 bool_t
00171 xdr_u_long(xdrs, ulp)
00172         register XDR *xdrs;
00173         u_long *ulp;
00174 {
00175 
00176         if (xdrs->x_op == XDR_DECODE)
00177                 return (XDR_GETLONG(xdrs, (long *)ulp));
00178         if (xdrs->x_op == XDR_ENCODE)
00179                 return (XDR_PUTLONG(xdrs, (long *)ulp));
00180         if (xdrs->x_op == XDR_FREE)
00181                 return (TRUE);
00182         return (FALSE);
00183 }
00184 
00185 /*
00186  * XDR short integers
00187  */
00188 bool_t
00189 xdr_short(xdrs, sp)
00190         register XDR *xdrs;
00191         short *sp;
00192 {
00193         long l;
00194 
00195         switch (xdrs->x_op) {
00196 
00197         case XDR_ENCODE:
00198                 l = (long) *sp;
00199                 return (XDR_PUTLONG(xdrs, &l));
00200 
00201         case XDR_DECODE:
00202                 if (!XDR_GETLONG(xdrs, &l)) {
00203                         return (FALSE);
00204                 }
00205                 *sp = (short) l;
00206                 return (TRUE);
00207 
00208         case XDR_FREE:
00209                 return (TRUE);
00210         }
00211         return (FALSE);
00212 }
00213 
00214 /*
00215  * XDR unsigned short integers
00216  */
00217 bool_t
00218 xdr_u_short(xdrs, usp)
00219         register XDR *xdrs;
00220         u_short *usp;
00221 {
00222         u_long l;
00223 
00224         switch (xdrs->x_op) {
00225 
00226         case XDR_ENCODE:
00227                 l = (u_long) *usp;
00228                 return (XDR_PUTLONG(xdrs, &l));
00229 
00230         case XDR_DECODE:
00231                 if (!XDR_GETLONG(xdrs, &l)) {
00232                         return (FALSE);
00233                 }
00234                 *usp = (u_short) l;
00235                 return (TRUE);
00236 
00237         case XDR_FREE:
00238                 return (TRUE);
00239         }
00240         return (FALSE);
00241 }
00242 
00243 
00244 /*
00245  * XDR a char
00246  */
00247 bool_t
00248 xdr_char(xdrs, cp)
00249         XDR *xdrs;
00250         char *cp;
00251 {
00252         int i;
00253 
00254         i = (*cp);
00255         if (!xdr_int(xdrs, &i)) {
00256                 return (FALSE);
00257         }
00258         *cp = i;
00259         return (TRUE);
00260 }
00261 
00262 /*
00263  * XDR an unsigned char
00264  */
00265 bool_t
00266 xdr_u_char(xdrs, cp)
00267         XDR *xdrs;
00268         char *cp;
00269 {
00270         u_int u;
00271 
00272         u = (*cp);
00273         if (!xdr_u_int(xdrs, &u)) {
00274                 return (FALSE);
00275         }
00276         *cp = u;
00277         return (TRUE);
00278 }
00279 
00280 /*
00281  * XDR booleans
00282  */
00283 bool_t
00284 xdr_bool(xdrs, bp)
00285         register XDR *xdrs;
00286         bool_t *bp;
00287 {
00288         long lb;
00289 
00290         switch (xdrs->x_op) {
00291 
00292         case XDR_ENCODE:
00293                 lb = *bp ? XDR_TRUE : XDR_FALSE;
00294                 return (XDR_PUTLONG(xdrs, &lb));
00295 
00296         case XDR_DECODE:
00297                 if (!XDR_GETLONG(xdrs, &lb)) {
00298                         return (FALSE);
00299                 }
00300                 *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
00301                 return (TRUE);
00302 
00303         case XDR_FREE:
00304                 return (TRUE);
00305         }
00306         return (FALSE);
00307 }
00308 
00309 /*
00310  * XDR enumerations
00311  */
00312 bool_t
00313 xdr_enum(xdrs, ep)
00314         XDR *xdrs;
00315         enum_t *ep;
00316 {
00317 #ifndef lint
00318         enum sizecheck { SIZEVAL };     /* used to find the size of an enum */
00319 
00320         /*
00321          * enums are treated as ints
00322          */
00323         if (sizeof (enum sizecheck) == sizeof (long)) {
00324                 return (xdr_long(xdrs, (long *)ep));
00325         } else if (sizeof (enum sizecheck) == sizeof (short)) {
00326                 return (xdr_short(xdrs, (short *)ep));
00327         } else {
00328                 return (FALSE);
00329         }
00330 #else
00331         (void) (xdr_short(xdrs, (short *)ep));
00332         return (xdr_long(xdrs, (long *)ep));
00333 #endif
00334 }
00335 
00336 /*
00337  * XDR opaque data
00338  * Allows the specification of a fixed size sequence of opaque bytes.
00339  * cp points to the opaque object and cnt gives the byte length.
00340  */
00341 bool_t
00342 xdr_opaque(xdrs, cp, cnt)
00343         register XDR *xdrs;
00344         caddr_t cp;
00345         register u_int cnt;
00346 {
00347         register u_int rndup;
00348         static crud[BYTES_PER_XDR_UNIT];
00349 
00350         /*
00351          * if no data we are done
00352          */
00353         if (cnt == 0)
00354                 return (TRUE);
00355 
00356         /*
00357          * round byte count to full xdr units
00358          */
00359         rndup = cnt % BYTES_PER_XDR_UNIT;
00360         if (rndup > 0)
00361                 rndup = BYTES_PER_XDR_UNIT - rndup;
00362 
00363         if (xdrs->x_op == XDR_DECODE) {
00364                 if (!XDR_GETBYTES(xdrs, cp, cnt)) {
00365                         return (FALSE);
00366                 }
00367                 if (rndup == 0)
00368                         return (TRUE);
00369                 return (XDR_GETBYTES(xdrs, crud, rndup));
00370         }
00371 
00372         if (xdrs->x_op == XDR_ENCODE) {
00373                 if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
00374                         return (FALSE);
00375                 }
00376                 if (rndup == 0)
00377                         return (TRUE);
00378                 return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
00379         }
00380 
00381         if (xdrs->x_op == XDR_FREE) {
00382                 return (TRUE);
00383         }
00384 
00385         return (FALSE);
00386 }
00387 
00388 /*
00389  * XDR counted bytes
00390  * *cpp is a pointer to the bytes, *sizep is the count.
00391  * If *cpp is NULL maxsize bytes are allocated
00392  */
00393 bool_t
00394 xdr_bytes(xdrs, cpp, sizep, maxsize)
00395         register XDR *xdrs;
00396         char **cpp;
00397         register u_int *sizep;
00398         u_int maxsize;
00399 {
00400         register char *sp = *cpp;  /* sp is the actual string pointer */
00401         register u_int nodesize;
00402 
00403         /*
00404          * first deal with the length since xdr bytes are counted
00405          */
00406         if (! xdr_u_int(xdrs, sizep)) {
00407                 return (FALSE);
00408         }
00409         nodesize = *sizep;
00410         if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
00411                 return (FALSE);
00412         }
00413 
00414         /*
00415          * now deal with the actual bytes
00416          */
00417         switch (xdrs->x_op) {
00418 
00419         case XDR_DECODE:
00420                 if (nodesize == 0) {
00421                         return (TRUE);
00422                 }
00423                 if (sp == NULL) {
00424                         *cpp = sp = (char *)mem_alloc(nodesize);
00425                 }
00426                 if (sp == NULL) {
00427 #if !defined(UNDER_CE) && !defined(WINDOWS_CE)
00428                         (void) fprintf(stderr, "xdr_bytes: out of memory\n");
00429 #endif
00430                         return (FALSE);
00431                 }
00432                 /* fall into ... */
00433 
00434         case XDR_ENCODE:
00435                 return (xdr_opaque(xdrs, sp, nodesize));
00436 
00437         case XDR_FREE:
00438                 if (sp != NULL) {
00439                         mem_free(sp, nodesize);
00440                         *cpp = NULL;
00441                 }
00442                 return (TRUE);
00443         }
00444         return (FALSE);
00445 }
00446 
00447 /*
00448  * Implemented here due to commonality of the object.
00449  */
00450 bool_t
00451 xdr_netobj(xdrs, np)
00452         XDR *xdrs;
00453         struct netobj *np;
00454 {
00455 
00456         return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
00457 }
00458 
00459 /*
00460  * XDR a descriminated union
00461  * Support routine for discriminated unions.
00462  * You create an array of xdrdiscrim structures, terminated with
00463  * an entry with a null procedure pointer.  The routine gets
00464  * the discriminant value and then searches the array of xdrdiscrims
00465  * looking for that value.  It calls the procedure given in the xdrdiscrim
00466  * to handle the discriminant.  If there is no specific routine a default
00467  * routine may be called.
00468  * If there is no specific or default routine an error is returned.
00469  */
00470 bool_t
00471 xdr_union(xdrs, dscmp, unp, choices, dfault)
00472         register XDR *xdrs;
00473         enum_t *dscmp;          /* enum to decide which arm to work on */
00474         char *unp;              /* the union itself */
00475         struct xdr_discrim *choices;    /* [value, xdr proc] for each arm */
00476         xdrproc_t dfault;       /* default xdr routine */
00477 {
00478         register enum_t dscm;
00479 
00480         /*
00481          * we deal with the discriminator;  it's an enum
00482          */
00483         if (! xdr_enum(xdrs, dscmp)) {
00484                 return (FALSE);
00485         }
00486         dscm = *dscmp;
00487 
00488         /*
00489          * search choices for a value that matches the discriminator.
00490          * if we find one, execute the xdr routine for that value.
00491          */
00492         for (; choices->proc != NULL_xdrproc_t; choices++) {
00493                 if (choices->value == dscm)
00494                         return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
00495         }
00496 
00497         /*
00498          * no match - execute the default xdr routine if there is one
00499          */
00500         return ((dfault == NULL_xdrproc_t) ? FALSE :
00501             (*dfault)(xdrs, unp, LASTUNSIGNED));
00502 }
00503 
00504 
00505 /*
00506  * Non-portable xdr primitives.
00507  * Care should be taken when moving these routines to new architectures.
00508  */
00509 
00510 
00511 /*
00512  * XDR null terminated ASCII strings
00513  * xdr_string deals with "C strings" - arrays of bytes that are
00514  * terminated by a NULL character.  The parameter cpp references a
00515  * pointer to storage; If the pointer is null, then the necessary
00516  * storage is allocated.  The last parameter is the max allowed length
00517  * of the string as specified by a protocol.
00518  */
00519 bool_t
00520 xdr_string(xdrs, cpp, maxsize)
00521         register XDR *xdrs;
00522         char **cpp;
00523         u_int maxsize;
00524 {
00525         register char *sp = *cpp;  /* sp is the actual string pointer */
00526         u_int size;
00527         u_int nodesize;
00528 
00529         /*
00530          * first deal with the length since xdr strings are counted-strings
00531          */
00532         switch (xdrs->x_op) {
00533         case XDR_FREE:
00534                 if (sp == NULL) {
00535                         return(TRUE);   /* already free */
00536                 }
00537                 /* fall through... */
00538         case XDR_ENCODE:
00539                 size = strlen(sp);
00540                 break;
00541         }
00542         if (! xdr_u_int(xdrs, &size)) {
00543                 return (FALSE);
00544         }
00545         if (size > maxsize) {
00546                 return (FALSE);
00547         }
00548         nodesize = size + 1;
00549 
00550         /*
00551          * now deal with the actual bytes
00552          */
00553         switch (xdrs->x_op) {
00554 
00555         case XDR_DECODE:
00556                 if (nodesize == 0) {
00557                         return (TRUE);
00558                 }
00559                 if (sp == NULL)
00560                         *cpp = sp = (char *)mem_alloc(nodesize);
00561                 if (sp == NULL) {
00562 #if !defined(UNDER_CE) && !defined(WINDOWS_CE)
00563                         (void) fprintf(stderr, "xdr_string: out of memory\n");
00564 #endif
00565                         return (FALSE);
00566                 }
00567                 sp[size] = 0;
00568                 /* fall into ... */
00569 
00570         case XDR_ENCODE:
00571                 return (xdr_opaque(xdrs, sp, size));
00572 
00573         case XDR_FREE:
00574                 mem_free(sp, nodesize);
00575                 *cpp = NULL;
00576                 return (TRUE);
00577         }
00578         return (FALSE);
00579 }
00580 
00581 /*
00582  * Wrapper for xdr_string that can be called directly from
00583  * routines like clnt_call
00584  */
00585 bool_t
00586 xdr_wrapstring(xdrs, cpp)
00587         XDR *xdrs;
00588         char **cpp;
00589 {
00590         if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
00591                 return (TRUE);
00592         }
00593         return (FALSE);
00594 }

Generated on Sun Dec 2 15:56:54 2001 for rcslib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001