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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [librpc/] [src/] [rpc/] [svc.c] - Blame information for rev 587

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3
 * unrestricted use provided that this legend is included on all tape
4
 * media and as a part of the software program in whole or part.  Users
5
 * may copy or modify Sun RPC without charge, but are not authorized
6
 * to license or distribute it to anyone else except as part of a product or
7
 * program developed by the user.
8
 *
9
 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10
 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11
 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12
 *
13
 * Sun RPC is provided with no support and without any obligation on the
14
 * part of Sun Microsystems, Inc. to assist in its use, correction,
15
 * modification or enhancement.
16
 *
17
 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18
 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19
 * OR ANY PART THEREOF.
20
 *
21
 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22
 * or profits or other special, indirect and consequential damages, even if
23
 * Sun has been advised of the possibility of such damages.
24
 *
25
 * Sun Microsystems, Inc.
26
 * 2550 Garcia Avenue
27
 * Mountain View, California  94043
28
 */
29
 
30
#if defined(LIBC_SCCS) && !defined(lint)
31
/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/
32
/*static char *sccsid = "from: @(#)svc.c        2.4 88/08/11 4.0 RPCSRC";*/
33
static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc.c,v 1.14 1999/08/28 00:00:48 peter Exp $";
34
#endif
35
 
36
/*
37
 * svc.c, Server-side remote procedure call interface.
38
 *
39
 * There are two sets of procedures here.  The xprt routines are
40
 * for handling transport handles.  The svc routines handle the
41
 * list of service routines.
42
 *
43
 * Copyright (C) 1984, Sun Microsystems, Inc.
44
 */
45
 
46
#include <string.h>
47
#include <stdlib.h>
48
#include <sys/errno.h>
49
#include <rpc/rpc.h>
50
#include <rpc/pmap_clnt.h>
51
 
52
#define xports ((SVCXPRT **)((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_xports)
53
#define xportssize (((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_xportssize)
54
 
55
#define NULL_SVC ((struct svc_callout *)0)
56
#define RQCRED_SIZE     400             /* this size is excessive */
57
 
58
#define max(a, b) (a > b ? a : b)
59
 
60
/*
61
 * The services list
62
 * Each entry represents a set of procedures (an rpc program).
63
 * The dispatch routine takes request structs and runs the
64
 * apropriate procedure.
65
 */
66
struct svc_callout {
67
        struct svc_callout *sc_next;
68
        u_long              sc_prog;
69
        u_long              sc_vers;
70
        void                (*sc_dispatch)();
71
};
72
#define svc_head (struct svc_callout *)(((struct rtems_rpc_task_variables *)rtems_rpc_task_variables)->svc_svc_head)
73
 
74
static struct svc_callout *svc_find();
75
 
76
/* ***************  SVCXPRT related stuff **************** */
77
 
78
/*
79
 * Activate a transport handle.
80
 */
81
void
82
xprt_register(xprt)
83
        SVCXPRT *xprt;
84
{
85
        register int sock = xprt->xp_sock;
86
 
87
        if (sock + 1 > __svc_fdsetsize) {
88
                int bytes = sizeof (fd_set);
89
                fd_set *fds;
90
 
91
                fds = (fd_set *)malloc(bytes);
92
                memset(fds, 0, bytes);
93
                if (__svc_fdset) {
94
                        memcpy(fds, __svc_fdset, bytes);
95
                        free(__svc_fdset);
96
                }
97
                __svc_fdset = fds;
98
                __svc_fdsetsize = bytes * NBBY;
99
        }
100
 
101
        if (sock < FD_SETSIZE)
102
                FD_SET(sock, &svc_fdset);
103
        FD_SET(sock, __svc_fdset);
104
 
105
        if (xports == NULL || sock + 1 > xportssize) {
106
                SVCXPRT **xp;
107
                int size = FD_SETSIZE;
108
 
109
                if (sock + 1 > size)
110
                        size = sock + 1;
111
                xp = (SVCXPRT **)mem_alloc(size * sizeof(SVCXPRT *));
112
                memset(xp, 0, size * sizeof(SVCXPRT *));
113
                if (xports) {
114
                        memcpy(xp, xports, xportssize * sizeof(SVCXPRT *));
115
                        free(xports);
116
                }
117
                xportssize = size;
118
                xports = xp;
119
        }
120
        xports[sock] = xprt;
121
        svc_maxfd = max(svc_maxfd, sock);
122
}
123
 
