ReactOS  0.4.14-dev-50-g13bb5e2
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>
90 static bool_t xdrrec_getlong(XDR *, long *);
91 static bool_t xdrrec_putlong(XDR *, const long *);
92 static bool_t xdrrec_getbytes(XDR *, char *, u_int);
93 
94 static bool_t xdrrec_putbytes(XDR *, const char *, u_int);
95 static u_int xdrrec_getpos(XDR *);
96 static bool_t xdrrec_setpos(XDR *, u_int);
97 static int32_t *xdrrec_inline(XDR *, u_int);
98 static void xdrrec_destroy(XDR *);
99 
100 static 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 
126 typedef struct rec_strm {
127  char *tcp_handle;
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;
158 } RECSTREAM;
159 
160 static u_int fix_buf_size(u_int);
161 static bool_t flush_out(RECSTREAM *, bool_t);
163 static 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  */
178 void
179 xdrrec_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 
246 static bool_t
247 xdrrec_getlong(xdrs, lp)
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 
270 static bool_t
271 xdrrec_putlong(xdrs, lp)
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 
294 static 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);
301  u_int current;
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 
322 static 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) {
332  current = (size_t)(PtrToUlong(rstrm->out_boundry) -
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 
348 static 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 
375 static 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 
414 int32_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 
436 static 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 
468 static 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 
495 bool_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  */
530 bool_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  */
554 bool_t
555 xdrrec_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  */
580 bool_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 
662 bool_t
663 __xdrrec_setnonblock(xdrs, maxrec)
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 
676 bool_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  */
688 static bool_t
689 flush_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 
708 static 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 
731 static 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 
764 static 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);
774  header = ntohl(header);
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 
790 static bool_t /* consumes input bytes; knows nothing about records! */
791 skip_input_bytes(rstrm, cnt)
792  RECSTREAM *rstrm;
793  u_int cnt;
794 {
796 
797  while (cnt > 0) {
798  current = (u_int32_t)(PtrToUlong(rstrm->in_boundry) -
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 
812 static 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  */
825 static 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 realloc
Definition: debug_ros.c:6
bool_t xdrrec_eof(XDR *xdrs)
Definition: xdr_rec.c:531
static bool_t fill_input_buf(RECSTREAM *)
Definition: xdr_rec.c:709
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define TRUE
Definition: types.h:120
xprt_stat
Definition: svc.h:81
static const struct xdr_ops xdrrec_ops
Definition: xdr_rec.c:100
#define int32_t
Definition: nsiface.idl:56
unsigned long u_long
Definition: linux.h:269
char * in_boundry
Definition: xdr_rec.c:144
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
static bool_t xdrrec_getbytes(XDR *, char *, u_int)
Definition: xdr_rec.c:295
static bool_t xdrrec_putbytes(XDR *, const char *, u_int)
Definition: xdr_rec.c:323
char * in_base
Definition: xdr_rec.c:142
#define htonl(x)
Definition: module.h:212
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
int32_t bool_t
Definition: types.h:101
static u_int xdrrec_getpos(XDR *)
Definition: xdr_rec.c:349
char * tcp_handle
Definition: xdr_rec.c:127
Definition: svc.h:82
__kernel_off_t off_t
Definition: linux.h:201
#define PtrToLong(p)
Definition: basetsd.h:84
GLdouble n
Definition: glext.h:7729
bool_t xdrrec_endofrecord(XDR *xdrs, bool_t sendnow)
Definition: xdr_rec.c:555
char * out_base
Definition: xdr_rec.c:132
Definition: svc.h:84
static bool_t skip_input_bytes(RECSTREAM *, u_int)
Definition: xdr_rec.c:791
int(* readit)(void *, void *, int)
Definition: xdr_rec.c:140
Definition: xdr.h:103
u_int32_t * frag_header
Definition: xdr_rec.c:135
static bool_t set_input_fragment(RECSTREAM *)
Definition: xdr_rec.c:765
#define LAST_FRAG
Definition: xdr_rec.c:124
char * out_finger
Definition: xdr_rec.c:133
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
#define mem_alloc(bsize)
Definition: types.h:123
void xdrrec_setlastfrag(XDR *xdrs)
Definition: xdr_rec.c:488
static int32_t * xdrrec_inline(XDR *, u_int)
Definition: xdr_rec.c:437
bool_t in_haveheader
Definition: xdr_rec.c:151
u_int in_maxrec
Definition: xdr_rec.c:157
smooth NULL
Definition: ftsmooth.c:416
bool_t __xdrrec_setblock(XDR *xdrs)
Definition: xdr_rec.c:677
bool_t frag_sent
Definition: xdr_rec.c:136
bool_t __xdrrec_getrec(XDR *xdrs, enum xprt_stat *statp, bool_t expectdata)
Definition: xdr_rec.c:581
struct rec_strm RECSTREAM
switch(r->id)
Definition: btrfs.c:2932
#define off_t
Definition: dosfsck.h:5
u_int sendsize
Definition: xdr_rec.c:147
#define PtrToUlong(u)
Definition: config.h:107
__kernel_size_t size_t
Definition: linux.h:237
int(* writeit)(void *, void *, int)
Definition: xdr_rec.c:131
bool_t __xdrrec_setnonblock(XDR *xdrs, int maxrec)
Definition: xdr_rec.c:663
GLsizeiptr size
Definition: glext.h:5919
if(!(yy_init))
Definition: macro.lex.yy.c:714
u_long in_size
Definition: xdr_rec.c:141
char * in_hdrp
Definition: xdr_rec.c:153
static bool_t xdrrec_setpos(XDR *, u_int)
Definition: xdr_rec.c:376
bool_t last_frag
Definition: xdr_rec.c:146
char * out_boundry
Definition: xdr_rec.c:134
bool_t nonblock
Definition: xdr_rec.c:150
u_int in_received
Definition: xdr_rec.c:156
enum xdr_op x_op
Definition: xdr.h:104
u_int fbtbc
Definition: xdr_rec.c:145
GLenum const GLvoid * addr
Definition: glext.h:9621
static bool_t realloc_stream(RECSTREAM *, u_int)
Definition: xdr_rec.c:826
static void xdrrec_destroy(XDR *)
Definition: xdr_rec.c:469
Definition: xdr.h:85
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned int u_int32_t
Definition: rosdhcp.h:35
GLdouble s
Definition: gl.h:2039
#define RNDUP(x)
Definition: xdr.h:94
INT32 int32_t
Definition: types.h:71
static bool_t get_input_bytes(RECSTREAM *, char *, u_int)
Definition: xdr_rec.c:732
u_int in_reclen
Definition: xdr_rec.c:155
char * in_finger
Definition: xdr_rec.c:143
void * x_private
Definition: xdr.h:125
UINT32 u_int
Definition: types.h:82
#define long
Definition: qsort.c:33
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
const struct __rpc_xdr::xdr_ops * x_ops
Definition: xdr.h:87
int32_t * xdrrec_getoutbase(XDR *xdrs)
Definition: xdr_rec.c:415
Definition: xdr.h:86
#define mem_free(ptr, bsize)
Definition: types.h:124
bool_t xdrrec_skiprecord(XDR *xdrs)
Definition: xdr_rec.c:496
static bool_t flush_out(RECSTREAM *, bool_t)
Definition: xdr_rec.c:689
static bool_t xdrrec_putlong(XDR *, const long *)
Definition: xdr_rec.c:271
#define u_int32_t
Definition: icmp.c:103
u_int recvsize
Definition: xdr_rec.c:148
static u_int fix_buf_size(u_int)
Definition: xdr_rec.c:813
struct CFHEADER header
Definition: fdi.c:109
static bool_t xdrrec_getlong(XDR *, long *)
Definition: xdr_rec.c:247
u_int in_hdrlen
Definition: xdr_rec.c:154
void xdrrec_create(XDR *xdrs, u_int sendsize, u_int recvsize, int *void *, int *readit, int *writeit)
Definition: xdr_rec.c:179
u_int32_t in_header
Definition: xdr_rec.c:152
struct task_struct * current
Definition: linux.c:32
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define ntohl(x)
Definition: module.h:203
#define BYTES_PER_XDR_UNIT
Definition: xdr.h:93