diff options
Diffstat (limited to 'sunrpc/svc.c')
-rw-r--r-- | sunrpc/svc.c | 527 |
1 files changed, 273 insertions, 254 deletions
diff --git a/sunrpc/svc.c b/sunrpc/svc.c index fcd7b36..93d8bbd 100644 --- a/sunrpc/svc.c +++ b/sunrpc/svc.c @@ -41,8 +41,9 @@ static char sccsid[] = "@(#)svc.c 1.41 87/10/13 Copyr 1984 Sun Micro"; * Copyright (C) 1984, Sun Microsystems, Inc. */ -#include <sys/errno.h> +#include <errno.h> #include <rpc/rpc.h> +#include <rpc/svc.h> #include <rpc/pmap_clnt.h> #ifndef errno @@ -58,7 +59,7 @@ static SVCXPRT *xports[NOFILE]; #endif /* def FD_SETSIZE */ #define NULL_SVC ((struct svc_callout *)0) -#define RQCRED_SIZE 400 /* this size is excessive */ +#define RQCRED_SIZE 400 /* this size is excessive */ /* * The services list @@ -66,14 +67,16 @@ static SVCXPRT *xports[NOFILE]; * The dispatch routine takes request structs and runs the * appropriate procedure. */ -static struct svc_callout { - struct svc_callout *sc_next; - u_long sc_prog; - u_long sc_vers; - void (*sc_dispatch)(); -} *svc_head; +static struct svc_callout + { + struct svc_callout *sc_next; + u_long sc_prog; + u_long sc_vers; + void (*sc_dispatch) (struct svc_req *, SVCXPRT *); + } + *svc_head; -static struct svc_callout *svc_find(); +static struct svc_callout *svc_find (u_long, u_long, struct svc_callout **); /* *************** SVCXPRT related stuff **************** */ @@ -81,25 +84,27 @@ static struct svc_callout *svc_find(); * Activate a transport handle. */ void -xprt_register(xprt) - SVCXPRT *xprt; +xprt_register (SVCXPRT *xprt) { - register int sock = xprt->xp_sock; + register int sock = xprt->xp_sock; #ifdef FD_SETSIZE - if (xports == NULL) { - xports = (SVCXPRT **) - mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); - } - if (sock < _rpc_dtablesize()) { - xports[sock] = xprt; - FD_SET(sock, &svc_fdset); - } + if (xports == NULL) + { + xports = (SVCXPRT **) + mem_alloc (FD_SETSIZE * sizeof (SVCXPRT *)); + } + if (sock < _rpc_dtablesize ()) + { + xports[sock] = xprt; + FD_SET (sock, &svc_fdset); + } #else - if (sock < NOFILE) { - xports[sock] = xprt; - svc_fds |= (1 << sock); - } + if (sock < NOFILE) + { + xports[sock] = xprt; + svc_fds |= (1 << sock); + } #endif /* def FD_SETSIZE */ } @@ -108,21 +113,23 @@ xprt_register(xprt) * De-activate a transport handle. */ void -xprt_unregister(xprt) - SVCXPRT *xprt; +xprt_unregister (xprt) + SVCXPRT *xprt; { - register int sock = xprt->xp_sock; + register int sock = xprt->xp_sock; #ifdef FD_SETSIZE - if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) { - xports[sock] = (SVCXPRT *)0; - FD_CLR(sock, &svc_fdset); - } + if ((sock < _rpc_dtablesize ()) && (xports[sock] == xprt)) + { + xports[sock] = (SVCXPRT *) 0; + FD_CLR (sock, &svc_fdset); + } #else - if ((sock < NOFILE) && (xports[sock] == xprt)) { - xports[sock] = (SVCXPRT *)0; - svc_fds &= ~(1 << sock); - } + if ((sock < NOFILE) && (xports[sock] == xprt)) + { + xports[sock] = (SVCXPRT *) 0; + svc_fds &= ~(1 << sock); + } #endif /* def FD_SETSIZE */ } @@ -135,60 +142,62 @@ xprt_unregister(xprt) * program number comes in. */ bool_t -svc_register(xprt, prog, vers, dispatch, protocol) - SVCXPRT *xprt; - u_long prog; - u_long vers; - void (*dispatch)(); - int protocol; +svc_register (SVCXPRT *xprt, u_long prog, u_long vers, + void (*dispatch) (struct svc_req *, SVCXPRT *), u_long protocol) { - struct svc_callout *prev; - register struct svc_callout *s; - - if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) { - if (s->sc_dispatch == dispatch) - goto pmap_it; /* he is registering another xptr */ - return (FALSE); - } - s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout)); - if (s == (struct svc_callout *)0) { - return (FALSE); - } - s->sc_prog = prog; - s->sc_vers = vers; - s->sc_dispatch = dispatch; - s->sc_next = svc_head; - svc_head = s; + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find (prog, vers, &prev)) != NULL_SVC) + { + if (s->sc_dispatch == dispatch) + goto pmap_it; /* he is registering another xptr */ + return FALSE; + } + s = (struct svc_callout *) mem_alloc (sizeof (struct svc_callout)); + if (s == (struct svc_callout *) 0) + { + return FALSE; + } + s->sc_prog = prog; + s->sc_vers = vers; + s->sc_dispatch = dispatch; + s->sc_next = svc_head; + svc_head = s; pmap_it: - /* now register the information with the local binder service */ - if (protocol) { - return (pmap_set(prog, vers, protocol, xprt->xp_port)); - } - return (TRUE); + /* now register the information with the local binder service */ + if (protocol) + { + return pmap_set (prog, vers, protocol, xprt->xp_port); + } + return TRUE; } /* * Remove a service program from the callout list. */ void -svc_unregister(prog, vers) - u_long prog; - u_long vers; +svc_unregister (prog, vers) + u_long prog; + u_long vers; { - struct svc_callout *prev; - register struct svc_callout *s; - - if ((s = svc_find(prog, vers, &prev)) == NULL_SVC) - return; - if (prev == NULL_SVC) { - svc_head = s->sc_next; - } else { - prev->sc_next = s->sc_next; - } - s->sc_next = NULL_SVC; - mem_free((char *) s, (u_int) sizeof(struct svc_callout)); - /* now unregister the information with the local binder service */ - (void)pmap_unset(prog, vers); + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find (prog, vers, &prev)) == NULL_SVC) + return; + if (prev == NULL_SVC) + { + svc_head = s->sc_next; + } + else + { + prev->sc_next = s->sc_next; + } + s->sc_next = NULL_SVC; + mem_free ((char *) s, (u_int) sizeof (struct svc_callout)); + /* now unregister the information with the local binder service */ + (void) pmap_unset (prog, vers); } /* @@ -196,22 +205,20 @@ svc_unregister(prog, vers) * struct. */ static struct svc_callout * -svc_find(prog, vers, prev) - u_long prog; - u_long vers; - struct svc_callout **prev; +svc_find (u_long prog, u_long vers, struct svc_callout **prev) { - register struct svc_callout *s, *p; - - p = NULL_SVC; - for (s = svc_head; s != NULL_SVC; s = s->sc_next) { - if ((s->sc_prog == prog) && (s->sc_vers == vers)) - goto done; - p = s; - } + register struct svc_callout *s, *p; + + p = NULL_SVC; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) + { + if ((s->sc_prog == prog) && (s->sc_vers == vers)) + goto done; + p = s; + } done: - *prev = p; - return (s); + *prev = p; + return s; } /* ******************* REPLY GENERATION ROUTINES ************ */ @@ -220,132 +227,132 @@ done: * Send a reply to an rpc request */ bool_t -svc_sendreply(xprt, xdr_results, xdr_location) - register SVCXPRT *xprt; - xdrproc_t xdr_results; - caddr_t xdr_location; +svc_sendreply (xprt, xdr_results, xdr_location) + register SVCXPRT *xprt; + xdrproc_t xdr_results; + caddr_t xdr_location; { - struct rpc_msg rply; - - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = SUCCESS; - rply.acpted_rply.ar_results.where = xdr_location; - rply.acpted_rply.ar_results.proc = xdr_results; - return (SVC_REPLY(xprt, &rply)); + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SUCCESS; + rply.acpted_rply.ar_results.where = xdr_location; + rply.acpted_rply.ar_results.proc = xdr_results; + return SVC_REPLY (xprt, &rply); } /* * No procedure error reply */ void -svcerr_noproc(xprt) - register SVCXPRT *xprt; +svcerr_noproc (xprt) + register SVCXPRT *xprt; { - struct rpc_msg rply; + struct rpc_msg rply; - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = PROC_UNAVAIL; - SVC_REPLY(xprt, &rply); + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROC_UNAVAIL; + SVC_REPLY (xprt, &rply); } /* * Can't decode args error reply */ void -svcerr_decode(xprt) - register SVCXPRT *xprt; +svcerr_decode (xprt) + register SVCXPRT *xprt; { - struct rpc_msg rply; + struct rpc_msg rply; - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = GARBAGE_ARGS; - SVC_REPLY(xprt, &rply); + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = GARBAGE_ARGS; + SVC_REPLY (xprt, &rply); } /* * Some system error */ void -svcerr_systemerr(xprt) - register SVCXPRT *xprt; +svcerr_systemerr (xprt) + register SVCXPRT *xprt; { - struct rpc_msg rply; + struct rpc_msg rply; - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = SYSTEM_ERR; - SVC_REPLY(xprt, &rply); + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SYSTEM_ERR; + SVC_REPLY (xprt, &rply); } /* * Authentication error reply */ void -svcerr_auth(xprt, why) - SVCXPRT *xprt; - enum auth_stat why; +svcerr_auth (xprt, why) + SVCXPRT *xprt; + enum auth_stat why; { - struct rpc_msg rply; + struct rpc_msg rply; - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_DENIED; - rply.rjcted_rply.rj_stat = AUTH_ERROR; - rply.rjcted_rply.rj_why = why; - SVC_REPLY(xprt, &rply); + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_DENIED; + rply.rjcted_rply.rj_stat = AUTH_ERROR; + rply.rjcted_rply.rj_why = why; + SVC_REPLY (xprt, &rply); } /* * Auth too weak error reply */ void -svcerr_weakauth(xprt) - SVCXPRT *xprt; +svcerr_weakauth (xprt) + SVCXPRT *xprt; { - svcerr_auth(xprt, AUTH_TOOWEAK); + svcerr_auth (xprt, AUTH_TOOWEAK); } /* * Program unavailable error reply */ void -svcerr_noprog(xprt) - register SVCXPRT *xprt; +svcerr_noprog (xprt) + register SVCXPRT *xprt; { - struct rpc_msg rply; + struct rpc_msg rply; - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = PROG_UNAVAIL; - SVC_REPLY(xprt, &rply); + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_UNAVAIL; + SVC_REPLY (xprt, &rply); } /* * Program version mismatch error reply */ void -svcerr_progvers(xprt, low_vers, high_vers) - register SVCXPRT *xprt; - u_long low_vers; - u_long high_vers; +svcerr_progvers (xprt, low_vers, high_vers) + register SVCXPRT *xprt; + u_long low_vers; + u_long high_vers; { - struct rpc_msg rply; - - rply.rm_direction = REPLY; - rply.rm_reply.rp_stat = MSG_ACCEPTED; - rply.acpted_rply.ar_verf = xprt->xp_verf; - rply.acpted_rply.ar_stat = PROG_MISMATCH; - rply.acpted_rply.ar_vers.low = low_vers; - rply.acpted_rply.ar_vers.high = high_vers; - SVC_REPLY(xprt, &rply); + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_MISMATCH; + rply.acpted_rply.ar_vers.low = low_vers; + rply.acpted_rply.ar_vers.high = high_vers; + SVC_REPLY (xprt, &rply); } /* ******************* SERVER INPUT STUFF ******************* */ @@ -367,115 +374,127 @@ svcerr_progvers(xprt, low_vers, high_vers) */ void -svc_getreq(rdfds) - int rdfds; +svc_getreq (rdfds) + int rdfds; { #ifdef FD_SETSIZE - fd_set readfds; + fd_set readfds; - FD_ZERO(&readfds); - readfds.fds_bits[0] = rdfds; - svc_getreqset(&readfds); + FD_ZERO (&readfds); + readfds.fds_bits[0] = rdfds; + svc_getreqset (&readfds); #else - int readfds = rdfds & svc_fds; + int readfds = rdfds & svc_fds; - svc_getreqset(&readfds); + svc_getreqset (&readfds); #endif /* def FD_SETSIZE */ } void -svc_getreqset(readfds) +svc_getreqset (readfds) #ifdef FD_SETSIZE - fd_set *readfds; + fd_set *readfds; { #else - int *readfds; + int *readfds; { - int readfds_local = *readfds; + int readfds_local = *readfds; #endif /* def FD_SETSIZE */ - enum xprt_stat stat; - struct rpc_msg msg; - int prog_found; - u_long low_vers; - u_long high_vers; - struct svc_req r; - register SVCXPRT *xprt; - register u_long mask; - register int bit; - register u_int32_t *maskp; - register int setsize; - register int sock; - char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE]; - msg.rm_call.cb_cred.oa_base = cred_area; - msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); - r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]); + enum xprt_stat stat; + struct rpc_msg msg; + int prog_found; + u_long low_vers; + u_long high_vers; + struct svc_req r; + register SVCXPRT *xprt; + register u_long mask; + register int bit; + register u_int32_t *maskp; + register int setsize; + register int sock; + char cred_area[2 * MAX_AUTH_BYTES + RQCRED_SIZE]; + msg.rm_call.cb_cred.oa_base = cred_area; + msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); + r.rq_clntcred = &(cred_area[2 * MAX_AUTH_BYTES]); #ifdef FD_SETSIZE - setsize = _rpc_dtablesize(); - maskp = (u_int32_t *)readfds->fds_bits; - for (sock = 0; sock < setsize; sock += 32) { - for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) { - /* sock has input waiting */ - xprt = xports[sock + bit - 1]; + setsize = _rpc_dtablesize (); + maskp = (u_int32_t *) readfds->fds_bits; + for (sock = 0; sock < setsize; sock += 32) + { + for (mask = *maskp++; bit = ffs (mask); mask ^= (1 << (bit - 1))) + { + /* sock has input waiting */ + xprt = xports[sock + bit - 1]; #else - for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) { - if ((readfds_local & 1) != 0) { - /* sock has input waiting */ - xprt = xports[sock]; + for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) + { + if ((readfds_local & 1) != 0) + { + /* sock has input waiting */ + xprt = xports[sock]; #endif /* def FD_SETSIZE */ - /* now receive msgs from xprtprt (support batch calls) */ - do { - if (SVC_RECV(xprt, &msg)) { - - /* now find the exported program and call it */ - register struct svc_callout *s; - enum auth_stat why; - - r.rq_xprt = xprt; - r.rq_prog = msg.rm_call.cb_prog; - r.rq_vers = msg.rm_call.cb_vers; - r.rq_proc = msg.rm_call.cb_proc; - r.rq_cred = msg.rm_call.cb_cred; - /* first authenticate the message */ - if ((why= _authenticate(&r, &msg)) != AUTH_OK) { - svcerr_auth(xprt, why); - goto call_done; - } - /* now match message with a registered service*/ - prog_found = FALSE; - low_vers = 0 - 1; - high_vers = 0; - for (s = svc_head; s != NULL_SVC; s = s->sc_next) { - if (s->sc_prog == r.rq_prog) { - if (s->sc_vers == r.rq_vers) { - (*s->sc_dispatch)(&r, xprt); - goto call_done; - } /* found correct version */ - prog_found = TRUE; - if (s->sc_vers < low_vers) - low_vers = s->sc_vers; - if (s->sc_vers > high_vers) - high_vers = s->sc_vers; - } /* found correct program */ - } - /* - * if we got here, the program or version - * is not served ... - */ - if (prog_found) - svcerr_progvers(xprt, - low_vers, high_vers); - else - svcerr_noprog(xprt); - /* Fall through to ... */ - } - call_done: - if ((stat = SVC_STAT(xprt)) == XPRT_DIED){ - SVC_DESTROY(xprt); - break; - } - } while (stat == XPRT_MOREREQS); + /* now receive msgs from xprtprt (support batch calls) */ + do + { + if (SVC_RECV (xprt, &msg)) + { + + /* now find the exported program and call it */ + register struct svc_callout *s; + enum auth_stat why; + + r.rq_xprt = xprt; + r.rq_prog = msg.rm_call.cb_prog; + r.rq_vers = msg.rm_call.cb_vers; + r.rq_proc = msg.rm_call.cb_proc; + r.rq_cred = msg.rm_call.cb_cred; + /* first authenticate the message */ + if ((why = _authenticate (&r, &msg)) != AUTH_OK) + { + svcerr_auth (xprt, why); + goto call_done; + } + /* now match message with a registered service */ + prog_found = FALSE; + low_vers = 0 - 1; + high_vers = 0; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) + { + if (s->sc_prog == r.rq_prog) + { + if (s->sc_vers == r.rq_vers) + { + (*s->sc_dispatch) (&r, xprt); + goto call_done; + } /* found correct version */ + prog_found = TRUE; + if (s->sc_vers < low_vers) + low_vers = s->sc_vers; + if (s->sc_vers > high_vers) + high_vers = s->sc_vers; + } /* found correct program */ + } + /* + * if we got here, the program or version + * is not served ... + */ + if (prog_found) + svcerr_progvers (xprt, + low_vers, high_vers); + else + svcerr_noprog (xprt); + /* Fall through to ... */ + } + call_done: + if ((stat = SVC_STAT (xprt)) == XPRT_DIED) + { + SVC_DESTROY (xprt); + break; + } } + while (stat == XPRT_MOREREQS); } + } } |