11897Swollman/*
21897Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
31897Swollman * unrestricted use provided that this legend is included on all tape
41897Swollman * media and as a part of the software program in whole or part.  Users
51897Swollman * may copy or modify Sun RPC without charge, but are not authorized
61897Swollman * to license or distribute it to anyone else except as part of a product or
71897Swollman * program developed by the user.
8100441Scharnier *
91897Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
101897Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
111897Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12100441Scharnier *
131897Swollman * Sun RPC is provided with no support and without any obligation on the
141897Swollman * part of Sun Microsystems, Inc. to assist in its use, correction,
151897Swollman * modification or enhancement.
16100441Scharnier *
171897Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
181897Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
191897Swollman * OR ANY PART THEREOF.
20100441Scharnier *
211897Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue
221897Swollman * or profits or other special, indirect and consequential damages, even if
231897Swollman * Sun has been advised of the possibility of such damages.
24100441Scharnier *
251897Swollman * Sun Microsystems, Inc.
261897Swollman * 2550 Garcia Avenue
271897Swollman * Mountain View, California  94043
281897Swollman */
2912798Swpaul
30100441Scharnier#if 0
311897Swollman#ifndef lint
32146833Sstefanf#ident	"@(#)rpc_clntout.c	1.15	94/04/25 SMI"
3312798Swpaulstatic char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
341897Swollman#endif
3599979Salfred#endif
361897Swollman
37100441Scharnier#include <sys/cdefs.h>
38100441Scharnier__FBSDID("$FreeBSD$");
39100441Scharnier
401897Swollman/*
411897Swollman * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
421897Swollman * Copyright (C) 1987, Sun Microsytsems, Inc.
431897Swollman */
441897Swollman#include <stdio.h>
45200462Sdelphij#include <string.h>
4612798Swpaul#include <rpc/types.h>
471897Swollman#include "rpc_parse.h"
48149682Sstefanf#include "rpc_scan.h"
491897Swollman#include "rpc_util.h"
501897Swollman
5192921Simpstatic void write_program( definition * );
5292921Simpstatic void printbody( proc_list * );
5312798Swpaul
5412798Swpaulstatic char RESULT[] = "clnt_res";
5512798Swpaul
5612798Swpaul
571897Swollman#define DEFAULT_TIMEOUT 25	/* in seconds */
581897Swollman
591897Swollman
601897Swollmanvoid
61152398Sdwmalonewrite_stubs(void)
621897Swollman{
631897Swollman	list *l;
641897Swollman	definition *def;
651897Swollman
6612798Swpaul	f_print(fout,
6712798Swpaul		"\n/* Default timeout can be changed using clnt_control() */\n");
6812798Swpaul	f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
691897Swollman		DEFAULT_TIMEOUT);
701897Swollman	for (l = defined; l != NULL; l = l->next) {
711897Swollman		def = (definition *) l->val;
721897Swollman		if (def->def_kind == DEF_PROGRAM) {
731897Swollman			write_program(def);
741897Swollman		}
751897Swollman	}
761897Swollman}
771897Swollman
7817142Sjkhstatic void
79152398Sdwmalonewrite_program(definition *def)
801897Swollman{
811897Swollman	version_list *vp;
821897Swollman	proc_list *proc;
831897Swollman
841897Swollman	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
851897Swollman		for (proc = vp->procs; proc != NULL; proc = proc->next) {
861897Swollman			f_print(fout, "\n");
8712798Swpaul			if (mtflag == 0) {
8812798Swpaul				ptype(proc->res_prefix, proc->res_type, 1);
8912798Swpaul				f_print(fout, "*\n");
9012798Swpaul				pvname(proc->proc_name, vp->vers_num);
9112798Swpaul				printarglist(proc, RESULT, "clnt", "CLIENT *");
9212798Swpaul			} else {
9312798Swpaul				f_print(fout, "enum clnt_stat \n");
9412798Swpaul				pvname(proc->proc_name, vp->vers_num);
9512798Swpaul				printarglist(proc, RESULT,  "clnt", "CLIENT *");
9612798Swpaul
9712798Swpaul			}
981897Swollman			f_print(fout, "{\n");
991897Swollman			printbody(proc);
10012798Swpaul
10112798Swpaul			f_print(fout, "}\n");
1021897Swollman		}
1031897Swollman	}
1041897Swollman}
1051897Swollman
10612798Swpaul/*
10712798Swpaul * Writes out declarations of procedure's argument list.
10812798Swpaul * In either ANSI C style, in one of old rpcgen style (pass by reference),
10912798Swpaul * or new rpcgen style (multiple arguments, pass by value);
11012798Swpaul */
11112798Swpaul
11212798Swpaul/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
11312798Swpaul
114152398Sdwmalonevoid
115152398Sdwmaloneprintarglist(proc_list *proc, const char *result, const char *addargname,
116152398Sdwmalone    const char *addargtype)
11712798Swpaul{
11812798Swpaul
11912798Swpaul	decl_list *l;
12012798Swpaul
12112798Swpaul	if (!newstyle) {
12212798Swpaul		/* old style: always pass argument by reference */
123149709Sstefanf		f_print(fout, "(");
124149709Sstefanf		ptype(proc->args.decls->decl.prefix,
125149709Sstefanf		      proc->args.decls->decl.type, 1);
12612798Swpaul
127149709Sstefanf		if (mtflag) {/* Generate result field */
128149709Sstefanf			f_print(fout, "*argp, ");
129149709Sstefanf			ptype(proc->res_prefix, proc->res_type, 1);
130149709Sstefanf			f_print(fout, "*%s, %s%s)\n",
131149709Sstefanf				result, addargtype, addargname);
132149709Sstefanf		} else
133149709Sstefanf			f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
13412798Swpaul	} else if (streq(proc->args.decls->decl.type, "void")) {
13512798Swpaul		/* newstyle, 0 argument */
13612798Swpaul		if (mtflag) {
137149709Sstefanf			f_print(fout, "(");
138149709Sstefanf			ptype(proc->res_prefix, proc->res_type, 1);
139149709Sstefanf			f_print(fout, "*%s, %s%s)\n",
140149709Sstefanf				result, addargtype, addargname);
14112798Swpaul		} else
14212798Swpaul			f_print(fout, "(%s%s)\n", addargtype, addargname);
14312798Swpaul	} else {
14412798Swpaul		/* new style, 1 or multiple arguments */
145149709Sstefanf		f_print(fout, "(");
146149709Sstefanf		for (l = proc->args.decls; l != NULL; l = l->next) {
147149709Sstefanf			pdeclaration(proc->args.argname, &l->decl, 0, ", ");
148149709Sstefanf		}
149149709Sstefanf		if (mtflag) {
150149709Sstefanf			ptype(proc->res_prefix, proc->res_type, 1);
151149709Sstefanf			f_print(fout, "*%s, ", result);
15212798Swpaul
15312798Swpaul		}
154149709Sstefanf		f_print(fout, "%s%s)\n", addargtype, addargname);
15512798Swpaul	}
15612798Swpaul}
15712798Swpaul
15812798Swpaul
15912798Swpaul
160152398Sdwmalonestatic const char *
161152398Sdwmaloneampr(const char *type)
1621897Swollman{
1631897Swollman	if (isvectordef(type, REL_ALIAS)) {
1641897Swollman		return ("");
1651897Swollman	} else {
1661897Swollman		return ("&");
1671897Swollman	}
1681897Swollman}
1691897Swollman
17017142Sjkhstatic void
171152398Sdwmaloneprintbody(proc_list *proc)
1721897Swollman{
17312798Swpaul	decl_list *l;
17412798Swpaul	bool_t args2 = (proc->arg_num > 1);
17512798Swpaul
17612798Swpaul	/*
17712798Swpaul	 * For new style with multiple arguments, need a structure in which
17812798Swpaul	 *  to stuff the arguments.
17912798Swpaul	 */
18012798Swpaul
18112798Swpaul
18212798Swpaul	if (newstyle && args2) {
18312798Swpaul		f_print(fout, "\t%s", proc->args.argname);
18412798Swpaul		f_print(fout, " arg;\n");
1851897Swollman	}
18612798Swpaul	if (!mtflag) {
18712798Swpaul		f_print(fout, "\tstatic ");
18812798Swpaul		if (streq(proc->res_type, "void")) {
18912798Swpaul			f_print(fout, "char ");
19012798Swpaul		} else {
19112798Swpaul			ptype(proc->res_prefix, proc->res_type, 0);
19212798Swpaul		}
19312798Swpaul		f_print(fout, "%s;\n", RESULT);
19412798Swpaul		f_print(fout, "\n");
19512798Swpaul		f_print(fout, "\tmemset((char *)%s%s, 0, sizeof (%s));\n",
19612798Swpaul			ampr(proc->res_type), RESULT, RESULT);
19712798Swpaul
1981897Swollman	}
19912798Swpaul	if (newstyle && !args2 &&
20012798Swpaul	    (streq(proc->args.decls->decl.type, "void"))) {
20112798Swpaul		/* newstyle, 0 arguments */
20212798Swpaul
20312798Swpaul		if (mtflag)
20412798Swpaul			f_print(fout, "\t return ");
20512798Swpaul		else
20612798Swpaul			f_print(fout, "\t if ");
20712798Swpaul
20812798Swpaul		f_print(fout,
209100441Scharnier			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_void, ",
21012798Swpaul			proc->proc_name);
21112798Swpaul		f_print(fout,
21212798Swpaul			"(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
21312798Swpaul			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
21412798Swpaul			RESULT);
21512798Swpaul
21612798Swpaul		if (mtflag)
21739642Sobrien			f_print(fout, "\n\t\tTIMEOUT));\n");
21812798Swpaul		else
21912798Swpaul			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
22012798Swpaul
22112798Swpaul	} else if (newstyle && args2) {
22212798Swpaul		/*
22312798Swpaul		 * Newstyle, multiple arguments
22412798Swpaul		 * stuff arguments into structure
22512798Swpaul		 */
22612798Swpaul		for (l = proc->args.decls;  l != NULL; l = l->next) {
22712798Swpaul			f_print(fout, "\targ.%s = %s;\n",
22812798Swpaul				l->decl.name, l->decl.name);
22912798Swpaul		}
23012798Swpaul		if (mtflag)
23112798Swpaul			f_print(fout, "\treturn ");
23212798Swpaul		else
23312798Swpaul			f_print(fout, "\tif ");
23412798Swpaul		f_print(fout,
23512798Swpaul			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s",
23612798Swpaul			proc->proc_name,proc->args.argname);
23712798Swpaul		f_print(fout,
23812798Swpaul			", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
23912798Swpaul			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
24012798Swpaul			RESULT);
24112798Swpaul		if (mtflag)
24212798Swpaul			f_print(fout, "\n\t\tTIMEOUT));\n");
24312798Swpaul		else
24412798Swpaul			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
24512798Swpaul	} else {		/* single argument, new or old style */
24612798Swpaul		if (!mtflag)
24712798Swpaul			f_print(fout,
24812798Swpaul			"\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",
24912798Swpaul			proc->proc_name,
25012798Swpaul			stringfix(proc->args.decls->decl.type),
25112798Swpaul			(newstyle ? "&" : ""),
25212798Swpaul			(newstyle ? proc->args.decls->decl.name : "argp"),
25312798Swpaul			stringfix(proc->res_type), ampr(proc->res_type),
25412798Swpaul			RESULT);
25512798Swpaul		else
25612798Swpaul
25712798Swpaul		f_print(fout,
25812798Swpaul			"\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",
25912798Swpaul			proc->proc_name,
26012798Swpaul			stringfix(proc->args.decls->decl.type),
26112798Swpaul			(newstyle ? "&" : ""),
26212798Swpaul			(newstyle ? proc->args.decls->decl.name : "argp"),
26312798Swpaul			stringfix(proc->res_type), "",
26412798Swpaul			RESULT);
26512798Swpaul	}
26612798Swpaul	if (!mtflag) {
26712798Swpaul		f_print(fout, "\t\treturn (NULL);\n");
26812798Swpaul		f_print(fout, "\t}\n");
26912798Swpaul
27012798Swpaul		if (streq(proc->res_type, "void")) {
27112798Swpaul			f_print(fout, "\treturn ((void *)%s%s);\n",
27212798Swpaul				ampr(proc->res_type), RESULT);
27312798Swpaul		} else {
27412798Swpaul			f_print(fout, "\treturn (%s%s);\n",
27512798Swpaul				ampr(proc->res_type), RESULT);
27612798Swpaul		}
27712798Swpaul	}
2781897Swollman}
279