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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/* @(#)xdr.c    2.1 88/07/29 4.0 RPCSRC */
2
/*
3
 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4
 * unrestricted use provided that this legend is included on all tape
5
 * media and as a part of the software program in whole or part.  Users
6
 * may copy or modify Sun RPC without charge, but are not authorized
7
 * to license or distribute it to anyone else except as part of a product or
8
 * program developed by the user.
9
 *
10
 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11
 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12
 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13
 *
14
 * Sun RPC is provided with no support and without any obligation on the
15
 * part of Sun Microsystems, Inc. to assist in its use, correction,
16
 * modification or enhancement.
17
 *
18
 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19
 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20
 * OR ANY PART THEREOF.
21
 *
22
 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23
 * or profits or other special, indirect and consequential damages, even if
24
 * Sun has been advised of the possibility of such damages.
25
 *
26
 * Sun Microsystems, Inc.
27
 * 2550 Garcia Avenue
28
 * Mountain View, California  94043
29
 */
30
#if 0
31
static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
32
#endif
33
 
34
/*
35
 * xdr.c, Generic XDR routines implementation.
36
 *
37
 * Copyright (C) 1986, Sun Microsystems, Inc.
38
 *
39
 * These are the "generic" xdr routines used to serialize and de-serialize
40
 * most common data items.  See xdr.h for more info on the interface to
41
 * xdr.
42
 */
43
 
44
#define __FORCE_GLIBC
45
#define _GNU_SOURCE
46
#include <features.h>
47
 
48
#include <stdio.h>
49
#include <limits.h>
50
#include <string.h>
51
 
52
#include <rpc/types.h>
53
#include <rpc/xdr.h>
54
 
55
#ifdef USE_IN_LIBIO
56
# include <wchar.h>
57
#endif
58
 
59
/*
60
 * constants specific to the xdr "protocol"
61
 */
62
#define XDR_FALSE       ((long) 0)
63
#define XDR_TRUE        ((long) 1)
64
#define LASTUNSIGNED    ((u_int) 0-1)
65
 
66
/*
67
 * for unit alignment
68
 */
69
static const char xdr_zero[BYTES_PER_XDR_UNIT] = {0, 0, 0, 0};
70
 
71
/*
72
 * Free a data structure using XDR
73
 * Not a filter, but a convenient utility nonetheless
74
 */
75
void
76
xdr_free (xdrproc_t proc, char *objp)
77
{
78
  XDR x;
79
 
80
  x.x_op = XDR_FREE;
81
  (*proc) (&x, objp);
82
}
83
 
84
/*
85
 * XDR nothing
86
 */
87
bool_t
88
xdr_void (void)
89
{
90
  return TRUE;
91
}
92
 
93
/*
94
 * XDR integers
95
 */
96
bool_t
97
xdr_int (XDR *xdrs, int *ip)
98
{
99
 
100
#if INT_MAX < LONG_MAX
101
  long l;
102
 
103
  switch (xdrs->x_op)
104
    {
105
    case XDR_ENCODE:
106
      l = (long) *ip;
107
      return XDR_PUTLONG (xdrs, &l);
108
 
109
    case XDR_DECODE:
110
      if (!XDR_GETLONG (xdrs, &l))
111
        {
112
          return FALSE;
113
        }
114
      *ip = (int) l;
115
    case XDR_FREE:
116
      return TRUE;
117
    }
118
  return FALSE;
119
#elif INT_MAX == LONG_MAX
120
  return xdr_long (xdrs, (long *) ip);
121
#elif INT_MAX == SHRT_MAX
122
  return xdr_short (xdrs, (short *) ip);
123
#else
124
#error unexpected integer sizes in_xdr_int()
125
#endif
126
}
127
 
128
/*
129
 * XDR unsigned integers
130
 */
131
bool_t
132
xdr_u_int (XDR *xdrs, u_int *up)
133
{
134
#if UINT_MAX < ULONG_MAX
135
  u_long l;
136
 
137
  switch (xdrs->x_op)
138
    {
139
    case XDR_ENCODE:
140
      l = (u_long) * up;
141
      return XDR_PUTLONG (xdrs, &l);
142
 
143
    case XDR_DECODE:
144
      if (!XDR_GETLONG (xdrs, &l))
145
        {
146
          return FALSE;
147
        }
148
      *up = (u_int) l;
149
    case XDR_FREE:
150
      return TRUE;
151
    }
152
  return FALSE;
153
#elif UINT_MAX == ULONG_MAX
154
  return xdr_u_long (xdrs, (u_long *) up);
155
#elif UINT_MAX == USHRT_MAX
156
  return xdr_short (xdrs, (short *) up);
157
#else
158
#error unexpected integer sizes in_xdr_u_int()
159
#endif
160
}
161
 
