xref: /freebsd/usr.bin/rpcgen/rpc_clntout.c (revision e390e3af7c6aa20ef57a33a4895039ee4787509c)
14e115012SGarrett Wollman /*
24e115012SGarrett Wollman  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
34e115012SGarrett Wollman  * unrestricted use provided that this legend is included on all tape
44e115012SGarrett Wollman  * media and as a part of the software program in whole or part.  Users
54e115012SGarrett Wollman  * may copy or modify Sun RPC without charge, but are not authorized
64e115012SGarrett Wollman  * to license or distribute it to anyone else except as part of a product or
74e115012SGarrett Wollman  * program developed by the user.
84e115012SGarrett Wollman  *
94e115012SGarrett Wollman  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
104e115012SGarrett Wollman  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
114e115012SGarrett Wollman  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
124e115012SGarrett Wollman  *
134e115012SGarrett Wollman  * Sun RPC is provided with no support and without any obligation on the
144e115012SGarrett Wollman  * part of Sun Microsystems, Inc. to assist in its use, correction,
154e115012SGarrett Wollman  * modification or enhancement.
164e115012SGarrett Wollman  *
174e115012SGarrett Wollman  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
184e115012SGarrett Wollman  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
194e115012SGarrett Wollman  * OR ANY PART THEREOF.
204e115012SGarrett Wollman  *
214e115012SGarrett Wollman  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
224e115012SGarrett Wollman  * or profits or other special, indirect and consequential damages, even if
234e115012SGarrett Wollman  * Sun has been advised of the possibility of such damages.
244e115012SGarrett Wollman  *
254e115012SGarrett Wollman  * Sun Microsystems, Inc.
264e115012SGarrett Wollman  * 2550 Garcia Avenue
274e115012SGarrett Wollman  * Mountain View, California  94043
284e115012SGarrett Wollman  */
29ff49530fSBill Paul 
3040ad8885SAlfred Perlstein #if 0
3175863a6dSPhilippe Charnier #ifndef lint
3263f17371SStefan Farfeleder #ident	"@(#)rpc_clntout.c	1.15	94/04/25 SMI"
33ff49530fSBill Paul static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
344e115012SGarrett Wollman #endif
3540ad8885SAlfred Perlstein #endif
364e115012SGarrett Wollman 
3775863a6dSPhilippe Charnier #include <sys/cdefs.h>
3875863a6dSPhilippe Charnier __FBSDID("$FreeBSD$");
3975863a6dSPhilippe Charnier 
404e115012SGarrett Wollman /*
414e115012SGarrett Wollman  * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
424e115012SGarrett Wollman  * Copyright (C) 1987, Sun Microsytsems, Inc.
434e115012SGarrett Wollman  */
444e115012SGarrett Wollman #include <stdio.h>
45ff49530fSBill Paul #include <string.h>
46ff49530fSBill Paul #include <rpc/types.h>
474e115012SGarrett Wollman #include "rpc_parse.h"
48d0cc804bSStefan Farfeleder #include "rpc_scan.h"
494e115012SGarrett Wollman #include "rpc_util.h"
504e115012SGarrett Wollman 
51d3cb5dedSWarner Losh static void write_program( definition * );
52d3cb5dedSWarner Losh static void printbody( proc_list * );
534e115012SGarrett Wollman 
54ff49530fSBill Paul static char RESULT[] = "clnt_res";
55ff49530fSBill Paul 
56ff49530fSBill Paul 
57ff49530fSBill Paul #define DEFAULT_TIMEOUT 25	/* in seconds */
584e115012SGarrett Wollman 
594e115012SGarrett Wollman 
604e115012SGarrett Wollman void
61e390e3afSDavid Malone write_stubs(void)
624e115012SGarrett Wollman {
634e115012SGarrett Wollman 	list *l;
644e115012SGarrett Wollman 	definition *def;
654e115012SGarrett Wollman 
664e115012SGarrett Wollman 	f_print(fout,
674e115012SGarrett Wollman 		"\n/* Default timeout can be changed using clnt_control() */\n");
684e115012SGarrett Wollman 	f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
694e115012SGarrett Wollman 		DEFAULT_TIMEOUT);
704e115012SGarrett Wollman 	for (l = defined; l != NULL; l = l->next) {
714e115012SGarrett Wollman 		def = (definition *) l->val;
724e115012SGarrett Wollman 		if (def->def_kind == DEF_PROGRAM) {
734e115012SGarrett Wollman 			write_program(def);
744e115012SGarrett Wollman 		}
754e115012SGarrett Wollman 	}
764e115012SGarrett Wollman }
774e115012SGarrett Wollman 
78526195adSJordan K. Hubbard static void
79e390e3afSDavid Malone write_program(definition *def)
804e115012SGarrett Wollman {
814e115012SGarrett Wollman 	version_list *vp;
824e115012SGarrett Wollman 	proc_list *proc;
834e115012SGarrett Wollman 
844e115012SGarrett Wollman 	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
854e115012SGarrett Wollman 		for (proc = vp->procs; proc != NULL; proc = proc->next) {
864e115012SGarrett Wollman 			f_print(fout, "\n");
87ff49530fSBill Paul 			if (mtflag == 0) {
884e115012SGarrett Wollman 				ptype(proc->res_prefix, proc->res_type, 1);
894e115012SGarrett Wollman 				f_print(fout, "*\n");
904e115012SGarrett Wollman 				pvname(proc->proc_name, vp->vers_num);
91ff49530fSBill Paul 				printarglist(proc, RESULT, "clnt", "CLIENT *");
92ff49530fSBill Paul 			} else {
93ff49530fSBill Paul 				f_print(fout, "enum clnt_stat \n");
94ff49530fSBill Paul 				pvname(proc->proc_name, vp->vers_num);
95ff49530fSBill Paul 				printarglist(proc, RESULT,  "clnt", "CLIENT *");
96ff49530fSBill Paul 
97ff49530fSBill Paul 			}
984e115012SGarrett Wollman 			f_print(fout, "{\n");
994e115012SGarrett Wollman 			printbody(proc);
100ff49530fSBill Paul 
101ff49530fSBill Paul 			f_print(fout, "}\n");
1024e115012SGarrett Wollman 		}
1034e115012SGarrett Wollman 	}
1044e115012SGarrett Wollman }
1054e115012SGarrett Wollman 
106ff49530fSBill Paul /*
107ff49530fSBill Paul  * Writes out declarations of procedure's argument list.
108ff49530fSBill Paul  * In either ANSI C style, in one of old rpcgen style (pass by reference),
109ff49530fSBill Paul  * or new rpcgen style (multiple arguments, pass by value);
110ff49530fSBill Paul  */
111ff49530fSBill Paul 
112ff49530fSBill Paul /* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
113ff49530fSBill Paul 
114e390e3afSDavid Malone void
115e390e3afSDavid Malone printarglist(proc_list *proc, const char *result, const char *addargname,
116e390e3afSDavid Malone     const char *addargtype)
117ff49530fSBill Paul {
118ff49530fSBill Paul 
119ff49530fSBill Paul 	decl_list *l;
120ff49530fSBill Paul 
121ff49530fSBill Paul 	if (!newstyle) {
122ff49530fSBill Paul 		/* old style: always pass argument by reference */
123ff49530fSBill Paul 		f_print(fout, "(");
124ff49530fSBill Paul 		ptype(proc->args.decls->decl.prefix,
125ff49530fSBill Paul 		      proc->args.decls->decl.type, 1);
126ff49530fSBill Paul 
127ff49530fSBill Paul 		if (mtflag) {/* Generate result field */
128ff49530fSBill Paul 			f_print(fout, "*argp, ");
129ff49530fSBill Paul 			ptype(proc->res_prefix, proc->res_type, 1);
130ff49530fSBill Paul 			f_print(fout, "*%s, %s%s)\n",
131ff49530fSBill Paul 				result, addargtype, addargname);
132ff49530fSBill Paul 		} else
133ff49530fSBill Paul 			f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
134ff49530fSBill Paul 	} else if (streq(proc->args.decls->decl.type, "void")) {
135ff49530fSBill Paul 		/* newstyle, 0 argument */
136ff49530fSBill Paul 		if (mtflag) {
137ff49530fSBill Paul 			f_print(fout, "(");
138ff49530fSBill Paul 			ptype(proc->res_prefix, proc->res_type, 1);
139ff49530fSBill Paul 			f_print(fout, "*%s, %s%s)\n",
140ff49530fSBill Paul 				result, addargtype, addargname);
141ff49530fSBill Paul 		} else
142ff49530fSBill Paul 			f_print(fout, "(%s%s)\n", addargtype, addargname);
143ff49530fSBill Paul 	} else {
144ff49530fSBill Paul 		/* new style, 1 or multiple arguments */
145ff49530fSBill Paul 		f_print(fout, "(");
146ff49530fSBill Paul 		for (l = proc->args.decls; l != NULL; l = l->next) {
14715df5e2dSStefan Farfeleder 			pdeclaration(proc->args.argname, &l->decl, 0, ", ");
148ff49530fSBill Paul 		}
149ff49530fSBill Paul 		if (mtflag) {
150ff49530fSBill Paul 			ptype(proc->res_prefix, proc->res_type, 1);
151ff49530fSBill Paul 			f_print(fout, "*%s, ", result);
152ff49530fSBill Paul 
153ff49530fSBill Paul 		}
154ff49530fSBill Paul 		f_print(fout, "%s%s)\n", addargtype, addargname);
155ff49530fSBill Paul 	}
156ff49530fSBill Paul }
157ff49530fSBill Paul 
158ff49530fSBill Paul 
159ff49530fSBill Paul 
160e390e3afSDavid Malone static const char *
161e390e3afSDavid Malone ampr(const char *type)
1624e115012SGarrett Wollman {
1634e115012SGarrett Wollman 	if (isvectordef(type, REL_ALIAS)) {
1644e115012SGarrett Wollman 		return ("");
1654e115012SGarrett Wollman 	} else {
1664e115012SGarrett Wollman 		return ("&");
1674e115012SGarrett Wollman 	}
1684e115012SGarrett Wollman }
1694e115012SGarrett Wollman 
170526195adSJordan K. Hubbard static void
171e390e3afSDavid Malone printbody(proc_list *proc)
1724e115012SGarrett Wollman {
173ff49530fSBill Paul 	decl_list *l;
174ff49530fSBill Paul 	bool_t args2 = (proc->arg_num > 1);
175ff49530fSBill Paul 
176ff49530fSBill Paul 	/*
177ff49530fSBill Paul 	 * For new style with multiple arguments, need a structure in which
178ff49530fSBill Paul 	 *  to stuff the arguments.
179ff49530fSBill Paul 	 */
180ff49530fSBill Paul 
181ff49530fSBill Paul 
182ff49530fSBill Paul 	if (newstyle && args2) {
183ff49530fSBill Paul 		f_print(fout, "\t%s", proc->args.argname);
184ff49530fSBill Paul 		f_print(fout, " arg;\n");
185ff49530fSBill Paul 	}
186ff49530fSBill Paul 	if (!mtflag) {
1874e115012SGarrett Wollman 		f_print(fout, "\tstatic ");
1884e115012SGarrett Wollman 		if (streq(proc->res_type, "void")) {
1894e115012SGarrett Wollman 			f_print(fout, "char ");
1904e115012SGarrett Wollman 		} else {
1914e115012SGarrett Wollman 			ptype(proc->res_prefix, proc->res_type, 0);
1924e115012SGarrett Wollman 		}
193ff49530fSBill Paul 		f_print(fout, "%s;\n", RESULT);
1944e115012SGarrett Wollman 		f_print(fout, "\n");
195ff49530fSBill Paul 		f_print(fout, "\tmemset((char *)%s%s, 0, sizeof (%s));\n",
196ff49530fSBill Paul 			ampr(proc->res_type), RESULT, RESULT);
197ff49530fSBill Paul 
198ff49530fSBill Paul 	}
199ff49530fSBill Paul 	if (newstyle && !args2 &&
200ff49530fSBill Paul 	    (streq(proc->args.decls->decl.type, "void"))) {
201ff49530fSBill Paul 		/* newstyle, 0 arguments */
202ff49530fSBill Paul 
203ff49530fSBill Paul 		if (mtflag)
204ff49530fSBill Paul 			f_print(fout, "\t return ");
205ff49530fSBill Paul 		else
206ff49530fSBill Paul 			f_print(fout, "\t if ");
207ff49530fSBill Paul 
2084e115012SGarrett Wollman 		f_print(fout,
209ff49530fSBill Paul 			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_void, ",
210ff49530fSBill Paul 			proc->proc_name);
211ff49530fSBill Paul 		f_print(fout,
212ff49530fSBill Paul 			"(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
213ff49530fSBill Paul 			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
214ff49530fSBill Paul 			RESULT);
215ff49530fSBill Paul 
216ff49530fSBill Paul 		if (mtflag)
21735ab9586SDavid E. O'Brien 			f_print(fout, "\n\t\tTIMEOUT));\n");
218ff49530fSBill Paul 		else
219ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
220ff49530fSBill Paul 
221ff49530fSBill Paul 	} else if (newstyle && args2) {
222ff49530fSBill Paul 		/*
223ff49530fSBill Paul 		 * Newstyle, multiple arguments
224ff49530fSBill Paul 		 * stuff arguments into structure
225ff49530fSBill Paul 		 */
226ff49530fSBill Paul 		for (l = proc->args.decls;  l != NULL; l = l->next) {
227ff49530fSBill Paul 			f_print(fout, "\targ.%s = %s;\n",
228ff49530fSBill Paul 				l->decl.name, l->decl.name);
229ff49530fSBill Paul 		}
230ff49530fSBill Paul 		if (mtflag)
231ff49530fSBill Paul 			f_print(fout, "\treturn ");
232ff49530fSBill Paul 		else
233ff49530fSBill Paul 			f_print(fout, "\tif ");
234ff49530fSBill Paul 		f_print(fout,
235ff49530fSBill Paul 			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s",
236ff49530fSBill Paul 			proc->proc_name,proc->args.argname);
237ff49530fSBill Paul 		f_print(fout,
238ff49530fSBill Paul 			", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
239ff49530fSBill Paul 			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
240ff49530fSBill Paul 			RESULT);
241ff49530fSBill Paul 		if (mtflag)
242ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT));\n");
243ff49530fSBill Paul 		else
244ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
245ff49530fSBill Paul 	} else {		/* single argument, new or old style */
246ff49530fSBill Paul 		if (!mtflag)
247ff49530fSBill Paul 			f_print(fout,
248ff49530fSBill Paul 			"\tif (clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT) != RPC_SUCCESS) {\n",
249ff49530fSBill Paul 			proc->proc_name,
250ff49530fSBill Paul 			stringfix(proc->args.decls->decl.type),
251ff49530fSBill Paul 			(newstyle ? "&" : ""),
252ff49530fSBill Paul 			(newstyle ? proc->args.decls->decl.name : "argp"),
253ff49530fSBill Paul 			stringfix(proc->res_type), ampr(proc->res_type),
254ff49530fSBill Paul 			RESULT);
255ff49530fSBill Paul 		else
256ff49530fSBill Paul 
257ff49530fSBill Paul 		f_print(fout,
258ff49530fSBill Paul 			"\treturn (clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT));\n",
259ff49530fSBill Paul 			proc->proc_name,
260ff49530fSBill Paul 			stringfix(proc->args.decls->decl.type),
261ff49530fSBill Paul 			(newstyle ? "&" : ""),
262ff49530fSBill Paul 			(newstyle ? proc->args.decls->decl.name : "argp"),
263ff49530fSBill Paul 			stringfix(proc->res_type), "",
264ff49530fSBill Paul 			RESULT);
265ff49530fSBill Paul 	}
266ff49530fSBill Paul 	if (!mtflag) {
2674e115012SGarrett Wollman 		f_print(fout, "\t\treturn (NULL);\n");
2684e115012SGarrett Wollman 		f_print(fout, "\t}\n");
269ff49530fSBill Paul 
2704e115012SGarrett Wollman 		if (streq(proc->res_type, "void")) {
271ff49530fSBill Paul 			f_print(fout, "\treturn ((void *)%s%s);\n",
272ff49530fSBill Paul 				ampr(proc->res_type), RESULT);
2734e115012SGarrett Wollman 		} else {
274ff49530fSBill Paul 			f_print(fout, "\treturn (%s%s);\n",
275ff49530fSBill Paul 				ampr(proc->res_type), RESULT);
276ff49530fSBill Paul 		}
2774e115012SGarrett Wollman 	}
2784e115012SGarrett Wollman }
279