1 /* $OpenBSD: rpc_sample.c,v 1.16 2009/10/27 23:59:42 deraadt Exp $ */ 2 /* $NetBSD: rpc_sample.c,v 1.2 1995/06/11 21:50:01 pk Exp $ */ 3 /* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or 9 * program developed by the user or with the express written consent of 10 * Sun Microsystems, Inc. 11 * 12 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 13 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 14 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 15 * 16 * Sun RPC is provided with no support and without any obligation on the 17 * part of Sun Microsystems, Inc. to assist in its use, correction, 18 * modification or enhancement. 19 * 20 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 21 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 22 * OR ANY PART THEREOF. 23 * 24 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 25 * or profits or other special, indirect and consequential damages, even if 26 * Sun has been advised of the possibility of such damages. 27 * 28 * Sun Microsystems, Inc. 29 * 2550 Garcia Avenue 30 * Mountain View, California 94043 31 */ 32 33 /* 34 * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler 35 */ 36 37 #include <sys/cdefs.h> 38 #include <stdio.h> 39 #include <string.h> 40 #include "rpc_parse.h" 41 #include "rpc_util.h" 42 43 static char RQSTP[] = "rqstp"; 44 45 static void write_sample_client(char *, version_list *); 46 static void write_sample_server(definition *); 47 static void return_type(proc_list *); 48 49 void 50 write_sample_svc(def) 51 definition *def; 52 { 53 54 if (def->def_kind != DEF_PROGRAM) 55 return; 56 write_sample_server(def); 57 } 58 59 60 int 61 write_sample_clnt(def) 62 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 write_sample_client(def->def_name, vp); 72 ++count; 73 } 74 return(count); 75 } 76 77 78 static void 79 write_sample_client(program_name, vp) 80 char *program_name; 81 version_list *vp; 82 { 83 proc_list *proc; 84 int i; 85 decl_list *l; 86 87 fprintf(fout, "\n\nvoid\n"); 88 pvname(program_name, vp->vers_num); 89 if (Cflag) 90 fprintf(fout,"(char *host)\n{\n"); 91 else 92 fprintf(fout, "(host)\nchar *host;\n{\n"); 93 fprintf(fout, "\tCLIENT *clnt;\n"); 94 95 i = 0; 96 for (proc = vp->procs; proc != NULL; proc = proc->next) { 97 fprintf(fout, "\t"); 98 ptype(proc->res_prefix, proc->res_type, 1); 99 fprintf(fout, " *result_%d;\n",++i); 100 /* print out declarations for arguments */ 101 if (proc->arg_num < 2 && !newstyle) { 102 fprintf(fout, "\t"); 103 if (!streq(proc->args.decls->decl.type, "void")) 104 ptype(proc->args.decls->decl.prefix, 105 proc->args.decls->decl.type, 1); 106 else 107 fprintf(fout, "char *"); /* cannot have "void" type */ 108 fprintf(fout, " "); 109 pvname(proc->proc_name, vp->vers_num); 110 fprintf(fout, "_arg;\n"); 111 } else if (!streq(proc->args.decls->decl.type, "void")) { 112 for (l = proc->args.decls; l != NULL; l = l->next) { 113 fprintf(fout, "\t"); 114 ptype(l->decl.prefix, l->decl.type, 1); 115 fprintf(fout, " "); 116 pvname(proc->proc_name, vp->vers_num); 117 fprintf(fout, "_%s;\n", l->decl.name); 118 /* pdeclaration(proc->args.argname, &l->decl, 1, ";\n");*/ 119 } 120 } 121 } 122 123 /* generate creation of client handle */ 124 fprintf(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n", 125 program_name, vp->vers_name, tirpcflag? "netpath" : "udp"); 126 fprintf(fout, "\tif (clnt == NULL) {\n"); 127 fprintf(fout, "\t\tclnt_pcreateerror(host);\n"); 128 fprintf(fout, "\t\texit(1);\n\t}\n"); 129 130 /* generate calls to procedures */ 131 i = 0; 132 for (proc = vp->procs; proc != NULL; proc = proc->next) { 133 fprintf(fout, "\tresult_%d = ",++i); 134 pvname(proc->proc_name, vp->vers_num); 135 if (proc->arg_num < 2 && !newstyle) { 136 fprintf(fout, "("); 137 if (streq(proc->args.decls->decl.type, "void")) 138 fprintf(fout, "(void*)"); 139 fprintf(fout, "&"); 140 pvname(proc->proc_name, vp->vers_num); 141 fprintf(fout, "_arg, clnt);\n"); 142 } else if (streq(proc->args.decls->decl.type, "void")) { 143 fprintf(fout, "(clnt);\n"); 144 } else { 145 fprintf(fout, "("); 146 for (l = proc->args.decls; l != NULL; l = l->next) { 147 pvname(proc->proc_name, vp->vers_num); 148 fprintf(fout, "_%s, ", l->decl.name); 149 } 150 fprintf(fout, "clnt);\n"); 151 } 152 fprintf(fout, "\tif (result_%d == NULL) {\n", i); 153 fprintf(fout, "\t\tclnt_perror(clnt, \"call failed:\");\n"); 154 fprintf(fout, "\t}\n"); 155 } 156 157 fprintf(fout, "\tclnt_destroy(clnt);\n"); 158 fprintf(fout, "}\n"); 159 } 160 161 static void 162 write_sample_server(def) 163 definition *def; 164 { 165 version_list *vp; 166 proc_list *proc; 167 168 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 169 for (proc = vp->procs; proc != NULL; proc = proc->next) { 170 fprintf(fout, "\n"); 171 /* if (Cflag) 172 fprintf(fout, "extern \"C\"{\n"); 173 */ 174 return_type(proc); 175 fprintf(fout, "* \n"); 176 pvname_svc(proc->proc_name, vp->vers_num); 177 printarglist(proc, RQSTP, "struct svc_req *"); 178 179 fprintf(fout, "{\n"); 180 fprintf(fout, "\n\tstatic "); 181 if (!streq(proc->res_type, "void")) 182 return_type(proc); 183 else 184 fprintf(fout, "char*"); /* cannot have void type */ 185 fprintf(fout, " result;\n"); 186 fprintf(fout, 187 "\n\t/*\n\t * insert server code here\n\t */\n\n"); 188 if (!streq(proc->res_type, "void")) 189 fprintf(fout, "\treturn(&result);\n}\n"); 190 else /* cast back to void * */ 191 fprintf(fout, "\treturn((void*) &result);\n}\n"); 192 /* if (Cflag) 193 fprintf(fout, "}\n"); 194 */ 195 } 196 } 197 } 198 199 static void 200 return_type(plist) 201 proc_list *plist; 202 { 203 ptype(plist->res_prefix, plist->res_type, 1); 204 } 205 206 void 207 add_sample_msg(void) 208 { 209 fprintf(fout, "/*\n"); 210 fprintf(fout, " * This is sample code generated by rpcgen.\n"); 211 fprintf(fout, " * These are only templates and you can use them\n"); 212 fprintf(fout, " * as a guideline for developing your own functions.\n"); 213 fprintf(fout, " */\n\n"); 214 } 215 216 void 217 write_sample_clnt_main() 218 { 219 list *l; 220 definition *def; 221 version_list *vp; 222 223 fprintf(fout, "\n\n"); 224 if (Cflag) 225 fprintf(fout,"main(int argc, char *argv[])\n{\n"); 226 else 227 fprintf(fout, "main(argc, argv)\nint argc;\nchar *argv[];\n{\n"); 228 229 fprintf(fout, "\tchar *host;"); 230 fprintf(fout, "\n\n\tif (argc < 2) {"); 231 fprintf(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n"); 232 fprintf(fout, "\t\texit(1);\n\t}"); 233 fprintf(fout, "\n\thost = argv[1];\n"); 234 235 for (l = defined; l != NULL; l = l->next) { 236 def = l->val; 237 if (def->def_kind != DEF_PROGRAM) 238 continue; 239 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 240 fprintf(fout, "\t"); 241 pvname(def->def_name, vp->vers_num); 242 fprintf(fout, "(host);\n"); 243 } 244 } 245 fprintf(fout, "}\n"); 246 } 247