![]() |
|
|
Generated: 8 Jan 2009 |
00001 00002 /********************************************************************* 00003 * RPC for the Windows NT Operating System 00004 * 1993 by Martin F. Gergeleit 00005 * Users may use, copy or modify Sun RPC for the Windows NT Operating 00006 * System according to the Sun copyright below. 00007 * 00008 * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 00009 * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 00010 * USE OF. USE ENTIRELY AT YOUR OWN RISK!!! 00011 *********************************************************************/ 00012 00013 /* @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC */ 00014 /* 00015 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 00016 * unrestricted use provided that this legend is included on all tape 00017 * media and as a part of the software program in whole or part. Users 00018 * may copy or modify Sun RPC without charge, but are not authorized 00019 * to license or distribute it to anyone else except as part of a product or 00020 * program developed by the user. 00021 * 00022 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 00023 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 00024 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 00025 * 00026 * Sun RPC is provided with no support and without any obligation on the 00027 * part of Sun Microsystems, Inc. to assist in its use, correction, 00028 * modification or enhancement. 00029 * 00030 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 00031 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 00032 * OR ANY PART THEREOF. 00033 * 00034 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 00035 * or profits or other special, indirect and consequential damages, even if 00036 * Sun has been advised of the possibility of such damages. 00037 * 00038 * Sun Microsystems, Inc. 00039 * 2550 Garcia Avenue 00040 * Mountain View, California 94043 00041 */ 00042 00044 #ifdef WIN32 00045 00046 #if !defined(lint) && defined(SCCSIDS) 00047 static char sccsid[] = "@(#)xdr.c 1.35 87/08/12"; 00048 #endif 00049 00050 /* 00051 * xdr.c, Generic XDR routines implementation. 00052 * 00053 * Copyright (C) 1986, Sun Microsystems, Inc. 00054 * 00055 * These are the "generic" xdr routines used to serialize and de-serialize 00056 * most common data items. See xdr.h for more info on the interface to 00057 * xdr. 00058 */ 00059 00060 #include <stdio.h> 00061 #include <stdlib.h> /* malloc,free */ 00062 #include <string.h> /* strlen() */ 00063 00064 #include <Winsock2.h> 00065 #include "xdr.h" 00066 00067 /* 00068 * constants specific to the xdr "protocol" 00069 */ 00070 #define XDR_FALSE ((long) 0) 00071 #define XDR_TRUE ((long) 1) 00072 #define LASTUNSIGNED ((u_int) 0-1) 00073 00074 /* 00075 * for unit alignment 00076 */ 00077 static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; 00078 00079 /* 00080 * Free a data structure using XDR 00081 * Not a filter, but a convenient utility nonetheless 00082 */ 00083 void 00084 xdr_free(xdrproc_t proc, char *objp) 00085 { 00086 XDR x; 00087 00088 x.x_op = XDR_FREE; 00089 (*proc)(&x, objp); 00090 } 00091 00092 /* 00093 * XDR nothing 00094 */ 00095 bool_t 00096 xdr_void(/* xdrs, addr */) 00097 /* XDR *xdrs; */ 00098 /* caddr_t addr; */ 00099 { 00100 00101 return (TRUE); 00102 } 00103 00104 /* 00105 * XDR integers 00106 */ 00107 bool_t 00108 xdr_int(XDR *xdrs, 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 long integers 00125 * same as xdr_u_long - open coded to save a proc call! 00126 */ 00127 bool_t 00128 xdr_long(register XDR *xdrs, long *lp) 00129 { 00130 00131 if (xdrs->x_op == XDR_ENCODE) 00132 return (XDR_PUTLONG(xdrs, lp)); 00133 00134 if (xdrs->x_op == XDR_DECODE) 00135 return (XDR_GETLONG(xdrs, lp)); 00136 00137 if (xdrs->x_op == XDR_FREE) 00138 return (TRUE); 00139 00140 return (FALSE); 00141 } 00142 00143 /* 00144 * XDR unsigned long integers 00145 * same as xdr_long - open coded to save a proc call! 00146 */ 00147 bool_t 00148 xdr_u_long(register XDR *xdrs, u_long *ulp) 00149 { 00150 00151 if (xdrs->x_op == XDR_DECODE) 00152 return (XDR_GETLONG(xdrs, (long *)ulp)); 00153 if (xdrs->x_op == XDR_ENCODE) 00154 return (XDR_PUTLONG(xdrs, (long *)ulp)); 00155 if (xdrs->x_op == XDR_FREE) 00156 return (TRUE); 00157 return (FALSE); 00158 } 00159 00160 /* 00161 * XDR short integers 00162 */ 00163 bool_t 00164 xdr_short(register XDR *xdrs, short *sp) 00165 { 00166 long l; 00167 00168 switch (xdrs->x_op) { 00169 00170 case XDR_ENCODE: 00171 l = (long) *sp; 00172 return (XDR_PUTLONG(xdrs, &l)); 00173 00174 case XDR_DECODE: 00175 if (!XDR_GETLONG(xdrs, &l)) { 00176 return (FALSE); 00177 } 00178 *sp = (short) l; 00179 return (TRUE); 00180 00181 case XDR_FREE: 00182 return (TRUE); 00183 } 00184 return (FALSE); 00185 } 00186 00187 /* 00188 * XDR unsigned short integers 00189 */ 00190 bool_t 00191 xdr_u_short(register XDR *xdrs, u_short *usp) 00192 { 00193 long l; 00194 00195 switch (xdrs->x_op) { 00196 00197 case XDR_ENCODE: 00198 l = (long) *usp; 00199 return (XDR_PUTLONG(xdrs, &l)); 00200 00201 case XDR_DECODE: 00202 if (!XDR_GETLONG(xdrs, &l)) { 00203 return (FALSE); 00204 } 00205 *usp = (u_short) l; 00206 return (TRUE); 00207 00208 case XDR_FREE: 00209 return (TRUE); 00210 } 00211 return (FALSE); 00212 } 00213 00214 /* 00215 * XDR unsigned integers 00216 */ 00217 bool_t 00218 xdr_u_int(XDR *xdrs, u_int *up) 00219 { 00220 00221 #ifdef lint 00222 (void) (xdr_short(xdrs, (short *)up)); 00223 return (xdr_u_long(xdrs, (u_long *)up)); 00224 #else 00225 if (sizeof (u_int) == sizeof (u_long)) { 00226 return (xdr_u_long(xdrs, (u_long *)up)); 00227 } else { 00228 return (xdr_short(xdrs, (short *)up)); 00229 } 00230 #endif 00231 } 00232 00233 /* 00234 * XDR opaque data 00235 * Allows the specification of a fixed size sequence of opaque bytes. 00236 * cp points to the opaque object and cnt gives the byte length. 00237 */ 00238 bool_t 00239 xdr_opaque(register XDR *xdrs, caddr_t cp, register u_int cnt) 00240 { 00241 register u_int rndup; 00242 static crud[BYTES_PER_XDR_UNIT]; 00243 00244 /* 00245 * if no data we are done 00246 */ 00247 if (cnt == 0) 00248 return (TRUE); 00249 00250 /* 00251 * round byte count to full xdr units 00252 */ 00253 rndup = cnt % BYTES_PER_XDR_UNIT; 00254 if (rndup > 0) 00255 rndup = BYTES_PER_XDR_UNIT - rndup; 00256 00257 if (xdrs->x_op == XDR_DECODE) { 00258 if (!XDR_GETBYTES(xdrs, cp, cnt)) { 00259 return (FALSE); 00260 } 00261 if (rndup == 0) 00262 return (TRUE); 00263 return (XDR_GETBYTES(xdrs, crud, rndup)); 00264 } 00265 00266 if (xdrs->x_op == XDR_ENCODE) { 00267 if (!XDR_PUTBYTES(xdrs, cp, cnt)) { 00268 return (FALSE); 00269 } 00270 if (rndup == 0) 00271 return (TRUE); 00272 return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); 00273 } 00274 00275 if (xdrs->x_op == XDR_FREE) { 00276 return (TRUE); 00277 } 00278 00279 return (FALSE); 00280 } 00281 00282 /* 00283 * XDR null terminated ASCII strings 00284 * xdr_string deals with "C strings" - arrays of bytes that are 00285 * terminated by a NULL character. The parameter cpp references a 00286 * pointer to storage; If the pointer is null, then the necessary 00287 * storage is allocated. The last parameter is the max allowed length 00288 * of the string as specified by a protocol. 00289 */ 00290 bool_t 00291 xdr_string(register XDR *xdrs, char **cpp, u_int maxsize) 00292 { 00293 register char *sp = *cpp; /* sp is the actual string pointer */ 00294 u_int size; 00295 u_int nodesize; 00296 00297 /* 00298 * first deal with the length since xdr strings are counted-strings 00299 */ 00300 switch (xdrs->x_op) { 00301 case XDR_FREE: 00302 if (sp == NULL) { 00303 return(TRUE); /* already free */ 00304 } 00305 /* fall through... */ 00306 case XDR_ENCODE: 00307 size = strlen(sp); 00308 break; 00309 } 00310 if (! xdr_u_int(xdrs, &size)) { 00311 return (FALSE); 00312 } 00313 if (size > maxsize) { 00314 return (FALSE); 00315 } 00316 nodesize = size + 1; 00317 00318 /* 00319 * now deal with the actual bytes 00320 */ 00321 switch (xdrs->x_op) { 00322 00323 case XDR_DECODE: 00324 if (nodesize == 0) { 00325 return (TRUE); 00326 } 00327 if (sp == NULL) 00328 *cpp = sp = (char *)mem_alloc(nodesize); 00329 if (sp == NULL) { 00330 (void) fprintf(stderr, "xdr_string: out of memory\n"); 00331 return (FALSE); 00332 } 00333 sp[size] = 0; 00334 /* fall into ... */ 00335 00336 case XDR_ENCODE: 00337 return (xdr_opaque(xdrs, sp, size)); 00338 00339 case XDR_FREE: 00340 mem_free(sp, nodesize); 00341 *cpp = NULL; 00342 return (TRUE); 00343 } 00344 return (FALSE); 00345 } 00346 00347 bool_t 00348 xdr_float(register XDR *xdrs, register float *fp) 00349 { 00350 switch (xdrs->x_op) { 00351 case XDR_ENCODE: 00352 return (XDR_PUTLONG(xdrs, (long *)fp)); 00353 case XDR_DECODE: 00354 return (XDR_GETLONG(xdrs, (long *)fp)); 00355 case XDR_FREE: 00356 return (TRUE); 00357 } 00358 return (FALSE); 00359 } 00360 00361 bool_t 00362 xdr_double(register XDR *xdrs, double *dp) 00363 { 00364 register long *lp; 00365 00366 switch (xdrs->x_op) { 00367 case XDR_ENCODE: 00368 lp = (long *)dp; 00369 return (XDR_PUTLONG(xdrs, lp+1) && XDR_PUTLONG(xdrs, lp)); 00370 case XDR_DECODE: 00371 lp = (long *)dp; 00372 return (XDR_GETLONG(xdrs, lp+1) && XDR_GETLONG(xdrs, lp)); 00373 case XDR_FREE: 00374 return (TRUE); 00375 } 00376 return (FALSE); 00377 } 00378 00379 00380 /************************* XDR operations with memory buffers **************************/ 00381 00382 void xdrmem_destroy(void *); 00383 bool_t xdrmem_getlong(void *xdrs, long *lp); 00384 bool_t xdrmem_putlong(void *xdrs, long *lp); 00385 bool_t xdrmem_getbytes(void *xdrs, void *addr, register int len); 00386 bool_t xdrmem_putbytes(void *xdrs, void *addr, register int len); 00387 u_int xdrmem_getpos(void *xdrs); 00388 bool_t xdrmem_setpos(void *xdrs, int pos); 00389 long * xdrmem_inline(void *xdrs, int len); 00390 00391 static XDR::xdr_ops xdrmem_ops = { 00392 &xdrmem_getlong, 00393 &xdrmem_putlong, 00394 &xdrmem_getbytes, 00395 &xdrmem_putbytes, 00396 &xdrmem_getpos, 00397 &xdrmem_setpos, 00398 &xdrmem_inline, 00399 &xdrmem_destroy 00400 }; 00401 00402 /* 00403 * The procedure xdrmem_create initializes a stream descriptor for a 00404 * memory buffer. 00405 */ 00406 void 00407 xdrmem_create(register XDR *xdrs, caddr_t addr, u_int size, enum xdr_op op) 00408 { 00409 00410 xdrs->x_op = op; 00411 xdrs->x_ops = &xdrmem_ops; 00412 xdrs->x_private = xdrs->x_base = addr; 00413 xdrs->x_handy = size; 00414 } 00415 00416 static void 00417 xdrmem_destroy(void *xdrs) 00418 { 00419 } 00420 00421 static bool_t 00422 xdrmem_getlong(void *xdrsv, long *lp) 00423 { 00424 register XDR *xdrs = (XDR *)xdrsv; 00425 if ((xdrs->x_handy -= sizeof(long)) < 0) 00426 return (FALSE); 00427 *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private)))); 00428 xdrs->x_private += sizeof(long); 00429 return (TRUE); 00430 } 00431 00432 static bool_t 00433 xdrmem_putlong(void *xdrsv, long *lp) 00434 { 00435 00436 register XDR *xdrs = (XDR *)xdrsv; 00437 if ((xdrs->x_handy -= sizeof(long)) < 0) 00438 return (FALSE); 00439 *(long *)xdrs->x_private = (long)htonl((u_long)(*lp)); 00440 xdrs->x_private += sizeof(long); 00441 return (TRUE); 00442 } 00443 00444 static bool_t 00445 xdrmem_getbytes(void *xdrsv, void *addr, register int len) 00446 { 00447 register XDR *xdrs = (XDR *)xdrsv; 00448 if ((xdrs->x_handy -= len) < 0) 00449 return (FALSE); 00450 memcpy(addr, xdrs->x_private, len); 00451 xdrs->x_private += len; 00452 return (TRUE); 00453 } 00454 00455 static bool_t 00456 xdrmem_putbytes(void *xdrsv, void *addr, register int len) 00457 { 00458 register XDR *xdrs = (XDR *)xdrsv; 00459 if ((xdrs->x_handy -= len) < 0) 00460 return (FALSE); 00461 memcpy(xdrs->x_private, addr, len); 00462 xdrs->x_private += len; 00463 return (TRUE); 00464 } 00465 00466 static u_int 00467 xdrmem_getpos(void *xdrsv) 00468 { 00469 register XDR *xdrs = (XDR *)xdrsv; 00470 return ((u_int)xdrs->x_private - (u_int)xdrs->x_base); 00471 } 00472 00473 static bool_t 00474 xdrmem_setpos(void *xdrsv, int pos) 00475 { 00476 register XDR *xdrs = (XDR *)xdrsv; 00477 register caddr_t newaddr = xdrs->x_base + pos; 00478 register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy; 00479 00480 if ((long)newaddr > (long)lastaddr) 00481 return (FALSE); 00482 xdrs->x_private = newaddr; 00483 xdrs->x_handy = (int)lastaddr - (int)newaddr; 00484 return (TRUE); 00485 } 00486 00487 static long * 00488 xdrmem_inline(void *xdrsv, int len) 00489 { 00490 long *buf = 0; 00491 register XDR *xdrs = (XDR *)xdrsv; 00492 if (xdrs->x_handy >= len) { 00493 xdrs->x_handy -= len; 00494 buf = (long *) xdrs->x_private; 00495 xdrs->x_private += len; 00496 } 00497 return (buf); 00498 } 00499 00500 #endif /* WIN32 */