Update to 2.17
[platform/upstream/glibc.git] / sunrpc / rpc_sample.c
1 /*
2  * From: @(#)rpc_sample.c  1.1  90/08/30
3  *
4  * Copyright (c) 2010, Oracle America, Inc.
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials
14  *       provided with the distribution.
15  *     * Neither the name of the "Oracle America, Inc." nor the names of its
16  *       contributors may be used to endorse or promote products derived
17  *       from this software without specific prior written permission.
18  *
19  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /*
34  * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
35  */
36
37 #include <stdio.h>
38 #include <string.h>
39 #include "rpc_parse.h"
40 #include "rpc_util.h"
41 #include "proto.h"
42
43
44 static const char RQSTP[] = "rqstp";
45
46 static void write_sample_client (const char *program_name, version_list * vp);
47 static void write_sample_server (definition * def);
48 static void return_type (proc_list * plist);
49
50
51 void
52 write_sample_svc (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 (definition * def)
63 {
64   version_list *vp;
65   int count = 0;
66
67   if (def->def_kind != DEF_PROGRAM)
68     return 0;
69   /* generate sample code for each version */
70   for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
71     {
72       write_sample_client (def->def_name, vp);
73       ++count;
74     }
75   return count;
76 }
77
78
79 static void
80 write_sample_client (const char *program_name, version_list * vp)
81 {
82   proc_list *proc;
83   int i;
84   decl_list *l;
85
86   f_print (fout, "\n\nvoid\n");
87   pvname (program_name, vp->vers_num);
88   if (Cflag)
89     f_print (fout, "(char *host)\n{\n");
90   else
91     f_print (fout, "(host)\nchar *host;\n{\n");
92   f_print (fout, "\tCLIENT *clnt;\n");
93
94   i = 0;
95   for (proc = vp->procs; proc != NULL; proc = proc->next)
96     {
97       f_print (fout, "\t");
98       ++i;
99       if (mtflag)
100         {
101           f_print (fout, "enum clnt_stat retval_%d;\n\t", i);
102           ptype (proc->res_prefix, proc->res_type, 1);
103           if (!streq (proc->res_type, "void"))
104             f_print (fout, "result_%d;\n", i);
105           else
106             fprintf (fout, "*result_%d;\n", i);
107         }
108       else
109         {
110           ptype (proc->res_prefix, proc->res_type, 1);
111           f_print (fout, " *result_%d;\n", i);
112         }
113       /* print out declarations for arguments */
114       if (proc->arg_num < 2 && !newstyle)
115         {
116           f_print (fout, "\t");
117           if (!streq (proc->args.decls->decl.type, "void"))
118             {
119               ptype (proc->args.decls->decl.prefix,
120                      proc->args.decls->decl.type, 1);
121               f_print (fout, " ");
122             }
123           else
124             f_print (fout, "char *");   /* cannot have "void" type */
125           pvname (proc->proc_name, vp->vers_num);
126           f_print (fout, "_arg;\n");
127         }
128       else if (!streq (proc->args.decls->decl.type, "void"))
129         {
130           for (l = proc->args.decls; l != NULL; l = l->next)
131             {
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 == 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     {
155       if (mtflag)
156         f_print(fout, "\tretval_%d = ",++i);
157       else
158         f_print (fout, "\tresult_%d = ", ++i);
159       pvname (proc->proc_name, vp->vers_num);
160       if (proc->arg_num < 2 && !newstyle)
161         {
162           f_print (fout, "(");
163           if (streq (proc->args.decls->decl.type, "void"))/* cast to void* */
164             f_print (fout, "(void*)");
165           f_print (fout, "&");
166           pvname (proc->proc_name, vp->vers_num);
167           if (mtflag)
168             f_print(fout, "_arg, &result_%d, clnt);\n", i);
169           else
170             f_print (fout, "_arg, clnt);\n");
171         }
172       else if (streq (proc->args.decls->decl.type, "void"))
173         {
174           if (mtflag)
175             f_print (fout, "(&result_%d, clnt);\n", i);
176           else
177             f_print (fout, "(clnt);\n");
178         }
179       else
180         {
181           f_print (fout, "(");
182           for (l = proc->args.decls; l != NULL; l = l->next)
183             {
184               pvname (proc->proc_name, vp->vers_num);
185               f_print (fout, "_%s, ", l->decl.name);
186             }
187           if (mtflag)
188             f_print(fout, "&result_%d, ", i);
189           f_print (fout, "clnt);\n");
190         }
191       if (mtflag)
192         {
193           f_print(fout, "\tif (retval_%d != RPC_SUCCESS) {\n", i);
194         }
195       else
196         {
197           f_print(fout, "\tif (result_%d == (", i);
198           ptype(proc->res_prefix, proc->res_type, 1);
199           f_print(fout, "*) NULL) {\n");
200         }
201       f_print(fout, "\t\tclnt_perror (clnt, \"call failed\");\n");
202       f_print(fout, "\t}\n");
203     }
204
205   f_print (fout, "#ifndef\tDEBUG\n");
206   f_print (fout, "\tclnt_destroy (clnt);\n");
207   f_print (fout, "#endif\t /* DEBUG */\n");
208   f_print (fout, "}\n");
209 }
210
211 static void
212 write_sample_server (definition * def)
213 {
214   version_list *vp;
215   proc_list *proc;
216
217   for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
218     {
219       for (proc = vp->procs; proc != NULL; proc = proc->next)
220         {
221           f_print (fout, "\n");
222           if (!mtflag)
223             {
224               return_type (proc);
225               f_print (fout, "*\n");
226             }
227           else
228             f_print (fout, "bool_t\n");
229           if (Cflag || mtflag)
230             pvname_svc (proc->proc_name, vp->vers_num);
231           else
232             pvname(proc->proc_name, vp->vers_num);
233           printarglist(proc, "result", RQSTP, "struct svc_req *");
234           f_print(fout, "{\n");
235           if (!mtflag)
236             {
237               f_print(fout, "\tstatic ");
238               if(!streq(proc->res_type, "void"))
239                 return_type(proc);
240               else
241                 f_print(fout, "char *");
242                                 /* cannot have void type */
243               /* f_print(fout, " result;\n", proc->res_type); */
244               f_print(fout, " result;\n");
245             }
246           else
247             f_print(fout, "\tbool_t retval;\n");
248           fprintf (fout, "\n\t/*\n\t * insert server code here\n\t */\n\n");
249
250           if (!mtflag)
251             {
252               if (!streq(proc->res_type, "void"))
253                 f_print(fout, "\treturn &result;\n}\n");
254               else /* cast back to void * */
255                 f_print(fout, "\treturn (void *) &result;\n}\n");
256             }
257           else
258             f_print(fout, "\treturn retval;\n}\n");
259         }
260
261       /* put in sample freeing routine */
262       if (mtflag)
263         {
264           f_print(fout, "\nint\n");
265           pvname(def->def_name, vp->vers_num);
266           if (Cflag)
267             f_print(fout,"_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)\n");
268           else
269             {
270               f_print(fout,"_freeresult (transp, xdr_result, result)\n");
271               f_print(fout,"\tSVCXPRT *transp;\n");
272               f_print(fout,"\txdrproc_t xdr_result;\n");
273               f_print(fout,"\tcaddr_t result;\n");
274             }
275           f_print(fout, "{\n");
276           f_print(fout, "\txdr_free (xdr_result, result);\n");
277           f_print(fout,
278                   "\n\t/*\n\t * Insert additional freeing code here, if needed\n\t */\n");
279           f_print(fout, "\n\treturn 1;\n}\n");
280         }
281     }
282 }
283
284
285
286 static void
287 return_type (proc_list * plist)
288 {
289   ptype (plist->res_prefix, plist->res_type, 1);
290 }
291
292 void
293 add_sample_msg (void)
294 {
295   f_print (fout, "/*\n");
296   f_print (fout, " * This is sample code generated by rpcgen.\n");
297   f_print (fout, " * These are only templates and you can use them\n");
298   f_print (fout, " * as a guideline for developing your own functions.\n");
299   f_print (fout, " */\n\n");
300 }
301
302 void
303 write_sample_clnt_main (void)
304 {
305   list *l;
306   definition *def;
307   version_list *vp;
308
309   f_print (fout, "\n\n");
310   if (Cflag)
311     f_print (fout, "int\nmain (int argc, char *argv[])\n{\n");
312   else
313     f_print (fout, "int\nmain (argc, argv)\nint argc;\nchar *argv[];\n{\n");
314
315   f_print (fout, "\tchar *host;");
316   f_print (fout, "\n\n\tif (argc < 2) {");
317   f_print (fout, "\n\t\tprintf (\"usage: %%s server_host\\n\", argv[0]);\n");
318   f_print (fout, "\t\texit (1);\n\t}");
319   f_print (fout, "\n\thost = argv[1];\n");
320
321   for (l = defined; l != NULL; l = l->next)
322     {
323       def = l->val;
324       if (def->def_kind != DEF_PROGRAM)
325         {
326           continue;
327         }
328       for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
329         {
330           f_print (fout, "\t");
331           pvname (def->def_name, vp->vers_num);
332           f_print (fout, " (host);\n");
333         }
334     }
335   f_print (fout, "exit (0);\n}\n");
336 }