Main Page   Modules   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

/projects/cubeos/src_current/net/rpc/xdr.c

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

Generated on Thu Feb 20 15:38:45 2003 for cubeOS by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002