1 |
|
|
/* $OpenBSD: rpc_sample.c,v 1.18 2012/12/05 23:20:26 deraadt Exp $ */ |
2 |
|
|
/* $NetBSD: rpc_sample.c,v 1.2 1995/06/11 21:50:01 pk Exp $ */ |
3 |
|
|
|
4 |
|
|
/* |
5 |
|
|
* Copyright (c) 2010, Oracle America, Inc. |
6 |
|
|
* |
7 |
|
|
* Redistribution and use in source and binary forms, with or without |
8 |
|
|
* modification, are permitted provided that the following conditions are |
9 |
|
|
* met: |
10 |
|
|
* |
11 |
|
|
* * Redistributions of source code must retain the above copyright |
12 |
|
|
* notice, this list of conditions and the following disclaimer. |
13 |
|
|
* * Redistributions in binary form must reproduce the above |
14 |
|
|
* copyright notice, this list of conditions and the following |
15 |
|
|
* disclaimer in the documentation and/or other materials |
16 |
|
|
* provided with the distribution. |
17 |
|
|
* * Neither the name of the "Oracle America, Inc." nor the names of its |
18 |
|
|
* contributors may be used to endorse or promote products derived |
19 |
|
|
* from this software without specific prior written permission. |
20 |
|
|
* |
21 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
22 |
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
23 |
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
24 |
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
25 |
|
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
26 |
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
27 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
28 |
|
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
29 |
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
30 |
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
31 |
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
32 |
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 |
|
|
*/ |
34 |
|
|
|
35 |
|
|
/* |
36 |
|
|
* rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler |
37 |
|
|
*/ |
38 |
|
|
|
39 |
|
|
#include <stdio.h> |
40 |
|
|
#include <string.h> |
41 |
|
|
#include "rpc_parse.h" |
42 |
|
|
#include "rpc_util.h" |
43 |
|
|
|
44 |
|
|
static char RQSTP[] = "rqstp"; |
45 |
|
|
|
46 |
|
|
static void write_sample_client(char *, version_list *); |
47 |
|
|
static void write_sample_server(definition *); |
48 |
|
|
static void return_type(proc_list *); |
49 |
|
|
|
50 |
|
|
void |
51 |
|
|
write_sample_svc(def) |
52 |
|
|
definition *def; |
53 |
|
|
{ |
54 |
|
|
|
55 |
|
|
if (def->def_kind != DEF_PROGRAM) |
56 |
|
|
return; |
57 |
|
|
write_sample_server(def); |
58 |
|
|
} |
59 |
|
|
|
60 |
|
|
|
61 |
|
|
int |
62 |
|
|
write_sample_clnt(def) |
63 |
|
|
definition *def; |
64 |
|
|
{ |
65 |
|
|
version_list *vp; |
66 |
|
|
int count = 0; |
67 |
|
|
|
68 |
|
|
if (def->def_kind != DEF_PROGRAM) |
69 |
|
|
return(0); |
70 |
|
|
/* generate sample code for each version */ |
71 |
|
|
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { |
72 |
|
|
write_sample_client(def->def_name, vp); |
73 |
|
|
++count; |
74 |
|
|
} |
75 |
|
|
return(count); |
76 |
|
|
} |
77 |
|
|
|
78 |
|
|
|
79 |
|
|
static void |
80 |
|
|
write_sample_client(program_name, vp) |
81 |
|
|
char *program_name; |
82 |
|
|
version_list *vp; |
83 |
|
|
{ |
84 |
|
|
proc_list *proc; |
85 |
|
|
int i; |
86 |
|
|
decl_list *l; |
87 |
|
|
|
88 |
|
|
fprintf(fout, "\n\nvoid\n"); |
89 |
|
|
pvname(program_name, vp->vers_num); |
90 |
|
|
if (Cflag) |
91 |
|
|
fprintf(fout,"(char *host)\n{\n"); |
92 |
|
|
else |
93 |
|
|
fprintf(fout, "(host)\nchar *host;\n{\n"); |
94 |
|
|
fprintf(fout, "\tCLIENT *clnt;\n"); |
95 |
|
|
|
96 |
|
|
i = 0; |
97 |
|
|
for (proc = vp->procs; proc != NULL; proc = proc->next) { |
98 |
|
|
fprintf(fout, "\t"); |
99 |
|
|
ptype(proc->res_prefix, proc->res_type, 1); |
100 |
|
|
fprintf(fout, " *result_%d;\n",++i); |
101 |
|
|
/* print out declarations for arguments */ |
102 |
|
|
if (proc->arg_num < 2 && !newstyle) { |
103 |
|
|
fprintf(fout, "\t"); |
104 |
|
|
if (!streq(proc->args.decls->decl.type, "void")) |
105 |
|
|
ptype(proc->args.decls->decl.prefix, |
106 |
|
|
proc->args.decls->decl.type, 1); |
107 |
|
|
else |
108 |
|
|
fprintf(fout, "char *"); /* cannot have "void" type */ |
109 |
|
|
fprintf(fout, " "); |
110 |
|
|
pvname(proc->proc_name, vp->vers_num); |
111 |
|
|
fprintf(fout, "_arg;\n"); |
112 |
|
|
} else if (!streq(proc->args.decls->decl.type, "void")) { |
113 |
|
|
for (l = proc->args.decls; l != NULL; l = l->next) { |
114 |
|
|
fprintf(fout, "\t"); |
115 |
|
|
ptype(l->decl.prefix, l->decl.type, 1); |
116 |
|
|
fprintf(fout, " "); |
117 |
|
|
pvname(proc->proc_name, vp->vers_num); |
118 |
|
|
fprintf(fout, "_%s;\n", l->decl.name); |
119 |
|
|
/* pdeclaration(proc->args.argname, &l->decl, 1, ";\n");*/ |
120 |
|
|
} |
121 |
|
|
} |
122 |
|
|
} |
123 |
|
|
|
124 |
|
|
/* generate creation of client handle */ |
125 |
|
|
fprintf(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n", |
126 |
|
|
program_name, vp->vers_name, tirpcflag? "netpath" : "udp"); |
127 |
|
|
fprintf(fout, "\tif (clnt == NULL) {\n"); |
128 |
|
|
fprintf(fout, "\t\tclnt_pcreateerror(host);\n"); |
129 |
|
|
fprintf(fout, "\t\texit(1);\n\t}\n"); |
130 |
|
|
|
131 |
|
|
/* generate calls to procedures */ |
132 |
|
|
i = 0; |
133 |
|
|
for (proc = vp->procs; proc != NULL; proc = proc->next) { |
134 |
|
|
fprintf(fout, "\tresult_%d = ",++i); |
135 |
|
|
pvname(proc->proc_name, vp->vers_num); |
136 |
|
|
if (proc->arg_num < 2 && !newstyle) { |
137 |
|
|
fprintf(fout, "("); |
138 |
|
|
if (streq(proc->args.decls->decl.type, "void")) |
139 |
|
|
fprintf(fout, "(void*)"); |
140 |
|
|
fprintf(fout, "&"); |
141 |
|
|
pvname(proc->proc_name, vp->vers_num); |
142 |
|
|
fprintf(fout, "_arg, clnt);\n"); |
143 |
|
|
} else if (streq(proc->args.decls->decl.type, "void")) { |
144 |
|
|
fprintf(fout, "(clnt);\n"); |
145 |
|
|
} else { |
146 |
|
|
fprintf(fout, "("); |
147 |
|
|
for (l = proc->args.decls; l != NULL; l = l->next) { |
148 |
|
|
pvname(proc->proc_name, vp->vers_num); |
149 |
|
|
fprintf(fout, "_%s, ", l->decl.name); |
150 |
|
|
} |
151 |
|
|
fprintf(fout, "clnt);\n"); |
152 |
|
|
} |
153 |
|
|
fprintf(fout, "\tif (result_%d == NULL) {\n", i); |
154 |
|
|
fprintf(fout, "\t\tclnt_perror(clnt, \"call failed:\");\n"); |
155 |
|
|
fprintf(fout, "\t}\n"); |
156 |
|
|
} |
157 |
|
|
|
158 |
|
|
fprintf(fout, "\tclnt_destroy(clnt);\n"); |
159 |
|
|
fprintf(fout, "}\n"); |
160 |
|
|
} |
161 |
|
|
|
162 |
|
|
static void |
163 |
|
|
write_sample_server(def) |
164 |
|
|
definition *def; |
165 |
|
|
{ |
166 |
|
|
version_list *vp; |
167 |
|
|
proc_list *proc; |
168 |
|
|
|
169 |
|
|
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { |
170 |
|
|
for (proc = vp->procs; proc != NULL; proc = proc->next) { |
171 |
|
|
fprintf(fout, "\n"); |
172 |
|
|
/* if (Cflag) |
173 |
|
|
fprintf(fout, "extern \"C\"{\n"); |
174 |
|
|
*/ |
175 |
|
|
return_type(proc); |
176 |
|
|
fprintf(fout, "* \n"); |
177 |
|
|
pvname_svc(proc->proc_name, vp->vers_num); |
178 |
|
|
printarglist(proc, RQSTP, "struct svc_req *"); |
179 |
|
|
|
180 |
|
|
fprintf(fout, "{\n"); |
181 |
|
|
fprintf(fout, "\n\tstatic "); |
182 |
|
|
if (!streq(proc->res_type, "void")) |
183 |
|
|
return_type(proc); |
184 |
|
|
else |
185 |
|
|
fprintf(fout, "char*"); /* cannot have void type */ |
186 |
|
|
fprintf(fout, " result;\n"); |
187 |
|
|
fprintf(fout, |
188 |
|
|
"\n\t/*\n\t * insert server code here\n\t */\n\n"); |
189 |
|
|
if (!streq(proc->res_type, "void")) |
190 |
|
|
fprintf(fout, "\treturn(&result);\n}\n"); |
191 |
|
|
else /* cast back to void * */ |
192 |
|
|
fprintf(fout, "\treturn((void*) &result);\n}\n"); |
193 |
|
|
/* if (Cflag) |
194 |
|
|
fprintf(fout, "}\n"); |
195 |
|
|
*/ |
196 |
|
|
} |
197 |
|
|
} |
198 |
|
|
} |
199 |
|
|
|
200 |
|
|
static void |
201 |
|
|
return_type(plist) |
202 |
|
|
proc_list *plist; |
203 |
|
|
{ |
204 |
|
|
ptype(plist->res_prefix, plist->res_type, 1); |
205 |
|
|
} |
206 |
|
|
|
207 |
|
|
void |
208 |
|
|
add_sample_msg(void) |
209 |
|
|
{ |
210 |
|
|
fprintf(fout, "/*\n"); |
211 |
|
|
fprintf(fout, " * This is sample code generated by rpcgen.\n"); |
212 |
|
|
fprintf(fout, " * These are only templates and you can use them\n"); |
213 |
|
|
fprintf(fout, " * as a guideline for developing your own functions.\n"); |
214 |
|
|
fprintf(fout, " */\n\n"); |
215 |
|
|
} |
216 |
|
|
|
217 |
|
|
void |
218 |
|
|
write_sample_clnt_main() |
219 |
|
|
{ |
220 |
|
|
list *l; |
221 |
|
|
definition *def; |
222 |
|
|
version_list *vp; |
223 |
|
|
|
224 |
|
|
fprintf(fout, "\n\n"); |
225 |
|
|
if (Cflag) |
226 |
|
|
fprintf(fout,"main(int argc, char *argv[])\n{\n"); |
227 |
|
|
else |
228 |
|
|
fprintf(fout, "main(argc, argv)\nint argc;\nchar *argv[];\n{\n"); |
229 |
|
|
|
230 |
|
|
fprintf(fout, "\tchar *host;"); |
231 |
|
|
fprintf(fout, "\n\n\tif (argc < 2) {"); |
232 |
|
|
fprintf(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n"); |
233 |
|
|
fprintf(fout, "\t\texit(1);\n\t}"); |
234 |
|
|
fprintf(fout, "\n\thost = argv[1];\n"); |
235 |
|
|
|
236 |
|
|
for (l = defined; l != NULL; l = l->next) { |
237 |
|
|
def = l->val; |
238 |
|
|
if (def->def_kind != DEF_PROGRAM) |
239 |
|
|
continue; |
240 |
|
|
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { |
241 |
|
|
fprintf(fout, "\t"); |
242 |
|
|
pvname(def->def_name, vp->vers_num); |
243 |
|
|
fprintf(fout, "(host);\n"); |
244 |
|
|
} |
245 |
|
|
} |
246 |
|
|
fprintf(fout, "}\n"); |
247 |
|
|
} |