OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [inet/] [rpc/] [xdr_rec.c] - Blame information for rev 1325

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.