Annotation of 43BSD/contrib/sunrpc/xdr_rec.c, revision 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_rec.c 1.5 85/03/14 Copyr 1984 Sun Micro";
        !            31: #endif
        !            32: 
        !            33: /*
        !            34:  * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
        !            35:  * layer above tcp (for rpc's use).
        !            36:  *
        !            37:  * Copyright (C) 1984, Sun Microsystems, Inc.
        !            38:  *
        !            39:  * These routines interface XDRSTREAMS to a tcp/ip connection.
        !            40:  * There is a record marking layer between the xdr stream
        !            41:  * and the tcp transport level.  A record is composed on one or more
        !            42:  * record fragments.  A record fragment is a thirty-two bit header followed
        !            43:  * by n bytes of data, where n is contained in the header.  The header
        !            44:  * is represented as a htonl(u_long).  Thegh order bit encodes
        !            45:  * whether or not the fragment is the last fragment of the record
        !            46:  * (1 => fragment is last, 0 => more fragments to follow. 
        !            47:  * The other 31 bits encode the byte length of the fragment.
        !            48:  */
        !            49: 
        !            50: #include <stdio.h>
        !            51: #include "types.h"
        !            52: #include "xdr.h"
        !            53: #include <sys/time.h>
        !            54: #include <netinet/in.h>
        !            55: 
        !            56: char *mem_alloc();
        !            57: 
        !            58: static u_int   fix_buf_size();
        !            59: 
        !            60: static bool_t  xdrrec_getlong();
        !            61: static bool_t  xdrrec_putlong();
        !            62: static bool_t  xdrrec_getbytes();
        !            63: static bool_t  xdrrec_putbytes();
        !            64: static u_int   xdrrec_getpos();
        !            65: static bool_t  xdrrec_setpos();
        !            66: static long *  xdrrec_inline();
        !            67: static void    xdrrec_destroy();
        !            68: 
        !            69: static struct  xdr_ops xdrrec_ops = {
        !            70:        xdrrec_getlong,
        !            71:        xdrrec_putlong,
        !            72:        xdrrec_getbytes,
        !            73:        xdrrec_putbytes,
        !            74:        xdrrec_getpos,
        !            75:        xdrrec_setpos,
        !            76:        xdrrec_inline,
        !            77:        xdrrec_destroy
        !            78: };
        !            79: 
        !            80: /*
        !            81:  * A record is composed of one or more record fragments.
        !            82:  * A record fragment is a two-byte header followed by zero to
        !            83:  * 2**32-1 bytes.  The header is treated as a long unsigned and is
        !            84:  * encode/decoded to the network via htonl/ntohl.  The low order 31 bits
        !            85:  * are a byte count of the fragment.  The highest order bit is a boolean:
        !            86:  * 1 => this fragment is the last fragment of the record,
        !            87:  * 0 => this fragment is followed by more fragment(s).
        !            88:  *
        !            89:  * The fragment/record machinery is not general;  it is constructed to
        !            90:  * meet the needs of xdr and rpc based on tcp.
        !            91:  */
        !            92: 
        !            93: #define LAST_FRAG ((u_long)(1 << 31))
        !            94: 
        !            95: typedef struct rec_strm {
        !            96:        caddr_t tcp_handle;
        !            97:        /*
        !            98:         * out-goung bits
        !            99:         */
        !           100:        int (*writeit)();
        !           101:        caddr_t out_base;       /* output buffer (points to frag header) */
        !           102:        caddr_t out_finger;     /* next output position */
        !           103:        caddr_t out_boundry;    /* data cannot up to this address */
        !           104:        u_long *frag_header;    /* beginning of curren fragment */
        !           105:        bool_t frag_sent;       /* true if buffer sent in middle of record */
        !           106:        /*
        !           107:         * in-coming bits
        !           108:         */
        !           109:        int (*readit)();
        !           110:        u_long in_size; /* fixed size of the input buffer */
        !           111:        caddr_t in_base;
        !           112:        caddr_t in_finger;      /* location of next byte to be had */
        !           113:        caddr_t in_boundry;     /* can read up to this location */
        !           114:        long fbtbc;             /* fragment bytes to be consumed */
        !           115:        bool_t last_frag;
        !           116:        u_int sendsize;
        !           117:        u_int recvsize;
        !           118: } RECSTREAM;
        !           119: 
        !           120: 
        !           121: /*
        !           122:  * Create an xdr handle for xdrrec
        !           123:  * xdrrec_create fills in xdrs.  Sendsize and recvsize are
        !           124:  * send and recv buffer sizes (0 => use default).
        !           125:  * tcp_handle is an opaque handle that is passed as the first parameter to
        !           126:  * the procedures readit and writeit.  Readit and writeit are read and
        !           127:  * write respectively.   They are like the system
        !           128:  * calls expect that they take an opaque handle rather than an fd.
        !           129:  */
        !           130: void
        !           131: xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
        !           132:        register XDR *xdrs;
        !           133:        u_int sendsize;
        !           134:        u_int recvsize;
        !           135:        caddr_t tcp_handle;
        !           136:        int (*readit)();  /* like read, but pass it a tcp_handle, not sock */
        !           137:        int (*writeit)();  /* like write, but pass it a tcp_handle, not sock */
        !           138: {
        !           139:        register RECSTREAM *rstrm =
        !           140:            (RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
        !           141: 
        !           142:        if (rstrm == NULL) {
        !           143:                fprintf(stderr, "xdrrec_create: out of memory\n");
        !           144:                /* 
        !           145:                 *  This is bad.  Should rework xdrrec_create to 
        !           146:                 *  return a handle, and in this case return NULL
        !           147:                 */
        !           148:                return;
        !           149:        }
        !           150:        xdrs->x_ops = &xdrrec_ops;
        !           151:        xdrs->x_private = (caddr_t)rstrm;
        !           152:        rstrm->tcp_handle = tcp_handle;
        !           153:        rstrm->readit = readit;
        !           154:        rstrm->writeit = writeit;
        !           155:        sendsize = fix_buf_size(sendsize);
        !           156:        if ((rstrm->out_base = rstrm->out_finger = rstrm->out_boundry =
        !           157:            mem_alloc(sendsize)) == NULL) {
        !           158:                fprintf(stderr, "xdrrec_create: out of memory\n");
        !           159:                return;
        !           160:        }
        !           161:        rstrm->frag_header = (u_long *)rstrm->out_base;
        !           162:        rstrm->out_finger += sizeof(u_long);
        !           163:        rstrm->out_boundry += sendsize;
        !           164:        rstrm->frag_sent = FALSE;
        !           165:        rstrm->in_size = recvsize = fix_buf_size(recvsize);
        !           166:        if ((rstrm->in_base = rstrm->in_boundry=mem_alloc(recvsize)) == NULL) {
        !           167:                fprintf(stderr, "xdrrec_create: out of memory\n");
        !           168:                return;
        !           169:        }
        !           170:        rstrm->in_finger = (rstrm->in_boundry += recvsize);
        !           171:        rstrm->fbtbc = 0;
        !           172:        rstrm->last_frag = TRUE;
        !           173:        rstrm->sendsize = sendsize;
        !           174:        rstrm->recvsize = recvsize;
        !           175: }
        !           176: 
        !           177: 
        !           178: /*
        !           179:  * The reoutines defined below are the xdr ops which will go into the
        !           180:  * xdr handle filled in by xdrrec_create.
        !           181:  */
        !           182: 
        !           183: static bool_t
        !           184: xdrrec_getlong(xdrs, lp)
        !           185:        XDR *xdrs;
        !           186:        long *lp;
        !           187: {
        !           188:        register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        !           189:        register long *buflp = (long *)(rstrm->in_finger);
        !           190:        long mylong;
        !           191: 
        !           192:        /* first try the inline, fast case */
        !           193:        if ((rstrm->fbtbc >= sizeof(long)) &&
        !           194:            (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) {
        !           195:                *lp = ntohl(*buflp);
        !           196:                rstrm->fbtbc -= sizeof(long);
        !           197:                rstrm->in_finger += sizeof(long);
        !           198:        } else {
        !           199:                if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
        !           200:                        return (FALSE);
        !           201:                *lp = ntohl(mylong);
        !           202:        }
        !           203:        return (TRUE);
        !           204: }
        !           205: 
        !           206: static bool_t
        !           207: xdrrec_putlong(xdrs, lp)
        !           208:        XDR *xdrs;
        !           209:        long *lp;
        !           210: {
        !           211:        register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        !           212:        register long *dest_lp = ((long *)(rstrm->out_finger));
        !           213: 
        !           214:        if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) {
        !           215:                /*
        !           216:                 * this case should almost never happen so the code is
        !           217:                 * inefficient
        !           218:                 */
        !           219:                rstrm->out_finger -= sizeof(long);
        !           220:                rstrm->frag_sent = TRUE;
        !           221:                if (! flush_out(rstrm, FALSE))
        !           222:                        return (FALSE);
        !           223:                dest_lp = ((long *)(rstrm->out_finger));
        !           224:                rstrm->out_finger += sizeof(long);
        !           225:        }
        !           226:        *dest_lp = htonl(*lp);
        !           227:        return (TRUE);
        !           228: }
        !           229: 
        !           230: static bool_t  /* must manage buffers, fragments, and records */
        !           231: xdrrec_getbytes(xdrs, addr, len)
        !           232:        XDR *xdrs;
        !           233:        register caddr_t addr;
        !           234:        register u_int len;
        !           235: {
        !           236:        register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        !           237:        register int current;
        !           238: 
        !           239:        while (len > 0) {
        !           240:                current = rstrm->fbtbc;
        !           241:                if (current == 0) {
        !           242:                        if (rstrm->last_frag)
        !           243:                                return (FALSE);
        !           244:                        if (! set_input_fragment(rstrm))
        !           245:                                return (FALSE);
        !           246:                        continue;
        !           247:                }
        !           248:                current = (len < current) ? len : current;
        !           249:                if (! get_input_bytes(rstrm, addr, current))
        !           250:                        return (FALSE);
        !           251:                addr += current; 
        !           252:                rstrm->fbtbc -= current;
        !           253:                len -= current;
        !           254:        }
        !           255:        return (TRUE);
        !           256: }
        !           257: 
        !           258: static bool_t
        !           259: xdrrec_putbytes(xdrs, addr, len)
        !           260:        XDR *xdrs;
        !           261:        register caddr_t addr;
        !           262:        register u_int len;
        !           263: {
        !           264:        register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        !           265:        register int current;
        !           266: 
        !           267:        while (len > 0) {
        !           268:                current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger;
        !           269:                current = (len < current) ? len : current;
        !           270:                bcopy(addr, rstrm->out_finger, current);
        !           271:                rstrm->out_finger += current;
        !           272:                addr += current;
        !           273:                len -= current;
        !           274:                if (rstrm->out_finger == rstrm->out_boundry) {
        !           275:                        rstrm->frag_sent = TRUE;
        !           276:                        if (! flush_out(rstrm, FALSE))
        !           277:                                return (FALSE);
        !           278:                }
        !           279:        }
        !           280:        return (TRUE);
        !           281: }
        !           282: 
        !           283: static u_int
        !           284: xdrrec_getpos(xdrs)
        !           285:        register XDR *xdrs;
        !           286: {
        !           287:        register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
        !           288:        register u_int pos;
        !           289: 
        !           290:        pos = lseek((int)rstrm->tcp_handle, 0, 1);
        !           291:        if ((int)pos != -1)
        !           292:                switch (xdrs->x_op) {
        !           293: 
        !           294:                case XDR_ENCODE:
        !           295:                        pos += rstrm->out_finger - rstrm->out_base;
        !           296:                        break;
        !           297: 
        !           298:                case XDR_DECODE:
        !           299:                        pos -= rstrm->in_boundry - rstrm->in_finger;
        !           300:                        break;
        !           301: 
        !           302:                default:
        !           303:                        pos = (u_int) -1;
        !           304:                        break;
        !           305:                }
        !           306:        return (pos);
        !           307: }
        !           308: 
        !           309: static bool_t
        !           310: xdrrec_setpos(xdrs, pos)
        !           311:        register XDR *xdrs;
        !           312:        u_int pos;
        !           313: {
        !           314:        register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
        !           315:        u_int currpos = xdrrec_getpos(xdrs);
        !           316:        int delta = currpos - pos;
        !           317:        caddr_t newpos;
        !           318: 
        !           319:        if ((int)currpos != -1)
        !           320:                switch (xdrs->x_op) {
        !           321: 
        !           322:                case XDR_ENCODE:
        !           323:                        newpos = rstrm->out_finger - delta;
        !           324:                        if ((newpos > (caddr_t)(rstrm->frag_header)) &&
        !           325:                            (newpos < rstrm->out_boundry)) {
        !           326:                                rstrm->out_finger = newpos;
        !           327:                                return (TRUE);
        !           328:                        }
        !           329:                        break;
        !           330: 
        !           331:                case XDR_DECODE:
        !           332:                        newpos = rstrm->in_finger - delta;
        !           333:                        if ((delta < (int)(rstrm->fbtbc)) &&
        !           334:                            (newpos <= rstrm->in_boundry) &&
        !           335:                            (newpos >= rstrm->in_base)) {
        !           336:                                rstrm->in_finger = newpos;
        !           337:                                rstrm->fbtbc -= delta;
        !           338:                                return (TRUE);
        !           339:                        }
        !           340:                        break;
        !           341:                }
        !           342:        return (FALSE);
        !           343: }
        !           344: 
        !           345: static long *
        !           346: xdrrec_inline(xdrs, len)
        !           347:        register XDR *xdrs;
        !           348:        int len;
        !           349: {
        !           350:        register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
        !           351:        long * buf = NULL;
        !           352: 
        !           353:        switch (xdrs->x_op) {
        !           354: 
        !           355:        case XDR_ENCODE:
        !           356:                if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
        !           357:                        buf = (long *) rstrm->out_finger;
        !           358:                        rstrm->out_finger += len;
        !           359:                }
        !           360:                break;
        !           361: 
        !           362:        case XDR_DECODE:
        !           363:                if ((len <= rstrm->fbtbc) &&
        !           364:                    ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
        !           365:                        buf = (long *) rstrm->in_finger;
        !           366:                        rstrm->fbtbc -= len;
        !           367:                        rstrm->in_finger += len;
        !           368:                }
        !           369:                break;
        !           370:        }
        !           371:        return (buf);
        !           372: }
        !           373: 
        !           374: static void
        !           375: xdrrec_destroy(xdrs)
        !           376:        register XDR *xdrs;
        !           377: {
        !           378:        register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
        !           379: 
        !           380:        mem_free(rstrm->out_base, rstrm->sendsize);
        !           381:        mem_free(rstrm->in_base, rstrm->recvsize);
        !           382:        mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
        !           383: }
        !           384: 
        !           385: 
        !           386: /*
        !           387:  * Exported routines to manage xdr records
        !           388:  */
        !           389: 
        !           390: /*
        !           391:  * Before reading (deserializing from the stream, one should always call
        !           392:  * this procedure to guarantee proper record alignment.
        !           393:  */
        !           394: bool_t
        !           395: xdrrec_skiprecord(xdrs)
        !           396:        XDR *xdrs;
        !           397: {
        !           398:        register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        !           399: 
        !           400:        while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
        !           401:                if (! skip_input_bytes(rstrm, rstrm->fbtbc))
        !           402:                        return (FALSE);
        !           403:                rstrm->fbtbc = 0;
        !           404:                if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
        !           405:                        return (FALSE);
        !           406:        }
        !           407:        rstrm->last_frag = FALSE;
        !           408:        return (TRUE);
        !           409: }
        !           410: 
        !           411: /*
        !           412:  * Look ahead fuction.
        !           413:  * Returns TRUE iff there is no more input in the buffer 
        !           414:  * after consuming the rest of the current record.
        !           415:  */
        !           416: bool_t
        !           417: xdrrec_eof(xdrs)
        !           418:        XDR *xdrs;
        !           419: {
        !           420:        register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        !           421: 
        !           422:        while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
        !           423:                if (! skip_input_bytes(rstrm, rstrm->fbtbc))
        !           424:                        return (TRUE);
        !           425:                rstrm->fbtbc = 0;
        !           426:                if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
        !           427:                        return (TRUE);
        !           428:        }
        !           429:        if (rstrm->in_finger == rstrm->in_boundry)
        !           430:                return (TRUE);
        !           431:        return (FALSE);
        !           432: }
        !           433: 
        !           434: /*
        !           435:  * The client must tell the package when an end-of-record has occurred.
        !           436:  * The second paraemters tells whether the record should be flushed to the
        !           437:  * (output) tcp stream.  (This let's the package support batched or
        !           438:  * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
        !           439:  */
        !           440: bool_t
        !           441: xdrrec_endofrecord(xdrs, sendnow)
        !           442:        XDR *xdrs;
        !           443:        bool_t sendnow;
        !           444: {
        !           445:        register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        !           446:        register u_long len;  /* fragment length */
        !           447: 
        !           448:        if (sendnow || rstrm->frag_sent ||
        !           449:            ((u_long)rstrm->out_finger + sizeof(u_long) >=
        !           450:            (u_long)rstrm->out_boundry)) {
        !           451:                rstrm->frag_sent = FALSE;
        !           452:                return (flush_out(rstrm, TRUE));
        !           453:        }
        !           454:        len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
        !           455:           sizeof(u_long);
        !           456:        *(rstrm->frag_header) = htonl(len | LAST_FRAG);
        !           457:        rstrm->frag_header = (u_long *)rstrm->out_finger;
        !           458:        rstrm->out_finger += sizeof(u_long);
        !           459:        return (TRUE);
        !           460: }
        !           461: 
        !           462: 
        !           463: /*
        !           464:  * Internal useful routines
        !           465:  */
        !           466: static bool_t
        !           467: flush_out(rstrm, eor)
        !           468:        register RECSTREAM *rstrm;
        !           469:        bool_t eor;
        !           470: {
        !           471:        register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
        !           472:        register u_long len = (u_long)(rstrm->out_finger) - 
        !           473:            (u_long)(rstrm->frag_header) - sizeof(u_long);
        !           474: 
        !           475:        *(rstrm->frag_header) = htonl(len | eormask);
        !           476:        len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
        !           477:        if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
        !           478:            != (int)len)
        !           479:                return (FALSE);
        !           480:        rstrm->frag_header = (u_long *)rstrm->out_base;
        !           481:        rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long);
        !           482:        return (TRUE);
        !           483: }
        !           484: 
        !           485: static bool_t  /* knows nothing about records!  Only about input buffers */
        !           486: fill_input_buf(rstrm)
        !           487:        register RECSTREAM *rstrm;
        !           488: {
        !           489:        register caddr_t where = rstrm->in_base;
        !           490:        register int len = rstrm->in_size;
        !           491: 
        !           492:        if (((int)rstrm->in_boundry % 2) != 0) {
        !           493:                /* keep stream odd bytes aligned with memory odd bytes */
        !           494:                where++;
        !           495:                len--;
        !           496:        }
        !           497:        if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
        !           498:                return (FALSE);
        !           499:        rstrm->in_finger = where;
        !           500:        where += len;
        !           501:        rstrm->in_boundry = where;
        !           502:        return (TRUE);
        !           503: }
        !           504: 
        !           505: static bool_t  /* knows nothing about records!  Only about input buffers */
        !           506: get_input_bytes(rstrm, addr, len)
        !           507:        register RECSTREAM *rstrm;
        !           508:        register caddr_t addr;
        !           509:        register int len;
        !           510: {
        !           511:        register int current;
        !           512: 
        !           513:        while (len > 0) {
        !           514:                current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
        !           515:                if (current == 0) {
        !           516:                        if (! fill_input_buf(rstrm))
        !           517:                                return (FALSE);
        !           518:                        continue;
        !           519:                }
        !           520:                current = (len < current) ? len : current;
        !           521:                bcopy(rstrm->in_finger, addr, current);
        !           522:                rstrm->in_finger += current;
        !           523:                addr += current;
        !           524:                len -= current;
        !           525:        }
        !           526:        return (TRUE);
        !           527: }
        !           528: 
        !           529: static bool_t  /* next two bytes of the input stream are treated as a header */
        !           530: set_input_fragment(rstrm)
        !           531:        register RECSTREAM *rstrm;
        !           532: {
        !           533:        u_long header;
        !           534: 
        !           535:        if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
        !           536:                return (FALSE);
        !           537:        header = ntohl(header);
        !           538:        rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
        !           539:        rstrm->fbtbc = header & (~LAST_FRAG);
        !           540:        return (TRUE);
        !           541: }
        !           542: 
        !           543: static bool_t  /* consumes input bytes; knows nothing about records! */
        !           544: skip_input_bytes(rstrm, cnt)
        !           545:        register RECSTREAM *rstrm;
        !           546:        int cnt;
        !           547: {
        !           548:        register int current;
        !           549: 
        !           550:        while (cnt > 0) {
        !           551:                current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
        !           552:                if (current == 0) {
        !           553:                        if (! fill_input_buf(rstrm))
        !           554:                                return (FALSE);
        !           555:                        continue;
        !           556:                }
        !           557:                current = (cnt < current) ? cnt : current;
        !           558:                rstrm->in_finger += current;
        !           559:                cnt -= current;
        !           560:        }
        !           561:        return (TRUE);
        !           562: }
        !           563: 
        !           564: static u_int
        !           565: fix_buf_size(s)
        !           566:        register u_int s;
        !           567: {
        !           568: 
        !           569:        if (s < 100)
        !           570:                return (3998);
        !           571:        for (; (s % 4) != 2; --s);
        !           572:        return (s);
        !           573: }

unix.superglobalmegacorp.com

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