svc_simple.c revision 1.2
1/*	$OpenBSD: svc_simple.c,v 1.2 1996/07/20 06:12:44 deraadt Exp $	*/
2/*	$NetBSD: svc_simple.c,v 1.4 1995/04/14 19:48:28 jtc Exp $	*/
3
4/*
5 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
6 * unrestricted use provided that this legend is included on all tape
7 * media and as a part of the software program in whole or part.  Users
8 * may copy or modify Sun RPC without charge, but are not authorized
9 * to license or distribute it to anyone else except as part of a product or
10 * program developed by the user.
11 *
12 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
13 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
14 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
15 *
16 * Sun RPC is provided with no support and without any obligation on the
17 * part of Sun Microsystems, Inc. to assist in its use, correction,
18 * modification or enhancement.
19 *
20 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
21 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
22 * OR ANY PART THEREOF.
23 *
24 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
25 * or profits or other special, indirect and consequential damages, even if
26 * Sun has been advised of the possibility of such damages.
27 *
28 * Sun Microsystems, Inc.
29 * 2550 Garcia Avenue
30 * Mountain View, California  94043
31 */
32
33#if defined(LIBC_SCCS) && !defined(lint)
34/*static char *sccsid = "from: @(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";*/
35/*static char *sccsid = "from: @(#)svc_simple.c	2.2 88/08/01 4.0 RPCSRC";*/
36static char *rcsid = "$OpenBSD: svc_simple.c,v 1.2 1996/07/20 06:12:44 deraadt Exp $";
37#endif
38
39/*
40 * svc_simple.c
41 * Simplified front end to rpc.
42 *
43 * Copyright (C) 1984, Sun Microsystems, Inc.
44 */
45
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <rpc/rpc.h>
50#include <sys/socket.h>
51#include <netdb.h>
52
53static struct proglst {
54	char *(*p_progname)();
55	int  p_prognum;
56	int  p_procnum;
57	xdrproc_t p_inproc, p_outproc;
58	struct proglst *p_nxt;
59} *proglst;
60static void universal();
61static SVCXPRT *transp;
62struct proglst *pl;
63
64registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
65	char *(*progname)();
66	xdrproc_t inproc, outproc;
67{
68
69	if (procnum == NULLPROC) {
70		(void) fprintf(stderr,
71		    "can't reassign procedure number %d\n", NULLPROC);
72		return (-1);
73	}
74	if (transp == 0) {
75		transp = svcudp_create(RPC_ANYSOCK);
76		if (transp == NULL) {
77			(void) fprintf(stderr, "couldn't create an rpc server\n");
78			return (-1);
79		}
80	}
81	(void) pmap_unset((u_long)prognum, (u_long)versnum);
82	if (!svc_register(transp, (u_long)prognum, (u_long)versnum,
83	    universal, IPPROTO_UDP)) {
84	    	(void) fprintf(stderr, "couldn't register prog %d vers %d\n",
85		    prognum, versnum);
86		return (-1);
87	}
88	pl = (struct proglst *)malloc(sizeof(struct proglst));
89	if (pl == NULL) {
90		(void) fprintf(stderr, "registerrpc: out of memory\n");
91		return (-1);
92	}
93	pl->p_progname = progname;
94	pl->p_prognum = prognum;
95	pl->p_procnum = procnum;
96	pl->p_inproc = inproc;
97	pl->p_outproc = outproc;
98	pl->p_nxt = proglst;
99	proglst = pl;
100	return (0);
101}
102
103static void
104universal(rqstp, transp)
105	struct svc_req *rqstp;
106	SVCXPRT *transp;
107{
108	int prog, proc;
109	char *outdata;
110	char xdrbuf[UDPMSGSIZE];
111	struct proglst *pl;
112
113	/*
114	 * enforce "procnum 0 is echo" convention
115	 */
116	if (rqstp->rq_proc == NULLPROC) {
117		if (svc_sendreply(transp, xdr_void, NULL) == FALSE) {
118			(void) fprintf(stderr, "xxx\n");
119			exit(1);
120		}
121		return;
122	}
123	prog = rqstp->rq_prog;
124	proc = rqstp->rq_proc;
125	for (pl = proglst; pl != NULL; pl = pl->p_nxt)
126		if (pl->p_prognum == prog && pl->p_procnum == proc) {
127			/* decode arguments into a CLEAN buffer */
128			memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */
129			if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) {
130				svcerr_decode(transp);
131				return;
132			}
133			outdata = (*(pl->p_progname))(xdrbuf);
134			if (outdata == NULL &&
135			    pl->p_outproc != xdr_void)
136				/* there was an error */
137				return;
138			if (!svc_sendreply(transp, pl->p_outproc, outdata)) {
139				(void) fprintf(stderr,
140				    "trouble replying to prog %d\n",
141				    pl->p_prognum);
142				exit(1);
143			}
144			/* free the decoded arguments */
145			(void)svc_freeargs(transp, pl->p_inproc, xdrbuf);
146			return;
147		}
148	(void) fprintf(stderr, "never registered prog %d\n", prog);
149	exit(1);
150}
151
152