ReactOS 0.4.15-dev-7958-gcd0bb1a
xdr_rec.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009, Sun Microsystems, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of Sun Microsystems, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29//#include <sys/cdefs.h>
30//#include <sys/cdefs.h>
31
32/*
33 * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
34 * layer above tcp (for rpc's use).
35 *
36 * Copyright (C) 1984, Sun Microsystems, Inc.
37 *
38 * These routines interface XDRSTREAMS to a tcp/ip connection.
39 * There is a record marking layer between the xdr stream
40 * and the tcp transport level. A record is composed on one or more
41 * record fragments. A record fragment is a thirty-two bit header followed
42 * by n bytes of data, where n is contained in the header. The header
43 * is represented as a htonl(u_long). Thegh order bit encodes
44 * whether or not the fragment is the last fragment of the record
45 * (1 => fragment is last, 0 => more fragments to follow.
46 * The other 31 bits encode the byte length of the fragment.
47 */
48
49/* NFSv4.1 client for Windows
50 * Copyright © 2012 The Regents of the University of Michigan
51 *
52 * Olga Kornievskaia <aglo@umich.edu>
53 * Casey Bodley <cbodley@umich.edu>
54 *
55 * This library is free software; you can redistribute it and/or modify it
56 * under the terms of the GNU Lesser General Public License as published by
57 * the Free Software Foundation; either version 2.1 of the License, or (at
58 * your option) any later version.
59 *
60 * This library is distributed in the hope that it will be useful, but
61 * without any warranty; without even the implied warranty of merchantability
62 * or fitness for a particular purpose. See the GNU Lesser General Public
63 * License for more details.
64 *
65 * You should have received a copy of the GNU Lesser General Public License
66 * along with this library; if not, write to the Free Software Foundation,
67 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
68 */
69
70#include <wintirpc.h>
71#include <io.h>
72#include <sys/types.h>
73
74//#include <netinet/in.h>
75
76//#include <err.h>
77#include <stdio.h>
78#include <stdlib.h>
79#include <string.h>
80
81#include <rpc/types.h>
82#include <rpc/xdr.h>
83#include <rpc/auth.h>
84#include <rpc/svc_auth.h>
85#include <rpc/svc.h>
86#include <rpc/clnt.h>
87#include <stddef.h>
88#include "rpc_com.h"
89//#include <unistd.h>
90static bool_t xdrrec_getlong(XDR *, long *);
91static bool_t xdrrec_putlong(XDR *, const long *);
92static bool_t xdrrec_getbytes(XDR *, char *, u_int);
93
94static bool_t xdrrec_putbytes(XDR *, const char *, u_int);
95static u_int xdrrec_getpos(XDR *);
96static bool_t xdrrec_setpos(XDR *, u_int);
97static int32_t *xdrrec_inline(XDR *, u_int);
98static void xdrrec_destroy(XDR *);
99
100static const struct xdr_ops xdrrec_ops = {
109};
110
111/*
112 * A record is composed of one or more record fragments.
113 * A record fragment is a four-byte header followed by zero to
114 * 2**32-1 bytes. The header is treated as a long unsigned and is
115 * encode/decoded to the network via htonl/ntohl. The low order 31 bits
116 * are a byte count of the fragment. The highest order bit is a boolean:
117 * 1 => this fragment is the last fragment of the record,
118 * 0 => this fragment is followed by more fragment(s).
119 *
120 * The fragment/record machinery is not general; it is constructed to
121 * meet the needs of xdr and rpc based on tcp.
122 */
123
124#define LAST_FRAG ((u_int32_t)(1 << 31))
125
126typedef struct rec_strm {
128 /*
129 * out-goung bits
130 */
131 int (*writeit)(void *, void *, int);
132 char *out_base; /* output buffer (points to frag header) */
133 char *out_finger; /* next output position */
134 char *out_boundry; /* data cannot up to this address */
135 u_int32_t *frag_header; /* beginning of curren fragment */
136 bool_t frag_sent; /* true if buffer sent in middle of record */
137 /*
138 * in-coming bits
139 */
140 int (*readit)(void *, void *, int);
141 u_long in_size; /* fixed size of the input buffer */
142 char *in_base;
143 char *in_finger; /* location of next byte to be had */
144 char *in_boundry; /* can read up to this location */
145 u_int fbtbc; /* fragment bytes to be consumed */
149
153 char *in_hdrp;
159
160static u_int fix_buf_size(u_int);
163static bool_t get_input_bytes(RECSTREAM *, char *, u_int);
167
168
169/*
170 * Create an xdr handle for xdrrec
171 * xdrrec_create fills in xdrs. Sendsize and recvsize are
172 * send and recv buffer sizes (0 => use default).
173 * tcp_handle is an opaque handle that is passed as the first parameter to
174 * the procedures readit and writeit. Readit and writeit are read and
175 * write respectively. They are like the system
176 * calls expect that they take an opaque handle rather than an fd.
177 */
178void
179xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
180 XDR *xdrs;
181 u_int sendsize;
182 u_int recvsize;
183 void *tcp_handle;
184 /* like read, but pass it a tcp_handle, not sock */
185 int (*readit)(void *, void *, int);
186 /* like write, but pass it a tcp_handle, not sock */
187 int (*writeit)(void *, void *, int);
188{
189 RECSTREAM *rstrm = mem_alloc(sizeof(RECSTREAM));
190
191 if (rstrm == NULL) {
192 //warnx("xdrrec_create: out of memory");
193 /*
194 * This is bad. Should rework xdrrec_create to
195 * return a handle, and in this case return NULL
196 */
197 return;
198 }
199 rstrm->sendsize = sendsize = fix_buf_size(sendsize);
200 rstrm->out_base = mem_alloc(rstrm->sendsize);
201 if (rstrm->out_base == NULL) {
202 //warnx("xdrrec_create: out of memory");
203 mem_free(rstrm, sizeof(RECSTREAM));
204 return;
205 }
206 rstrm->recvsize = recvsize = fix_buf_size(recvsize);
207 rstrm->in_base = mem_alloc(recvsize);
208 if (rstrm->in_base == NULL) {
209 //warnx("xdrrec_create: out of memory");
210 mem_free(rstrm->out_base, sendsize);
211 mem_free(rstrm, sizeof(RECSTREAM));
212 return;
213 }
214 /*
215 * now the rest ...
216 */
217 xdrs->x_ops = &xdrrec_ops;
218 xdrs->x_private = rstrm;
219 rstrm->tcp_handle = tcp_handle;
220 rstrm->readit = readit;
221 rstrm->writeit = writeit;
222 rstrm->out_finger = rstrm->out_boundry = rstrm->out_base;
223 rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_base;
224 rstrm->out_finger += sizeof(u_int32_t);
225 rstrm->out_boundry += sendsize;
226 rstrm->frag_sent = FALSE;
227 rstrm->in_size = recvsize;
228 rstrm->in_boundry = rstrm->in_base;
229 rstrm->in_finger = (rstrm->in_boundry += recvsize);
230 rstrm->fbtbc = 0;
231 rstrm->last_frag = TRUE;
232 rstrm->in_haveheader = FALSE;
233 rstrm->in_hdrlen = 0;
234 rstrm->in_hdrp = (char *)(void *)&rstrm->in_header;
235 rstrm->nonblock = FALSE;
236 rstrm->in_reclen = 0;
237 rstrm->in_received = 0;
238}
239
240
241/*
242 * The reoutines defined below are the xdr ops which will go into the
243 * xdr handle filled in by xdrrec_create.
244 */
245
246static bool_t
248 XDR *xdrs;
249 long *lp;
250{
251 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
252 int32_t *buflp = (int32_t *)(void *)(rstrm->in_finger);
253 int32_t mylong;
254
255 /* first try the inline, fast case */
256 if ((rstrm->fbtbc >= sizeof(int32_t)) &&
257 ((PtrToLong(rstrm->in_boundry) - PtrToLong(buflp)) >= sizeof(int32_t))) {
258 *lp = (long)ntohl((u_int32_t)(*buflp));
259 rstrm->fbtbc -= sizeof(int32_t);
260 rstrm->in_finger += sizeof(int32_t);
261 } else {
262 if (! xdrrec_getbytes(xdrs, (char *)(void *)&mylong,
263 sizeof(int32_t)))
264 return (FALSE);
265 *lp = (long)ntohl((u_int32_t)mylong);
266 }
267 return (TRUE);
268}
269
270static bool_t
272 XDR *xdrs;
273 const long *lp;
274{
275 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
276 int32_t *dest_lp = ((int32_t *)(void *)(rstrm->out_finger));
277
278 if ((rstrm->out_finger += sizeof(int32_t)) > rstrm->out_boundry) {
279 /*
280 * this case should almost never happen so the code is
281 * inefficient
282 */
283 rstrm->out_finger -= sizeof(int32_t);
284 rstrm->frag_sent = TRUE;
285 if (! flush_out(rstrm, FALSE))
286 return (FALSE);
287 dest_lp = ((int32_t *)(void *)(rstrm->out_finger));
288 rstrm->out_finger += sizeof(int32_t);
289 }
290 *dest_lp = (int32_t)htonl((u_int32_t)(*lp));
291 return (TRUE);
292}
293
294static bool_t /* must manage buffers, fragments, and records */
296 XDR *xdrs;
297 char *addr;
298 u_int len;
299{
300 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
302
303 while (len > 0) {
304 current = (int)rstrm->fbtbc;
305 if (current == 0) {
306 if (rstrm->last_frag)
307 return (FALSE);
308 if (! set_input_fragment(rstrm))
309 return (FALSE);
310 continue;
311 }
312 current = (len < current) ? len : current;
313 if (! get_input_bytes(rstrm, addr, current))
314 return (FALSE);
315 addr += current;
316 rstrm->fbtbc -= current;
317 len -= current;
318 }
319 return (TRUE);
320}
321
322static bool_t
324 XDR *xdrs;
325 const char *addr;
326 u_int len;
327{
328 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
329 size_t current;
330
331 while (len > 0) {
333 PtrToUlong(rstrm->out_finger));
334 current = (len < current) ? len : current;
335 memmove(rstrm->out_finger, addr, current);
336 rstrm->out_finger += current;
337 addr += current;
338 len -= current;
339 if (rstrm->out_finger == rstrm->out_boundry) {
340 rstrm->frag_sent = TRUE;
341 if (! flush_out(rstrm, FALSE))
342 return (FALSE);
343 }
344 }
345 return (TRUE);
346}
347
348static u_int
350 XDR *xdrs;
351{
352 RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
353 off_t pos = 0;
354
355 //pos = lseek((int)(u_long)rstrm->tcp_handle, (off_t)0, 1);
356 //pos = _lseek((int)PtrToUlong(rstrm->tcp_handle), (off_t)0, 1);
357 if (pos != -1)
358 switch (xdrs->x_op) {
359
360 case XDR_ENCODE:
361 pos += PtrToLong(rstrm->out_finger) - PtrToLong(rstrm->out_base);
362 break;
363
364 case XDR_DECODE:
365 pos -= PtrToLong(rstrm->in_boundry) - PtrToLong(rstrm->in_finger);
366 break;
367
368 default:
369 pos = (off_t) -1;
370 break;
371 }
372 return ((u_int) pos);
373}
374
375static bool_t
377 XDR *xdrs;
378 u_int pos;
379{
380 RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
381 u_int currpos = xdrrec_getpos(xdrs);
382 int delta = currpos - pos;
383 char *newpos;
384
385 if ((int)currpos != -1)
386 switch (xdrs->x_op) {
387
388 case XDR_ENCODE:
389 newpos = rstrm->out_finger - delta;
390 if ((newpos > (char *)(void *)(rstrm->frag_header)) &&
391 (newpos < rstrm->out_boundry)) {
392 rstrm->out_finger = newpos;
393 return (TRUE);
394 }
395 break;
396
397 case XDR_DECODE:
398 newpos = rstrm->in_finger - delta;
399 if ((delta < (int)(rstrm->fbtbc)) &&
400 (newpos <= rstrm->in_boundry) &&
401 (newpos >= rstrm->in_base)) {
402 rstrm->in_finger = newpos;
403 rstrm->fbtbc -= delta;
404 return (TRUE);
405 }
406 break;
407
408 case XDR_FREE:
409 break;
410 }
411 return (FALSE);
412}
413
414int32_t *
416 XDR *xdrs;
417{
418 RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
419 int32_t *buf = NULL;
420
421 switch (xdrs->x_op) {
422
423 case XDR_ENCODE:
424 buf = rstrm->out_base;
425 break;
426
427 case XDR_DECODE:
428 break;
429
430 case XDR_FREE:
431 break;
432 }
433 return (buf);
434}
435
436static int32_t *
438 XDR *xdrs;
439 u_int len;
440{
441 RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
442 int32_t *buf = NULL;
443
444 switch (xdrs->x_op) {
445
446 case XDR_ENCODE:
447 if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
448 buf = (int32_t *)(void *)rstrm->out_finger;
449 rstrm->out_finger += len;
450 }
451 break;
452
453 case XDR_DECODE:
454 if ((len <= rstrm->fbtbc) &&
455 ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
456 buf = (int32_t *)(void *)rstrm->in_finger;
457 rstrm->fbtbc -= len;
458 rstrm->in_finger += len;
459 }
460 break;
461
462 case XDR_FREE:
463 break;
464 }
465 return (buf);
466}
467
468static void
470 XDR *xdrs;
471{
472 RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
473
474 mem_free(rstrm->out_base, rstrm->sendsize);
475 mem_free(rstrm->in_base, rstrm->recvsize);
476 mem_free(rstrm, sizeof(RECSTREAM));
477}
478
479
480/*
481 * Exported routines to manage xdr records
482 */
483
484/*
485 * Before reading (deserializing from the stream, one should always call
486 * this procedure to guarantee proper record alignment.
487 */
489 XDR *xdrs;
490{
491 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
492 rstrm->last_frag = 1;
493}
494
495bool_t
497 XDR *xdrs;
498{
499 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
500 enum xprt_stat xstat;
501
502 if (rstrm->nonblock) {
503 if (__xdrrec_getrec(xdrs, &xstat, FALSE))
504 return TRUE;
505
506 if (rstrm->in_finger == rstrm->in_boundry &&
507 xstat == XPRT_MOREREQS) {
508 rstrm->fbtbc = 0;
509 return TRUE;
510 }
511 return FALSE;
512 }
513
514 while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
515 if (! skip_input_bytes(rstrm, rstrm->fbtbc))
516 return (FALSE);
517 rstrm->fbtbc = 0;
518 if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
519 return (FALSE);
520 }
521 rstrm->last_frag = FALSE;
522 return (TRUE);
523}
524
525/*
526 * Look ahead function.
527 * Returns TRUE iff there is no more input in the buffer
528 * after consuming the rest of the current record.
529 */
530bool_t
532 XDR *xdrs;
533{
534 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
535
536 while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
537 if (! skip_input_bytes(rstrm, rstrm->fbtbc))
538 return (TRUE);
539 rstrm->fbtbc = 0;
540 if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
541 return (TRUE);
542 }
543 if (rstrm->in_finger == rstrm->in_boundry)
544 return (TRUE);
545 return (FALSE);
546}
547
548/*
549 * The client must tell the package when an end-of-record has occurred.
550 * The second paraemters tells whether the record should be flushed to the
551 * (output) tcp stream. (This let's the package support batched or
552 * pipelined procedure calls.) TRUE => immmediate flush to tcp connection.
553 */
554bool_t
555xdrrec_endofrecord(xdrs, sendnow)
556 XDR *xdrs;
557 bool_t sendnow;
558{
559 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
560 u_long len; /* fragment length */
561
562 if (sendnow || rstrm->frag_sent ||
563 (PtrToUlong(rstrm->out_finger) + sizeof(u_int32_t) >=
564 PtrToUlong(rstrm->out_boundry))) {
565 rstrm->frag_sent = FALSE;
566 return (flush_out(rstrm, TRUE));
567 }
568 len = PtrToUlong(rstrm->out_finger) - PtrToUlong(rstrm->frag_header) -
569 sizeof(u_int32_t);
570 *(rstrm->frag_header) = htonl((u_int32_t)len | LAST_FRAG);
571 rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_finger;
572 rstrm->out_finger += sizeof(u_int32_t);
573 return (TRUE);
574}
575
576/*
577 * Fill the stream buffer with a record for a non-blocking connection.
578 * Return true if a record is available in the buffer, false if not.
579 */
580bool_t
581__xdrrec_getrec(xdrs, statp, expectdata)
582 XDR *xdrs;
583 enum xprt_stat *statp;
584 bool_t expectdata;
585{
586 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
587 int n;
588 u_int fraglen;
589
590 if (!rstrm->in_haveheader) {
591 n = rstrm->readit(rstrm->tcp_handle, rstrm->in_hdrp,
592 (int)sizeof (rstrm->in_header) - rstrm->in_hdrlen);
593 if (n == 0) {
594 *statp = expectdata ? XPRT_DIED : XPRT_IDLE;
595 return FALSE;
596 }
597 if (n < 0) {
598 *statp = XPRT_DIED;
599 return FALSE;
600 }
601 rstrm->in_hdrp += n;
602 rstrm->in_hdrlen += n;
603 if (rstrm->in_hdrlen < sizeof (rstrm->in_header)) {
604 *statp = XPRT_MOREREQS;
605 return FALSE;
606 }
607 rstrm->in_header = ntohl(rstrm->in_header);
608 fraglen = (int)(rstrm->in_header & ~LAST_FRAG);
609 if (fraglen == 0 || fraglen > rstrm->in_maxrec ||
610 (rstrm->in_reclen + fraglen) > rstrm->in_maxrec) {
611 *statp = XPRT_DIED;
612 return FALSE;
613 }
614 rstrm->fbtbc = rstrm->in_header & (~LAST_FRAG);
615 rstrm->in_reclen += fraglen;
616 if (rstrm->in_reclen > rstrm->recvsize)
617 realloc_stream(rstrm, rstrm->in_reclen);
618 if (rstrm->in_header & LAST_FRAG) {
619 rstrm->in_header &= ~LAST_FRAG;
620 rstrm->last_frag = TRUE;
621 }
622 }
623
624 do {
625 n = rstrm->readit(rstrm->tcp_handle,
626 rstrm->in_base + rstrm->in_received,
627 (rstrm->in_reclen - rstrm->in_received));
628
629 /* this case is needed for non-block as socket returns TIMEDOUT and -1
630 * -2 is an error case and covered by the next if() statement */
631 if (n == -1) continue;
632
633 if (n < 0) {
634 *statp = XPRT_DIED;
635 return FALSE;
636 }
637
638 if (n == 0) {
639 *statp = expectdata ? XPRT_DIED : XPRT_IDLE;
640 return FALSE;
641 }
642
643 rstrm->in_received += n;
644 if (rstrm->in_received == rstrm->in_reclen) {
645 rstrm->in_haveheader = FALSE;
646 rstrm->in_hdrp = (char *)(void *)&rstrm->in_header;
647 rstrm->in_hdrlen = 0;
648 if (rstrm->last_frag) {
649 rstrm->in_boundry = rstrm->in_base + rstrm->in_reclen;
650 rstrm->in_finger = rstrm->in_base;
651 rstrm->in_reclen = rstrm->in_received = 0;
652 *statp = XPRT_MOREREQS;
653 return TRUE;
654 }
655 }
656 } while (1);
657
658 *statp = XPRT_MOREREQS;
659 return FALSE;
660}
661
662bool_t
664 XDR *xdrs;
665 int maxrec;
666{
667 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
668
669 rstrm->nonblock = TRUE;
670 if (maxrec == 0)
671 maxrec = rstrm->recvsize;
672 rstrm->in_maxrec = maxrec;
673 return TRUE;
674}
675
676bool_t
678 XDR *xdrs;
679{
680 RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
681
682 rstrm->nonblock = FALSE;
683 return TRUE;
684}
685/*
686 * Internal useful routines
687 */
688static bool_t
689flush_out(rstrm, eor)
690 RECSTREAM *rstrm;
691 bool_t eor;
692{
693 u_int32_t eormask = (eor == TRUE) ? LAST_FRAG : 0;
695 PtrToUlong(rstrm->frag_header) - sizeof(u_int32_t));
696
697 *(rstrm->frag_header) = htonl(len | eormask);
698 len = (u_int32_t)(PtrToUlong(rstrm->out_finger) -
699 PtrToUlong(rstrm->out_base));
700 if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
701 != (int)len)
702 return (FALSE);
703 rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_base;
704 rstrm->out_finger = (char *)rstrm->out_base + sizeof(u_int32_t);
705 return (TRUE);
706}
707
708static bool_t /* knows nothing about records! Only about input buffers */
710 RECSTREAM *rstrm;
711{
712 char *where;
713 u_int32_t i;
714 int len;
715
716 if (rstrm->nonblock)
717 return FALSE;
718
719 where = rstrm->in_base;
721 where += i;
722 len = (u_int32_t)(rstrm->in_size - i);
723 if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
724 return (FALSE);
725 rstrm->in_finger = where;
726 where += len;
727 rstrm->in_boundry = where;
728 return (TRUE);
729}
730
731static bool_t /* knows nothing about records! Only about input buffers */
733 RECSTREAM *rstrm;
734 char *addr;
735 u_int len;
736{
737 size_t current;
738
739 if (rstrm->nonblock) {
740 if (len > (u_int)(rstrm->in_boundry - rstrm->in_finger))
741 return FALSE;
742 memcpy(addr, rstrm->in_finger, (size_t)len);
743 rstrm->in_finger += len;
744 return TRUE;
745 }
746
747 while (len > 0) {
748 current = (size_t)(PtrToLong(rstrm->in_boundry) -
749 PtrToLong(rstrm->in_finger));
750 if (current == 0) {
751 if (! fill_input_buf(rstrm))
752 return (FALSE);
753 continue;
754 }
755 current = (len < current) ? len : current;
756 memmove(addr, rstrm->in_finger, current);
757 rstrm->in_finger += current;
758 addr += current;
759 len -= current;
760 }
761 return (TRUE);
762}
763
764static bool_t /* next two bytes of the input stream are treated as a header */
766 RECSTREAM *rstrm;
767{
769
770 if (rstrm->nonblock)
771 return FALSE;
772 if (! get_input_bytes(rstrm, (char *)(void *)&header, sizeof(header)))
773 return (FALSE);
775 rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
776 /*
777 * Sanity check. Try not to accept wildly incorrect
778 * record sizes. Unfortunately, the only record size
779 * we can positively identify as being 'wildly incorrect'
780 * is zero. Ridiculously large record sizes may look wrong,
781 * but we don't have any way to be certain that they aren't
782 * what the client actually intended to send us.
783 */
784 if (header == 0)
785 return(FALSE);
786 rstrm->fbtbc = header & (~LAST_FRAG);
787 return (TRUE);
788}
789
790static bool_t /* consumes input bytes; knows nothing about records! */
792 RECSTREAM *rstrm;
793 u_int cnt;
794{
796
797 while (cnt > 0) {
799 PtrToUlong(rstrm->in_finger));
800 if (current == 0) {
801 if (! fill_input_buf(rstrm))
802 return (FALSE);
803 continue;
804 }
805 current = (u_int32_t)((cnt < current) ? cnt : current);
806 rstrm->in_finger += current;
807 cnt -= current;
808 }
809 return (TRUE);
810}
811
812static u_int
814 u_int s;
815{
816
817 if (s < 100)
818 s = 4000;
819 return (RNDUP(s));
820}
821
822/*
823 * Reallocate the input buffer for a non-block stream.
824 */
825static bool_t
827 RECSTREAM *rstrm;
828 u_int size;
829{
830 ptrdiff_t diff;
831 char *buf;
832
833 if (size > rstrm->recvsize) {
834 buf = realloc(rstrm->in_base, (size_t)size);
835 if (buf == NULL)
836 return FALSE;
837 diff = buf - rstrm->in_base;
838 rstrm->in_finger += diff;
839 rstrm->in_base = buf;
840 rstrm->in_boundry = buf + size;
841 rstrm->recvsize = size;
842 rstrm->in_size = size;
843 }
844
845 return TRUE;
846}
#define PtrToLong(p)
Definition: basetsd.h:84
#define realloc
Definition: debug_ros.c:6
xprt_stat
Definition: svc.h:81
@ XPRT_IDLE
Definition: svc.h:84
@ XPRT_DIED
Definition: svc.h:82
@ XPRT_MOREREQS
Definition: svc.h:83
UINT32 u_int
Definition: types.h:82
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
#define mem_alloc(bsize)
Definition: types.h:123
int32_t bool_t
Definition: types.h:101
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
INT32 int32_t
Definition: types.h:71
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define off_t
Definition: dosfsck.h:5
switch(r->id)
Definition: btrfs.c:3046
__kernel_size_t size_t
Definition: linux.h:237
unsigned long u_long
Definition: linux.h:269
__kernel_off_t off_t
Definition: linux.h:201
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
#define PtrToUlong(u)
Definition: config.h:107
GLdouble s
Definition: gl.h:2039
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum const GLvoid * addr
Definition: glext.h:9621
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
struct task_struct * current
Definition: linux.c:32
#define ntohl(x)
Definition: module.h:205
#define htonl(x)
Definition: module.h:214
#define int32_t
Definition: nsiface.idl:56
#define long
Definition: qsort.c:33
unsigned int u_int32_t
Definition: rosdhcp.h:35
Definition: xdr.h:103
const struct __rpc_xdr::xdr_ops * x_ops
enum xdr_op x_op
Definition: xdr.h:104
void * x_private
Definition: xdr.h:125
u_int recvsize
Definition: xdr_rec.c:148
u_int in_received
Definition: xdr_rec.c:156
char * out_boundry
Definition: xdr_rec.c:134
char * in_base
Definition: xdr_rec.c:142
bool_t last_frag
Definition: xdr_rec.c:146
char * tcp_handle
Definition: xdr_rec.c:127
u_int sendsize
Definition: xdr_rec.c:147
bool_t nonblock
Definition: xdr_rec.c:150
u_long in_size
Definition: xdr_rec.c:141
u_int32_t * frag_header
Definition: xdr_rec.c:135
u_int fbtbc
Definition: xdr_rec.c:145
char * out_base
Definition: xdr_rec.c:132
bool_t frag_sent
Definition: xdr_rec.c:136
char * out_finger
Definition: xdr_rec.c:133
bool_t in_haveheader
Definition: xdr_rec.c:151
int(* writeit)(void *, void *, int)
Definition: xdr_rec.c:131
char * in_finger
Definition: xdr_rec.c:143
int(* readit)(void *, void *, int)
Definition: xdr_rec.c:140
char * in_boundry
Definition: xdr_rec.c:144
u_int32_t in_header
Definition: xdr_rec.c:152
u_int in_maxrec
Definition: xdr_rec.c:157
u_int in_reclen
Definition: xdr_rec.c:155
char * in_hdrp
Definition: xdr_rec.c:153
u_int in_hdrlen
Definition: xdr_rec.c:154
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
@ XDR_DECODE
Definition: xdr.h:86
@ XDR_FREE
Definition: xdr.h:87
@ XDR_ENCODE
Definition: xdr.h:85
#define BYTES_PER_XDR_UNIT
Definition: xdr.h:93
#define RNDUP(x)
Definition: xdr.h:94
static u_int xdrrec_getpos(XDR *)
Definition: xdr_rec.c:349
bool_t __xdrrec_setblock(XDR *xdrs)
Definition: xdr_rec.c:677
static bool_t set_input_fragment(RECSTREAM *)
Definition: xdr_rec.c:765
int32_t * xdrrec_getoutbase(XDR *xdrs)
Definition: xdr_rec.c:415
static bool_t xdrrec_getlong(XDR *, long *)
Definition: xdr_rec.c:247
static u_int fix_buf_size(u_int)
Definition: xdr_rec.c:813
static const struct xdr_ops xdrrec_ops
Definition: xdr_rec.c:100
#define LAST_FRAG
Definition: xdr_rec.c:124
static bool_t xdrrec_getbytes(XDR *, char *, u_int)
Definition: xdr_rec.c:295
static void xdrrec_destroy(XDR *)
Definition: xdr_rec.c:469
static bool_t get_input_bytes(RECSTREAM *, char *, u_int)
Definition: xdr_rec.c:732
bool_t xdrrec_endofrecord(XDR *xdrs, bool_t sendnow)
Definition: xdr_rec.c:555
bool_t __xdrrec_getrec(XDR *xdrs, enum xprt_stat *statp, bool_t expectdata)
Definition: xdr_rec.c:581
void xdrrec_setlastfrag(XDR *xdrs)
Definition: xdr_rec.c:488
bool_t xdrrec_eof(XDR *xdrs)
Definition: xdr_rec.c:531
static bool_t realloc_stream(RECSTREAM *, u_int)
Definition: xdr_rec.c:826
bool_t __xdrrec_setnonblock(XDR *xdrs, int maxrec)
Definition: xdr_rec.c:663
static int32_t * xdrrec_inline(XDR *, u_int)
Definition: xdr_rec.c:437
static bool_t flush_out(RECSTREAM *, bool_t)
Definition: xdr_rec.c:689
static bool_t skip_input_bytes(RECSTREAM *, u_int)
Definition: xdr_rec.c:791
static bool_t xdrrec_putlong(XDR *, const long *)
Definition: xdr_rec.c:271
void xdrrec_create(XDR *xdrs, u_int sendsize, u_int recvsize, int *void *, int *readit, int *writeit)
Definition: xdr_rec.c:179
bool_t xdrrec_skiprecord(XDR *xdrs)
Definition: xdr_rec.c:496
static bool_t fill_input_buf(RECSTREAM *)
Definition: xdr_rec.c:709
static bool_t xdrrec_putbytes(XDR *, const char *, u_int)
Definition: xdr_rec.c:323
static bool_t xdrrec_setpos(XDR *, u_int)
Definition: xdr_rec.c:376
struct rec_strm RECSTREAM