124
/*
125
 * De-activate a transport handle.
126
 */
127
void
128
xprt_unregister(xprt)
129
        SVCXPRT *xprt;
130
{
131
        register int sock = xprt->xp_sock;
132
 
133
        if (xports[sock] == xprt) {
134
                xports[sock] = (SVCXPRT *)0;
135
                if (sock < FD_SETSIZE)
136
                        FD_CLR(sock, &svc_fdset);
137
                FD_CLR(sock, __svc_fdset);
138
                if (sock == svc_maxfd) {
139
                        for (svc_maxfd--; svc_maxfd >= 0; svc_maxfd--)
140
                                if (xports[svc_maxfd])
141
                                        break;
142
                }
143
                /*
144
                 * XXX could use svc_maxfd as a hint to
145
                 * decrease the size of __svc_fdset
146
                 */
147
        }
148
}
149
 
150
 
151
/* ********************** CALLOUT list related stuff ************* */
152
 
153
/*
154
 * Add a service program to the callout list.
155
 * The dispatch routine will be called when a rpc request for this
156
 * program number comes in.
157
 */
158
bool_t
159
svc_register(xprt, prog, vers, dispatch, protocol)
160
        SVCXPRT *xprt;
161
        u_long prog;
162
        u_long vers;
163
        void (*dispatch)();
164
        int protocol;
165
{
166
        struct svc_callout *prev;
167
        register struct svc_callout *s;
168
 
169
        if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) {
170
                if (s->sc_dispatch == dispatch)
171
                        goto pmap_it;  /* he is registering another xptr */
172
                return (FALSE);
173
        }
174
        s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout));
175
        if (s == (struct svc_callout *)0) {
176
                return (FALSE);
177
        }
178
        s->sc_prog = prog;
179
        s->sc_vers = vers;
180
        s->sc_dispatch = dispatch;
181
        s->sc_next = svc_head;
182
        svc_head = s;
183
pmap_it:
184
        /* now register the information with the local binder service */
185
        if (protocol) {
186
                return (pmap_set(prog, vers, protocol, xprt->xp_port));
187
        }
188
        return (TRUE);
189
}
190
 
191
/*
192
 * Remove a service program from the callout list.
193
 */
194
void
195
svc_unregister(prog, vers)
196
        u_long prog;
197
        u_long vers;
198
{
199
        struct svc_callout *prev;
200
        register struct svc_callout *s;
201
 
202
        if ((s = svc_find(prog, vers, &prev)) == NULL_SVC)
203
                return;
204
        if (prev == NULL_SVC) {
205
                svc_head = s->sc_next;
206
        } else {
207
                prev->sc_next = s->sc_next;
208
        }
209
        s->sc_next = NULL_SVC;
210
        mem_free((char *) s, (u_int) sizeof(struct svc_callout));
211
        /* now unregister the information with the local binder service */
212
        (void)pmap_unset(prog, vers);
213
}
214
 
215
/*
216
 * Search the callout list for a program number, return the callout
217
 * struct.
218
 */
219
static struct svc_callout *
220
svc_find(prog, vers, prev)
221
        u_long prog;
222
        u_long vers;
223
        struct svc_callout **prev;
224
{
225
        register struct svc_callout *s, *p;
226
 
227
        p = NULL_SVC;
228
        for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
229
                if ((s->sc_prog == prog) && (s->sc_vers == vers))
230
                        goto done;
231
                p = s;
232
        }
233
done:
234
        *prev = p;
235
        return (s);
236
}
237
 
238
/* ******************* REPLY GENERATION ROUTINES  ************ */
239
 
240
/*
241
 * Send a reply to an rpc request
242
 */
243
bool_t
244
svc_sendreply(xprt, xdr_results, xdr_location)
245
        register SVCXPRT *xprt;
246
        xdrproc_t xdr_results;
247
        caddr_t xdr_location;