162
/*
163
 * XDR long integers
164
 * The definition of xdr_long() is kept for backward
165
 * compatibility. Instead xdr_int() should be used.
166
 */
167
bool_t
168
xdr_long (XDR *xdrs, long *lp)
169
{
170
 
171
  if (xdrs->x_op == XDR_ENCODE
172
      && (sizeof (int32_t) == sizeof (long)
173
          || (int32_t) *lp == *lp))
174
    return XDR_PUTLONG (xdrs, lp);
175
 
176
  if (xdrs->x_op == XDR_DECODE)
177
    return XDR_GETLONG (xdrs, lp);
178
 
179
  if (xdrs->x_op == XDR_FREE)
180
    return TRUE;
181
 
182
  return FALSE;
183
}
184
 
185
/*
186
 * XDR unsigned long integers
187
 * The definition of xdr_u_long() is kept for backward
188
 * compatibility. Instead xdr_u_int() should be used.
189
 */
190
bool_t
191
xdr_u_long (XDR *xdrs, u_long *ulp)
192
{
193
  switch (xdrs->x_op)
194
    {
195
    case XDR_DECODE:
196
      {
197
        long int tmp;
198
 
199
        if (XDR_GETLONG (xdrs, &tmp) == FALSE)
200
          return FALSE;
201
 
202
        *ulp = (uint32_t) tmp;
203
        return TRUE;
204
      }
205
 
206
    case XDR_ENCODE:
207
      if (sizeof (uint32_t) != sizeof (u_long)
208
          && (uint32_t) *ulp != *ulp)
209
        return FALSE;
210
 
211
      return XDR_PUTLONG (xdrs, (long *) ulp);
212
 
213
    case XDR_FREE:
214
      return TRUE;
215
    }
216
  return FALSE;
217
}
218
 
219
/*
220
 * XDR hyper integers
221
 * same as xdr_u_hyper - open coded to save a proc call!
222
 */
223
bool_t
224
xdr_hyper (XDR *xdrs, quad_t *llp)
225
{
226
  long t1;
227
  unsigned long int t2;
228
 
229
  if (xdrs->x_op == XDR_ENCODE)
230
    {
231
      t1 = (long) ((*llp) >> 32);
232
      t2 = (long) (*llp);
233
      return (XDR_PUTLONG(xdrs, &t1) && XDR_PUTLONG(xdrs, &t2));
234
    }
235
 
236
  if (xdrs->x_op == XDR_DECODE)
237
    {
238
      if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2))
239
        return FALSE;
240
      *llp = ((quad_t) t1) << 32;
241
      *llp |= t2;
242
      return TRUE;
243
    }
244
 
245
  if (xdrs->x_op == XDR_FREE)
246
    return TRUE;
247
 
248
  return FALSE;
249
}
250
 
251
 
252
/*
253
 * XDR hyper integers
254
 * same as xdr_hyper - open coded to save a proc call!
255
 */
256
bool_t
257
xdr_u_hyper (XDR *xdrs, u_quad_t *ullp)
258
{
259
  unsigned long t1;
260
  unsigned long t2;
261
 
262
  if (xdrs->x_op == XDR_ENCODE)
263
    {
264
      t1 = (unsigned long) ((*ullp) >> 32);
265
      t2 = (unsigned long) (*ullp);
266
      return (XDR_PUTLONG(xdrs, &t1) && XDR_PUTLONG(xdrs, &t2));
267
    }
268
 
269
  if (xdrs->x_op == XDR_DECODE)
270
    {
271
      if (!XDR_GETLONG(xdrs, &t1) || !XDR_GETLONG(xdrs, &t2))
272
        return FALSE;
273
      *ullp = ((u_quad_t) t1) << 32;
274
      *ullp |= t2;
275
      return TRUE;
276
    }
277
 
278
  if (xdrs->x_op == XDR_FREE)
279
    return TRUE;
280
 
281
  return FALSE;
282
}
283
 
284
bool_t
285
xdr_longlong_t (XDR *xdrs, quad_t *llp)
286
{
287
  return xdr_hyper (xdrs, llp);
288
}
289
 
