xref: /freebsd/usr.bin/rpcgen/rpc_clntout.c (revision 5b31cc94b10d4bb7109c6b27940a0fc76a44a331)
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 
304e115012SGarrett Wollman /*
314e115012SGarrett Wollman  * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
324e115012SGarrett Wollman  * Copyright (C) 1987, Sun Microsytsems, Inc.
334e115012SGarrett Wollman  */
344e115012SGarrett Wollman #include <stdio.h>
35821df508SXin LI #include <string.h>
36ff49530fSBill Paul #include <rpc/types.h>
374e115012SGarrett Wollman #include "rpc_parse.h"
38d0cc804bSStefan Farfeleder #include "rpc_scan.h"
394e115012SGarrett Wollman #include "rpc_util.h"
404e115012SGarrett Wollman 
41d3cb5dedSWarner Losh static void write_program( definition * );
42d3cb5dedSWarner Losh static void printbody( proc_list * );
434e115012SGarrett Wollman 
44ff49530fSBill Paul static char RESULT[] = "clnt_res";
45ff49530fSBill Paul 
46ff49530fSBill Paul 
47ff49530fSBill Paul #define DEFAULT_TIMEOUT 25	/* in seconds */
484e115012SGarrett Wollman 
494e115012SGarrett Wollman 
504e115012SGarrett Wollman void
write_stubs(void)51e390e3afSDavid Malone write_stubs(void)
524e115012SGarrett Wollman {
534e115012SGarrett Wollman 	list *l;
544e115012SGarrett Wollman 	definition *def;
554e115012SGarrett Wollman 
564e115012SGarrett Wollman 	f_print(fout,
574e115012SGarrett Wollman 		"\n/* Default timeout can be changed using clnt_control() */\n");
584e115012SGarrett Wollman 	f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
594e115012SGarrett Wollman 		DEFAULT_TIMEOUT);
604e115012SGarrett Wollman 	for (l = defined; l != NULL; l = l->next) {
614e115012SGarrett Wollman 		def = (definition *) l->val;
624e115012SGarrett Wollman 		if (def->def_kind == DEF_PROGRAM) {
634e115012SGarrett Wollman 			write_program(def);
644e115012SGarrett Wollman 		}
654e115012SGarrett Wollman 	}
664e115012SGarrett Wollman }
674e115012SGarrett Wollman 
68526195adSJordan K. Hubbard static void
write_program(definition * def)69e390e3afSDavid Malone write_program(definition *def)
704e115012SGarrett Wollman {
714e115012SGarrett Wollman 	version_list *vp;
724e115012SGarrett Wollman 	proc_list *proc;
734e115012SGarrett Wollman 
744e115012SGarrett Wollman 	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
754e115012SGarrett Wollman 		for (proc = vp->procs; proc != NULL; proc = proc->next) {
764e115012SGarrett Wollman 			f_print(fout, "\n");
77ff49530fSBill Paul 			if (mtflag == 0) {
784e115012SGarrett Wollman 				ptype(proc->res_prefix, proc->res_type, 1);
794e115012SGarrett Wollman 				f_print(fout, "*\n");
804e115012SGarrett Wollman 				pvname(proc->proc_name, vp->vers_num);
81ff49530fSBill Paul 				printarglist(proc, RESULT, "clnt", "CLIENT *");
82ff49530fSBill Paul 			} else {
83ff49530fSBill Paul 				f_print(fout, "enum clnt_stat \n");
84ff49530fSBill Paul 				pvname(proc->proc_name, vp->vers_num);
85ff49530fSBill Paul 				printarglist(proc, RESULT,  "clnt", "CLIENT *");
86ff49530fSBill Paul 
87ff49530fSBill Paul 			}
884e115012SGarrett Wollman 			f_print(fout, "{\n");
894e115012SGarrett Wollman 			printbody(proc);
90ff49530fSBill Paul 
91ff49530fSBill Paul 			f_print(fout, "}\n");
924e115012SGarrett Wollman 		}
934e115012SGarrett Wollman 	}
944e115012SGarrett Wollman }
954e115012SGarrett Wollman 
96ff49530fSBill Paul /*
97ff49530fSBill Paul  * Writes out declarations of procedure's argument list.
98ff49530fSBill Paul  * In either ANSI C style, in one of old rpcgen style (pass by reference),
99ff49530fSBill Paul  * or new rpcgen style (multiple arguments, pass by value);
100ff49530fSBill Paul  */
101ff49530fSBill Paul 
102ff49530fSBill Paul /* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
103ff49530fSBill Paul 
104e390e3afSDavid Malone void
printarglist(proc_list * proc,const char * result,const char * addargname,const char * addargtype)105e390e3afSDavid Malone printarglist(proc_list *proc, const char *result, const char *addargname,
106e390e3afSDavid Malone     const char *addargtype)
107ff49530fSBill Paul {
108ff49530fSBill Paul 
109ff49530fSBill Paul 	decl_list *l;
110ff49530fSBill Paul 
111ff49530fSBill Paul 	if (!newstyle) {
112ff49530fSBill Paul 		/* old style: always pass argument by reference */
113ff49530fSBill Paul 		f_print(fout, "(");
114ff49530fSBill Paul 		ptype(proc->args.decls->decl.prefix,
115ff49530fSBill Paul 		      proc->args.decls->decl.type, 1);
116ff49530fSBill Paul 
117ff49530fSBill Paul 		if (mtflag) {/* Generate result field */
118ff49530fSBill Paul 			f_print(fout, "*argp, ");
119ff49530fSBill Paul 			ptype(proc->res_prefix, proc->res_type, 1);
120ff49530fSBill Paul 			f_print(fout, "*%s, %s%s)\n",
121ff49530fSBill Paul 				result, addargtype, addargname);
122ff49530fSBill Paul 		} else
123ff49530fSBill Paul 			f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
124ff49530fSBill Paul 	} else if (streq(proc->args.decls->decl.type, "void")) {
125ff49530fSBill Paul 		/* newstyle, 0 argument */
126ff49530fSBill Paul 		if (mtflag) {
127ff49530fSBill Paul 			f_print(fout, "(");
128ff49530fSBill Paul 			ptype(proc->res_prefix, proc->res_type, 1);
129ff49530fSBill Paul 			f_print(fout, "*%s, %s%s)\n",
130ff49530fSBill Paul 				result, addargtype, addargname);
131ff49530fSBill Paul 		} else
132ff49530fSBill Paul 			f_print(fout, "(%s%s)\n", addargtype, addargname);
133ff49530fSBill Paul 	} else {
134ff49530fSBill Paul 		/* new style, 1 or multiple arguments */
135ff49530fSBill Paul 		f_print(fout, "(");
136ff49530fSBill Paul 		for (l = proc->args.decls; l != NULL; l = l->next) {
13715df5e2dSStefan Farfeleder 			pdeclaration(proc->args.argname, &l->decl, 0, ", ");
138ff49530fSBill Paul 		}
139ff49530fSBill Paul 		if (mtflag) {
140ff49530fSBill Paul 			ptype(proc->res_prefix, proc->res_type, 1);
141ff49530fSBill Paul 			f_print(fout, "*%s, ", result);
142ff49530fSBill Paul 
143ff49530fSBill Paul 		}
144ff49530fSBill Paul 		f_print(fout, "%s%s)\n", addargtype, addargname);
145ff49530fSBill Paul 	}
146ff49530fSBill Paul }
147ff49530fSBill Paul 
148ff49530fSBill Paul 
149ff49530fSBill Paul 
150e390e3afSDavid Malone static const char *
ampr(const char * type)151e390e3afSDavid Malone ampr(const char *type)
1524e115012SGarrett Wollman {
1534e115012SGarrett Wollman 	if (isvectordef(type, REL_ALIAS)) {
1544e115012SGarrett Wollman 		return ("");
1554e115012SGarrett Wollman 	} else {
1564e115012SGarrett Wollman 		return ("&");
1574e115012SGarrett Wollman 	}
1584e115012SGarrett Wollman }
1594e115012SGarrett Wollman 
160526195adSJordan K. Hubbard static void
printbody(proc_list * proc)161e390e3afSDavid Malone printbody(proc_list *proc)
1624e115012SGarrett Wollman {
163ff49530fSBill Paul 	decl_list *l;
164ff49530fSBill Paul 	bool_t args2 = (proc->arg_num > 1);
165ff49530fSBill Paul 
166ff49530fSBill Paul 	/*
167ff49530fSBill Paul 	 * For new style with multiple arguments, need a structure in which
168ff49530fSBill Paul 	 *  to stuff the arguments.
169ff49530fSBill Paul 	 */
170ff49530fSBill Paul 
171ff49530fSBill Paul 
172ff49530fSBill Paul 	if (newstyle && args2) {
173ff49530fSBill Paul 		f_print(fout, "\t%s", proc->args.argname);
174ff49530fSBill Paul 		f_print(fout, " arg;\n");
175ff49530fSBill Paul 	}
176ff49530fSBill Paul 	if (!mtflag) {
1774e115012SGarrett Wollman 		f_print(fout, "\tstatic ");
1784e115012SGarrett Wollman 		if (streq(proc->res_type, "void")) {
1794e115012SGarrett Wollman 			f_print(fout, "char ");
1804e115012SGarrett Wollman 		} else {
1814e115012SGarrett Wollman 			ptype(proc->res_prefix, proc->res_type, 0);
1824e115012SGarrett Wollman 		}
183ff49530fSBill Paul 		f_print(fout, "%s;\n", RESULT);
1844e115012SGarrett Wollman 		f_print(fout, "\n");
185ff49530fSBill Paul 		f_print(fout, "\tmemset((char *)%s%s, 0, sizeof (%s));\n",
186ff49530fSBill Paul 			ampr(proc->res_type), RESULT, RESULT);
187ff49530fSBill Paul 
188ff49530fSBill Paul 	}
189ff49530fSBill Paul 	if (newstyle && !args2 &&
190ff49530fSBill Paul 	    (streq(proc->args.decls->decl.type, "void"))) {
191ff49530fSBill Paul 		/* newstyle, 0 arguments */
192ff49530fSBill Paul 
193ff49530fSBill Paul 		if (mtflag)
194ff49530fSBill Paul 			f_print(fout, "\t return ");
195ff49530fSBill Paul 		else
196ff49530fSBill Paul 			f_print(fout, "\t if ");
197ff49530fSBill Paul 
1984e115012SGarrett Wollman 		f_print(fout,
199ff49530fSBill Paul 			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_void, ",
200ff49530fSBill Paul 			proc->proc_name);
201ff49530fSBill Paul 		f_print(fout,
202ff49530fSBill Paul 			"(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
203ff49530fSBill Paul 			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
204ff49530fSBill Paul 			RESULT);
205ff49530fSBill Paul 
206ff49530fSBill Paul 		if (mtflag)
20735ab9586SDavid E. O'Brien 			f_print(fout, "\n\t\tTIMEOUT));\n");
208ff49530fSBill Paul 		else
209ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
210ff49530fSBill Paul 
211ff49530fSBill Paul 	} else if (newstyle && args2) {
212ff49530fSBill Paul 		/*
213ff49530fSBill Paul 		 * Newstyle, multiple arguments
214ff49530fSBill Paul 		 * stuff arguments into structure
215ff49530fSBill Paul 		 */
216ff49530fSBill Paul 		for (l = proc->args.decls;  l != NULL; l = l->next) {
217ff49530fSBill Paul 			f_print(fout, "\targ.%s = %s;\n",
218ff49530fSBill Paul 				l->decl.name, l->decl.name);
219ff49530fSBill Paul 		}
220ff49530fSBill Paul 		if (mtflag)
221ff49530fSBill Paul 			f_print(fout, "\treturn ");
222ff49530fSBill Paul 		else
223ff49530fSBill Paul 			f_print(fout, "\tif ");
224ff49530fSBill Paul 		f_print(fout,
225ff49530fSBill Paul 			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s",
226ff49530fSBill Paul 			proc->proc_name,proc->args.argname);
227ff49530fSBill Paul 		f_print(fout,
228ff49530fSBill Paul 			", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
229ff49530fSBill Paul 			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
230ff49530fSBill Paul 			RESULT);
231ff49530fSBill Paul 		if (mtflag)
232ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT));\n");
233ff49530fSBill Paul 		else
234ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
235ff49530fSBill Paul 	} else {		/* single argument, new or old style */
236ff49530fSBill Paul 		if (!mtflag)
237ff49530fSBill Paul 			f_print(fout,
238ff49530fSBill 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",
239ff49530fSBill Paul 			proc->proc_name,
240ff49530fSBill Paul 			stringfix(proc->args.decls->decl.type),
241ff49530fSBill Paul 			(newstyle ? "&" : ""),
242ff49530fSBill Paul 			(newstyle ? proc->args.decls->decl.name : "argp"),
243ff49530fSBill Paul 			stringfix(proc->res_type), ampr(proc->res_type),
244ff49530fSBill Paul 			RESULT);
245ff49530fSBill Paul 		else
246ff49530fSBill Paul 
247ff49530fSBill Paul 		f_print(fout,
248ff49530fSBill 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",
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), "",
254ff49530fSBill Paul 			RESULT);
255ff49530fSBill Paul 	}
256ff49530fSBill Paul 	if (!mtflag) {
2574e115012SGarrett Wollman 		f_print(fout, "\t\treturn (NULL);\n");
2584e115012SGarrett Wollman 		f_print(fout, "\t}\n");
259ff49530fSBill Paul 
2604e115012SGarrett Wollman 		if (streq(proc->res_type, "void")) {
261ff49530fSBill Paul 			f_print(fout, "\treturn ((void *)%s%s);\n",
262ff49530fSBill Paul 				ampr(proc->res_type), RESULT);
2634e115012SGarrett Wollman 		} else {
264ff49530fSBill Paul 			f_print(fout, "\treturn (%s%s);\n",
265ff49530fSBill Paul 				ampr(proc->res_type), RESULT);
266ff49530fSBill Paul 		}
2674e115012SGarrett Wollman 	}
2684e115012SGarrett Wollman }
269