xref: /illumos-gate/usr/src/cmd/rpcgen/rpc_sample.c (revision 7c478bd9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  *
22  * Copyright 2001 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
27 /*
28  * University Copyright- Copyright (c) 1982, 1986, 1988
29  * The Regents of the University of California
30  * All Rights Reserved
31  *
32  * University Acknowledgment- Portions of this document are derived from
33  * software developed by the University of California, Berkeley, and its
34  * contributors.
35  */
36 
37 #pragma ident	"%Z%%M%	%I%	%E% SMI"
38 
39 /*
40  * rpc_sample.c, Sample client-server code outputter
41  * for the RPC protocol compiler
42  */
43 
44 #include <stdio.h>
45 #include <string.h>
46 #include "rpc_parse.h"
47 #include "rpc_util.h"
48 
49 
50 static char RQSTP[] = "rqstp";
51 
52 void printarglist();
53 
54 void
55 write_sample_svc(def)
56 	definition *def;
57 {
58 
59 	if (def->def_kind != DEF_PROGRAM)
60 		return;
61 	write_sample_server(def);
62 }
63 
64 
65 int
66 write_sample_clnt(def)
67 	definition *def;
68 {
69 	version_list *vp;
70 	int count = 0;
71 
72 	if (def->def_kind != DEF_PROGRAM)
73 		return (0);
74 	/* generate sample code for each version */
75 	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
76 		write_sample_client(def->def_name, vp);
77 		++count;
78 	}
79 	return (count);
80 }
81 
82 
83 static
84 write_sample_client(program_name, vp)
85 	char *program_name;
86 	version_list *vp;
87 {
88 	proc_list *proc;
89 	int i;
90 	decl_list *l;
91 
92 	f_print(fout, "\n\nvoid\n");
93 	pvname(program_name, vp->vers_num);
94 	if (Cflag)
95 		f_print(fout, "(char *host)\n{\n");
96 	else
97 		f_print(fout, "(host)\n\tchar *host;\n{\n");
98 	f_print(fout, "\tCLIENT *clnt;\n");
99 
100 	i = 0;
101 	for (proc = vp->procs; proc != NULL; proc = proc->next) {
102 		f_print(fout, "\t");
103 		if (mtflag) {
104 			f_print(fout, "enum clnt_stat retval_%d;\n", ++i);
105 			if (!streq(proc->res_type, "oneway")) {
106 				f_print(fout, "\t");
107 				if (!streq(proc->res_type, "void"))
108 					ptype(proc->res_prefix,
109 					    proc->res_type, 1);
110 				else
111 					f_print(fout, "void *");
112 				f_print(fout, "result_%d;\n", i);
113 			}
114 		} else {
115 			ptype(proc->res_prefix, proc->res_type, 1);
116 			f_print(fout, " *result_%d;\n", ++i);
117 		}
118 		/* print out declarations for arguments */
119 		if (proc->arg_num < 2 && !newstyle) {
120 			f_print(fout, "\t");
121 			if (!streq(proc->args.decls->decl.type, "void"))
122 				ptype(proc->args.decls->decl.prefix,
123 					proc->args.decls->decl.type, 1);
124 			else
125 				/* cannot have "void" type */
126 				f_print(fout, "char * ");
127 			f_print(fout, " ");
128 			pvname(proc->proc_name, vp->vers_num);
129 			f_print(fout, "_arg;\n");
130 		} else if (!streq(proc->args.decls->decl.type, "void")) {
131 			for (l = proc->args.decls; l != NULL; l = l->next) {
132 				f_print(fout, "\t");
133 				ptype(l->decl.prefix, l->decl.type, 1);
134 				if (strcmp(l->decl.type, "string") == 1)
135 				    f_print(fout, " ");
136 				pvname(proc->proc_name, vp->vers_num);
137 				f_print(fout, "_%s;\n", l->decl.name);
138 			}
139 		}
140 	}
141 
142 	/* generate creation of client handle */
143 	f_print(fout, "\n#ifndef\tDEBUG\n");
144 	f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n",
145 		program_name, vp->vers_name, tirpcflag? "netpath" : "udp");
146 	f_print(fout, "\tif (clnt == (CLIENT *) NULL) {\n");
147 	f_print(fout, "\t\tclnt_pcreateerror(host);\n");
148 	f_print(fout, "\t\texit(1);\n\t}\n");
149 	f_print(fout, "#endif\t/* DEBUG */\n\n");
150 
151 	/* generate calls to procedures */
152 	i = 0;
153 	for (proc = vp->procs; proc != NULL; proc = proc->next) {
154 		if (mtflag)
155 			f_print(fout, "\tretval_%d = ", ++i);
156 		else
157 			f_print(fout, "\tresult_%d = ", ++i);
158 		pvname(proc->proc_name, vp->vers_num);
159 		if (proc->arg_num < 2 && !newstyle) {
160 			f_print(fout, "(");
161 			if (streq(proc->args.decls->decl.type, "void"))
162 				/* cast to void * */
163 				f_print(fout, "(void *)");
164 			f_print(fout, "&");
165 			pvname(proc->proc_name, vp->vers_num);
166 			if (mtflag) {
167 				if (streq(proc->res_type, "oneway")) {
168 					f_print(fout, "_arg, clnt);\n");
169 				} else {
170 					f_print(fout,
171 					    "_arg, &result_%d, clnt);\n", i);
172 				}
173 			} else
174 				f_print(fout, "_arg, clnt);\n");
175 
176 		} else if (streq(proc->args.decls->decl.type, "void")) {
177 			if (mtflag) {
178 				if (streq(proc->res_type, "oneway")) {
179 					f_print(fout, "(clnt);\n");
180 				} else {
181 					f_print(fout,
182 					    "(&result_%d, clnt);\n", i);
183 				}
184 			} else
185 				f_print(fout, "(clnt);\n");
186 		} else {
187 			f_print(fout, "(");
188 			for (l = proc->args.decls;  l != NULL; l = l->next) {
189 				pvname(proc->proc_name, vp->vers_num);
190 				f_print(fout, "_%s, ", l->decl.name);
191 			}
192 			if (mtflag) {
193 				if (!streq(proc->res_type, "oneway")) {
194 					f_print(fout, "&result_%d, ", i);
195 				}
196 			}
197 
198 			f_print(fout, "clnt);\n");
199 		}
200 		if (mtflag) {
201 			f_print(fout, "\tif (retval_%d != RPC_SUCCESS) {\n", i);
202 
203 		} else {
204 			f_print(fout, "\tif (result_%d == (", i);
205 			ptype(proc->res_prefix, proc->res_type, 1);
206 			f_print(fout, "*) NULL) {\n");
207 		}
208 		f_print(fout, "\t\tclnt_perror(clnt, \"call failed\");\n");
209 		f_print(fout, "\t}\n");
210 	}
211 
212 	f_print(fout, "#ifndef\tDEBUG\n");
213 	f_print(fout, "\tclnt_destroy(clnt);\n");
214 	f_print(fout, "#endif\t	/* DEBUG */\n");
215 	f_print(fout, "}\n");
216 }
217 
218 static
219 write_sample_server(def)
220 	definition *def;
221 {
222 	version_list *vp;
223 	proc_list *proc;
224 
225 	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
226 		for (proc = vp->procs; proc != NULL; proc = proc->next) {
227 			f_print(fout, "\n");
228 			if (!mtflag) {
229 				return_type(proc);
230 				f_print(fout, "*\n");
231 			} else {
232 				f_print(fout, "bool_t\n");
233 			}
234 			if (Cflag || mtflag)
235 				pvname_svc(proc->proc_name, vp->vers_num);
236 			else
237 				pvname(proc->proc_name, vp->vers_num);
238 			printarglist(proc, "result", RQSTP, "struct svc_req *");
239 
240 			f_print(fout, "{\n");
241 
242 			if (!mtflag) {
243 				f_print(fout, "\tstatic ");
244 				if ((!streq(proc->res_type, "void")) &&
245 				    (!streq(proc->res_type, "oneway")))
246 					return_type(proc);
247 				else
248 					f_print(fout, "char *");
249 				/* cannot have void type */
250 				f_print(fout, " result;\n",
251 				    proc->res_type);
252 			}
253 
254 			f_print(fout, "\n\t/*\n\t * insert server code "
255 						"here\n\t */\n\n");
256 
257 			if (!mtflag)
258 				if (!streq(proc->res_type, "void"))
259 					f_print(fout,
260 					    "\treturn (&result);\n}\n");
261 				else /* cast back to void * */
262 					f_print(fout, "\treturn((void *) "
263 					    "&result);\n}\n");
264 			else
265 				f_print(fout, "\treturn (retval);\n}\n");
266 		}
267 		/* put in sample freeing routine */
268 		if (mtflag) {
269 			f_print(fout, "\nint\n");
270 			pvname(def->def_name, vp->vers_num);
271 			if (Cflag)
272 				f_print(fout, "_freeresult(SVCXPRT *transp,"
273 					" xdrproc_t xdr_result,"
274 					" caddr_t result)\n");
275 			else {
276 				f_print(fout, "_freeresult(transp, xdr_result,"
277 					" result)\n");
278 				f_print(fout, "\tSVCXPRT *transp;\n");
279 				f_print(fout, "\txdrproc_t xdr_result;\n");
280 				f_print(fout, "\tcaddr_t result;\n");
281 			}
282 			f_print(fout, "{\n"
283 				"\t(void) xdr_free(xdr_result, result);\n"
284 				"\n\t/*\n\t * Insert additional freeing"
285 				" code here, if needed\n\t */\n"
286 				"\n\n\treturn (TRUE);\n}\n");
287 		}
288 	}
289 }
290 
291 
292 
293 static
294 return_type(plist)
295 	proc_list *plist;
296 {
297 	ptype(plist->res_prefix, plist->res_type, 1);
298 }
299 
300 add_sample_msg()
301 {
302 	f_print(fout, "/*\n");
303 	f_print(fout, " * This is sample code generated by rpcgen.\n");
304 	f_print(fout, " * These are only templates and you can use them\n");
305 	f_print(fout, " * as a guideline for developing your own functions.\n");
306 	f_print(fout, " */\n\n");
307 }
308 
309 void
310 write_sample_clnt_main()
311 {
312 	list *l;
313 	definition *def;
314 	version_list *vp;
315 
316 	f_print(fout, "\n\n");
317 	if (Cflag)
318 		f_print(fout, "main(int argc, char *argv[])\n{\n");
319 	else
320 		f_print(fout, "main(argc, argv)\n\tint argc;\n"
321 			"\tchar *argv[];\n{\n");
322 
323 	f_print(fout, "\tchar *host;");
324 	f_print(fout, "\n\n\tif (argc < 2) {");
325 	f_print(fout, "\n\t\tprintf(\"usage:  %%s server_host\\n\","
326 			" argv[0]);\n");
327 	f_print(fout, "\t\texit(1);\n\t}");
328 	f_print(fout, "\n\thost = argv[1];\n");
329 
330 	for (l = defined; l != NULL; l = l->next) {
331 		def = l->val;
332 		if (def->def_kind != DEF_PROGRAM) {
333 			continue;
334 		}
335 		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
336 			f_print(fout, "\t");
337 			pvname(def->def_name, vp->vers_num);
338 			f_print(fout, "(host);\n");
339 		}
340 	}
341 	f_print(fout, "}\n");
342 }
343