290
bool_t
291
xdr_u_longlong_t (XDR *xdrs, u_quad_t *ullp)
292
{
293
  return xdr_u_hyper (xdrs, ullp);
294
}
295
 
296
/*
297
 * XDR short integers
298
 */
299
bool_t
300
xdr_short (XDR *xdrs, short *sp)
301
{
302
  long l;
303
 
304
  switch (xdrs->x_op)
305
    {
306
    case XDR_ENCODE:
307
      l = (long) *sp;
308
      return XDR_PUTLONG (xdrs, &l);
309
 
310
    case XDR_DECODE:
311
      if (!XDR_GETLONG (xdrs, &l))
312
        {
313
          return FALSE;
314
        }
315
      *sp = (short) l;
316
      return TRUE;
317
 
318
    case XDR_FREE:
319
      return TRUE;
320
    }
321
  return FALSE;
322
}
323
 
324
/*
325
 * XDR unsigned short integers
326
 */
327
bool_t
328
xdr_u_short (XDR *xdrs, u_short *usp)
329
{
330
  u_long l;
331
 
332
  switch (xdrs->x_op)
333
    {
334
    case XDR_ENCODE:
335
      l = (u_long) * usp;
336
      return XDR_PUTLONG (xdrs, &l);
337
 
338
    case XDR_DECODE:
339
      if (!XDR_GETLONG (xdrs, &l))
340
        {
341
          return FALSE;
342
        }
343
      *usp = (u_short) l;
344
      return TRUE;
345
 
346
    case XDR_FREE:
347
      return TRUE;
348
    }
349
  return FALSE;
350
}
351
 
352
 
353
/*
354
 * XDR a char
355
 */
356
bool_t
357
xdr_char (XDR *xdrs, char *cp)
358
{
359
  int i;
360
 
361
  i = (*cp);
362
  if (!xdr_int (xdrs, &i))
363
    {
364
      return FALSE;
365
    }
366
  *cp = i;
367
  return TRUE;
368
}
369
 
370
/*
371
 * XDR an unsigned char
372
 */
373
bool_t
374
xdr_u_char (XDR *xdrs, u_char *cp)
375
{
376
  u_int u;
377
 
378
  u = (*cp);
379
  if (!xdr_u_int (xdrs, &u))
380
    {
381
      return FALSE;
382
    }
383
  *cp = u;
384
  return TRUE;
385
}
386
 
387
/*
388
 * XDR booleans
389
 */
390
bool_t
391
xdr_bool (XDR *xdrs, bool_t *bp)
392
{
393
  long lb;
394
 
395
  switch (xdrs->x_op)
396
    {
397
    case XDR_ENCODE:
398
      lb = *bp ? XDR_TRUE : XDR_FALSE;
399
      return XDR_PUTLONG (xdrs, &lb);
400
 
401
    case XDR_DECODE:
402
      if (!XDR_GETLONG (xdrs, &lb))
403
        {
404
          return FALSE;
405
        }
406
      *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
407
      return TRUE;
408
 
409
    case XDR_FREE:
410
      return TRUE;
411
    }
412
  return FALSE;
413
}
414
 
415
/*
416
 * XDR enumerations
417
 */
418
bool_t
419
xdr_enum (XDR *xdrs, enum_t *ep)
420
{
421
  enum sizecheck
422
    {
423
      SIZEVAL
424
    };                          /* used to find the size of an enum */
425
 
426
  /*
427
   * enums are treated as ints
428
   */
429
  if (sizeof (enum sizecheck) == 4)
430
    {
431
#if INT_MAX < LONG_MAX
432
      long l;
433
 
434
      switch (xdrs->x_op)
435
        {
436
        case XDR_ENCODE:
437
          l = *ep;
438
          return XDR_PUTLONG (xdrs, &l);
439
 
440
        case XDR_DECODE:
441
          if (!XDR_GETLONG (xdrs, &l))
442
            {
443
              return FALSE;
444
            }
445
          *ep = l;
446
        case XDR_FREE:
447
          return TRUE;
448
 
449
        }
450
      return FALSE;
451
#else
452
      return xdr_long (xdrs, (long *) ep);
453
#endif
454
    }
455
  else if (sizeof (enum sizecheck) == sizeof (short))
456
    {
457
      return xdr_short (xdrs, (short *) ep);
458
    }
459
  else
460
    {
461
      return FALSE;
462
    }
463
}
464
 
