Back to index

glibc  2.9
rpc_sample.c
Go to the documentation of this file.
00001 /*
00002  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00003  * unrestricted use provided that this legend is included on all tape
00004  * media and as a part of the software program in whole or part.  Users
00005  * may copy or modify Sun RPC without charge, but are not authorized
00006  * to license or distribute it to anyone else except as part of a product or
00007  * program developed by the user or with the express written consent of
00008  * Sun Microsystems, Inc.
00009  *
00010  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00011  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00012  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00013  *
00014  * Sun RPC is provided with no support and without any obligation on the
00015  * part of Sun Microsystems, Inc. to assist in its use, correction,
00016  * modification or enhancement.
00017  *
00018  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00019  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00020  * OR ANY PART THEREOF.
00021  *
00022  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00023  * or profits or other special, indirect and consequential damages, even if
00024  * Sun has been advised of the possibility of such damages.
00025  *
00026  * Sun Microsystems, Inc.
00027  * 2550 Garcia Avenue
00028  * Mountain View, California  94043
00029  */
00030 
00031 /*
00032  * From: @(#)rpc_sample.c  1.1  90/08/30  (C) 1987 SMI
00033  */
00034 
00035 /*
00036  * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
00037  */
00038 
00039 #include <stdio.h>
00040 #include <string.h>
00041 #include "rpc_parse.h"
00042 #include "rpc_util.h"
00043 #include "proto.h"
00044 
00045 
00046 static const char RQSTP[] = "rqstp";
00047 
00048 static void write_sample_client (const char *program_name, version_list * vp);
00049 static void write_sample_server (definition * def);
00050 static void return_type (proc_list * plist);
00051 
00052 
00053 void
00054 write_sample_svc (definition * def)
00055 {
00056 
00057   if (def->def_kind != DEF_PROGRAM)
00058     return;
00059   write_sample_server (def);
00060 }
00061 
00062 
00063 int
00064 write_sample_clnt (definition * def)
00065 {
00066   version_list *vp;
00067   int count = 0;
00068 
00069   if (def->def_kind != DEF_PROGRAM)
00070     return 0;
00071   /* generate sample code for each version */
00072   for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
00073     {
00074       write_sample_client (def->def_name, vp);
00075       ++count;
00076     }
00077   return count;
00078 }
00079 
00080 
00081 static void
00082 write_sample_client (const char *program_name, version_list * vp)
00083 {
00084   proc_list *proc;
00085   int i;
00086   decl_list *l;
00087 
00088   f_print (fout, "\n\nvoid\n");
00089   pvname (program_name, vp->vers_num);
00090   if (Cflag)
00091     f_print (fout, "(char *host)\n{\n");
00092   else
00093     f_print (fout, "(host)\nchar *host;\n{\n");
00094   f_print (fout, "\tCLIENT *clnt;\n");
00095 
00096   i = 0;
00097   for (proc = vp->procs; proc != NULL; proc = proc->next)
00098     {
00099       f_print (fout, "\t");
00100       ++i;
00101       if (mtflag)
00102        {
00103          f_print (fout, "enum clnt_stat retval_%d;\n\t", i);
00104          ptype (proc->res_prefix, proc->res_type, 1);
00105          if (!streq (proc->res_type, "void"))
00106            f_print (fout, "result_%d;\n", i);
00107          else
00108            fprintf (fout, "*result_%d;\n", i);
00109        }
00110       else
00111        {
00112          ptype (proc->res_prefix, proc->res_type, 1);
00113          f_print (fout, " *result_%d;\n", i);
00114        }
00115       /* print out declarations for arguments */
00116       if (proc->arg_num < 2 && !newstyle)
00117        {
00118          f_print (fout, "\t");
00119          if (!streq (proc->args.decls->decl.type, "void"))
00120            {
00121              ptype (proc->args.decls->decl.prefix,
00122                    proc->args.decls->decl.type, 1);
00123              f_print (fout, " ");
00124            }
00125          else
00126            f_print (fout, "char *");      /* cannot have "void" type */
00127          pvname (proc->proc_name, vp->vers_num);
00128          f_print (fout, "_arg;\n");
00129        }
00130       else if (!streq (proc->args.decls->decl.type, "void"))
00131        {
00132          for (l = proc->args.decls; l != NULL; l = l->next)
00133            {
00134              f_print (fout, "\t");
00135              ptype (l->decl.prefix, l->decl.type, 1);
00136              if (strcmp (l->decl.type, "string") == 1)
00137               f_print (fout, " ");
00138              pvname (proc->proc_name, vp->vers_num);
00139              f_print (fout, "_%s;\n", l->decl.name);
00140            }
00141        }
00142     }
00143 
00144   /* generate creation of client handle */
00145   f_print(fout, "\n#ifndef\tDEBUG\n");
00146   f_print (fout, "\tclnt = clnt_create (host, %s, %s, \"%s\");\n",
00147           program_name, vp->vers_name, tirpcflag ? "netpath" : "udp");
00148   f_print (fout, "\tif (clnt == NULL) {\n");
00149   f_print (fout, "\t\tclnt_pcreateerror (host);\n");
00150   f_print (fout, "\t\texit (1);\n\t}\n");
00151   f_print(fout, "#endif\t/* DEBUG */\n\n");
00152 
00153   /* generate calls to procedures */
00154   i = 0;
00155   for (proc = vp->procs; proc != NULL; proc = proc->next)
00156     {
00157       if (mtflag)
00158        f_print(fout, "\tretval_%d = ",++i);
00159       else
00160        f_print (fout, "\tresult_%d = ", ++i);
00161       pvname (proc->proc_name, vp->vers_num);
00162       if (proc->arg_num < 2 && !newstyle)
00163        {
00164          f_print (fout, "(");
00165          if (streq (proc->args.decls->decl.type, "void"))/* cast to void* */
00166            f_print (fout, "(void*)");
00167          f_print (fout, "&");
00168          pvname (proc->proc_name, vp->vers_num);
00169          if (mtflag)
00170            f_print(fout, "_arg, &result_%d, clnt);\n", i);
00171          else
00172            f_print (fout, "_arg, clnt);\n");
00173        }
00174       else if (streq (proc->args.decls->decl.type, "void"))
00175        {
00176          if (mtflag)
00177            f_print (fout, "(&result_%d, clnt);\n", i);
00178          else
00179            f_print (fout, "(clnt);\n");
00180        }
00181       else
00182        {
00183          f_print (fout, "(");
00184          for (l = proc->args.decls; l != NULL; l = l->next)
00185            {
00186              pvname (proc->proc_name, vp->vers_num);
00187              f_print (fout, "_%s, ", l->decl.name);
00188            }
00189          if (mtflag)
00190            f_print(fout, "&result_%d, ", i);
00191          f_print (fout, "clnt);\n");
00192        }
00193       if (mtflag)
00194        {
00195          f_print(fout, "\tif (retval_%d != RPC_SUCCESS) {\n", i);
00196        }
00197       else
00198        {
00199          f_print(fout, "\tif (result_%d == (", i);
00200          ptype(proc->res_prefix, proc->res_type, 1);
00201          f_print(fout, "*) NULL) {\n");
00202        }
00203       f_print(fout, "\t\tclnt_perror (clnt, \"call failed\");\n");
00204       f_print(fout, "\t}\n");
00205     }
00206 
00207   f_print (fout, "#ifndef\tDEBUG\n");
00208   f_print (fout, "\tclnt_destroy (clnt);\n");
00209   f_print (fout, "#endif\t /* DEBUG */\n");
00210   f_print (fout, "}\n");
00211 }
00212 
00213 static void
00214 write_sample_server (definition * def)
00215 {
00216   version_list *vp;
00217   proc_list *proc;
00218 
00219   for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
00220     {
00221       for (proc = vp->procs; proc != NULL; proc = proc->next)
00222        {
00223          f_print (fout, "\n");
00224          if (!mtflag)
00225            {
00226              return_type (proc);
00227              f_print (fout, "*\n");
00228            }
00229          else
00230            f_print (fout, "bool_t\n");
00231          if (Cflag || mtflag)
00232            pvname_svc (proc->proc_name, vp->vers_num);
00233          else
00234            pvname(proc->proc_name, vp->vers_num);
00235          printarglist(proc, "result", RQSTP, "struct svc_req *");
00236          f_print(fout, "{\n");
00237          if (!mtflag)
00238            {
00239              f_print(fout, "\tstatic ");
00240              if(!streq(proc->res_type, "void"))
00241               return_type(proc);
00242              else
00243               f_print(fout, "char *");
00244                                 /* cannot have void type */
00245              /* f_print(fout, " result;\n", proc->res_type); */
00246              f_print(fout, " result;\n");
00247            }
00248          else
00249            f_print(fout, "\tbool_t retval;\n");
00250          fprintf (fout, "\n\t/*\n\t * insert server code here\n\t */\n\n");
00251 
00252          if (!mtflag)
00253            {
00254              if (!streq(proc->res_type, "void"))
00255               f_print(fout, "\treturn &result;\n}\n");
00256              else /* cast back to void * */
00257               f_print(fout, "\treturn (void *) &result;\n}\n");
00258            }
00259          else
00260            f_print(fout, "\treturn retval;\n}\n");
00261        }
00262 
00263       /* put in sample freeing routine */
00264       if (mtflag)
00265        {
00266          f_print(fout, "\nint\n");
00267          pvname(def->def_name, vp->vers_num);
00268          if (Cflag)
00269            f_print(fout,"_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)\n");
00270          else
00271            {
00272              f_print(fout,"_freeresult (transp, xdr_result, result)\n");
00273              f_print(fout,"\tSVCXPRT *transp;\n");
00274              f_print(fout,"\txdrproc_t xdr_result;\n");
00275              f_print(fout,"\tcaddr_t result;\n");
00276            }
00277          f_print(fout, "{\n");
00278          f_print(fout, "\txdr_free (xdr_result, result);\n");
00279          f_print(fout,
00280                 "\n\t/*\n\t * Insert additional freeing code here, if needed\n\t */\n");
00281          f_print(fout, "\n\treturn 1;\n}\n");
00282        }
00283     }
00284 }
00285 
00286 
00287 
00288 static void
00289 return_type (proc_list * plist)
00290 {
00291   ptype (plist->res_prefix, plist->res_type, 1);
00292 }
00293 
00294 void
00295 add_sample_msg (void)
00296 {
00297   f_print (fout, "/*\n");
00298   f_print (fout, " * This is sample code generated by rpcgen.\n");
00299   f_print (fout, " * These are only templates and you can use them\n");
00300   f_print (fout, " * as a guideline for developing your own functions.\n");
00301   f_print (fout, " */\n\n");
00302 }
00303 
00304 void
00305 write_sample_clnt_main (void)
00306 {
00307   list *l;
00308   definition *def;
00309   version_list *vp;
00310 
00311   f_print (fout, "\n\n");
00312   if (Cflag)
00313     f_print (fout, "int\nmain (int argc, char *argv[])\n{\n");
00314   else
00315     f_print (fout, "int\nmain (argc, argv)\nint argc;\nchar *argv[];\n{\n");
00316 
00317   f_print (fout, "\tchar *host;");
00318   f_print (fout, "\n\n\tif (argc < 2) {");
00319   f_print (fout, "\n\t\tprintf (\"usage: %%s server_host\\n\", argv[0]);\n");
00320   f_print (fout, "\t\texit (1);\n\t}");
00321   f_print (fout, "\n\thost = argv[1];\n");
00322 
00323   for (l = defined; l != NULL; l = l->next)
00324     {
00325       def = l->val;
00326       if (def->def_kind != DEF_PROGRAM)
00327        {
00328          continue;
00329        }
00330       for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
00331        {
00332          f_print (fout, "\t");
00333          pvname (def->def_name, vp->vers_num);
00334          f_print (fout, " (host);\n");
00335        }
00336     }
00337   f_print (fout, "exit (0);\n}\n");
00338 }