xdr_rec.c (95658) | xdr_rec.c (109359) |
---|---|
1/* $NetBSD: xdr_rec.c,v 1.18 2000/07/06 03:10:35 christos Exp $ */ 2 3/* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or --- 21 unchanged lines hidden (view full) --- 30 */ 31 32#include <sys/cdefs.h> 33#if defined(LIBC_SCCS) && !defined(lint) 34static char *sccsid = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro"; 35static char *sccsid = "@(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC"; 36#endif 37#include <sys/cdefs.h> | 1/* $NetBSD: xdr_rec.c,v 1.18 2000/07/06 03:10:35 christos Exp $ */ 2 3/* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or --- 21 unchanged lines hidden (view full) --- 30 */ 31 32#include <sys/cdefs.h> 33#if defined(LIBC_SCCS) && !defined(lint) 34static char *sccsid = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro"; 35static char *sccsid = "@(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC"; 36#endif 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/lib/libc/xdr/xdr_rec.c 95658 2002-04-28 15:18:50Z des $"); | 38__FBSDID("$FreeBSD: head/lib/libc/xdr/xdr_rec.c 109359 2003-01-16 07:13:51Z mbr $"); |
39 40/* 41 * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" 42 * layer above tcp (for rpc's use). 43 * 44 * Copyright (C) 1984, Sun Microsystems, Inc. 45 * 46 * These routines interface XDRSTREAMS to a tcp/ip connection. --- 14 unchanged lines hidden (view full) --- 61 62#include <err.h> 63#include <stdio.h> 64#include <stdlib.h> 65#include <string.h> 66 67#include <rpc/types.h> 68#include <rpc/xdr.h> | 39 40/* 41 * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" 42 * layer above tcp (for rpc's use). 43 * 44 * Copyright (C) 1984, Sun Microsystems, Inc. 45 * 46 * These routines interface XDRSTREAMS to a tcp/ip connection. --- 14 unchanged lines hidden (view full) --- 61 62#include <err.h> 63#include <stdio.h> 64#include <stdlib.h> 65#include <string.h> 66 67#include <rpc/types.h> 68#include <rpc/xdr.h> |
69#include <rpc/auth.h> 70#include <rpc/svc.h> 71#include <rpc/clnt.h> 72#include <sys/stddef.h> |
|
69#include "un-namespace.h" 70 71static bool_t xdrrec_getlong(XDR *, long *); 72static bool_t xdrrec_putlong(XDR *, const long *); 73static bool_t xdrrec_getbytes(XDR *, char *, u_int); 74 75static bool_t xdrrec_putbytes(XDR *, const char *, u_int); 76static u_int xdrrec_getpos(XDR *); --- 9 unchanged lines hidden (view full) --- 86 xdrrec_getpos, 87 xdrrec_setpos, 88 xdrrec_inline, 89 xdrrec_destroy 90}; 91 92/* 93 * A record is composed of one or more record fragments. | 73#include "un-namespace.h" 74 75static bool_t xdrrec_getlong(XDR *, long *); 76static bool_t xdrrec_putlong(XDR *, const long *); 77static bool_t xdrrec_getbytes(XDR *, char *, u_int); 78 79static bool_t xdrrec_putbytes(XDR *, const char *, u_int); 80static u_int xdrrec_getpos(XDR *); --- 9 unchanged lines hidden (view full) --- 90 xdrrec_getpos, 91 xdrrec_setpos, 92 xdrrec_inline, 93 xdrrec_destroy 94}; 95 96/* 97 * A record is composed of one or more record fragments. |
94 * A record fragment is a two-byte header followed by zero to | 98 * A record fragment is a four-byte header followed by zero to |
95 * 2**32-1 bytes. The header is treated as a long unsigned and is 96 * encode/decoded to the network via htonl/ntohl. The low order 31 bits 97 * are a byte count of the fragment. The highest order bit is a boolean: 98 * 1 => this fragment is the last fragment of the record, 99 * 0 => this fragment is followed by more fragment(s). 100 * 101 * The fragment/record machinery is not general; it is constructed to 102 * meet the needs of xdr and rpc based on tcp. 103 */ 104 105#define LAST_FRAG ((u_int32_t)(1 << 31)) 106 107typedef struct rec_strm { 108 char *tcp_handle; | 99 * 2**32-1 bytes. The header is treated as a long unsigned and is 100 * encode/decoded to the network via htonl/ntohl. The low order 31 bits 101 * are a byte count of the fragment. The highest order bit is a boolean: 102 * 1 => this fragment is the last fragment of the record, 103 * 0 => this fragment is followed by more fragment(s). 104 * 105 * The fragment/record machinery is not general; it is constructed to 106 * meet the needs of xdr and rpc based on tcp. 107 */ 108 109#define LAST_FRAG ((u_int32_t)(1 << 31)) 110 111typedef struct rec_strm { 112 char *tcp_handle; |
109 char *the_buffer; | |
110 /* 111 * out-goung bits 112 */ 113 int (*writeit)(void *, void *, int); 114 char *out_base; /* output buffer (points to frag header) */ 115 char *out_finger; /* next output position */ 116 char *out_boundry; /* data cannot up to this address */ 117 u_int32_t *frag_header; /* beginning of curren fragment */ --- 5 unchanged lines hidden (view full) --- 123 u_long in_size; /* fixed size of the input buffer */ 124 char *in_base; 125 char *in_finger; /* location of next byte to be had */ 126 char *in_boundry; /* can read up to this location */ 127 long fbtbc; /* fragment bytes to be consumed */ 128 bool_t last_frag; 129 u_int sendsize; 130 u_int recvsize; | 113 /* 114 * out-goung bits 115 */ 116 int (*writeit)(void *, void *, int); 117 char *out_base; /* output buffer (points to frag header) */ 118 char *out_finger; /* next output position */ 119 char *out_boundry; /* data cannot up to this address */ 120 u_int32_t *frag_header; /* beginning of curren fragment */ --- 5 unchanged lines hidden (view full) --- 126 u_long in_size; /* fixed size of the input buffer */ 127 char *in_base; 128 char *in_finger; /* location of next byte to be had */ 129 char *in_boundry; /* can read up to this location */ 130 long fbtbc; /* fragment bytes to be consumed */ 131 bool_t last_frag; 132 u_int sendsize; 133 u_int recvsize; |
134 135 bool_t nonblock; 136 bool_t in_haveheader; 137 u_int32_t in_header; 138 char *in_hdrp; 139 int in_hdrlen; 140 int in_reclen; 141 int in_received; 142 int in_maxrec; |
|
131} RECSTREAM; 132 133static u_int fix_buf_size(u_int); 134static bool_t flush_out(RECSTREAM *, bool_t); 135static bool_t fill_input_buf(RECSTREAM *); 136static bool_t get_input_bytes(RECSTREAM *, char *, int); 137static bool_t set_input_fragment(RECSTREAM *); 138static bool_t skip_input_bytes(RECSTREAM *, long); | 143} RECSTREAM; 144 145static u_int fix_buf_size(u_int); 146static bool_t flush_out(RECSTREAM *, bool_t); 147static bool_t fill_input_buf(RECSTREAM *); 148static bool_t get_input_bytes(RECSTREAM *, char *, int); 149static bool_t set_input_fragment(RECSTREAM *); 150static bool_t skip_input_bytes(RECSTREAM *, long); |
151static bool_t realloc_stream(RECSTREAM *, int); |
|
139 140 141/* 142 * Create an xdr handle for xdrrec 143 * xdrrec_create fills in xdrs. Sendsize and recvsize are 144 * send and recv buffer sizes (0 => use default). 145 * tcp_handle is an opaque handle that is passed as the first parameter to 146 * the procedures readit and writeit. Readit and writeit are read and --- 16 unchanged lines hidden (view full) --- 163 if (rstrm == NULL) { 164 warnx("xdrrec_create: out of memory"); 165 /* 166 * This is bad. Should rework xdrrec_create to 167 * return a handle, and in this case return NULL 168 */ 169 return; 170 } | 152 153 154/* 155 * Create an xdr handle for xdrrec 156 * xdrrec_create fills in xdrs. Sendsize and recvsize are 157 * send and recv buffer sizes (0 => use default). 158 * tcp_handle is an opaque handle that is passed as the first parameter to 159 * the procedures readit and writeit. Readit and writeit are read and --- 16 unchanged lines hidden (view full) --- 176 if (rstrm == NULL) { 177 warnx("xdrrec_create: out of memory"); 178 /* 179 * This is bad. Should rework xdrrec_create to 180 * return a handle, and in this case return NULL 181 */ 182 return; 183 } |
171 /* 172 * adjust sizes and allocate buffer quad byte aligned 173 */ | |
174 rstrm->sendsize = sendsize = fix_buf_size(sendsize); | 184 rstrm->sendsize = sendsize = fix_buf_size(sendsize); |
185 rstrm->out_base = mem_alloc(rstrm->sendsize); 186 if (rstrm->out_base == NULL) { 187 warnx("xdrrec_create: out of memory"); 188 mem_free(rstrm, sizeof(RECSTREAM)); 189 return; 190 } |
|
175 rstrm->recvsize = recvsize = fix_buf_size(recvsize); | 191 rstrm->recvsize = recvsize = fix_buf_size(recvsize); |
176 rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); 177 if (rstrm->the_buffer == NULL) { | 192 rstrm->in_base = mem_alloc(recvsize); 193 if (rstrm->in_base == NULL) { |
178 warnx("xdrrec_create: out of memory"); | 194 warnx("xdrrec_create: out of memory"); |
195 mem_free(rstrm->out_base, sendsize); 196 mem_free(rstrm, sizeof(RECSTREAM)); |
|
179 return; 180 } | 197 return; 198 } |
181 for (rstrm->out_base = rstrm->the_buffer; 182 (u_long)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; 183 rstrm->out_base++); 184 rstrm->in_base = rstrm->out_base + sendsize; | |
185 /* 186 * now the rest ... 187 */ 188 xdrs->x_ops = &xdrrec_ops; 189 xdrs->x_private = rstrm; 190 rstrm->tcp_handle = tcp_handle; 191 rstrm->readit = readit; 192 rstrm->writeit = writeit; 193 rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; 194 rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_base; 195 rstrm->out_finger += sizeof(u_int32_t); 196 rstrm->out_boundry += sendsize; 197 rstrm->frag_sent = FALSE; 198 rstrm->in_size = recvsize; 199 rstrm->in_boundry = rstrm->in_base; 200 rstrm->in_finger = (rstrm->in_boundry += recvsize); 201 rstrm->fbtbc = 0; 202 rstrm->last_frag = TRUE; | 199 /* 200 * now the rest ... 201 */ 202 xdrs->x_ops = &xdrrec_ops; 203 xdrs->x_private = rstrm; 204 rstrm->tcp_handle = tcp_handle; 205 rstrm->readit = readit; 206 rstrm->writeit = writeit; 207 rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; 208 rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_base; 209 rstrm->out_finger += sizeof(u_int32_t); 210 rstrm->out_boundry += sendsize; 211 rstrm->frag_sent = FALSE; 212 rstrm->in_size = recvsize; 213 rstrm->in_boundry = rstrm->in_base; 214 rstrm->in_finger = (rstrm->in_boundry += recvsize); 215 rstrm->fbtbc = 0; 216 rstrm->last_frag = TRUE; |
217 rstrm->in_haveheader = FALSE; 218 rstrm->in_hdrlen = 0; 219 rstrm->in_hdrp = (char *)(void *)&rstrm->in_header; 220 rstrm->nonblock = FALSE; 221 rstrm->in_reclen = 0; 222 rstrm->in_received = 0; |
|
203} 204 205 206/* 207 * The reoutines defined below are the xdr ops which will go into the 208 * xdr handle filled in by xdrrec_create. 209 */ 210 --- 197 unchanged lines hidden (view full) --- 408} 409 410static void 411xdrrec_destroy(xdrs) 412 XDR *xdrs; 413{ 414 RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; 415 | 223} 224 225 226/* 227 * The reoutines defined below are the xdr ops which will go into the 228 * xdr handle filled in by xdrrec_create. 229 */ 230 --- 197 unchanged lines hidden (view full) --- 428} 429 430static void 431xdrrec_destroy(xdrs) 432 XDR *xdrs; 433{ 434 RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; 435 |
416 mem_free(rstrm->the_buffer, 417 rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); | 436 mem_free(rstrm->out_base, rstrm->sendsize); 437 mem_free(rstrm->in_base, rstrm->recvsize); |
418 mem_free(rstrm, sizeof(RECSTREAM)); 419} 420 421 422/* 423 * Exported routines to manage xdr records 424 */ 425 426/* 427 * Before reading (deserializing from the stream, one should always call 428 * this procedure to guarantee proper record alignment. 429 */ 430bool_t 431xdrrec_skiprecord(xdrs) 432 XDR *xdrs; 433{ 434 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); | 438 mem_free(rstrm, sizeof(RECSTREAM)); 439} 440 441 442/* 443 * Exported routines to manage xdr records 444 */ 445 446/* 447 * Before reading (deserializing from the stream, one should always call 448 * this procedure to guarantee proper record alignment. 449 */ 450bool_t 451xdrrec_skiprecord(xdrs) 452 XDR *xdrs; 453{ 454 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); |
455 enum xprt_stat xstat; |
|
435 | 456 |
457 if (rstrm->nonblock) { 458 if (__xdrrec_getrec(xdrs, &xstat, FALSE)) { 459 rstrm->fbtbc = 0; 460 return TRUE; 461 } 462 if (rstrm->in_finger == rstrm->in_boundry && 463 xstat == XPRT_MOREREQS) { 464 rstrm->fbtbc = 0; 465 return TRUE; 466 } 467 return FALSE; 468 } 469 |
|
436 while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { 437 if (! skip_input_bytes(rstrm, rstrm->fbtbc)) 438 return (FALSE); 439 rstrm->fbtbc = 0; 440 if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) 441 return (FALSE); 442 } 443 rstrm->last_frag = FALSE; --- 5 unchanged lines hidden (view full) --- 449 * Returns TRUE iff there is no more input in the buffer 450 * after consuming the rest of the current record. 451 */ 452bool_t 453xdrrec_eof(xdrs) 454 XDR *xdrs; 455{ 456 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); | 470 while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { 471 if (! skip_input_bytes(rstrm, rstrm->fbtbc)) 472 return (FALSE); 473 rstrm->fbtbc = 0; 474 if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) 475 return (FALSE); 476 } 477 rstrm->last_frag = FALSE; --- 5 unchanged lines hidden (view full) --- 483 * Returns TRUE iff there is no more input in the buffer 484 * after consuming the rest of the current record. 485 */ 486bool_t 487xdrrec_eof(xdrs) 488 XDR *xdrs; 489{ 490 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); |
491 enum xprt_stat xstat; |
|
457 | 492 |
493 if (rstrm->nonblock) { 494 if (__xdrrec_getrec(xdrs, &xstat, FALSE)) 495 return FALSE; 496 if (!rstrm->in_haveheader && xstat == XPRT_IDLE) 497 return TRUE; 498 return FALSE; 499 } 500 |
|
458 while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { 459 if (! skip_input_bytes(rstrm, rstrm->fbtbc)) 460 return (TRUE); 461 rstrm->fbtbc = 0; 462 if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) 463 return (TRUE); 464 } 465 if (rstrm->in_finger == rstrm->in_boundry) --- 24 unchanged lines hidden (view full) --- 490 len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) - 491 sizeof(u_int32_t); 492 *(rstrm->frag_header) = htonl((u_int32_t)len | LAST_FRAG); 493 rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_finger; 494 rstrm->out_finger += sizeof(u_int32_t); 495 return (TRUE); 496} 497 | 501 while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { 502 if (! skip_input_bytes(rstrm, rstrm->fbtbc)) 503 return (TRUE); 504 rstrm->fbtbc = 0; 505 if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) 506 return (TRUE); 507 } 508 if (rstrm->in_finger == rstrm->in_boundry) --- 24 unchanged lines hidden (view full) --- 533 len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) - 534 sizeof(u_int32_t); 535 *(rstrm->frag_header) = htonl((u_int32_t)len | LAST_FRAG); 536 rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_finger; 537 rstrm->out_finger += sizeof(u_int32_t); 538 return (TRUE); 539} 540 |
541/* 542 * Fill the stream buffer with a record for a non-blocking connection. 543 * Return true if a record is available in the buffer, false if not. 544 */ 545bool_t 546__xdrrec_getrec(xdrs, statp, expectdata) 547 XDR *xdrs; 548 enum xprt_stat *statp; 549 bool_t expectdata; 550{ 551 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); 552 ssize_t n; 553 int fraglen; |
|
498 | 554 |
555 if (!rstrm->in_haveheader) { 556 n = rstrm->readit(rstrm->tcp_handle, rstrm->in_hdrp, 557 (int)sizeof (rstrm->in_header) - rstrm->in_hdrlen); 558 if (n == 0) { 559 *statp = expectdata ? XPRT_DIED : XPRT_IDLE; 560 return FALSE; 561 } 562 if (n < 0) { 563 *statp = XPRT_DIED; 564 return FALSE; 565 } 566 rstrm->in_hdrp += n; 567 rstrm->in_hdrlen += n; 568 if (rstrm->in_hdrlen < sizeof (rstrm->in_header)) { 569 *statp = XPRT_MOREREQS; 570 return FALSE; 571 } 572 rstrm->in_header = ntohl(rstrm->in_header); 573 fraglen = (int)(rstrm->in_header & ~LAST_FRAG); 574 if (fraglen == 0 || fraglen > rstrm->in_maxrec || 575 (rstrm->in_reclen + fraglen) > rstrm->in_maxrec) { 576 *statp = XPRT_DIED; 577 return FALSE; 578 } 579 rstrm->in_reclen += fraglen; 580 if (rstrm->in_reclen > rstrm->recvsize) 581 realloc_stream(rstrm, rstrm->in_reclen); 582 if (rstrm->in_header & LAST_FRAG) { 583 rstrm->in_header &= ~LAST_FRAG; 584 rstrm->last_frag = TRUE; 585 } 586 } 587 588 n = rstrm->readit(rstrm->tcp_handle, 589 rstrm->in_base + rstrm->in_received, 590 (rstrm->in_reclen - rstrm->in_received)); 591 592 if (n < 0) { 593 *statp = XPRT_DIED; 594 return FALSE; 595 } 596 597 if (n == 0) { 598 *statp = expectdata ? XPRT_DIED : XPRT_IDLE; 599 return FALSE; 600 } 601 602 rstrm->in_received += n; 603 604 if (rstrm->in_received == rstrm->in_reclen) { 605 rstrm->in_haveheader = FALSE; 606 rstrm->in_hdrp = (char *)(void *)&rstrm->in_header; 607 rstrm->in_hdrlen = 0; 608 if (rstrm->last_frag) { 609 rstrm->fbtbc = rstrm->in_reclen; 610 rstrm->in_boundry = rstrm->in_base + rstrm->in_reclen; 611 rstrm->in_finger = rstrm->in_base; 612 *statp = XPRT_MOREREQS; 613 return TRUE; 614 } 615 } 616 617 *statp = XPRT_MOREREQS; 618 return FALSE; 619} 620 621bool_t 622__xdrrec_setnonblock(xdrs, maxrec) 623 XDR *xdrs; 624 int maxrec; 625{ 626 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); 627 628 rstrm->nonblock = TRUE; 629 if (maxrec == 0) 630 maxrec = rstrm->recvsize; 631 rstrm->in_maxrec = maxrec; 632 return TRUE; 633} 634 |
|
499/* 500 * Internal useful routines 501 */ 502static bool_t 503flush_out(rstrm, eor) 504 RECSTREAM *rstrm; 505 bool_t eor; 506{ --- 15 unchanged lines hidden (view full) --- 522static bool_t /* knows nothing about records! Only about input buffers */ 523fill_input_buf(rstrm) 524 RECSTREAM *rstrm; 525{ 526 char *where; 527 u_int32_t i; 528 int len; 529 | 635/* 636 * Internal useful routines 637 */ 638static bool_t 639flush_out(rstrm, eor) 640 RECSTREAM *rstrm; 641 bool_t eor; 642{ --- 15 unchanged lines hidden (view full) --- 658static bool_t /* knows nothing about records! Only about input buffers */ 659fill_input_buf(rstrm) 660 RECSTREAM *rstrm; 661{ 662 char *where; 663 u_int32_t i; 664 int len; 665 |
666 if (rstrm->nonblock) 667 return FALSE; 668 |
|
530 where = rstrm->in_base; 531 i = (u_int32_t)((u_long)rstrm->in_boundry % BYTES_PER_XDR_UNIT); 532 where += i; 533 len = (u_int32_t)(rstrm->in_size - i); 534 if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1) 535 return (FALSE); 536 rstrm->in_finger = where; 537 where += len; --- 76 unchanged lines hidden (view full) --- 614fix_buf_size(s) 615 u_int s; 616{ 617 618 if (s < 100) 619 s = 4000; 620 return (RNDUP(s)); 621} | 669 where = rstrm->in_base; 670 i = (u_int32_t)((u_long)rstrm->in_boundry % BYTES_PER_XDR_UNIT); 671 where += i; 672 len = (u_int32_t)(rstrm->in_size - i); 673 if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1) 674 return (FALSE); 675 rstrm->in_finger = where; 676 where += len; --- 76 unchanged lines hidden (view full) --- 753fix_buf_size(s) 754 u_int s; 755{ 756 757 if (s < 100) 758 s = 4000; 759 return (RNDUP(s)); 760} |
761 762/* 763 * Reallocate the input buffer for a non-block stream. 764 */ 765static bool_t 766realloc_stream(rstrm, size) 767 RECSTREAM *rstrm; 768 int size; 769{ 770 ptrdiff_t diff; 771 char *buf; 772 773 if (size > rstrm->recvsize) { 774 buf = realloc(rstrm->in_base, (size_t)size); 775 if (buf == NULL) 776 return FALSE; 777 diff = buf - rstrm->in_base; 778 rstrm->in_finger += diff; 779 rstrm->in_base = buf; 780 rstrm->in_boundry = buf + size; 781 rstrm->recvsize = size; 782 rstrm->in_size = size; 783 } 784 785 return TRUE; 786} |
|