465
/*
466
 * XDR opaque data
467
 * Allows the specification of a fixed size sequence of opaque bytes.
468
 * cp points to the opaque object and cnt gives the byte length.
469
 */
470
bool_t
471
xdr_opaque (XDR *xdrs, caddr_t cp, u_int cnt)
472
{
473
  u_int rndup;
474
  static char crud[BYTES_PER_XDR_UNIT];
475
 
476
  /*
477
   * if no data we are done
478
   */
479
  if (cnt == 0)
480
    return TRUE;
481
 
482
  /*
483
   * round byte count to full xdr units
484
   */
485
  rndup = cnt % BYTES_PER_XDR_UNIT;
486
  if (rndup > 0)
487
    rndup = BYTES_PER_XDR_UNIT - rndup;
488
 
489
  switch (xdrs->x_op)
490
    {
491
    case XDR_DECODE:
492
      if (!XDR_GETBYTES (xdrs, cp, cnt))
493
        {
494
          return FALSE;
495
        }
496
      if (rndup == 0)
497
        return TRUE;
498
      return XDR_GETBYTES (xdrs, (caddr_t)crud, rndup);
499
 
500
    case XDR_ENCODE:
501
      if (!XDR_PUTBYTES (xdrs, cp, cnt))
502
        {
503
          return FALSE;
504
        }
505
      if (rndup == 0)
506
        return TRUE;
507
      return XDR_PUTBYTES (xdrs, xdr_zero, rndup);
508
 
509
    case XDR_FREE:
510
      return TRUE;
511
    }
512
  return FALSE;
513
}
514
 
515
/*
516
 * XDR counted bytes
517
 * *cpp is a pointer to the bytes, *sizep is the count.
518
 * If *cpp is NULL maxsize bytes are allocated
519
 */
520
bool_t
521
xdr_bytes (xdrs, cpp, sizep, maxsize)
522
     XDR *xdrs;
523
     char **cpp;
524
     u_int *sizep;
525
     u_int maxsize;
526
{
527
  char *sp = *cpp;      /* sp is the actual string pointer */
528
  u_int nodesize;
529
 
530
  /*
531
   * first deal with the length since xdr bytes are counted
532
   */
533
  if (!xdr_u_int (xdrs, sizep))
534
    {
535
      return FALSE;
536
    }
537
  nodesize = *sizep;
538
  if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE))
539
    {
540
      return FALSE;
541
    }
542
 
543
  /*
544
   * now deal with the actual bytes
545
   */
546
  switch (xdrs->x_op)
547
    {
548
    case XDR_DECODE:
549
      if (nodesize == 0)
550
        {
551
          return TRUE;
552
        }
553
      if (sp == NULL)
554
        {
555
          *cpp = sp = (char *) mem_alloc (nodesize);
556
        }
557
      if (sp == NULL)
558
        {
559
#ifdef USE_IN_LIBIO
560
          if (_IO_fwide (stderr, 0) > 0)
561
            (void) __fwprintf (stderr, L"%s", _("xdr_bytes: out of memory\n"));
562
          else
563
#endif
564
            (void) fputs (_("xdr_bytes: out of memory\n"), stderr);
565
          return FALSE;
566
        }
567
      /* fall into ... */
568
 
569
    case XDR_ENCODE:
570
      return xdr_opaque (xdrs, sp, nodesize);
571
 
572
    case XDR_FREE:
573
      if (sp != NULL)
574
        {
575
          mem_free (sp, nodesize);
576
          *cpp = NULL;
577
        }
578
      return TRUE;
579
    }
580
  return FALSE;
581
}
582
 
583
/*
584
 * Implemented here due to commonality of the object.
585
 */
586
bool_t
587
xdr_netobj (xdrs, np)
588
     XDR *xdrs;
589
     struct netobj *np;
590
{
591
 
592
  return xdr_bytes (xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ);
593
}
594
 
595
/*
596
 * XDR a discriminated union
597
 * Support routine for discriminated unions.
598
 * You create an array of xdrdiscrim structures, terminated with
599
 * an entry with a null procedure pointer.  The routine gets
600
 * the discriminant value and then searches the array of xdrdiscrims
601
 * looking for that value.  It calls the procedure given in the xdrdiscrim
602
 * to handle the discriminant.  If there is no specific routine a default
603
 * routine may be called.
604
 * If there is no specific or default routine an error is returned.
605
 */