248
{
249
        struct rpc_msg rply;
250
 
251
        rply.rm_direction = REPLY;
252
        rply.rm_reply.rp_stat = MSG_ACCEPTED;
253
        rply.acpted_rply.ar_verf = xprt->xp_verf;
254
        rply.acpted_rply.ar_stat = SUCCESS;
255
        rply.acpted_rply.ar_results.where = xdr_location;
256
        rply.acpted_rply.ar_results.proc = xdr_results;
257
        return (SVC_REPLY(xprt, &rply));
258
}
259
 
260
/*
261
 * No procedure error reply
262
 */
263
void
264
svcerr_noproc(xprt)
265
        register SVCXPRT *xprt;
266
{
267
        struct rpc_msg rply;
268
 
269
        rply.rm_direction = REPLY;
270
        rply.rm_reply.rp_stat = MSG_ACCEPTED;
271
        rply.acpted_rply.ar_verf = xprt->xp_verf;
272
        rply.acpted_rply.ar_stat = PROC_UNAVAIL;
273
        SVC_REPLY(xprt, &rply);
274
}
275
 
276
/*
277
 * Can't decode args error reply
278
 */
279
void
280
svcerr_decode(xprt)
281
        register SVCXPRT *xprt;
282
{
283
        struct rpc_msg rply;
284
 
285
        rply.rm_direction = REPLY;
286
        rply.rm_reply.rp_stat = MSG_ACCEPTED;
287
        rply.acpted_rply.ar_verf = xprt->xp_verf;
288
        rply.acpted_rply.ar_stat = GARBAGE_ARGS;
289
        SVC_REPLY(xprt, &rply);
290
}
291
 
292
/*
293
 * Some system error
294
 */
295
void
296
svcerr_systemerr(xprt)
297
        register SVCXPRT *xprt;
298
{
299
        struct rpc_msg rply;
300
 
301
        rply.rm_direction = REPLY;
302
        rply.rm_reply.rp_stat = MSG_ACCEPTED;
303
        rply.acpted_rply.ar_verf = xprt->xp_verf;
304
        rply.acpted_rply.ar_stat = SYSTEM_ERR;
305
        SVC_REPLY(xprt, &rply);
306
}
307
 
308
/*
309
 * Authentication error reply
310
 */
311
void
312
svcerr_auth(xprt, why)
313
        SVCXPRT *xprt;
314
        enum auth_stat why;
315
{
316
        struct rpc_msg rply;
317
 
318
        rply.rm_direction = REPLY;
319
        rply.rm_reply.rp_stat = MSG_DENIED;
320
        rply.rjcted_rply.rj_stat = AUTH_ERROR;
321
        rply.rjcted_rply.rj_why = why;
322
        SVC_REPLY(xprt, &rply);
323
}
324
 
325
/*
326
 * Auth too weak error reply
327
 */
328
void
329
svcerr_weakauth(xprt)
330
        SVCXPRT *xprt;
331
{
332
 
333
        svcerr_auth(xprt, AUTH_TOOWEAK);
334
}
335
 
336
/*
337
 * Program unavailable error reply
338
 */
339
void
340
svcerr_noprog(xprt)
341
        register SVCXPRT *xprt;
342
{
343
        struct rpc_msg rply;
344
 
345
        rply.rm_direction = REPLY;
346
        rply.rm_reply.rp_stat = MSG_ACCEPTED;
347
        rply.acpted_rply.ar_verf = xprt->xp_verf;
348
        rply.acpted_rply.ar_stat = PROG_UNAVAIL;
349
        SVC_REPLY(xprt, &rply);
350
}
351
 
352
/*
353
 * Program version mismatch error reply
354
 */
355
void
356
svcerr_progvers(xprt, low_vers, high_vers)
357
        register SVCXPRT *xprt;
358
        u_long low_vers;
359
        u_long high_vers;
360
{
361
        struct rpc_msg rply;
362
 
363
        rply.rm_direction = REPLY;
364
        rply.rm_reply.rp_stat = MSG_ACCEPTED;
365
        rply.acpted_rply.ar_verf = xprt->xp_verf;
366
        rply.acpted_rply.ar_stat = PROG_MISMATCH;
367
        rply.acpted_rply.ar_vers.low = low_vers;
368
        rply.acpted_rply.ar_vers.high = high_vers;
369
        SVC_REPLY(xprt, &rply);
370
}
371
 
372
/* ******************* SERVER INPUT STUFF ******************* */
373
 
