mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 08:22:44 +00:00
Moving RPC stuff into libc, part 2.
This commit is contained in:
parent
990647991e
commit
eae561b30e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=1902
11
lib/libc/xdr/Makefile.inc
Normal file
11
lib/libc/xdr/Makefile.inc
Normal file
@ -0,0 +1,11 @@
|
||||
# @(#)Makefile 5.11 (Berkeley) 9/6/90
|
||||
|
||||
.PATH: ${.CURDIR}/rpc ${.CURDIR}/.
|
||||
CFLAGS+=-I${.CURDIR} -I${.CURDIR}/rpc
|
||||
SRCS= xdr.c xdr_array.c xdr_mem.c \
|
||||
xdr_rec.c xdr_reference.c xdr_stdio.c
|
||||
|
||||
MAN3= xdr/xdr.3
|
||||
|
||||
UNSUPPORTED+= xdr_float.c
|
||||
|
823
lib/libc/xdr/xdr.3
Normal file
823
lib/libc/xdr/xdr.3
Normal file
@ -0,0 +1,823 @@
|
||||
.\" @(#)xdr.3n 2.2 88/08/03 4.0 RPCSRC; from 1.16 88/03/14 SMI
|
||||
.TH XDR 3N "16 February 1988"
|
||||
.SH NAME
|
||||
xdr \- library routines for external data representation
|
||||
.SH SYNOPSIS AND DESCRIPTION
|
||||
.LP
|
||||
These routines allow C programmers to describe
|
||||
arbitrary data structures in a machine-independent fashion.
|
||||
Data for remote procedure calls are transmitted using these
|
||||
routines.
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_array(xdrs, arrp, sizep, maxsize, elsize, elproc)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
char **arrp;
|
||||
u_int *sizep, maxsize, elsize;
|
||||
xdrproc_t elproc;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between variable-length
|
||||
arrays
|
||||
and their corresponding external representations. The
|
||||
parameter
|
||||
.I arrp
|
||||
is the address of the pointer to the array, while
|
||||
.I sizep
|
||||
is the address of the element count of the array;
|
||||
this element count cannot exceed
|
||||
.IR maxsize .
|
||||
The parameter
|
||||
.I elsize
|
||||
is the
|
||||
.I sizeof
|
||||
each of the array's elements, and
|
||||
.I elproc
|
||||
is an
|
||||
.SM XDR
|
||||
filter that translates between
|
||||
the array elements' C form, and their external
|
||||
representation.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 8
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_bool(xdrs, bp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
bool_t *bp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between booleans (C
|
||||
integers)
|
||||
and their external representations. When encoding data, this
|
||||
filter produces values of either one or zero.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 10
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_bytes(xdrs, sp, sizep, maxsize)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
char **sp;
|
||||
u_int *sizep, maxsize;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between counted byte
|
||||
strings and their external representations.
|
||||
The parameter
|
||||
.I sp
|
||||
is the address of the string pointer. The length of the
|
||||
string is located at address
|
||||
.IR sizep ;
|
||||
strings cannot be longer than
|
||||
.IR maxsize .
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 7
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_char(xdrs, cp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
char *cp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C characters
|
||||
and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
Note: encoded characters are not packed, and occupy 4 bytes
|
||||
each. For arrays of characters, it is worthwhile to
|
||||
consider
|
||||
.BR xdr_bytes(\|) ,
|
||||
.B xdr_opaque(\|)
|
||||
or
|
||||
.BR xdr_string(\|) .
|
||||
.br
|
||||
.if t .ne 8
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
void
|
||||
xdr_destroy(xdrs)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A macro that invokes the destroy routine associated with the
|
||||
.SM XDR
|
||||
stream,
|
||||
.IR xdrs .
|
||||
Destruction usually involves freeing private data structures
|
||||
associated with the stream. Using
|
||||
.I xdrs
|
||||
after invoking
|
||||
.B xdr_destroy(\|)
|
||||
is undefined.
|
||||
.br
|
||||
.if t .ne 7
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_double(xdrs, dp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
double *dp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C
|
||||
.B double
|
||||
precision numbers and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 7
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_enum(xdrs, ep)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
enum_t *ep;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C
|
||||
.BR enum s
|
||||
(actually integers) and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 8
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_float(xdrs, fp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
float *fp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C
|
||||
.BR float s
|
||||
and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 9
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
void
|
||||
xdr_free(proc, objp)
|
||||
xdrproc_t proc;
|
||||
char *objp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
Generic freeing routine. The first argument is the
|
||||
.SM XDR
|
||||
routine for the object being freed. The second argument
|
||||
is a pointer to the object itself. Note: the pointer passed
|
||||
to this routine is
|
||||
.I not
|
||||
freed, but what it points to
|
||||
.I is
|
||||
freed (recursively).
|
||||
.br
|
||||
.if t .ne 8
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
u_int
|
||||
xdr_getpos(xdrs)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A macro that invokes the get-position routine
|
||||
associated with the
|
||||
.SM XDR
|
||||
stream,
|
||||
.IR xdrs .
|
||||
The routine returns an unsigned integer,
|
||||
which indicates the position of the
|
||||
.SM XDR
|
||||
byte stream.
|
||||
A desirable feature of
|
||||
.SM XDR
|
||||
streams is that simple arithmetic works with this number,
|
||||
although the
|
||||
.SM XDR
|
||||
stream instances need not guarantee this.
|
||||
.br
|
||||
.if t .ne 4
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
.br
|
||||
long *
|
||||
xdr_inline(xdrs, len)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
int len;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A macro that invokes the in-line routine associated with the
|
||||
.SM XDR
|
||||
stream,
|
||||
.IR xdrs .
|
||||
The routine returns a pointer
|
||||
to a contiguous piece of the stream's buffer;
|
||||
.I len
|
||||
is the byte length of the desired buffer.
|
||||
Note: pointer is cast to
|
||||
.BR "long *" .
|
||||
.IP
|
||||
Warning:
|
||||
.B xdr_inline(\|)
|
||||
may return
|
||||
.SM NULL
|
||||
(0)
|
||||
if it cannot allocate a contiguous piece of a buffer.
|
||||
Therefore the behavior may vary among stream instances;
|
||||
it exists for the sake of efficiency.
|
||||
.br
|
||||
.if t .ne 7
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_int(xdrs, ip)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
int *ip;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C integers
|
||||
and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 7
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_long(xdrs, lp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
long *lp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C
|
||||
.B long
|
||||
integers and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 12
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
void
|
||||
xdrmem_create(xdrs, addr, size, op)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
char *addr;
|
||||
u_int size;
|
||||
enum xdr_op op;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
This routine initializes the
|
||||
.SM XDR
|
||||
stream object pointed to by
|
||||
.IR xdrs .
|
||||
The stream's data is written to, or read from,
|
||||
a chunk of memory at location
|
||||
.I addr
|
||||
whose length is no more than
|
||||
.I size
|
||||
bytes long. The
|
||||
.I op
|
||||
determines the direction of the
|
||||
.SM XDR
|
||||
stream
|
||||
(either
|
||||
.BR \s-1XDR_ENCODE\s0 ,
|
||||
.BR \s-1XDR_DECODE\s0 ,
|
||||
or
|
||||
.BR \s-1XDR_FREE\s0 ).
|
||||
.br
|
||||
.if t .ne 10
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_opaque(xdrs, cp, cnt)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
char *cp;
|
||||
u_int cnt;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between fixed size opaque
|
||||
data
|
||||
and its external representation.
|
||||
The parameter
|
||||
.I cp
|
||||
is the address of the opaque object, and
|
||||
.I cnt
|
||||
is its size in bytes.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 10
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_pointer(xdrs, objpp, objsize, xdrobj)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
char **objpp;
|
||||
u_int objsize;
|
||||
xdrproc_t xdrobj;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
Like
|
||||
.B xdr_reference(\|)
|
||||
execpt that it serializes
|
||||
.SM NULL
|
||||
pointers, whereas
|
||||
.B xdr_reference(\|)
|
||||
does not. Thus,
|
||||
.B xdr_pointer(\|)
|
||||
can represent
|
||||
recursive data structures, such as binary trees or
|
||||
linked lists.
|
||||
.br
|
||||
.if t .ne 15
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
void
|
||||
xdrrec_create(xdrs, sendsize, recvsize, handle, readit, writeit)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
u_int sendsize, recvsize;
|
||||
char *handle;
|
||||
int (*readit) (\|), (*writeit) (\|);
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
This routine initializes the
|
||||
.SM XDR
|
||||
stream object pointed to by
|
||||
.IR xdrs .
|
||||
The stream's data is written to a buffer of size
|
||||
.IR sendsize ;
|
||||
a value of zero indicates the system should use a suitable
|
||||
default. The stream's data is read from a buffer of size
|
||||
.IR recvsize ;
|
||||
it too can be set to a suitable default by passing a zero
|
||||
value.
|
||||
When a stream's output buffer is full,
|
||||
.I writeit
|
||||
is called. Similarly, when a stream's input buffer is empty,
|
||||
.I readit
|
||||
is called. The behavior of these two routines is similar to
|
||||
the
|
||||
system calls
|
||||
.B read
|
||||
and
|
||||
.BR write ,
|
||||
except that
|
||||
.I handle
|
||||
is passed to the former routines as the first parameter.
|
||||
Note: the
|
||||
.SM XDR
|
||||
stream's
|
||||
.I op
|
||||
field must be set by the caller.
|
||||
.IP
|
||||
Warning: this
|
||||
.SM XDR
|
||||
stream implements an intermediate record stream.
|
||||
Therefore there are additional bytes in the stream
|
||||
to provide record boundary information.
|
||||
.br
|
||||
.if t .ne 9
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdrrec_endofrecord(xdrs, sendnow)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
int sendnow;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
This routine can be invoked only on
|
||||
streams created by
|
||||
.BR xdrrec_create(\|) .
|
||||
The data in the output buffer is marked as a completed
|
||||
record,
|
||||
and the output buffer is optionally written out if
|
||||
.I sendnow
|
||||
is non-zero. This routine returns one if it succeeds, zero
|
||||
otherwise.
|
||||
.br
|
||||
.if t .ne 8
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdrrec_eof(xdrs)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
int empty;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
This routine can be invoked only on
|
||||
streams created by
|
||||
.BR xdrrec_create(\|) .
|
||||
After consuming the rest of the current record in the stream,
|
||||
this routine returns one if the stream has no more input,
|
||||
zero otherwise.
|
||||
.br
|
||||
.if t .ne 3
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdrrec_skiprecord(xdrs)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
This routine can be invoked only on
|
||||
streams created by
|
||||
.BR xdrrec_create(\|) .
|
||||
It tells the
|
||||
.SM XDR
|
||||
implementation that the rest of the current record
|
||||
in the stream's input buffer should be discarded.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 11
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_reference(xdrs, pp, size, proc)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
char **pp;
|
||||
u_int size;
|
||||
xdrproc_t proc;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A primitive that provides pointer chasing within structures.
|
||||
The parameter
|
||||
.I pp
|
||||
is the address of the pointer;
|
||||
.I size
|
||||
is the
|
||||
.I sizeof
|
||||
the structure that
|
||||
.I *pp
|
||||
points to; and
|
||||
.I proc
|
||||
is an
|
||||
.SM XDR
|
||||
procedure that filters the structure
|
||||
between its C form and its external representation.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.IP
|
||||
Warning: this routine does not understand
|
||||
.SM NULL
|
||||
pointers. Use
|
||||
.B xdr_pointer(\|)
|
||||
instead.
|
||||
.br
|
||||
.if t .ne 10
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_setpos(xdrs, pos)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
u_int pos;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A macro that invokes the set position routine associated with
|
||||
the
|
||||
.SM XDR
|
||||
stream
|
||||
.IR xdrs .
|
||||
The parameter
|
||||
.I pos
|
||||
is a position value obtained from
|
||||
.BR xdr_getpos(\|) .
|
||||
This routine returns one if the
|
||||
.SM XDR
|
||||
stream could be repositioned,
|
||||
and zero otherwise.
|
||||
.IP
|
||||
Warning: it is difficult to reposition some types of
|
||||
.SM XDR
|
||||
streams, so this routine may fail with one
|
||||
type of stream and succeed with another.
|
||||
.br
|
||||
.if t .ne 8
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_short(xdrs, sp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
short *sp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C
|
||||
.B short
|
||||
integers and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 10
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
void
|
||||
xdrstdio_create(xdrs, file, op)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
\s-1FILE\s0 *file;
|
||||
enum xdr_op op;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
This routine initializes the
|
||||
.SM XDR
|
||||
stream object pointed to by
|
||||
.IR xdrs .
|
||||
The
|
||||
.SM XDR
|
||||
stream data is written to, or read from, the Standard
|
||||
.B I/O
|
||||
stream
|
||||
.IR file .
|
||||
The parameter
|
||||
.I op
|
||||
determines the direction of the
|
||||
.SM XDR
|
||||
stream (either
|
||||
.BR \s-1XDR_ENCODE\s0 ,
|
||||
.BR \s-1XDR_DECODE\s0 ,
|
||||
or
|
||||
.BR \s-1XDR_FREE\s0 ).
|
||||
.IP
|
||||
Warning: the destroy routine associated with such
|
||||
.SM XDR
|
||||
streams calls
|
||||
.B fflush(\|)
|
||||
on the
|
||||
.I file
|
||||
stream, but never
|
||||
.BR fclose(\|) .
|
||||
.br
|
||||
.if t .ne 9
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_string(xdrs, sp, maxsize)
|
||||
\s-1XDR\s0
|
||||
*xdrs;
|
||||
char **sp;
|
||||
u_int maxsize;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C strings and
|
||||
their
|
||||
corresponding external representations.
|
||||
Strings cannot be longer than
|
||||
.IR maxsize .
|
||||
Note:
|
||||
.I sp
|
||||
is the address of the string's pointer.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 8
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_u_char(xdrs, ucp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
unsigned char *ucp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between
|
||||
.B unsigned
|
||||
C characters and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 9
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_u_int(xdrs, up)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
unsigned *up;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C
|
||||
.B unsigned
|
||||
integers and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 7
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_u_long(xdrs, ulp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
unsigned long *ulp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C
|
||||
.B "unsigned long"
|
||||
integers and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 7
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_u_short(xdrs, usp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
unsigned short *usp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between C
|
||||
.B "unsigned short"
|
||||
integers and their external representations.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 16
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_union(xdrs, dscmp, unp, choices, dfault)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
int *dscmp;
|
||||
char *unp;
|
||||
struct xdr_discrim *choices;
|
||||
bool_t (*defaultarm) (\|); /* may equal \s-1NULL\s0 */
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between a discriminated C
|
||||
.B union
|
||||
and its corresponding external representation. It first
|
||||
translates the discriminant of the union located at
|
||||
.IR dscmp .
|
||||
This discriminant is always an
|
||||
.BR enum_t .
|
||||
Next the union located at
|
||||
.I unp
|
||||
is translated. The parameter
|
||||
.I choices
|
||||
is a pointer to an array of
|
||||
.B xdr_discrim(\|)
|
||||
structures. Each structure contains an ordered pair of
|
||||
.RI [ value , proc ].
|
||||
If the union's discriminant is equal to the associated
|
||||
.IR value ,
|
||||
then the
|
||||
.I proc
|
||||
is called to translate the union. The end of the
|
||||
.B xdr_discrim(\|)
|
||||
structure array is denoted by a routine of value
|
||||
.SM NULL\s0.
|
||||
If the discriminant is not found in the
|
||||
.I choices
|
||||
array, then the
|
||||
.I defaultarm
|
||||
procedure is called (if it is not
|
||||
.SM NULL\s0).
|
||||
Returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 6
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_vector(xdrs, arrp, size, elsize, elproc)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
char *arrp;
|
||||
u_int size, elsize;
|
||||
xdrproc_t elproc;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A filter primitive that translates between fixed-length
|
||||
arrays
|
||||
and their corresponding external representations. The
|
||||
parameter
|
||||
.I arrp
|
||||
is the address of the pointer to the array, while
|
||||
.I size
|
||||
is is the element count of the array. The parameter
|
||||
.I elsize
|
||||
is the
|
||||
.I sizeof
|
||||
each of the array's elements, and
|
||||
.I elproc
|
||||
is an
|
||||
.SM XDR
|
||||
filter that translates between
|
||||
the array elements' C form, and their external
|
||||
representation.
|
||||
This routine returns one if it succeeds, zero otherwise.
|
||||
.br
|
||||
.if t .ne 5
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_void(\|)
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
This routine always returns one.
|
||||
It may be passed to
|
||||
.SM RPC
|
||||
routines that require a function parameter,
|
||||
where nothing is to be done.
|
||||
.br
|
||||
.if t .ne 10
|
||||
.LP
|
||||
.ft B
|
||||
.nf
|
||||
.sp .5
|
||||
xdr_wrapstring(xdrs, sp)
|
||||
\s-1XDR\s0 *xdrs;
|
||||
char **sp;
|
||||
.fi
|
||||
.ft R
|
||||
.IP
|
||||
A primitive that calls
|
||||
.B "xdr_string(xdrs, sp,\s-1MAXUN.UNSIGNED\s0 );"
|
||||
where
|
||||
.B
|
||||
.SM MAXUN.UNSIGNED
|
||||
is the maximum value of an unsigned integer.
|
||||
.B xdr_wrapstring(\|)
|
||||
is handy because the
|
||||
.SM RPC
|
||||
package passes a maximum of two
|
||||
.SM XDR
|
||||
routines as parameters, and
|
||||
.BR xdr_string(\|) ,
|
||||
one of the most frequently used primitives, requires three.
|
||||
Returns one if it succeeds, zero otherwise.
|
||||
.SH SEE ALSO
|
||||
.BR rpc (3N)
|
||||
.LP
|
||||
The following manuals:
|
||||
.RS
|
||||
.ft I
|
||||
eXternal Data Representation Standard: Protocol Specification
|
||||
.br
|
||||
eXternal Data Representation: Sun Technical Notes
|
||||
.ft R
|
||||
.br
|
||||
.IR "\s-1XDR\s0: External Data Representation Standard" ,
|
||||
.SM RFC1014, Sun Microsystems, Inc.,
|
||||
.SM USC-ISI\s0.
|
578
lib/libc/xdr/xdr.c
Normal file
578
lib/libc/xdr/xdr.c
Normal file
@ -0,0 +1,578 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)xdr.c 1.35 87/08/12";*/
|
||||
/*static char *sccsid = "from: @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$Id: xdr.c,v 1.1 1993/10/27 05:41:06 paul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xdr.c, Generic XDR routines implementation.
|
||||
*
|
||||
* Copyright (C) 1986, Sun Microsystems, Inc.
|
||||
*
|
||||
* These are the "generic" xdr routines used to serialize and de-serialize
|
||||
* most common data items. See xdr.h for more info on the interface to
|
||||
* xdr.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
|
||||
/*
|
||||
* constants specific to the xdr "protocol"
|
||||
*/
|
||||
#define XDR_FALSE ((long) 0)
|
||||
#define XDR_TRUE ((long) 1)
|
||||
#define LASTUNSIGNED ((u_int) 0-1)
|
||||
|
||||
/*
|
||||
* for unit alignment
|
||||
*/
|
||||
static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
|
||||
|
||||
/*
|
||||
* Free a data structure using XDR
|
||||
* Not a filter, but a convenient utility nonetheless
|
||||
*/
|
||||
void
|
||||
xdr_free(proc, objp)
|
||||
xdrproc_t proc;
|
||||
char *objp;
|
||||
{
|
||||
XDR x;
|
||||
|
||||
x.x_op = XDR_FREE;
|
||||
(*proc)(&x, objp);
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR nothing
|
||||
*/
|
||||
bool_t
|
||||
xdr_void(/* xdrs, addr */)
|
||||
/* XDR *xdrs; */
|
||||
/* caddr_t addr; */
|
||||
{
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR integers
|
||||
*/
|
||||
bool_t
|
||||
xdr_int(xdrs, ip)
|
||||
XDR *xdrs;
|
||||
int *ip;
|
||||
{
|
||||
|
||||
#ifdef lint
|
||||
(void) (xdr_short(xdrs, (short *)ip));
|
||||
return (xdr_long(xdrs, (long *)ip));
|
||||
#else
|
||||
if (sizeof (int) == sizeof (long)) {
|
||||
return (xdr_long(xdrs, (long *)ip));
|
||||
} else {
|
||||
return (xdr_short(xdrs, (short *)ip));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR unsigned integers
|
||||
*/
|
||||
bool_t
|
||||
xdr_u_int(xdrs, up)
|
||||
XDR *xdrs;
|
||||
u_int *up;
|
||||
{
|
||||
|
||||
#ifdef lint
|
||||
(void) (xdr_short(xdrs, (short *)up));
|
||||
return (xdr_u_long(xdrs, (u_long *)up));
|
||||
#else
|
||||
if (sizeof (u_int) == sizeof (u_long)) {
|
||||
return (xdr_u_long(xdrs, (u_long *)up));
|
||||
} else {
|
||||
return (xdr_short(xdrs, (short *)up));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR long integers
|
||||
* same as xdr_u_long - open coded to save a proc call!
|
||||
*/
|
||||
bool_t
|
||||
xdr_long(xdrs, lp)
|
||||
register XDR *xdrs;
|
||||
long *lp;
|
||||
{
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE)
|
||||
return (XDR_PUTLONG(xdrs, lp));
|
||||
|
||||
if (xdrs->x_op == XDR_DECODE)
|
||||
return (XDR_GETLONG(xdrs, lp));
|
||||
|
||||
if (xdrs->x_op == XDR_FREE)
|
||||
return (TRUE);
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR unsigned long integers
|
||||
* same as xdr_long - open coded to save a proc call!
|
||||
*/
|
||||
bool_t
|
||||
xdr_u_long(xdrs, ulp)
|
||||
register XDR *xdrs;
|
||||
u_long *ulp;
|
||||
{
|
||||
|
||||
if (xdrs->x_op == XDR_DECODE)
|
||||
return (XDR_GETLONG(xdrs, (long *)ulp));
|
||||
if (xdrs->x_op == XDR_ENCODE)
|
||||
return (XDR_PUTLONG(xdrs, (long *)ulp));
|
||||
if (xdrs->x_op == XDR_FREE)
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR short integers
|
||||
*/
|
||||
bool_t
|
||||
xdr_short(xdrs, sp)
|
||||
register XDR *xdrs;
|
||||
short *sp;
|
||||
{
|
||||
long l;
|
||||
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_ENCODE:
|
||||
l = (long) *sp;
|
||||
return (XDR_PUTLONG(xdrs, &l));
|
||||
|
||||
case XDR_DECODE:
|
||||
if (!XDR_GETLONG(xdrs, &l)) {
|
||||
return (FALSE);
|
||||
}
|
||||
*sp = (short) l;
|
||||
return (TRUE);
|
||||
|
||||
case XDR_FREE:
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR unsigned short integers
|
||||
*/
|
||||
bool_t
|
||||
xdr_u_short(xdrs, usp)
|
||||
register XDR *xdrs;
|
||||
u_short *usp;
|
||||
{
|
||||
u_long l;
|
||||
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_ENCODE:
|
||||
l = (u_long) *usp;
|
||||
return (XDR_PUTLONG(xdrs, &l));
|
||||
|
||||
case XDR_DECODE:
|
||||
if (!XDR_GETLONG(xdrs, &l)) {
|
||||
return (FALSE);
|
||||
}
|
||||
*usp = (u_short) l;
|
||||
return (TRUE);
|
||||
|
||||
case XDR_FREE:
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* XDR a char
|
||||
*/
|
||||
bool_t
|
||||
xdr_char(xdrs, cp)
|
||||
XDR *xdrs;
|
||||
char *cp;
|
||||
{
|
||||
int i;
|
||||
|
||||
i = (*cp);
|
||||
if (!xdr_int(xdrs, &i)) {
|
||||
return (FALSE);
|
||||
}
|
||||
*cp = i;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR an unsigned char
|
||||
*/
|
||||
bool_t
|
||||
xdr_u_char(xdrs, cp)
|
||||
XDR *xdrs;
|
||||
char *cp;
|
||||
{
|
||||
u_int u;
|
||||
|
||||
u = (*cp);
|
||||
if (!xdr_u_int(xdrs, &u)) {
|
||||
return (FALSE);
|
||||
}
|
||||
*cp = u;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR booleans
|
||||
*/
|
||||
bool_t
|
||||
xdr_bool(xdrs, bp)
|
||||
register XDR *xdrs;
|
||||
bool_t *bp;
|
||||
{
|
||||
long lb;
|
||||
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_ENCODE:
|
||||
lb = *bp ? XDR_TRUE : XDR_FALSE;
|
||||
return (XDR_PUTLONG(xdrs, &lb));
|
||||
|
||||
case XDR_DECODE:
|
||||
if (!XDR_GETLONG(xdrs, &lb)) {
|
||||
return (FALSE);
|
||||
}
|
||||
*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
|
||||
return (TRUE);
|
||||
|
||||
case XDR_FREE:
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR enumerations
|
||||
*/
|
||||
bool_t
|
||||
xdr_enum(xdrs, ep)
|
||||
XDR *xdrs;
|
||||
enum_t *ep;
|
||||
{
|
||||
#ifndef lint
|
||||
enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
|
||||
|
||||
/*
|
||||
* enums are treated as ints
|
||||
*/
|
||||
if (sizeof (enum sizecheck) == sizeof (long)) {
|
||||
return (xdr_long(xdrs, (long *)ep));
|
||||
} else if (sizeof (enum sizecheck) == sizeof (short)) {
|
||||
return (xdr_short(xdrs, (short *)ep));
|
||||
} else {
|
||||
return (FALSE);
|
||||
}
|
||||
#else
|
||||
(void) (xdr_short(xdrs, (short *)ep));
|
||||
return (xdr_long(xdrs, (long *)ep));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR opaque data
|
||||
* Allows the specification of a fixed size sequence of opaque bytes.
|
||||
* cp points to the opaque object and cnt gives the byte length.
|
||||
*/
|
||||
bool_t
|
||||
xdr_opaque(xdrs, cp, cnt)
|
||||
register XDR *xdrs;
|
||||
caddr_t cp;
|
||||
register u_int cnt;
|
||||
{
|
||||
register u_int rndup;
|
||||
static crud[BYTES_PER_XDR_UNIT];
|
||||
|
||||
/*
|
||||
* if no data we are done
|
||||
*/
|
||||
if (cnt == 0)
|
||||
return (TRUE);
|
||||
|
||||
/*
|
||||
* round byte count to full xdr units
|
||||
*/
|
||||
rndup = cnt % BYTES_PER_XDR_UNIT;
|
||||
if (rndup > 0)
|
||||
rndup = BYTES_PER_XDR_UNIT - rndup;
|
||||
|
||||
if (xdrs->x_op == XDR_DECODE) {
|
||||
if (!XDR_GETBYTES(xdrs, cp, cnt)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (rndup == 0)
|
||||
return (TRUE);
|
||||
return (XDR_GETBYTES(xdrs, crud, rndup));
|
||||
}
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (rndup == 0)
|
||||
return (TRUE);
|
||||
return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
|
||||
}
|
||||
|
||||
if (xdrs->x_op == XDR_FREE) {
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR counted bytes
|
||||
* *cpp is a pointer to the bytes, *sizep is the count.
|
||||
* If *cpp is NULL maxsize bytes are allocated
|
||||
*/
|
||||
bool_t
|
||||
xdr_bytes(xdrs, cpp, sizep, maxsize)
|
||||
register XDR *xdrs;
|
||||
char **cpp;
|
||||
register u_int *sizep;
|
||||
u_int maxsize;
|
||||
{
|
||||
register char *sp = *cpp; /* sp is the actual string pointer */
|
||||
register u_int nodesize;
|
||||
|
||||
/*
|
||||
* first deal with the length since xdr bytes are counted
|
||||
*/
|
||||
if (! xdr_u_int(xdrs, sizep)) {
|
||||
return (FALSE);
|
||||
}
|
||||
nodesize = *sizep;
|
||||
if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* now deal with the actual bytes
|
||||
*/
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_DECODE:
|
||||
if (nodesize == 0) {
|
||||
return (TRUE);
|
||||
}
|
||||
if (sp == NULL) {
|
||||
*cpp = sp = (char *)mem_alloc(nodesize);
|
||||
}
|
||||
if (sp == NULL) {
|
||||
(void) fprintf(stderr, "xdr_bytes: out of memory\n");
|
||||
return (FALSE);
|
||||
}
|
||||
/* fall into ... */
|
||||
|
||||
case XDR_ENCODE:
|
||||
return (xdr_opaque(xdrs, sp, nodesize));
|
||||
|
||||
case XDR_FREE:
|
||||
if (sp != NULL) {
|
||||
mem_free(sp, nodesize);
|
||||
*cpp = NULL;
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implemented here due to commonality of the object.
|
||||
*/
|
||||
bool_t
|
||||
xdr_netobj(xdrs, np)
|
||||
XDR *xdrs;
|
||||
struct netobj *np;
|
||||
{
|
||||
|
||||
return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR a descriminated union
|
||||
* Support routine for discriminated unions.
|
||||
* You create an array of xdrdiscrim structures, terminated with
|
||||
* an entry with a null procedure pointer. The routine gets
|
||||
* the discriminant value and then searches the array of xdrdiscrims
|
||||
* looking for that value. It calls the procedure given in the xdrdiscrim
|
||||
* to handle the discriminant. If there is no specific routine a default
|
||||
* routine may be called.
|
||||
* If there is no specific or default routine an error is returned.
|
||||
*/
|
||||
bool_t
|
||||
xdr_union(xdrs, dscmp, unp, choices, dfault)
|
||||
register XDR *xdrs;
|
||||
enum_t *dscmp; /* enum to decide which arm to work on */
|
||||
char *unp; /* the union itself */
|
||||
struct xdr_discrim *choices; /* [value, xdr proc] for each arm */
|
||||
xdrproc_t dfault; /* default xdr routine */
|
||||
{
|
||||
register enum_t dscm;
|
||||
|
||||
/*
|
||||
* we deal with the discriminator; it's an enum
|
||||
*/
|
||||
if (! xdr_enum(xdrs, dscmp)) {
|
||||
return (FALSE);
|
||||
}
|
||||
dscm = *dscmp;
|
||||
|
||||
/*
|
||||
* search choices for a value that matches the discriminator.
|
||||
* if we find one, execute the xdr routine for that value.
|
||||
*/
|
||||
for (; choices->proc != NULL_xdrproc_t; choices++) {
|
||||
if (choices->value == dscm)
|
||||
return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
|
||||
}
|
||||
|
||||
/*
|
||||
* no match - execute the default xdr routine if there is one
|
||||
*/
|
||||
return ((dfault == NULL_xdrproc_t) ? FALSE :
|
||||
(*dfault)(xdrs, unp, LASTUNSIGNED));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Non-portable xdr primitives.
|
||||
* Care should be taken when moving these routines to new architectures.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* XDR null terminated ASCII strings
|
||||
* xdr_string deals with "C strings" - arrays of bytes that are
|
||||
* terminated by a NULL character. The parameter cpp references a
|
||||
* pointer to storage; If the pointer is null, then the necessary
|
||||
* storage is allocated. The last parameter is the max allowed length
|
||||
* of the string as specified by a protocol.
|
||||
*/
|
||||
bool_t
|
||||
xdr_string(xdrs, cpp, maxsize)
|
||||
register XDR *xdrs;
|
||||
char **cpp;
|
||||
u_int maxsize;
|
||||
{
|
||||
register char *sp = *cpp; /* sp is the actual string pointer */
|
||||
u_int size;
|
||||
u_int nodesize;
|
||||
|
||||
/*
|
||||
* first deal with the length since xdr strings are counted-strings
|
||||
*/
|
||||
switch (xdrs->x_op) {
|
||||
case XDR_FREE:
|
||||
if (sp == NULL) {
|
||||
return(TRUE); /* already free */
|
||||
}
|
||||
/* fall through... */
|
||||
case XDR_ENCODE:
|
||||
size = strlen(sp);
|
||||
break;
|
||||
}
|
||||
if (! xdr_u_int(xdrs, &size)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (size > maxsize) {
|
||||
return (FALSE);
|
||||
}
|
||||
nodesize = size + 1;
|
||||
|
||||
/*
|
||||
* now deal with the actual bytes
|
||||
*/
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_DECODE:
|
||||
if (nodesize == 0) {
|
||||
return (TRUE);
|
||||
}
|
||||
if (sp == NULL)
|
||||
*cpp = sp = (char *)mem_alloc(nodesize);
|
||||
if (sp == NULL) {
|
||||
(void) fprintf(stderr, "xdr_string: out of memory\n");
|
||||
return (FALSE);
|
||||
}
|
||||
sp[size] = 0;
|
||||
/* fall into ... */
|
||||
|
||||
case XDR_ENCODE:
|
||||
return (xdr_opaque(xdrs, sp, size));
|
||||
|
||||
case XDR_FREE:
|
||||
mem_free(sp, nodesize);
|
||||
*cpp = NULL;
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for xdr_string that can be called directly from
|
||||
* routines like clnt_call
|
||||
*/
|
||||
bool_t
|
||||
xdr_wrapstring(xdrs, cpp)
|
||||
XDR *xdrs;
|
||||
char **cpp;
|
||||
{
|
||||
if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
155
lib/libc/xdr/xdr_array.c
Normal file
155
lib/libc/xdr/xdr_array.c
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$Id: xdr_array.c,v 1.1 1993/10/27 05:41:09 paul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xdr_array.c, Generic XDR routines impelmentation.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*
|
||||
* These are the "non-trivial" xdr primitives used to serialize and de-serialize
|
||||
* arrays. See xdr.h for more info on the interface to xdr.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
|
||||
#define LASTUNSIGNED ((u_int)0-1)
|
||||
|
||||
|
||||
/*
|
||||
* XDR an array of arbitrary elements
|
||||
* *addrp is a pointer to the array, *sizep is the number of elements.
|
||||
* If addrp is NULL (*sizep * elsize) bytes are allocated.
|
||||
* elsize is the size (in bytes) of each element, and elproc is the
|
||||
* xdr procedure to call to handle each element of the array.
|
||||
*/
|
||||
bool_t
|
||||
xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
|
||||
register XDR *xdrs;
|
||||
caddr_t *addrp; /* array pointer */
|
||||
u_int *sizep; /* number of elements */
|
||||
u_int maxsize; /* max numberof elements */
|
||||
u_int elsize; /* size in bytes of each element */
|
||||
xdrproc_t elproc; /* xdr routine to handle each element */
|
||||
{
|
||||
register u_int i;
|
||||
register caddr_t target = *addrp;
|
||||
register u_int c; /* the actual element count */
|
||||
register bool_t stat = TRUE;
|
||||
register u_int nodesize;
|
||||
|
||||
/* like strings, arrays are really counted arrays */
|
||||
if (! xdr_u_int(xdrs, sizep)) {
|
||||
return (FALSE);
|
||||
}
|
||||
c = *sizep;
|
||||
if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
|
||||
return (FALSE);
|
||||
}
|
||||
nodesize = c * elsize;
|
||||
|
||||
/*
|
||||
* if we are deserializing, we may need to allocate an array.
|
||||
* We also save time by checking for a null array if we are freeing.
|
||||
*/
|
||||
if (target == NULL)
|
||||
switch (xdrs->x_op) {
|
||||
case XDR_DECODE:
|
||||
if (c == 0)
|
||||
return (TRUE);
|
||||
*addrp = target = mem_alloc(nodesize);
|
||||
if (target == NULL) {
|
||||
(void) fprintf(stderr,
|
||||
"xdr_array: out of memory\n");
|
||||
return (FALSE);
|
||||
}
|
||||
bzero(target, nodesize);
|
||||
break;
|
||||
|
||||
case XDR_FREE:
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* now we xdr each element of array
|
||||
*/
|
||||
for (i = 0; (i < c) && stat; i++) {
|
||||
stat = (*elproc)(xdrs, target, LASTUNSIGNED);
|
||||
target += elsize;
|
||||
}
|
||||
|
||||
/*
|
||||
* the array may need freeing
|
||||
*/
|
||||
if (xdrs->x_op == XDR_FREE) {
|
||||
mem_free(*addrp, nodesize);
|
||||
*addrp = NULL;
|
||||
}
|
||||
return (stat);
|
||||
}
|
||||
|
||||
/*
|
||||
* xdr_vector():
|
||||
*
|
||||
* XDR a fixed length array. Unlike variable-length arrays,
|
||||
* the storage of fixed length arrays is static and unfreeable.
|
||||
* > basep: base of the array
|
||||
* > size: size of the array
|
||||
* > elemsize: size of each element
|
||||
* > xdr_elem: routine to XDR each element
|
||||
*/
|
||||
bool_t
|
||||
xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem)
|
||||
register XDR *xdrs;
|
||||
register char *basep;
|
||||
register u_int nelem;
|
||||
register u_int elemsize;
|
||||
register xdrproc_t xdr_elem;
|
||||
{
|
||||
register u_int i;
|
||||
register char *elptr;
|
||||
|
||||
elptr = basep;
|
||||
for (i = 0; i < nelem; i++) {
|
||||
if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) {
|
||||
return(FALSE);
|
||||
}
|
||||
elptr += elemsize;
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
283
lib/libc/xdr/xdr_float.c
Normal file
283
lib/libc/xdr/xdr_float.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$Id: xdr_float.c,v 1.1 1993/10/27 05:41:10 paul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xdr_float.c, Generic XDR routines impelmentation.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*
|
||||
* These are the "floating point" xdr routines used to (de)serialize
|
||||
* most common data items. See xdr.h for more info on the interface to
|
||||
* xdr.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
|
||||
/*
|
||||
* NB: Not portable.
|
||||
* This routine works on Suns (Sky / 68000's), i386's, MIPS, NS32k and Vaxen.
|
||||
*/
|
||||
|
||||
#if defined(mc68000)||defined(sparc)||defined(i386)||defined(mips)||defined(ns32000)
|
||||
#define IEEEFP
|
||||
#endif
|
||||
|
||||
#ifdef vax
|
||||
|
||||
/* What IEEE single precision floating point looks like on a Vax */
|
||||
struct ieee_single {
|
||||
unsigned int mantissa: 23;
|
||||
unsigned int exp : 8;
|
||||
unsigned int sign : 1;
|
||||
};
|
||||
|
||||
/* Vax single precision floating point */
|
||||
struct vax_single {
|
||||
unsigned int mantissa1 : 7;
|
||||
unsigned int exp : 8;
|
||||
unsigned int sign : 1;
|
||||
unsigned int mantissa2 : 16;
|
||||
};
|
||||
|
||||
#define VAX_SNG_BIAS 0x81
|
||||
#define IEEE_SNG_BIAS 0x7f
|
||||
|
||||
static struct sgl_limits {
|
||||
struct vax_single s;
|
||||
struct ieee_single ieee;
|
||||
} sgl_limits[2] = {
|
||||
{{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
|
||||
{ 0x0, 0xff, 0x0 }}, /* Max IEEE */
|
||||
{{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
|
||||
{ 0x0, 0x0, 0x0 }} /* Min IEEE */
|
||||
};
|
||||
#endif /* vax */
|
||||
|
||||
bool_t
|
||||
xdr_float(xdrs, fp)
|
||||
register XDR *xdrs;
|
||||
register float *fp;
|
||||
{
|
||||
#ifndef IEEEFP
|
||||
struct ieee_single is;
|
||||
struct vax_single vs, *vsp;
|
||||
struct sgl_limits *lim;
|
||||
int i;
|
||||
#endif
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_ENCODE:
|
||||
#ifdef IEEEFP
|
||||
return (XDR_PUTLONG(xdrs, (long *)fp));
|
||||
#else
|
||||
vs = *((struct vax_single *)fp);
|
||||
for (i = 0, lim = sgl_limits;
|
||||
i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
|
||||
i++, lim++) {
|
||||
if ((vs.mantissa2 == lim->s.mantissa2) &&
|
||||
(vs.exp == lim->s.exp) &&
|
||||
(vs.mantissa1 == lim->s.mantissa1)) {
|
||||
is = lim->ieee;
|
||||
goto shipit;
|
||||
}
|
||||
}
|
||||
is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
|
||||
is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
|
||||
shipit:
|
||||
is.sign = vs.sign;
|
||||
return (XDR_PUTLONG(xdrs, (long *)&is));
|
||||
#endif
|
||||
|
||||
case XDR_DECODE:
|
||||
#ifdef IEEEFP
|
||||
return (XDR_GETLONG(xdrs, (long *)fp));
|
||||
#else
|
||||
vsp = (struct vax_single *)fp;
|
||||
if (!XDR_GETLONG(xdrs, (long *)&is))
|
||||
return (FALSE);
|
||||
for (i = 0, lim = sgl_limits;
|
||||
i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
|
||||
i++, lim++) {
|
||||
if ((is.exp == lim->ieee.exp) &&
|
||||
(is.mantissa == lim->ieee.mantissa)) {
|
||||
*vsp = lim->s;
|
||||
goto doneit;
|
||||
}
|
||||
}
|
||||
vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
|
||||
vsp->mantissa2 = is.mantissa;
|
||||
vsp->mantissa1 = (is.mantissa >> 16);
|
||||
doneit:
|
||||
vsp->sign = is.sign;
|
||||
return (TRUE);
|
||||
#endif
|
||||
|
||||
case XDR_FREE:
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine works on Suns (Sky / 68000's), i386's, MIPS and Vaxen.
|
||||
*/
|
||||
|
||||
#ifdef vax
|
||||
/* What IEEE double precision floating point looks like on a Vax */
|
||||
struct ieee_double {
|
||||
unsigned int mantissa1 : 20;
|
||||
unsigned int exp : 11;
|
||||
unsigned int sign : 1;
|
||||
unsigned int mantissa2 : 32;
|
||||
};
|
||||
|
||||
/* Vax double precision floating point */
|
||||
struct vax_double {
|
||||
unsigned int mantissa1 : 7;
|
||||
unsigned int exp : 8;
|
||||
unsigned int sign : 1;
|
||||
unsigned int mantissa2 : 16;
|
||||
unsigned int mantissa3 : 16;
|
||||
unsigned int mantissa4 : 16;
|
||||
};
|
||||
|
||||
#define VAX_DBL_BIAS 0x81
|
||||
#define IEEE_DBL_BIAS 0x3ff
|
||||
#define MASK(nbits) ((1 << nbits) - 1)
|
||||
|
||||
static struct dbl_limits {
|
||||
struct vax_double d;
|
||||
struct ieee_double ieee;
|
||||
} dbl_limits[2] = {
|
||||
{{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
|
||||
{ 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
|
||||
{{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
|
||||
{ 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
|
||||
};
|
||||
|
||||
#endif /* vax */
|
||||
|
||||
|
||||
bool_t
|
||||
xdr_double(xdrs, dp)
|
||||
register XDR *xdrs;
|
||||
double *dp;
|
||||
{
|
||||
register long *lp;
|
||||
#ifndef IEEEFP
|
||||
struct ieee_double id;
|
||||
struct vax_double vd;
|
||||
register struct dbl_limits *lim;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_ENCODE:
|
||||
#ifdef IEEEFP
|
||||
lp = (long *)dp;
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
|
||||
#else
|
||||
return (XDR_PUTLONG(xdrs, lp+1) && XDR_PUTLONG(xdrs, lp));
|
||||
#endif
|
||||
#else
|
||||
vd = *((struct vax_double *)dp);
|
||||
for (i = 0, lim = dbl_limits;
|
||||
i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
|
||||
i++, lim++) {
|
||||
if ((vd.mantissa4 == lim->d.mantissa4) &&
|
||||
(vd.mantissa3 == lim->d.mantissa3) &&
|
||||
(vd.mantissa2 == lim->d.mantissa2) &&
|
||||
(vd.mantissa1 == lim->d.mantissa1) &&
|
||||
(vd.exp == lim->d.exp)) {
|
||||
id = lim->ieee;
|
||||
goto shipit;
|
||||
}
|
||||
}
|
||||
id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
|
||||
id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
|
||||
id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
|
||||
(vd.mantissa3 << 13) |
|
||||
((vd.mantissa4 >> 3) & MASK(13));
|
||||
shipit:
|
||||
id.sign = vd.sign;
|
||||
lp = (long *)&id;
|
||||
return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
|
||||
#endif
|
||||
|
||||
case XDR_DECODE:
|
||||
#ifdef IEEEFP
|
||||
lp = (long *)dp;
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
|
||||
#else
|
||||
return (XDR_GETLONG(xdrs, lp+1) && XDR_GETLONG(xdrs, lp));
|
||||
#endif
|
||||
#else
|
||||
lp = (long *)&id;
|
||||
if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
|
||||
return (FALSE);
|
||||
for (i = 0, lim = dbl_limits;
|
||||
i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
|
||||
i++, lim++) {
|
||||
if ((id.mantissa2 == lim->ieee.mantissa2) &&
|
||||
(id.mantissa1 == lim->ieee.mantissa1) &&
|
||||
(id.exp == lim->ieee.exp)) {
|
||||
vd = lim->d;
|
||||
goto doneit;
|
||||
}
|
||||
}
|
||||
vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
|
||||
vd.mantissa1 = (id.mantissa1 >> 13);
|
||||
vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
|
||||
(id.mantissa2 >> 29);
|
||||
vd.mantissa3 = (id.mantissa2 >> 13);
|
||||
vd.mantissa4 = (id.mantissa2 << 3);
|
||||
doneit:
|
||||
vd.sign = id.sign;
|
||||
*dp = *((double *)&vd);
|
||||
return (TRUE);
|
||||
#endif
|
||||
|
||||
case XDR_FREE:
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
186
lib/libc/xdr/xdr_mem.c
Normal file
186
lib/libc/xdr/xdr_mem.c
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$Id: xdr_mem.c,v 1.1 1993/10/27 05:41:11 paul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xdr_mem.h, XDR implementation using memory buffers.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*
|
||||
* If you have some data to be interpreted as external data representation
|
||||
* or to be converted to external data representation in a memory buffer,
|
||||
* then this is the package for you.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
static bool_t xdrmem_getlong();
|
||||
static bool_t xdrmem_putlong();
|
||||
static bool_t xdrmem_getbytes();
|
||||
static bool_t xdrmem_putbytes();
|
||||
static u_int xdrmem_getpos();
|
||||
static bool_t xdrmem_setpos();
|
||||
static long * xdrmem_inline();
|
||||
static void xdrmem_destroy();
|
||||
|
||||
static struct xdr_ops xdrmem_ops = {
|
||||
xdrmem_getlong,
|
||||
xdrmem_putlong,
|
||||
xdrmem_getbytes,
|
||||
xdrmem_putbytes,
|
||||
xdrmem_getpos,
|
||||
xdrmem_setpos,
|
||||
xdrmem_inline,
|
||||
xdrmem_destroy
|
||||
};
|
||||
|
||||
/*
|
||||
* The procedure xdrmem_create initializes a stream descriptor for a
|
||||
* memory buffer.
|
||||
*/
|
||||
void
|
||||
xdrmem_create(xdrs, addr, size, op)
|
||||
register XDR *xdrs;
|
||||
caddr_t addr;
|
||||
u_int size;
|
||||
enum xdr_op op;
|
||||
{
|
||||
|
||||
xdrs->x_op = op;
|
||||
xdrs->x_ops = &xdrmem_ops;
|
||||
xdrs->x_private = xdrs->x_base = addr;
|
||||
xdrs->x_handy = size;
|
||||
}
|
||||
|
||||
static void
|
||||
xdrmem_destroy(/*xdrs*/)
|
||||
/*XDR *xdrs;*/
|
||||
{
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrmem_getlong(xdrs, lp)
|
||||
register XDR *xdrs;
|
||||
long *lp;
|
||||
{
|
||||
|
||||
if ((xdrs->x_handy -= sizeof(long)) < 0)
|
||||
return (FALSE);
|
||||
*lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private))));
|
||||
xdrs->x_private += sizeof(long);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrmem_putlong(xdrs, lp)
|
||||
register XDR *xdrs;
|
||||
long *lp;
|
||||
{
|
||||
|
||||
if ((xdrs->x_handy -= sizeof(long)) < 0)
|
||||
return (FALSE);
|
||||
*(long *)xdrs->x_private = (long)htonl((u_long)(*lp));
|
||||
xdrs->x_private += sizeof(long);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrmem_getbytes(xdrs, addr, len)
|
||||
register XDR *xdrs;
|
||||
caddr_t addr;
|
||||
register u_int len;
|
||||
{
|
||||
|
||||
if ((xdrs->x_handy -= len) < 0)
|
||||
return (FALSE);
|
||||
bcopy(xdrs->x_private, addr, len);
|
||||
xdrs->x_private += len;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrmem_putbytes(xdrs, addr, len)
|
||||
register XDR *xdrs;
|
||||
caddr_t addr;
|
||||
register u_int len;
|
||||
{
|
||||
|
||||
if ((xdrs->x_handy -= len) < 0)
|
||||
return (FALSE);
|
||||
bcopy(addr, xdrs->x_private, len);
|
||||
xdrs->x_private += len;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static u_int
|
||||
xdrmem_getpos(xdrs)
|
||||
register XDR *xdrs;
|
||||
{
|
||||
|
||||
return ((u_int)xdrs->x_private - (u_int)xdrs->x_base);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrmem_setpos(xdrs, pos)
|
||||
register XDR *xdrs;
|
||||
u_int pos;
|
||||
{
|
||||
register caddr_t newaddr = xdrs->x_base + pos;
|
||||
register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
|
||||
|
||||
if ((long)newaddr > (long)lastaddr)
|
||||
return (FALSE);
|
||||
xdrs->x_private = newaddr;
|
||||
xdrs->x_handy = (int)lastaddr - (int)newaddr;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static long *
|
||||
xdrmem_inline(xdrs, len)
|
||||
register XDR *xdrs;
|
||||
int len;
|
||||
{
|
||||
long *buf = 0;
|
||||
|
||||
if (xdrs->x_handy >= len) {
|
||||
xdrs->x_handy -= len;
|
||||
buf = (long *) xdrs->x_private;
|
||||
xdrs->x_private += len;
|
||||
}
|
||||
return (buf);
|
||||
}
|
586
lib/libc/xdr/xdr_rec.c
Normal file
586
lib/libc/xdr/xdr_rec.c
Normal file
@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$Id: xdr_rec.c,v 1.1 1993/10/27 05:41:12 paul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
|
||||
* layer above tcp (for rpc's use).
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*
|
||||
* These routines interface XDRSTREAMS to a tcp/ip connection.
|
||||
* There is a record marking layer between the xdr stream
|
||||
* and the tcp transport level. A record is composed on one or more
|
||||
* record fragments. A record fragment is a thirty-two bit header followed
|
||||
* by n bytes of data, where n is contained in the header. The header
|
||||
* is represented as a htonl(u_long). Thegh order bit encodes
|
||||
* whether or not the fragment is the last fragment of the record
|
||||
* (1 => fragment is last, 0 => more fragments to follow.
|
||||
* The other 31 bits encode the byte length of the fragment.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
extern long lseek();
|
||||
|
||||
static u_int fix_buf_size();
|
||||
static bool_t flush_out();
|
||||
static bool_t get_input_bytes();
|
||||
static bool_t set_input_fragment();
|
||||
static bool_t skip_input_bytes();
|
||||
|
||||
static bool_t xdrrec_getlong();
|
||||
static bool_t xdrrec_putlong();
|
||||
static bool_t xdrrec_getbytes();
|
||||
static bool_t xdrrec_putbytes();
|
||||
static u_int xdrrec_getpos();
|
||||
static bool_t xdrrec_setpos();
|
||||
static long * xdrrec_inline();
|
||||
static void xdrrec_destroy();
|
||||
|
||||
static struct xdr_ops xdrrec_ops = {
|
||||
xdrrec_getlong,
|
||||
xdrrec_putlong,
|
||||
xdrrec_getbytes,
|
||||
xdrrec_putbytes,
|
||||
xdrrec_getpos,
|
||||
xdrrec_setpos,
|
||||
xdrrec_inline,
|
||||
xdrrec_destroy
|
||||
};
|
||||
|
||||
/*
|
||||
* A record is composed of one or more record fragments.
|
||||
* A record fragment is a two-byte header followed by zero to
|
||||
* 2**32-1 bytes. The header is treated as a long unsigned and is
|
||||
* encode/decoded to the network via htonl/ntohl. The low order 31 bits
|
||||
* are a byte count of the fragment. The highest order bit is a boolean:
|
||||
* 1 => this fragment is the last fragment of the record,
|
||||
* 0 => this fragment is followed by more fragment(s).
|
||||
*
|
||||
* The fragment/record machinery is not general; it is constructed to
|
||||
* meet the needs of xdr and rpc based on tcp.
|
||||
*/
|
||||
|
||||
#define LAST_FRAG ((u_long)(1 << 31))
|
||||
|
||||
typedef struct rec_strm {
|
||||
caddr_t tcp_handle;
|
||||
caddr_t the_buffer;
|
||||
/*
|
||||
* out-goung bits
|
||||
*/
|
||||
int (*writeit)();
|
||||
caddr_t out_base; /* output buffer (points to frag header) */
|
||||
caddr_t out_finger; /* next output position */
|
||||
caddr_t out_boundry; /* data cannot up to this address */
|
||||
u_long *frag_header; /* beginning of curren fragment */
|
||||
bool_t frag_sent; /* true if buffer sent in middle of record */
|
||||
/*
|
||||
* in-coming bits
|
||||
*/
|
||||
int (*readit)();
|
||||
u_long in_size; /* fixed size of the input buffer */
|
||||
caddr_t in_base;
|
||||
caddr_t in_finger; /* location of next byte to be had */
|
||||
caddr_t in_boundry; /* can read up to this location */
|
||||
long fbtbc; /* fragment bytes to be consumed */
|
||||
bool_t last_frag;
|
||||
u_int sendsize;
|
||||
u_int recvsize;
|
||||
} RECSTREAM;
|
||||
|
||||
|
||||
/*
|
||||
* Create an xdr handle for xdrrec
|
||||
* xdrrec_create fills in xdrs. Sendsize and recvsize are
|
||||
* send and recv buffer sizes (0 => use default).
|
||||
* tcp_handle is an opaque handle that is passed as the first parameter to
|
||||
* the procedures readit and writeit. Readit and writeit are read and
|
||||
* write respectively. They are like the system
|
||||
* calls expect that they take an opaque handle rather than an fd.
|
||||
*/
|
||||
void
|
||||
xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
|
||||
register XDR *xdrs;
|
||||
register u_int sendsize;
|
||||
register u_int recvsize;
|
||||
caddr_t tcp_handle;
|
||||
int (*readit)(); /* like read, but pass it a tcp_handle, not sock */
|
||||
int (*writeit)(); /* like write, but pass it a tcp_handle, not sock */
|
||||
{
|
||||
register RECSTREAM *rstrm =
|
||||
(RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
|
||||
|
||||
if (rstrm == NULL) {
|
||||
(void)fprintf(stderr, "xdrrec_create: out of memory\n");
|
||||
/*
|
||||
* This is bad. Should rework xdrrec_create to
|
||||
* return a handle, and in this case return NULL
|
||||
*/
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* adjust sizes and allocate buffer quad byte aligned
|
||||
*/
|
||||
rstrm->sendsize = sendsize = fix_buf_size(sendsize);
|
||||
rstrm->recvsize = recvsize = fix_buf_size(recvsize);
|
||||
rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT);
|
||||
if (rstrm->the_buffer == NULL) {
|
||||
(void)fprintf(stderr, "xdrrec_create: out of memory\n");
|
||||
return;
|
||||
}
|
||||
for (rstrm->out_base = rstrm->the_buffer;
|
||||
(u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0;
|
||||
rstrm->out_base++);
|
||||
rstrm->in_base = rstrm->out_base + sendsize;
|
||||
/*
|
||||
* now the rest ...
|
||||
*/
|
||||
xdrs->x_ops = &xdrrec_ops;
|
||||
xdrs->x_private = (caddr_t)rstrm;
|
||||
rstrm->tcp_handle = tcp_handle;
|
||||
rstrm->readit = readit;
|
||||
rstrm->writeit = writeit;
|
||||
rstrm->out_finger = rstrm->out_boundry = rstrm->out_base;
|
||||
rstrm->frag_header = (u_long *)rstrm->out_base;
|
||||
rstrm->out_finger += sizeof(u_long);
|
||||
rstrm->out_boundry += sendsize;
|
||||
rstrm->frag_sent = FALSE;
|
||||
rstrm->in_size = recvsize;
|
||||
rstrm->in_boundry = rstrm->in_base;
|
||||
rstrm->in_finger = (rstrm->in_boundry += recvsize);
|
||||
rstrm->fbtbc = 0;
|
||||
rstrm->last_frag = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The reoutines defined below are the xdr ops which will go into the
|
||||
* xdr handle filled in by xdrrec_create.
|
||||
*/
|
||||
|
||||
static bool_t
|
||||
xdrrec_getlong(xdrs, lp)
|
||||
XDR *xdrs;
|
||||
long *lp;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
|
||||
register long *buflp = (long *)(rstrm->in_finger);
|
||||
long mylong;
|
||||
|
||||
/* first try the inline, fast case */
|
||||
if ((rstrm->fbtbc >= sizeof(long)) &&
|
||||
(((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) {
|
||||
*lp = (long)ntohl((u_long)(*buflp));
|
||||
rstrm->fbtbc -= sizeof(long);
|
||||
rstrm->in_finger += sizeof(long);
|
||||
} else {
|
||||
if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
|
||||
return (FALSE);
|
||||
*lp = (long)ntohl((u_long)mylong);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrrec_putlong(xdrs, lp)
|
||||
XDR *xdrs;
|
||||
long *lp;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
|
||||
register long *dest_lp = ((long *)(rstrm->out_finger));
|
||||
|
||||
if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) {
|
||||
/*
|
||||
* this case should almost never happen so the code is
|
||||
* inefficient
|
||||
*/
|
||||
rstrm->out_finger -= sizeof(long);
|
||||
rstrm->frag_sent = TRUE;
|
||||
if (! flush_out(rstrm, FALSE))
|
||||
return (FALSE);
|
||||
dest_lp = ((long *)(rstrm->out_finger));
|
||||
rstrm->out_finger += sizeof(long);
|
||||
}
|
||||
*dest_lp = (long)htonl((u_long)(*lp));
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t /* must manage buffers, fragments, and records */
|
||||
xdrrec_getbytes(xdrs, addr, len)
|
||||
XDR *xdrs;
|
||||
register caddr_t addr;
|
||||
register u_int len;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
|
||||
register int current;
|
||||
|
||||
while (len > 0) {
|
||||
current = rstrm->fbtbc;
|
||||
if (current == 0) {
|
||||
if (rstrm->last_frag)
|
||||
return (FALSE);
|
||||
if (! set_input_fragment(rstrm))
|
||||
return (FALSE);
|
||||
continue;
|
||||
}
|
||||
current = (len < current) ? len : current;
|
||||
if (! get_input_bytes(rstrm, addr, current))
|
||||
return (FALSE);
|
||||
addr += current;
|
||||
rstrm->fbtbc -= current;
|
||||
len -= current;
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrrec_putbytes(xdrs, addr, len)
|
||||
XDR *xdrs;
|
||||
register caddr_t addr;
|
||||
register u_int len;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
|
||||
register int current;
|
||||
|
||||
while (len > 0) {
|
||||
current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger;
|
||||
current = (len < current) ? len : current;
|
||||
bcopy(addr, rstrm->out_finger, current);
|
||||
rstrm->out_finger += current;
|
||||
addr += current;
|
||||
len -= current;
|
||||
if (rstrm->out_finger == rstrm->out_boundry) {
|
||||
rstrm->frag_sent = TRUE;
|
||||
if (! flush_out(rstrm, FALSE))
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static u_int
|
||||
xdrrec_getpos(xdrs)
|
||||
register XDR *xdrs;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
|
||||
register long pos;
|
||||
|
||||
pos = lseek((int)rstrm->tcp_handle, (long) 0, 1);
|
||||
if (pos != -1)
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_ENCODE:
|
||||
pos += rstrm->out_finger - rstrm->out_base;
|
||||
break;
|
||||
|
||||
case XDR_DECODE:
|
||||
pos -= rstrm->in_boundry - rstrm->in_finger;
|
||||
break;
|
||||
|
||||
default:
|
||||
pos = (u_int) -1;
|
||||
break;
|
||||
}
|
||||
return ((u_int) pos);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrrec_setpos(xdrs, pos)
|
||||
register XDR *xdrs;
|
||||
u_int pos;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
|
||||
u_int currpos = xdrrec_getpos(xdrs);
|
||||
int delta = currpos - pos;
|
||||
caddr_t newpos;
|
||||
|
||||
if ((int)currpos != -1)
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_ENCODE:
|
||||
newpos = rstrm->out_finger - delta;
|
||||
if ((newpos > (caddr_t)(rstrm->frag_header)) &&
|
||||
(newpos < rstrm->out_boundry)) {
|
||||
rstrm->out_finger = newpos;
|
||||
return (TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case XDR_DECODE:
|
||||
newpos = rstrm->in_finger - delta;
|
||||
if ((delta < (int)(rstrm->fbtbc)) &&
|
||||
(newpos <= rstrm->in_boundry) &&
|
||||
(newpos >= rstrm->in_base)) {
|
||||
rstrm->in_finger = newpos;
|
||||
rstrm->fbtbc -= delta;
|
||||
return (TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
static long *
|
||||
xdrrec_inline(xdrs, len)
|
||||
register XDR *xdrs;
|
||||
int len;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
|
||||
long * buf = NULL;
|
||||
|
||||
switch (xdrs->x_op) {
|
||||
|
||||
case XDR_ENCODE:
|
||||
if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
|
||||
buf = (long *) rstrm->out_finger;
|
||||
rstrm->out_finger += len;
|
||||
}
|
||||
break;
|
||||
|
||||
case XDR_DECODE:
|
||||
if ((len <= rstrm->fbtbc) &&
|
||||
((rstrm->in_finger + len) <= rstrm->in_boundry)) {
|
||||
buf = (long *) rstrm->in_finger;
|
||||
rstrm->fbtbc -= len;
|
||||
rstrm->in_finger += len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
xdrrec_destroy(xdrs)
|
||||
register XDR *xdrs;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
|
||||
|
||||
mem_free(rstrm->the_buffer,
|
||||
rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT);
|
||||
mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Exported routines to manage xdr records
|
||||
*/
|
||||
|
||||
/*
|
||||
* Before reading (deserializing from the stream, one should always call
|
||||
* this procedure to guarantee proper record alignment.
|
||||
*/
|
||||
bool_t
|
||||
xdrrec_skiprecord(xdrs)
|
||||
XDR *xdrs;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
|
||||
|
||||
while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
|
||||
if (! skip_input_bytes(rstrm, rstrm->fbtbc))
|
||||
return (FALSE);
|
||||
rstrm->fbtbc = 0;
|
||||
if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
|
||||
return (FALSE);
|
||||
}
|
||||
rstrm->last_frag = FALSE;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look ahead fuction.
|
||||
* Returns TRUE iff there is no more input in the buffer
|
||||
* after consuming the rest of the current record.
|
||||
*/
|
||||
bool_t
|
||||
xdrrec_eof(xdrs)
|
||||
XDR *xdrs;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
|
||||
|
||||
while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
|
||||
if (! skip_input_bytes(rstrm, rstrm->fbtbc))
|
||||
return (TRUE);
|
||||
rstrm->fbtbc = 0;
|
||||
if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
|
||||
return (TRUE);
|
||||
}
|
||||
if (rstrm->in_finger == rstrm->in_boundry)
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* The client must tell the package when an end-of-record has occurred.
|
||||
* The second paraemters tells whether the record should be flushed to the
|
||||
* (output) tcp stream. (This let's the package support batched or
|
||||
* pipelined procedure calls.) TRUE => immmediate flush to tcp connection.
|
||||
*/
|
||||
bool_t
|
||||
xdrrec_endofrecord(xdrs, sendnow)
|
||||
XDR *xdrs;
|
||||
bool_t sendnow;
|
||||
{
|
||||
register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
|
||||
register u_long len; /* fragment length */
|
||||
|
||||
if (sendnow || rstrm->frag_sent ||
|
||||
((u_long)rstrm->out_finger + sizeof(u_long) >=
|
||||
(u_long)rstrm->out_boundry)) {
|
||||
rstrm->frag_sent = FALSE;
|
||||
return (flush_out(rstrm, TRUE));
|
||||
}
|
||||
len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
|
||||
sizeof(u_long);
|
||||
*(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG);
|
||||
rstrm->frag_header = (u_long *)rstrm->out_finger;
|
||||
rstrm->out_finger += sizeof(u_long);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Internal useful routines
|
||||
*/
|
||||
static bool_t
|
||||
flush_out(rstrm, eor)
|
||||
register RECSTREAM *rstrm;
|
||||
bool_t eor;
|
||||
{
|
||||
register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
|
||||
register u_long len = (u_long)(rstrm->out_finger) -
|
||||
(u_long)(rstrm->frag_header) - sizeof(u_long);
|
||||
|
||||
*(rstrm->frag_header) = htonl(len | eormask);
|
||||
len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
|
||||
if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
|
||||
!= (int)len)
|
||||
return (FALSE);
|
||||
rstrm->frag_header = (u_long *)rstrm->out_base;
|
||||
rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t /* knows nothing about records! Only about input buffers */
|
||||
fill_input_buf(rstrm)
|
||||
register RECSTREAM *rstrm;
|
||||
{
|
||||
register caddr_t where;
|
||||
u_int i;
|
||||
register int len;
|
||||
|
||||
where = rstrm->in_base;
|
||||
i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT;
|
||||
where += i;
|
||||
len = rstrm->in_size - i;
|
||||
if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
|
||||
return (FALSE);
|
||||
rstrm->in_finger = where;
|
||||
where += len;
|
||||
rstrm->in_boundry = where;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t /* knows nothing about records! Only about input buffers */
|
||||
get_input_bytes(rstrm, addr, len)
|
||||
register RECSTREAM *rstrm;
|
||||
register caddr_t addr;
|
||||
register int len;
|
||||
{
|
||||
register int current;
|
||||
|
||||
while (len > 0) {
|
||||
current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
|
||||
if (current == 0) {
|
||||
if (! fill_input_buf(rstrm))
|
||||
return (FALSE);
|
||||
continue;
|
||||
}
|
||||
current = (len < current) ? len : current;
|
||||
bcopy(rstrm->in_finger, addr, current);
|
||||
rstrm->in_finger += current;
|
||||
addr += current;
|
||||
len -= current;
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t /* next two bytes of the input stream are treated as a header */
|
||||
set_input_fragment(rstrm)
|
||||
register RECSTREAM *rstrm;
|
||||
{
|
||||
u_long header;
|
||||
|
||||
if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
|
||||
return (FALSE);
|
||||
header = (long)ntohl(header);
|
||||
rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
|
||||
rstrm->fbtbc = header & (~LAST_FRAG);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t /* consumes input bytes; knows nothing about records! */
|
||||
skip_input_bytes(rstrm, cnt)
|
||||
register RECSTREAM *rstrm;
|
||||
long cnt;
|
||||
{
|
||||
register int current;
|
||||
|
||||
while (cnt > 0) {
|
||||
current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
|
||||
if (current == 0) {
|
||||
if (! fill_input_buf(rstrm))
|
||||
return (FALSE);
|
||||
continue;
|
||||
}
|
||||
current = (cnt < current) ? cnt : current;
|
||||
rstrm->in_finger += current;
|
||||
cnt -= current;
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static u_int
|
||||
fix_buf_size(s)
|
||||
register u_int s;
|
||||
{
|
||||
|
||||
if (s < 100)
|
||||
s = 4000;
|
||||
return (RNDUP(s));
|
||||
}
|
134
lib/libc/xdr/xdr_reference.c
Normal file
134
lib/libc/xdr/xdr_reference.c
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)xdr_reference.c 1.11 87/08/11 SMI";*/
|
||||
/*static char *sccsid = "from: @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$Id: xdr_reference.c,v 1.1 1993/10/27 05:41:13 paul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xdr_reference.c, Generic XDR routines impelmentation.
|
||||
*
|
||||
* Copyright (C) 1987, Sun Microsystems, Inc.
|
||||
*
|
||||
* These are the "non-trivial" xdr primitives used to serialize and de-serialize
|
||||
* "pointers". See xdr.h for more info on the interface to xdr.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
|
||||
#define LASTUNSIGNED ((u_int)0-1)
|
||||
|
||||
/*
|
||||
* XDR an indirect pointer
|
||||
* xdr_reference is for recursively translating a structure that is
|
||||
* referenced by a pointer inside the structure that is currently being
|
||||
* translated. pp references a pointer to storage. If *pp is null
|
||||
* the necessary storage is allocated.
|
||||
* size is the sizeof the referneced structure.
|
||||
* proc is the routine to handle the referenced structure.
|
||||
*/
|
||||
bool_t
|
||||
xdr_reference(xdrs, pp, size, proc)
|
||||
register XDR *xdrs;
|
||||
caddr_t *pp; /* the pointer to work on */
|
||||
u_int size; /* size of the object pointed to */
|
||||
xdrproc_t proc; /* xdr routine to handle the object */
|
||||
{
|
||||
register caddr_t loc = *pp;
|
||||
register bool_t stat;
|
||||
|
||||
if (loc == NULL)
|
||||
switch (xdrs->x_op) {
|
||||
case XDR_FREE:
|
||||
return (TRUE);
|
||||
|
||||
case XDR_DECODE:
|
||||
*pp = loc = (caddr_t) mem_alloc(size);
|
||||
if (loc == NULL) {
|
||||
(void) fprintf(stderr,
|
||||
"xdr_reference: out of memory\n");
|
||||
return (FALSE);
|
||||
}
|
||||
bzero(loc, (int)size);
|
||||
break;
|
||||
}
|
||||
|
||||
stat = (*proc)(xdrs, loc, LASTUNSIGNED);
|
||||
|
||||
if (xdrs->x_op == XDR_FREE) {
|
||||
mem_free(loc, size);
|
||||
*pp = NULL;
|
||||
}
|
||||
return (stat);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* xdr_pointer():
|
||||
*
|
||||
* XDR a pointer to a possibly recursive data structure. This
|
||||
* differs with xdr_reference in that it can serialize/deserialiaze
|
||||
* trees correctly.
|
||||
*
|
||||
* What's sent is actually a union:
|
||||
*
|
||||
* union object_pointer switch (boolean b) {
|
||||
* case TRUE: object_data data;
|
||||
* case FALSE: void nothing;
|
||||
* }
|
||||
*
|
||||
* > objpp: Pointer to the pointer to the object.
|
||||
* > obj_size: size of the object.
|
||||
* > xdr_obj: routine to XDR an object.
|
||||
*
|
||||
*/
|
||||
bool_t
|
||||
xdr_pointer(xdrs,objpp,obj_size,xdr_obj)
|
||||
register XDR *xdrs;
|
||||
char **objpp;
|
||||
u_int obj_size;
|
||||
xdrproc_t xdr_obj;
|
||||
{
|
||||
|
||||
bool_t more_data;
|
||||
|
||||
more_data = (*objpp != NULL);
|
||||
if (! xdr_bool(xdrs,&more_data)) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (! more_data) {
|
||||
*objpp = NULL;
|
||||
return (TRUE);
|
||||
}
|
||||
return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
|
||||
}
|
191
lib/libc/xdr/xdr_stdio.c
Normal file
191
lib/libc/xdr/xdr_stdio.c
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$Id: xdr_stdio.c,v 1.1 1993/10/27 05:41:14 paul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xdr_stdio.c, XDR implementation on standard i/o file.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*
|
||||
* This set of routines implements a XDR on a stdio stream.
|
||||
* XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
|
||||
* from the stream.
|
||||
*/
|
||||
|
||||
#include <rpc/types.h>
|
||||
#include <stdio.h>
|
||||
#include <rpc/xdr.h>
|
||||
|
||||
static bool_t xdrstdio_getlong();
|
||||
static bool_t xdrstdio_putlong();
|
||||
static bool_t xdrstdio_getbytes();
|
||||
static bool_t xdrstdio_putbytes();
|
||||
static u_int xdrstdio_getpos();
|
||||
static bool_t xdrstdio_setpos();
|
||||
static long * xdrstdio_inline();
|
||||
static void xdrstdio_destroy();
|
||||
|
||||
/*
|
||||
* Ops vector for stdio type XDR
|
||||
*/
|
||||
static struct xdr_ops xdrstdio_ops = {
|
||||
xdrstdio_getlong, /* deseraialize a long int */
|
||||
xdrstdio_putlong, /* seraialize a long int */
|
||||
xdrstdio_getbytes, /* deserialize counted bytes */
|
||||
xdrstdio_putbytes, /* serialize counted bytes */
|
||||
xdrstdio_getpos, /* get offset in the stream */
|
||||
xdrstdio_setpos, /* set offset in the stream */
|
||||
xdrstdio_inline, /* prime stream for inline macros */
|
||||
xdrstdio_destroy /* destroy stream */
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize a stdio xdr stream.
|
||||
* Sets the xdr stream handle xdrs for use on the stream file.
|
||||
* Operation flag is set to op.
|
||||
*/
|
||||
void
|
||||
xdrstdio_create(xdrs, file, op)
|
||||
register XDR *xdrs;
|
||||
FILE *file;
|
||||
enum xdr_op op;
|
||||
{
|
||||
|
||||
xdrs->x_op = op;
|
||||
xdrs->x_ops = &xdrstdio_ops;
|
||||
xdrs->x_private = (caddr_t)file;
|
||||
xdrs->x_handy = 0;
|
||||
xdrs->x_base = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a stdio xdr stream.
|
||||
* Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
|
||||
*/
|
||||
static void
|
||||
xdrstdio_destroy(xdrs)
|
||||
register XDR *xdrs;
|
||||
{
|
||||
(void)fflush((FILE *)xdrs->x_private);
|
||||
/* xx should we close the file ?? */
|
||||
};
|
||||
|
||||
static bool_t
|
||||
xdrstdio_getlong(xdrs, lp)
|
||||
XDR *xdrs;
|
||||
register long *lp;
|
||||
{
|
||||
|
||||
if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
|
||||
return (FALSE);
|
||||
#ifndef mc68000
|
||||
*lp = ntohl(*lp);
|
||||
#endif
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrstdio_putlong(xdrs, lp)
|
||||
XDR *xdrs;
|
||||
long *lp;
|
||||
{
|
||||
|
||||
#ifndef mc68000
|
||||
long mycopy = htonl(*lp);
|
||||
lp = &mycopy;
|
||||
#endif
|
||||
if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
|
||||
return (FALSE);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrstdio_getbytes(xdrs, addr, len)
|
||||
XDR *xdrs;
|
||||
caddr_t addr;
|
||||
u_int len;
|
||||
{
|
||||
|
||||
if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
|
||||
return (FALSE);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrstdio_putbytes(xdrs, addr, len)
|
||||
XDR *xdrs;
|
||||
caddr_t addr;
|
||||
u_int len;
|
||||
{
|
||||
|
||||
if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
|
||||
return (FALSE);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static u_int
|
||||
xdrstdio_getpos(xdrs)
|
||||
XDR *xdrs;
|
||||
{
|
||||
|
||||
return ((u_int) ftell((FILE *)xdrs->x_private));
|
||||
}
|
||||
|
||||
static bool_t
|
||||
xdrstdio_setpos(xdrs, pos)
|
||||
XDR *xdrs;
|
||||
u_int pos;
|
||||
{
|
||||
|
||||
return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
|
||||
FALSE : TRUE);
|
||||
}
|
||||
|
||||
static long *
|
||||
xdrstdio_inline(xdrs, len)
|
||||
XDR *xdrs;
|
||||
u_int len;
|
||||
{
|
||||
|
||||
/*
|
||||
* Must do some work to implement this: must insure
|
||||
* enough data in the underlying stdio buffer,
|
||||
* that the buffer is aligned so that we can indirect through a
|
||||
* long *, and stuff this pointer in xdrs->x_buf. Doing
|
||||
* a fread or fwrite to a scratch buffer would defeat
|
||||
* most of the gains to be had here and require storage
|
||||
* management on this buffer, so we don't do this.
|
||||
*/
|
||||
return (NULL);
|
||||
}
|
Loading…
Reference in New Issue
Block a user