606
bool_t
607
xdr_union (xdrs, dscmp, unp, choices, dfault)
608
     XDR *xdrs;
609
     enum_t *dscmp;             /* enum to decide which arm to work on */
610
     char *unp;                 /* the union itself */
611
     const struct xdr_discrim *choices; /* [value, xdr proc] for each arm */
612
     xdrproc_t dfault;          /* default xdr routine */
613
{
614
  enum_t dscm;
615
 
616
  /*
617
   * we deal with the discriminator;  it's an enum
618
   */
619
  if (!xdr_enum (xdrs, dscmp))
620
    {
621
      return FALSE;
622
    }
623
  dscm = *dscmp;
624
 
625
  /*
626
   * search choices for a value that matches the discriminator.
627
   * if we find one, execute the xdr routine for that value.
628
   */
629
  for (; choices->proc != NULL_xdrproc_t; choices++)
630
    {
631
      if (choices->value == dscm)
632
        return (*(choices->proc)) (xdrs, unp, LASTUNSIGNED);
633
    }
634
 
635
  /*
636
   * no match - execute the default xdr routine if there is one
637
   */
638
  return ((dfault == NULL_xdrproc_t) ? FALSE :
639
          (*dfault) (xdrs, unp, LASTUNSIGNED));
640
}
641
 
642
 
643
/*
644
 * Non-portable xdr primitives.
645
 * Care should be taken when moving these routines to new architectures.
646
 */
647
 
648
 
649
/*
650
 * XDR null terminated ASCII strings
651
 * xdr_string deals with "C strings" - arrays of bytes that are
652
 * terminated by a NULL character.  The parameter cpp references a
653
 * pointer to storage; If the pointer is null, then the necessary
654
 * storage is allocated.  The last parameter is the max allowed length
655
 * of the string as specified by a protocol.
656
 */
657
bool_t
658
xdr_string (xdrs, cpp, maxsize)
659
     XDR *xdrs;
660
     char **cpp;
661
     u_int maxsize;
662
{
663
  char *sp = *cpp;      /* sp is the actual string pointer */
664
  u_int size;
665
  u_int nodesize;
666
 
667
  /*
668
   * first deal with the length since xdr strings are counted-strings
669
   */
670
  switch (xdrs->x_op)
671
    {
672
    case XDR_FREE:
673
      if (sp == NULL)
674
        {
675
          return TRUE;          /* already free */
676
        }
677
      /* fall through... */
678
    case XDR_ENCODE:
679
      if (sp == NULL)
680
        return FALSE;
681
      size = strlen (sp);
682
      break;
683
    case XDR_DECODE:
684
      break;
685
    }
686
  if (!xdr_u_int (xdrs, &size))
687
    {
688
      return FALSE;
689
    }
690
  if (size > maxsize)
691
    {
692
      return FALSE;
693
    }
694
  nodesize = size + 1;
695
 
696
  /*
697
   * now deal with the actual bytes
698
   */
699
  switch (xdrs->x_op)
700
    {
701
    case XDR_DECODE:
702
      if (nodesize == 0)
703
        {
704
          return TRUE;
705
        }
706
      if (sp == NULL)
707
        *cpp = sp = (char *) mem_alloc (nodesize);
708
      if (sp == NULL)
709
        {
710
#ifdef USE_IN_LIBIO
711
          if (_IO_fwide (stderr, 0) > 0)
712
            (void) __fwprintf (stderr, L"%s",
713
                               _("xdr_string: out of memory\n"));
714
          else
715
#endif
716
            (void) fputs (_("xdr_string: out of memory\n"), stderr);
717
          return FALSE;
718
        }
719
      sp[size] = 0;
720
      /* fall into ... */
721
 
722
    case XDR_ENCODE:
723
      return xdr_opaque (xdrs, sp, size);
724
 
725
    case XDR_FREE:
726
      mem_free (sp, nodesize);
727
      *cpp = NULL;
728
      return TRUE;
729
    }
730
  return FALSE;
731
}
732
 
733
/*
734
 * Wrapper for xdr_string that can be called directly from
735
 * routines like clnt_call
736
 */
737
bool_t
738
xdr_wrapstring (xdrs, cpp)
739
     XDR *xdrs;
740
     char **cpp;
741
{
742
  if (xdr_string (xdrs, cpp, LASTUNSIGNED))
743
    {
744
      return TRUE;
745
    }
746
  return FALSE;
747
}

powered by: WebSVN 2.1.0

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