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