Annotation of 43BSD/contrib/sunrpc/xdr.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.