Windows: build src/rx/tests
[openafs.git] / src / rx / xdr_rx.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * xdr_rx.c.  XDR using RX.
12  */
13
14 #include <afsconfig.h>
15 #include <afs/param.h>
16
17 #ifdef KERNEL
18 # include "afs/sysincludes.h"
19 # ifndef UKERNEL
20 #  include "h/types.h"
21 #  include "h/uio.h"
22 #  ifdef AFS_LINUX20_ENV
23 #   include "h/socket.h"
24 #  else
25 #   include "rpc/types.h"
26 #  endif
27 #  ifdef AFS_LINUX22_ENV
28 #   ifndef quad_t
29 #    define quad_t __quad_t
30 #    define u_quad_t __u_quad_t
31 #   endif
32 #  endif
33 #  include "netinet/in.h"
34 # endif /* !UKERNEL */
35 #else /* KERNEL */
36 # include <roken.h>
37 # include <sys/types.h>
38 # include <stdio.h>
39 # ifndef AFS_NT40_ENV
40 #  include <netinet/in.h>
41 # endif
42 #endif /* KERNEL */
43
44 #include "rx.h"
45 #include "xdr.h"
46
47 /* Static prototypes */
48 #ifdef AFS_XDR_64BITOPS
49 static bool_t xdrrx_getint64(XDR *axdrs, long *lp);
50 static bool_t xdrrx_putint64(XDR *axdrs, long *lp);
51 #endif /* AFS_XDR_64BITOPS */
52
53 static bool_t xdrrx_getint32(XDR *axdrs, afs_int32 * lp);
54 static bool_t xdrrx_putint32(XDR *axdrs, afs_int32 * lp);
55 static bool_t xdrrx_getbytes(XDR *axdrs, caddr_t addr,
56                              u_int len);
57 static bool_t xdrrx_putbytes(XDR *axdrs, caddr_t addr,
58                              u_int len);
59 static afs_int32 *xdrrx_inline(XDR *axdrs, u_int len);
60
61
62 /*
63  * Ops vector for stdio type XDR
64  */
65 static struct xdr_ops xdrrx_ops = {
66 #ifndef HAVE_STRUCT_LABEL_SUPPORT
67 #ifdef AFS_XDR_64BITOPS
68     xdrrx_getint64,     /* deserialize an afs_int64 */
69     xdrrx_putint64,     /* serialize an afs_int64 */
70 #endif
71     /* Windows does not support labeled assigments */
72 #if !(defined(KERNEL) && defined(AFS_SUN57_ENV))
73     xdrrx_getint32,     /* deserialize an afs_int32 */
74     xdrrx_putint32,     /* serialize an afs_int32 */
75 #endif
76     xdrrx_getbytes,     /* deserialize counted bytes */
77     xdrrx_putbytes,     /* serialize counted bytes */
78     NULL,               /* get offset in the stream: not supported. */
79     NULL,               /* set offset in the stream: not supported. */
80     xdrrx_inline,       /* prime stream for inline macros */
81     NULL,               /* destroy stream */
82 #if (defined(KERNEL) && defined(AFS_SUN57_ENV))
83     NULL,               /* control - not implemented */
84     xdrrx_getint32,     /* not supported */
85     xdrrx_putint32,     /* serialize an afs_int32 */
86 #endif
87 #else
88 #ifdef AFS_XDR_64BITOPS
89     .x_getint64 = xdrrx_getint64,
90     .x_putint64 = xdrrx_putint64,
91 #endif /* AFS_XDR_64BITOPS */
92     .x_getint32 = xdrrx_getint32,       /* deserialize an afs_int32 */
93     .x_putint32 = xdrrx_putint32,       /* serialize an afs_int32 */
94     .x_getbytes = xdrrx_getbytes,       /* deserialize counted bytes */
95     .x_putbytes = xdrrx_putbytes,       /* serialize counted bytes */
96     .x_getpostn = NULL,         /* get offset in the stream: not supported. */
97     .x_setpostn = NULL,         /* set offset in the stream: not supported. */
98     .x_inline = xdrrx_inline,           /* prime stream for inline macros */
99     .x_destroy = NULL,                  /* destroy stream */
100 #if defined(KERNEL) && defined(AFS_SUN57_ENV)
101     .x_control = NULL,
102 #endif
103 #endif
104 };
105
106 /*
107  * Initialize an rx xdr handle, for a given rx call.  op must be XDR_ENCODE or XDR_DECODE.
108  * Call must have been returned by rx_MakeCall or rx_GetCall.
109  */
110 void
111 xdrrx_create(XDR * xdrs, struct rx_call *call,
112              enum xdr_op op)
113 {
114     xdrs->x_op = op;
115     xdrs->x_ops = &xdrrx_ops;
116     xdrs->x_private = (caddr_t) call;
117 }
118
119 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
120 #define STACK_TO_PIN    2*PAGESIZE      /* 8K */
121 int rx_pin_failed = 0;
122 #endif
123
124 #ifdef AFS_XDR_64BITOPS
125 static bool_t
126 xdrrx_getint64(XDR *axdrs, long *lp)
127 {
128     XDR * xdrs = (XDR *)axdrs;
129     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
130     afs_int32 i;
131
132     if (rx_Read32(call, &i) == sizeof(i)) {
133         *lp = ntohl(i);
134         return TRUE;
135     }
136     return FALSE;
137 }
138
139 static bool_t
140 xdrrx_putint64(XDR *axdrs, long *lp)
141 {
142     XDR * xdrs = (XDR *)axdrs;
143     afs_int32 code, i = htonl(*lp);
144     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
145
146     code = (rx_Write32(call, &i) == sizeof(i));
147     return code;
148 }
149 #endif /* AFS_XDR_64BITOPS */
150
151 static bool_t
152 xdrrx_getint32(XDR *axdrs, afs_int32 * lp)
153 {
154     afs_int32 l;
155     XDR * xdrs = (XDR *)axdrs;
156     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
157 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
158     char *saddr = (char *)&l;
159     saddr -= STACK_TO_PIN;
160     /*
161      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
162      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
163      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
164      * 2K stack we could try to bring the next few stack pages in here before we call the rx
165      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
166      * out between here and calling splnet. So we now pin (and unpin) them instead to
167      * guarantee that they remain there.
168      */
169     if (pin(saddr, STACK_TO_PIN)) {
170         /* XXX There's little we can do by continue XXX */
171         saddr = NULL;
172         rx_pin_failed++;
173     }
174 #endif
175     if (rx_Read32(call, &l) == sizeof(l)) {
176         *lp = ntohl(l);
177 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
178         if (saddr)
179             unpin(saddr, STACK_TO_PIN);
180 #endif
181         return TRUE;
182     }
183 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
184     if (saddr)
185         unpin(saddr, STACK_TO_PIN);
186 #endif
187     return FALSE;
188 }
189
190 static bool_t
191 xdrrx_putint32(XDR *axdrs, afs_int32 * lp)
192 {
193     afs_int32 code, l = htonl(*lp);
194     XDR * xdrs = (XDR *)axdrs;
195     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
196 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
197     char *saddr = (char *)&code;
198     saddr -= STACK_TO_PIN;
199     /*
200      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
201      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
202      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
203      * 2K stack we could try to bring the next few stack pages in here before we call the rx
204      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
205      * out between here and calling splnet. So we now pin (and unpin) them instead to
206      * guarantee that they remain there.
207      */
208     if (pin(saddr, STACK_TO_PIN)) {
209         saddr = NULL;
210         rx_pin_failed++;
211     }
212 #endif
213     code = (rx_Write32(call, &l) == sizeof(l));
214 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
215     if (saddr)
216         unpin(saddr, STACK_TO_PIN);
217 #endif
218     return code;
219 }
220
221 static bool_t
222 xdrrx_getbytes(XDR *axdrs, caddr_t addr, u_int len)
223 {
224     afs_int32 code;
225     XDR * xdrs = (XDR *)axdrs;
226     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
227 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
228     char *saddr = (char *)&code;
229     saddr -= STACK_TO_PIN;
230     /*
231      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
232      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
233      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
234      * 2K stack we could try to bring the next few stack pages in here before we call the rx
235      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
236      * out between here and calling splnet. So we now pin (and unpin) them instead to
237      * guarantee that they remain there.
238      */
239     if (pin(saddr, STACK_TO_PIN)) {
240         /* XXX There's little we can do by continue XXX */
241         saddr = NULL;
242         rx_pin_failed++;
243     }
244 #endif
245     code = (rx_Read(call, addr, len) == len);
246 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
247     if (saddr)
248         unpin(saddr, STACK_TO_PIN);
249 #endif
250     return code;
251 }
252
253 static bool_t
254 xdrrx_putbytes(XDR *axdrs, caddr_t addr, u_int len)
255 {
256     afs_int32 code;
257     XDR * xdrs = (XDR *)axdrs;
258     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
259 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
260     char *saddr = (char *)&code;
261     saddr -= STACK_TO_PIN;
262     /*
263      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under
264      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
265      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
266      * 2K stack we could try to bring the next few stack pages in here before we call the rx
267      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
268      * out between here and calling splnet. So we now pin (and unpin) them instead to
269      * guarantee that they remain there.
270      */
271     if (pin(saddr, STACK_TO_PIN)) {
272         /* XXX There's little we can do by continue XXX */
273         saddr = NULL;
274         rx_pin_failed++;
275     }
276 #endif
277     code = (rx_Write(call, addr, len) == len);
278 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
279     if (saddr)
280         unpin(saddr, STACK_TO_PIN);
281 #endif
282     return code;
283 }
284
285 #ifdef undef                    /* not used */
286 static u_int
287 xdrrx_getpos(XDR * xdrs)
288 {
289     /* Not supported.  What error code should we return? (It doesn't matter:  it will never be called, anyway!) */
290     return -1;
291 }
292
293 static bool_t
294 xdrrx_setpos(XDR * xdrs, u_int pos)
295 {
296     /* Not supported */
297     return FALSE;
298 }
299 #endif
300
301 static afs_int32 *
302 xdrrx_inline(XDR *axdrs, u_int len)
303 {
304     /* I don't know what this routine is supposed to do, but the stdio module returns null, so we will, too */
305     return (0);
306 }