xref: /freebsd/usr.bin/rpcgen/rpc_clntout.c (revision 526195ad0da110e4a8a5315ec86dddc8e179c06f)
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 
30ff49530fSBill Paul #ident	"@(#)rpc_clntout.c	1.15	94/04/25 SMI"
31ff49530fSBill Paul 
324e115012SGarrett Wollman #ifndef lint
33ff49530fSBill Paul static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
344e115012SGarrett Wollman #endif
354e115012SGarrett Wollman 
364e115012SGarrett Wollman /*
374e115012SGarrett Wollman  * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
384e115012SGarrett Wollman  * Copyright (C) 1987, Sun Microsytsems, Inc.
394e115012SGarrett Wollman  */
404e115012SGarrett Wollman #include <stdio.h>
41ff49530fSBill Paul #include <string.h>
42ff49530fSBill Paul #include <rpc/types.h>
434e115012SGarrett Wollman #include "rpc_parse.h"
444e115012SGarrett Wollman #include "rpc_util.h"
454e115012SGarrett Wollman 
46526195adSJordan K. Hubbard extern void pdeclaration __P(( char *, declaration *, int, char * ));
47ff49530fSBill Paul void printarglist __P(( proc_list *, char *, char *, char *));
48526195adSJordan K. Hubbard static void write_program __P(( definition * ));
49526195adSJordan K. Hubbard static void printbody __P(( proc_list * ));
504e115012SGarrett Wollman 
51ff49530fSBill Paul static char RESULT[] = "clnt_res";
52ff49530fSBill Paul 
53ff49530fSBill Paul 
54ff49530fSBill Paul #define DEFAULT_TIMEOUT 25	/* in seconds */
554e115012SGarrett Wollman 
564e115012SGarrett Wollman 
574e115012SGarrett Wollman void
584e115012SGarrett Wollman write_stubs()
594e115012SGarrett Wollman {
604e115012SGarrett Wollman 	list *l;
614e115012SGarrett Wollman 	definition *def;
624e115012SGarrett Wollman 
634e115012SGarrett Wollman 	f_print(fout,
644e115012SGarrett Wollman 		"\n/* Default timeout can be changed using clnt_control() */\n");
654e115012SGarrett Wollman 	f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
664e115012SGarrett Wollman 		DEFAULT_TIMEOUT);
674e115012SGarrett Wollman 	for (l = defined; l != NULL; l = l->next) {
684e115012SGarrett Wollman 		def = (definition *) l->val;
694e115012SGarrett Wollman 		if (def->def_kind == DEF_PROGRAM) {
704e115012SGarrett Wollman 			write_program(def);
714e115012SGarrett Wollman 		}
724e115012SGarrett Wollman 	}
734e115012SGarrett Wollman }
744e115012SGarrett Wollman 
75526195adSJordan K. Hubbard static void
764e115012SGarrett Wollman write_program(def)
774e115012SGarrett Wollman 	definition *def;
784e115012SGarrett Wollman {
794e115012SGarrett Wollman 	version_list *vp;
804e115012SGarrett Wollman 	proc_list *proc;
814e115012SGarrett Wollman 
824e115012SGarrett Wollman 	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
834e115012SGarrett Wollman 		for (proc = vp->procs; proc != NULL; proc = proc->next) {
844e115012SGarrett Wollman 			f_print(fout, "\n");
85ff49530fSBill Paul 			if (mtflag == 0) {
864e115012SGarrett Wollman 				ptype(proc->res_prefix, proc->res_type, 1);
874e115012SGarrett Wollman 				f_print(fout, "*\n");
884e115012SGarrett Wollman 				pvname(proc->proc_name, vp->vers_num);
89ff49530fSBill Paul 				printarglist(proc, RESULT, "clnt", "CLIENT *");
90ff49530fSBill Paul 			} else {
91ff49530fSBill Paul 				f_print(fout, "enum clnt_stat \n");
92ff49530fSBill Paul 				pvname(proc->proc_name, vp->vers_num);
93ff49530fSBill Paul 				printarglist(proc, RESULT,  "clnt", "CLIENT *");
94ff49530fSBill Paul 
95ff49530fSBill Paul 			}
964e115012SGarrett Wollman 			f_print(fout, "{\n");
974e115012SGarrett Wollman 			printbody(proc);
98ff49530fSBill Paul 
99ff49530fSBill Paul 			f_print(fout, "}\n");
1004e115012SGarrett Wollman 		}
1014e115012SGarrett Wollman 	}
1024e115012SGarrett Wollman }
1034e115012SGarrett Wollman 
104ff49530fSBill Paul /*
105ff49530fSBill Paul  * Writes out declarations of procedure's argument list.
106ff49530fSBill Paul  * In either ANSI C style, in one of old rpcgen style (pass by reference),
107ff49530fSBill Paul  * or new rpcgen style (multiple arguments, pass by value);
108ff49530fSBill Paul  */
109ff49530fSBill Paul 
110ff49530fSBill Paul /* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
111ff49530fSBill Paul 
112ff49530fSBill Paul void printarglist(proc, result, addargname, addargtype)
113ff49530fSBill Paul 	proc_list *proc;
114ff49530fSBill Paul 	char *result;
115ff49530fSBill Paul 	char* addargname, * addargtype;
116ff49530fSBill Paul {
117ff49530fSBill Paul 
118ff49530fSBill Paul 	decl_list *l;
119ff49530fSBill Paul 
120ff49530fSBill Paul 	if (!newstyle) {
121ff49530fSBill Paul 		/* old style: always pass argument by reference */
122ff49530fSBill Paul 		if (Cflag) {	/* C++ style heading */
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 {
135ff49530fSBill Paul 			if (!mtflag)
136ff49530fSBill Paul 				f_print(fout, "(argp, %s)\n", addargname);
137ff49530fSBill Paul 			else
138ff49530fSBill Paul 				f_print(fout, "(argp, %s, %s)\n",
139ff49530fSBill Paul 					result, addargname);
140ff49530fSBill Paul 			f_print(fout, "\t");
141ff49530fSBill Paul 			ptype(proc->args.decls->decl.prefix,
142ff49530fSBill Paul 			      proc->args.decls->decl.type, 1);
143ff49530fSBill Paul 			f_print(fout, "*argp;\n");
144ff49530fSBill Paul 			if (mtflag) {
145ff49530fSBill Paul 				f_print(fout, "\t");
146ff49530fSBill Paul 				ptype(proc->res_prefix, proc->res_type, 1);
147ff49530fSBill Paul 				f_print(fout, "*%s;\n", result);
148ff49530fSBill Paul 			}
149ff49530fSBill Paul 		}
150ff49530fSBill Paul 	} else if (streq(proc->args.decls->decl.type, "void")) {
151ff49530fSBill Paul 		/* newstyle, 0 argument */
152ff49530fSBill Paul 		if (mtflag) {
153ff49530fSBill Paul 				f_print(fout, "(");
154ff49530fSBill Paul 
155ff49530fSBill Paul 
156ff49530fSBill Paul 			if (Cflag) {
157ff49530fSBill Paul 				ptype(proc->res_prefix, proc->res_type, 1);
158ff49530fSBill Paul 				f_print(fout, "*%s, %s%s)\n",
159ff49530fSBill Paul 					result, addargtype, addargname);
160ff49530fSBill Paul 			}
161ff49530fSBill Paul 			else
162ff49530fSBill Paul 				f_print(fout, "(%s)\n", addargname);
163ff49530fSBill Paul 
164ff49530fSBill Paul 		} else
165ff49530fSBill Paul 		if (Cflag)
166ff49530fSBill Paul 			f_print(fout, "(%s%s)\n", addargtype, addargname);
167ff49530fSBill Paul 		else
168ff49530fSBill Paul 			f_print(fout, "(%s)\n", addargname);
169ff49530fSBill Paul 	} else {
170ff49530fSBill Paul 		/* new style, 1 or multiple arguments */
171ff49530fSBill Paul 		if (!Cflag) {
172ff49530fSBill Paul 			f_print(fout, "(");
173ff49530fSBill Paul 			for (l = proc->args.decls;  l != NULL; l = l->next)
174ff49530fSBill Paul 				f_print(fout, "%s, ", l->decl.name);
175ff49530fSBill Paul 			if (mtflag)
176ff49530fSBill Paul 				f_print(fout, "%s, ", result);
177ff49530fSBill Paul 
178ff49530fSBill Paul 			f_print(fout, "%s)\n", addargname);
179ff49530fSBill Paul 			for (l = proc->args.decls; l != NULL; l = l->next) {
180ff49530fSBill Paul 				pdeclaration(proc->args.argname,
181ff49530fSBill Paul 					     &l->decl, 1, ";\n");
182ff49530fSBill Paul 			}
183ff49530fSBill Paul 			if (mtflag) {
184ff49530fSBill Paul 				f_print(fout, "\t");
185ff49530fSBill Paul 				ptype(proc->res_prefix, proc->res_type, 1);
186ff49530fSBill Paul 				f_print(fout, "*%s;\n", result);
187ff49530fSBill Paul 			}
188ff49530fSBill Paul 
189ff49530fSBill Paul 		} else {	/* C++ style header */
190ff49530fSBill Paul 			f_print(fout, "(");
191ff49530fSBill Paul 			for (l = proc->args.decls; l != NULL; l = l->next) {
192ff49530fSBill Paul 				pdeclaration(proc->args.argname, &l->decl, 0,
193ff49530fSBill Paul 					     ", ");
194ff49530fSBill Paul 			}
195ff49530fSBill Paul 			if (mtflag) {
196ff49530fSBill Paul 				ptype(proc->res_prefix, proc->res_type, 1);
197ff49530fSBill Paul 				f_print(fout, "*%s, ", result);
198ff49530fSBill Paul 
199ff49530fSBill Paul 			}
200ff49530fSBill Paul 			f_print(fout, "%s%s)\n", addargtype, addargname);
201ff49530fSBill Paul 		}
202ff49530fSBill Paul 	}
203ff49530fSBill Paul 
204ff49530fSBill Paul 	if (!Cflag)
205ff49530fSBill Paul 		f_print(fout, "\t%s%s;\n", addargtype, addargname);
206ff49530fSBill Paul }
207ff49530fSBill Paul 
208ff49530fSBill Paul 
209ff49530fSBill Paul 
2104e115012SGarrett Wollman static char *
2114e115012SGarrett Wollman ampr(type)
2124e115012SGarrett Wollman 	char *type;
2134e115012SGarrett Wollman {
2144e115012SGarrett Wollman 	if (isvectordef(type, REL_ALIAS)) {
2154e115012SGarrett Wollman 		return ("");
2164e115012SGarrett Wollman 	} else {
2174e115012SGarrett Wollman 		return ("&");
2184e115012SGarrett Wollman 	}
2194e115012SGarrett Wollman }
2204e115012SGarrett Wollman 
221526195adSJordan K. Hubbard static void
2224e115012SGarrett Wollman printbody(proc)
2234e115012SGarrett Wollman 	proc_list *proc;
2244e115012SGarrett Wollman {
225ff49530fSBill Paul 	decl_list *l;
226ff49530fSBill Paul 	bool_t args2 = (proc->arg_num > 1);
227ff49530fSBill Paul 
228ff49530fSBill Paul 	/*
229ff49530fSBill Paul 	 * For new style with multiple arguments, need a structure in which
230ff49530fSBill Paul 	 *  to stuff the arguments.
231ff49530fSBill Paul 	 */
232ff49530fSBill Paul 
233ff49530fSBill Paul 
234ff49530fSBill Paul 	if (newstyle && args2) {
235ff49530fSBill Paul 		f_print(fout, "\t%s", proc->args.argname);
236ff49530fSBill Paul 		f_print(fout, " arg;\n");
237ff49530fSBill Paul 	}
238ff49530fSBill Paul 	if (!mtflag) {
2394e115012SGarrett Wollman 		f_print(fout, "\tstatic ");
2404e115012SGarrett Wollman 		if (streq(proc->res_type, "void")) {
2414e115012SGarrett Wollman 			f_print(fout, "char ");
2424e115012SGarrett Wollman 		} else {
2434e115012SGarrett Wollman 			ptype(proc->res_prefix, proc->res_type, 0);
2444e115012SGarrett Wollman 		}
245ff49530fSBill Paul 		f_print(fout, "%s;\n", RESULT);
2464e115012SGarrett Wollman 		f_print(fout, "\n");
247ff49530fSBill Paul 		f_print(fout, "\tmemset((char *)%s%s, 0, sizeof (%s));\n",
248ff49530fSBill Paul 			ampr(proc->res_type), RESULT, RESULT);
249ff49530fSBill Paul 
250ff49530fSBill Paul 	}
251ff49530fSBill Paul 	if (newstyle && !args2 &&
252ff49530fSBill Paul 	    (streq(proc->args.decls->decl.type, "void"))) {
253ff49530fSBill Paul 		/* newstyle, 0 arguments */
254ff49530fSBill Paul 
255ff49530fSBill Paul 		if (mtflag)
256ff49530fSBill Paul 			f_print(fout, "\t return ");
257ff49530fSBill Paul 		else
258ff49530fSBill Paul 			f_print(fout, "\t if ");
259ff49530fSBill Paul 
2604e115012SGarrett Wollman 		f_print(fout,
261ff49530fSBill Paul 			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_void, ",
262ff49530fSBill Paul 			proc->proc_name);
263ff49530fSBill Paul 		f_print(fout,
264ff49530fSBill Paul 			"(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
265ff49530fSBill Paul 			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
266ff49530fSBill Paul 			RESULT);
267ff49530fSBill Paul 
268ff49530fSBill Paul 		if (mtflag)
269ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT));\n}\n");
270ff49530fSBill Paul 		else
271ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
272ff49530fSBill Paul 
273ff49530fSBill Paul 	} else if (newstyle && args2) {
274ff49530fSBill Paul 		/*
275ff49530fSBill Paul 		 * Newstyle, multiple arguments
276ff49530fSBill Paul 		 * stuff arguments into structure
277ff49530fSBill Paul 		 */
278ff49530fSBill Paul 		for (l = proc->args.decls;  l != NULL; l = l->next) {
279ff49530fSBill Paul 			f_print(fout, "\targ.%s = %s;\n",
280ff49530fSBill Paul 				l->decl.name, l->decl.name);
281ff49530fSBill Paul 		}
282ff49530fSBill Paul 		if (mtflag)
283ff49530fSBill Paul 			f_print(fout, "\treturn ");
284ff49530fSBill Paul 		else
285ff49530fSBill Paul 			f_print(fout, "\tif ");
286ff49530fSBill Paul 		f_print(fout,
287ff49530fSBill Paul 			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s",
288ff49530fSBill Paul 			proc->proc_name,proc->args.argname);
289ff49530fSBill Paul 		f_print(fout,
290ff49530fSBill Paul 			", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
291ff49530fSBill Paul 			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
292ff49530fSBill Paul 			RESULT);
293ff49530fSBill Paul 		if (mtflag)
294ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT));\n");
295ff49530fSBill Paul 		else
296ff49530fSBill Paul 			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
297ff49530fSBill Paul 	} else {		/* single argument, new or old style */
298ff49530fSBill Paul 		if (!mtflag)
299ff49530fSBill Paul 			f_print(fout,
300ff49530fSBill 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",
301ff49530fSBill Paul 			proc->proc_name,
302ff49530fSBill Paul 			stringfix(proc->args.decls->decl.type),
303ff49530fSBill Paul 			(newstyle ? "&" : ""),
304ff49530fSBill Paul 			(newstyle ? proc->args.decls->decl.name : "argp"),
305ff49530fSBill Paul 			stringfix(proc->res_type), ampr(proc->res_type),
306ff49530fSBill Paul 			RESULT);
307ff49530fSBill Paul 		else
308ff49530fSBill Paul 
309ff49530fSBill Paul 		f_print(fout,
310ff49530fSBill 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",
311ff49530fSBill Paul 			proc->proc_name,
312ff49530fSBill Paul 			stringfix(proc->args.decls->decl.type),
313ff49530fSBill Paul 			(newstyle ? "&" : ""),
314ff49530fSBill Paul 			(newstyle ? proc->args.decls->decl.name : "argp"),
315ff49530fSBill Paul 			stringfix(proc->res_type), "",
316ff49530fSBill Paul 			RESULT);
317ff49530fSBill Paul 	}
318ff49530fSBill Paul 	if (!mtflag) {
3194e115012SGarrett Wollman 		f_print(fout, "\t\treturn (NULL);\n");
3204e115012SGarrett Wollman 		f_print(fout, "\t}\n");
321ff49530fSBill Paul 
3224e115012SGarrett Wollman 		if (streq(proc->res_type, "void")) {
323ff49530fSBill Paul 			f_print(fout, "\treturn ((void *)%s%s);\n",
324ff49530fSBill Paul 				ampr(proc->res_type), RESULT);
3254e115012SGarrett Wollman 		} else {
326ff49530fSBill Paul 			f_print(fout, "\treturn (%s%s);\n",
327ff49530fSBill Paul 				ampr(proc->res_type), RESULT);
328ff49530fSBill Paul 		}
3294e115012SGarrett Wollman 	}
3304e115012SGarrett Wollman }
331