rpc_clntout.c revision 149682
1219820Sjeff/*
2219820Sjeff * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3219820Sjeff * unrestricted use provided that this legend is included on all tape
4219820Sjeff * media and as a part of the software program in whole or part.  Users
5219820Sjeff * may copy or modify Sun RPC without charge, but are not authorized
6219820Sjeff * to license or distribute it to anyone else except as part of a product or
7219820Sjeff * program developed by the user.
8219820Sjeff *
9219820Sjeff * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10219820Sjeff * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11219820Sjeff * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12219820Sjeff *
13219820Sjeff * Sun RPC is provided with no support and without any obligation on the
14219820Sjeff * part of Sun Microsystems, Inc. to assist in its use, correction,
15219820Sjeff * modification or enhancement.
16219820Sjeff *
17219820Sjeff * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18219820Sjeff * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19219820Sjeff * OR ANY PART THEREOF.
20219820Sjeff *
21219820Sjeff * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22219820Sjeff * or profits or other special, indirect and consequential damages, even if
23219820Sjeff * Sun has been advised of the possibility of such damages.
24219820Sjeff *
25219820Sjeff * Sun Microsystems, Inc.
26219820Sjeff * 2550 Garcia Avenue
27219820Sjeff * Mountain View, California  94043
28219820Sjeff */
29219820Sjeff
30219820Sjeff#if 0
31219820Sjeff#ifndef lint
32219820Sjeff#ident	"@(#)rpc_clntout.c	1.15	94/04/25 SMI"
33219820Sjeffstatic char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
34219820Sjeff#endif
35219820Sjeff#endif
36219820Sjeff
37219820Sjeff#include <sys/cdefs.h>
38219820Sjeff__FBSDID("$FreeBSD: head/usr.bin/rpcgen/rpc_clntout.c 149682 2005-08-31 20:45:15Z stefanf $");
39219820Sjeff
40219820Sjeff/*
41219820Sjeff * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
42219820Sjeff * Copyright (C) 1987, Sun Microsytsems, Inc.
43219820Sjeff */
44219820Sjeff#include <stdio.h>
45219820Sjeff#include <string.h>
46219820Sjeff#include <rpc/types.h>
47219820Sjeff#include "rpc_parse.h"
48219820Sjeff#include "rpc_scan.h"
49219820Sjeff#include "rpc_util.h"
50219820Sjeff
51219820Sjeffextern void pdeclaration( char *, declaration *, int, char * );
52219820Sjeffvoid printarglist( proc_list *, char *, char *, char *);
53219820Sjeffstatic void write_program( definition * );
54219820Sjeffstatic void printbody( proc_list * );
55219820Sjeff
56219820Sjeffstatic char RESULT[] = "clnt_res";
57219820Sjeff
58219820Sjeff
59219820Sjeff#define DEFAULT_TIMEOUT 25	/* in seconds */
60219820Sjeff
61219820Sjeff
62219820Sjeffvoid
63219820Sjeffwrite_stubs()
64219820Sjeff{
65219820Sjeff	list *l;
66219820Sjeff	definition *def;
67219820Sjeff
68219820Sjeff	f_print(fout,
69219820Sjeff		"\n/* Default timeout can be changed using clnt_control() */\n");
70219820Sjeff	f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
71219820Sjeff		DEFAULT_TIMEOUT);
72219820Sjeff	for (l = defined; l != NULL; l = l->next) {
73219820Sjeff		def = (definition *) l->val;
74219820Sjeff		if (def->def_kind == DEF_PROGRAM) {
75219820Sjeff			write_program(def);
76219820Sjeff		}
77219820Sjeff	}
78219820Sjeff}
79219820Sjeff
80219820Sjeffstatic void
81219820Sjeffwrite_program(def)
82219820Sjeff	definition *def;
83219820Sjeff{
84219820Sjeff	version_list *vp;
85219820Sjeff	proc_list *proc;
86219820Sjeff
87	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
88		for (proc = vp->procs; proc != NULL; proc = proc->next) {
89			f_print(fout, "\n");
90			if (mtflag == 0) {
91				ptype(proc->res_prefix, proc->res_type, 1);
92				f_print(fout, "*\n");
93				pvname(proc->proc_name, vp->vers_num);
94				printarglist(proc, RESULT, "clnt", "CLIENT *");
95			} else {
96				f_print(fout, "enum clnt_stat \n");
97				pvname(proc->proc_name, vp->vers_num);
98				printarglist(proc, RESULT,  "clnt", "CLIENT *");
99
100			}
101			f_print(fout, "{\n");
102			printbody(proc);
103
104			f_print(fout, "}\n");
105		}
106	}
107}
108
109/*
110 * Writes out declarations of procedure's argument list.
111 * In either ANSI C style, in one of old rpcgen style (pass by reference),
112 * or new rpcgen style (multiple arguments, pass by value);
113 */
114
115/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
116
117void printarglist(proc, result, addargname, addargtype)
118	proc_list *proc;
119	char *result;
120	char* addargname, * addargtype;
121{
122
123	decl_list *l;
124
125	if (!newstyle) {
126		/* old style: always pass argument by reference */
127		if (Cflag) {	/* C++ style heading */
128			f_print(fout, "(");
129			ptype(proc->args.decls->decl.prefix,
130			      proc->args.decls->decl.type, 1);
131
132			if (mtflag) {/* Generate result field */
133				f_print(fout, "*argp, ");
134				ptype(proc->res_prefix, proc->res_type, 1);
135				f_print(fout, "*%s, %s%s)\n",
136					result, addargtype, addargname);
137			} else
138				f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
139		} else {
140			if (!mtflag)
141				f_print(fout, "(argp, %s)\n", addargname);
142			else
143				f_print(fout, "(argp, %s, %s)\n",
144					result, addargname);
145			f_print(fout, "\t");
146			ptype(proc->args.decls->decl.prefix,
147			      proc->args.decls->decl.type, 1);
148			f_print(fout, "*argp;\n");
149			if (mtflag) {
150				f_print(fout, "\t");
151				ptype(proc->res_prefix, proc->res_type, 1);
152				f_print(fout, "*%s;\n", result);
153			}
154		}
155	} else if (streq(proc->args.decls->decl.type, "void")) {
156		/* newstyle, 0 argument */
157		if (mtflag) {
158				f_print(fout, "(");
159
160
161			if (Cflag) {
162				ptype(proc->res_prefix, proc->res_type, 1);
163				f_print(fout, "*%s, %s%s)\n",
164					result, addargtype, addargname);
165			}
166			else
167				f_print(fout, "(%s)\n", addargname);
168
169		} else
170		if (Cflag)
171			f_print(fout, "(%s%s)\n", addargtype, addargname);
172		else
173			f_print(fout, "(%s)\n", addargname);
174	} else {
175		/* new style, 1 or multiple arguments */
176		if (!Cflag) {
177			f_print(fout, "(");
178			for (l = proc->args.decls;  l != NULL; l = l->next)
179				f_print(fout, "%s, ", l->decl.name);
180			if (mtflag)
181				f_print(fout, "%s, ", result);
182
183			f_print(fout, "%s)\n", addargname);
184			for (l = proc->args.decls; l != NULL; l = l->next) {
185				pdeclaration(proc->args.argname,
186					     &l->decl, 1, ";\n");
187			}
188			if (mtflag) {
189				f_print(fout, "\t");
190				ptype(proc->res_prefix, proc->res_type, 1);
191				f_print(fout, "*%s;\n", result);
192			}
193
194		} else {	/* C++ style header */
195			f_print(fout, "(");
196			for (l = proc->args.decls; l != NULL; l = l->next) {
197				pdeclaration(proc->args.argname, &l->decl, 0,
198					     ", ");
199			}
200			if (mtflag) {
201				ptype(proc->res_prefix, proc->res_type, 1);
202				f_print(fout, "*%s, ", result);
203
204			}
205			f_print(fout, "%s%s)\n", addargtype, addargname);
206		}
207	}
208
209	if (!Cflag)
210		f_print(fout, "\t%s%s;\n", addargtype, addargname);
211}
212
213
214
215static char *
216ampr(type)
217	char *type;
218{
219	if (isvectordef(type, REL_ALIAS)) {
220		return ("");
221	} else {
222		return ("&");
223	}
224}
225
226static void
227printbody(proc)
228	proc_list *proc;
229{
230	decl_list *l;
231	bool_t args2 = (proc->arg_num > 1);
232
233	/*
234	 * For new style with multiple arguments, need a structure in which
235	 *  to stuff the arguments.
236	 */
237
238
239	if (newstyle && args2) {
240		f_print(fout, "\t%s", proc->args.argname);
241		f_print(fout, " arg;\n");
242	}
243	if (!mtflag) {
244		f_print(fout, "\tstatic ");
245		if (streq(proc->res_type, "void")) {
246			f_print(fout, "char ");
247		} else {
248			ptype(proc->res_prefix, proc->res_type, 0);
249		}
250		f_print(fout, "%s;\n", RESULT);
251		f_print(fout, "\n");
252		f_print(fout, "\tmemset((char *)%s%s, 0, sizeof (%s));\n",
253			ampr(proc->res_type), RESULT, RESULT);
254
255	}
256	if (newstyle && !args2 &&
257	    (streq(proc->args.decls->decl.type, "void"))) {
258		/* newstyle, 0 arguments */
259
260		if (mtflag)
261			f_print(fout, "\t return ");
262		else
263			f_print(fout, "\t if ");
264
265		f_print(fout,
266			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_void, ",
267			proc->proc_name);
268		f_print(fout,
269			"(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
270			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
271			RESULT);
272
273		if (mtflag)
274			f_print(fout, "\n\t\tTIMEOUT));\n");
275		else
276			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
277
278	} else if (newstyle && args2) {
279		/*
280		 * Newstyle, multiple arguments
281		 * stuff arguments into structure
282		 */
283		for (l = proc->args.decls;  l != NULL; l = l->next) {
284			f_print(fout, "\targ.%s = %s;\n",
285				l->decl.name, l->decl.name);
286		}
287		if (mtflag)
288			f_print(fout, "\treturn ");
289		else
290			f_print(fout, "\tif ");
291		f_print(fout,
292			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s",
293			proc->proc_name,proc->args.argname);
294		f_print(fout,
295			", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
296			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
297			RESULT);
298		if (mtflag)
299			f_print(fout, "\n\t\tTIMEOUT));\n");
300		else
301			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
302	} else {		/* single argument, new or old style */
303		if (!mtflag)
304			f_print(fout,
305			"\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",
306			proc->proc_name,
307			stringfix(proc->args.decls->decl.type),
308			(newstyle ? "&" : ""),
309			(newstyle ? proc->args.decls->decl.name : "argp"),
310			stringfix(proc->res_type), ampr(proc->res_type),
311			RESULT);
312		else
313
314		f_print(fout,
315			"\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",
316			proc->proc_name,
317			stringfix(proc->args.decls->decl.type),
318			(newstyle ? "&" : ""),
319			(newstyle ? proc->args.decls->decl.name : "argp"),
320			stringfix(proc->res_type), "",
321			RESULT);
322	}
323	if (!mtflag) {
324		f_print(fout, "\t\treturn (NULL);\n");
325		f_print(fout, "\t}\n");
326
327		if (streq(proc->res_type, "void")) {
328			f_print(fout, "\treturn ((void *)%s%s);\n",
329				ampr(proc->res_type), RESULT);
330		} else {
331			f_print(fout, "\treturn (%s%s);\n",
332				ampr(proc->res_type), RESULT);
333		}
334	}
335}
336