4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
29 * University Copyright- Copyright (c) 1982, 1986, 1988
30 * The Regents of the University of California
33 * University Acknowledgment- Portions of this document are derived from
34 * software developed by the University of California, Berkeley, and its
39 * rpc_sample.c, Sample client-server code outputter
40 * for the RPC protocol compiler
45 #include "rpc_parse.h"
49 static char RQSTP
[] = "rqstp";
51 extern void printarglist(proc_list
*, char *, char *, char *);
53 static void write_sample_client(char *, version_list
*);
54 static void write_sample_server(definition
*);
55 static void return_type(proc_list
*);
58 write_sample_svc(definition
*def
)
60 if (def
->def_kind
!= DEF_PROGRAM
)
62 write_sample_server(def
);
66 write_sample_clnt(definition
*def
)
71 if (def
->def_kind
!= DEF_PROGRAM
)
73 /* generate sample code for each version */
74 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
75 write_sample_client(def
->def_name
, vp
);
82 write_sample_client(char *program_name
, version_list
*vp
)
88 f_print(fout
, "\n\nvoid\n");
89 pvname(program_name
, vp
->vers_num
);
91 f_print(fout
, "(char *host)\n{\n");
93 f_print(fout
, "(host)\n\tchar *host;\n{\n");
94 f_print(fout
, "\tCLIENT *clnt;\n");
97 for (proc
= vp
->procs
; proc
!= NULL
; proc
= proc
->next
) {
100 f_print(fout
, "enum clnt_stat retval_%d;\n", ++i
);
101 if (!streq(proc
->res_type
, "oneway")) {
103 if (!streq(proc
->res_type
, "void"))
104 ptype(proc
->res_prefix
,
107 f_print(fout
, "void *");
108 f_print(fout
, "result_%d;\n", i
);
111 ptype(proc
->res_prefix
, proc
->res_type
, 1);
112 f_print(fout
, " *result_%d;\n", ++i
);
114 /* print out declarations for arguments */
115 if (proc
->arg_num
< 2 && !newstyle
) {
117 if (!streq(proc
->args
.decls
->decl
.type
, "void"))
118 ptype(proc
->args
.decls
->decl
.prefix
,
119 proc
->args
.decls
->decl
.type
, 1);
121 /* cannot have "void" type */
122 f_print(fout
, "char * ");
124 pvname(proc
->proc_name
, vp
->vers_num
);
125 f_print(fout
, "_arg;\n");
126 } else if (!streq(proc
->args
.decls
->decl
.type
, "void")) {
127 for (l
= proc
->args
.decls
; l
!= NULL
; l
= l
->next
) {
129 ptype(l
->decl
.prefix
, l
->decl
.type
, 1);
130 if (strcmp(l
->decl
.type
, "string") == 1)
132 pvname(proc
->proc_name
, vp
->vers_num
);
133 f_print(fout
, "_%s;\n", l
->decl
.name
);
138 /* generate creation of client handle */
139 f_print(fout
, "\n#ifndef\tDEBUG\n");
140 f_print(fout
, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n",
141 program_name
, vp
->vers_name
, tirpcflag
? "netpath" : "udp");
142 f_print(fout
, "\tif (clnt == (CLIENT *) NULL) {\n");
143 f_print(fout
, "\t\tclnt_pcreateerror(host);\n");
144 f_print(fout
, "\t\texit(1);\n\t}\n");
145 f_print(fout
, "#endif\t/* DEBUG */\n\n");
147 /* generate calls to procedures */
149 for (proc
= vp
->procs
; proc
!= NULL
; proc
= proc
->next
) {
151 f_print(fout
, "\tretval_%d = ", ++i
);
153 f_print(fout
, "\tresult_%d = ", ++i
);
154 pvname(proc
->proc_name
, vp
->vers_num
);
155 if (proc
->arg_num
< 2 && !newstyle
) {
157 if (streq(proc
->args
.decls
->decl
.type
, "void"))
159 f_print(fout
, "(void *)");
161 pvname(proc
->proc_name
, vp
->vers_num
);
163 if (streq(proc
->res_type
, "oneway"))
164 f_print(fout
, "_arg, clnt);\n");
167 "_arg, &result_%d, clnt);\n", i
);
169 f_print(fout
, "_arg, clnt);\n");
171 } else if (streq(proc
->args
.decls
->decl
.type
, "void")) {
173 if (streq(proc
->res_type
, "oneway"))
174 f_print(fout
, "(clnt);\n");
177 "(&result_%d, clnt);\n", i
);
179 f_print(fout
, "(clnt);\n");
182 for (l
= proc
->args
.decls
; l
!= NULL
; l
= l
->next
) {
183 pvname(proc
->proc_name
, vp
->vers_num
);
184 f_print(fout
, "_%s, ", l
->decl
.name
);
187 if (!streq(proc
->res_type
, "oneway"))
188 f_print(fout
, "&result_%d, ", i
);
191 f_print(fout
, "clnt);\n");
194 f_print(fout
, "\tif (retval_%d != RPC_SUCCESS) {\n", i
);
196 f_print(fout
, "\tif (result_%d == (", i
);
197 ptype(proc
->res_prefix
, proc
->res_type
, 1);
198 f_print(fout
, "*) NULL) {\n");
200 f_print(fout
, "\t\tclnt_perror(clnt, \"call failed\");\n");
201 f_print(fout
, "\t}\n");
204 f_print(fout
, "#ifndef\tDEBUG\n");
205 f_print(fout
, "\tclnt_destroy(clnt);\n");
206 f_print(fout
, "#endif\t /* DEBUG */\n");
207 f_print(fout
, "}\n");
211 write_sample_server(definition
*def
)
216 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
217 for (proc
= vp
->procs
; proc
!= NULL
; proc
= proc
->next
) {
221 f_print(fout
, "*\n");
223 f_print(fout
, "bool_t\n");
226 pvname_svc(proc
->proc_name
, vp
->vers_num
);
228 pvname(proc
->proc_name
, vp
->vers_num
);
229 printarglist(proc
, "result", RQSTP
, "struct svc_req *");
231 f_print(fout
, "{\n");
234 f_print(fout
, "\tstatic ");
235 if ((!streq(proc
->res_type
, "void")) &&
236 (!streq(proc
->res_type
, "oneway")))
239 f_print(fout
, "char *");
240 /* cannot have void type */
241 f_print(fout
, " result;\n");
244 f_print(fout
, "\n\t/*\n\t * insert server code "
248 if (!streq(proc
->res_type
, "void"))
250 "\treturn (&result);\n}\n");
251 else /* cast back to void * */
252 f_print(fout
, "\treturn((void *) "
255 f_print(fout
, "\treturn (retval);\n}\n");
257 /* put in sample freeing routine */
259 f_print(fout
, "\nint\n");
260 pvname(def
->def_name
, vp
->vers_num
);
262 f_print(fout
, "_freeresult(SVCXPRT *transp,"
263 " xdrproc_t xdr_result,"
264 " caddr_t result)\n");
266 f_print(fout
, "_freeresult(transp, xdr_result,"
268 f_print(fout
, "\tSVCXPRT *transp;\n");
269 f_print(fout
, "\txdrproc_t xdr_result;\n");
270 f_print(fout
, "\tcaddr_t result;\n");
273 "\t(void) xdr_free(xdr_result, result);\n"
274 "\n\t/*\n\t * Insert additional freeing"
275 " code here, if needed\n\t */\n"
276 "\n\n\treturn (TRUE);\n}\n");
282 return_type(proc_list
*plist
)
284 ptype(plist
->res_prefix
, plist
->res_type
, 1);
290 f_print(fout
, "/*\n");
291 f_print(fout
, " * This is sample code generated by rpcgen.\n");
292 f_print(fout
, " * These are only templates and you can use them\n");
293 f_print(fout
, " * as a guideline for developing your own functions.\n");
294 f_print(fout
, " */\n\n");
298 write_sample_clnt_main(void)
304 f_print(fout
, "\n\n");
306 f_print(fout
, "int\nmain(int argc, char *argv[])\n{\n");
308 f_print(fout
, "int\nmain(argc, argv)\n\tint argc;\n"
309 "\tchar *argv[];\n{\n");
311 f_print(fout
, "\tchar *host;");
312 f_print(fout
, "\n\n\tif (argc < 2) {");
313 f_print(fout
, "\n\t\tprintf(\"usage: %%s server_host\\n\","
315 f_print(fout
, "\t\texit(1);\n\t}");
316 f_print(fout
, "\n\thost = argv[1];\n");
318 for (l
= defined
; l
!= NULL
; l
= l
->next
) {
320 if (def
->def_kind
!= DEF_PROGRAM
)
322 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
324 pvname(def
->def_name
, vp
->vers_num
);
325 f_print(fout
, "(host);\n");
328 f_print(fout
, "}\n");