374
/*
375
 * Get server side input from some transport.
376
 *
377
 * Statement of authentication parameters management:
378
 * This function owns and manages all authentication parameters, specifically
379
 * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
380
 * the "cooked" credentials (rqst->rq_clntcred).
381
 * However, this function does not know the structure of the cooked
382
 * credentials, so it make the following assumptions:
383
 *   a) the structure is contiguous (no pointers), and
384
 *   b) the cred structure size does not exceed RQCRED_SIZE bytes.
385
 * In all events, all three parameters are freed upon exit from this routine.
386
 * The storage is trivially management on the call stack in user land, but
387
 * is mallocated in kernel land.
388
 */
389
 
390
void
391
svc_getreq(rdfds)
392
        int rdfds;
393
{
394
        fd_set readfds;
395
 
396
        FD_ZERO(&readfds);
397
        readfds.fds_bits[0] = rdfds;
398
        svc_getreqset(&readfds);
399
}
400
 
401
void
402
svc_getreqset(readfds)
403
        fd_set *readfds;
404
{
405
        svc_getreqset2(readfds, FD_SETSIZE);
406
}
407
 
408
void
409
svc_getreqset2(readfds, width)
410
        fd_set *readfds;
411
        int width;
412
{
413
        enum xprt_stat stat;
414
        struct rpc_msg msg;
415
        int prog_found;
416
        u_long low_vers;
417
        u_long high_vers;
418
        struct svc_req r;
419
        register SVCXPRT *xprt;
420
        register int bit;
421
        register int sock;
422
        register fd_mask mask, *maskp;
423
        char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
424
        msg.rm_call.cb_cred.oa_base = cred_area;
425
        msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
426
        r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
427
 
428
 
429
        maskp = readfds->fds_bits;
430
        for (sock = 0; sock < width; sock += NFDBITS) {
431
            for (mask = *maskp++; (bit = ffs(mask)); mask ^= (1 << (bit - 1))) {
432
                /* sock has input waiting */
433
                xprt = xports[sock + bit - 1];
434
                if (xprt == NULL)
435
                        /* But do we control sock? */
436
                        continue;
437
                /* now receive msgs from xprtprt (support batch calls) */
438
                do {
439
                        if (SVC_RECV(xprt, &msg)) {
440
 
441
                                /* now find the exported program and call it */
442
                                register struct svc_callout *s;
443
                                enum auth_stat why;
444
 
445
                                r.rq_xprt = xprt;
446
                                r.rq_prog = msg.rm_call.cb_prog;
447
                                r.rq_vers = msg.rm_call.cb_vers;
448
                                r.rq_proc = msg.rm_call.cb_proc;
449
                                r.rq_cred = msg.rm_call.cb_cred;
450
                                /* first authenticate the message */
451
                                if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
452
                                        svcerr_auth(xprt, why);
453
                                        goto call_done;
454
                                }
455
                                /* now match message with a registered service*/
456
                                prog_found = FALSE;
457
                                low_vers = (u_long) - 1;
458
                                high_vers = 0;
459
                                for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
460
                                        if (s->sc_prog == r.rq_prog) {
461
                                                if (s->sc_vers == r.rq_vers) {
462
                                                        (*s->sc_dispatch)(&r, xprt);
463
                                                        goto call_done;
464
                                                }  /* found correct version */
465
                                                prog_found = TRUE;
466
                                                if (s->sc_vers < low_vers)
467
                                                        low_vers = s->sc_vers;
468
                                                if (s->sc_vers > high_vers)
469
                                                        high_vers = s->sc_vers;
470
                                        }   /* found correct program */
471
                                }
472
                                /*
473
                                 * if we got here, the program or version
474
                                 * is not served ...
475
                                 */
476
                                if (prog_found)
477
                                        svcerr_progvers(xprt,
478
                                        low_vers, high_vers);
479
                                else
480
                                         svcerr_noprog(xprt);
481
                                /* Fall through to ... */
482
                        }
483
                call_done:
484
                        if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
485
                                SVC_DESTROY(xprt);
486
                                break;
487
                        }
488
                } while (stat == XPRT_MOREREQS);
489
            }
490
        }
491
}

powered by: WebSVN 2.1.0

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