1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 /* 29 * University Copyright- Copyright (c) 1982, 1986, 1988 30 * The Regents of the University of California 31 * All Rights Reserved 32 * 33 * University Acknowledgment- Portions of this document are derived from 34 * software developed by the University of California, Berkeley, and its 35 * contributors. 36 */ 37 38 /* 39 * rpc_sample.c, Sample client-server code outputter 40 * for the RPC protocol compiler 41 */ 42 43 #include <stdio.h> 44 #include <string.h> 45 #include "rpc_parse.h" 46 #include "rpc_util.h" 47 48 49 static char RQSTP[] = "rqstp"; 50 51 extern void printarglist(proc_list *, char *, char *, char *); 52 53 static void write_sample_client(char *, version_list *); 54 static void write_sample_server(definition *); 55 static void return_type(proc_list *); 56 57 void 58 write_sample_svc(definition *def) 59 { 60 if (def->def_kind != DEF_PROGRAM) 61 return; 62 write_sample_server(def); 63 } 64 65 int 66 write_sample_clnt(definition *def) 67 { 68 version_list *vp; 69 int count = 0; 70 71 if (def->def_kind != DEF_PROGRAM) 72 return (0); 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); 76 ++count; 77 } 78 return (count); 79 } 80 81 static void 82 write_sample_client(char *program_name, version_list *vp) 83 { 84 proc_list *proc; 85 int i; 86 decl_list *l; 87 88 f_print(fout, "\n\nvoid\n"); 89 pvname(program_name, vp->vers_num); 90 if (Cflag) 91 f_print(fout, "(char *host)\n{\n"); 92 else 93 f_print(fout, "(host)\n\tchar *host;\n{\n"); 94 f_print(fout, "\tCLIENT *clnt;\n"); 95 96 i = 0; 97 for (proc = vp->procs; proc != NULL; proc = proc->next) { 98 f_print(fout, "\t"); 99 if (mtflag) { 100 f_print(fout, "enum clnt_stat retval_%d;\n", ++i); 101 if (!streq(proc->res_type, "oneway")) { 102 f_print(fout, "\t"); 103 if (!streq(proc->res_type, "void")) 104 ptype(proc->res_prefix, 105 proc->res_type, 1); 106 else 107 f_print(fout, "void *"); 108 f_print(fout, "result_%d;\n", i); 109 } 110 } else { 111 ptype(proc->res_prefix, proc->res_type, 1); 112 f_print(fout, " *result_%d;\n", ++i); 113 } 114 /* print out declarations for arguments */ 115 if (proc->arg_num < 2 && !newstyle) { 116 f_print(fout, "\t"); 117 if (!streq(proc->args.decls->decl.type, "void")) 118 ptype(proc->args.decls->decl.prefix, 119 proc->args.decls->decl.type, 1); 120 else 121 /* cannot have "void" type */ 122 f_print(fout, "char * "); 123 f_print(fout, " "); 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) { 128 f_print(fout, "\t"); 129 ptype(l->decl.prefix, l->decl.type, 1); 130 if (strcmp(l->decl.type, "string") == 1) 131 f_print(fout, " "); 132 pvname(proc->proc_name, vp->vers_num); 133 f_print(fout, "_%s;\n", l->decl.name); 134 } 135 } 136 } 137 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"); 146 147 /* generate calls to procedures */ 148 i = 0; 149 for (proc = vp->procs; proc != NULL; proc = proc->next) { 150 if (mtflag) 151 f_print(fout, "\tretval_%d = ", ++i); 152 else 153 f_print(fout, "\tresult_%d = ", ++i); 154 pvname(proc->proc_name, vp->vers_num); 155 if (proc->arg_num < 2 && !newstyle) { 156 f_print(fout, "("); 157 if (streq(proc->args.decls->decl.type, "void")) 158 /* cast to void * */ 159 f_print(fout, "(void *)"); 160 f_print(fout, "&"); 161 pvname(proc->proc_name, vp->vers_num); 162 if (mtflag) { 163 if (streq(proc->res_type, "oneway")) 164 f_print(fout, "_arg, clnt);\n"); 165 else 166 f_print(fout, 167 "_arg, &result_%d, clnt);\n", i); 168 } else 169 f_print(fout, "_arg, clnt);\n"); 170 171 } else if (streq(proc->args.decls->decl.type, "void")) { 172 if (mtflag) { 173 if (streq(proc->res_type, "oneway")) 174 f_print(fout, "(clnt);\n"); 175 else 176 f_print(fout, 177 "(&result_%d, clnt);\n", i); 178 } else 179 f_print(fout, "(clnt);\n"); 180 } else { 181 f_print(fout, "("); 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); 185 } 186 if (mtflag) { 187 if (!streq(proc->res_type, "oneway")) 188 f_print(fout, "&result_%d, ", i); 189 } 190 191 f_print(fout, "clnt);\n"); 192 } 193 if (mtflag) { 194 f_print(fout, "\tif (retval_%d != RPC_SUCCESS) {\n", i); 195 } else { 196 f_print(fout, "\tif (result_%d == (", i); 197 ptype(proc->res_prefix, proc->res_type, 1); 198 f_print(fout, "*) NULL) {\n"); 199 } 200 f_print(fout, "\t\tclnt_perror(clnt, \"call failed\");\n"); 201 f_print(fout, "\t}\n"); 202 } 203 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"); 208 } 209 210 static void 211 write_sample_server(definition *def) 212 { 213 version_list *vp; 214 proc_list *proc; 215 216 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 217 for (proc = vp->procs; proc != NULL; proc = proc->next) { 218 f_print(fout, "\n"); 219 if (!mtflag) { 220 return_type(proc); 221 f_print(fout, "*\n"); 222 } else { 223 f_print(fout, "bool_t\n"); 224 } 225 if (Cflag || mtflag) 226 pvname_svc(proc->proc_name, vp->vers_num); 227 else 228 pvname(proc->proc_name, vp->vers_num); 229 printarglist(proc, "result", RQSTP, "struct svc_req *"); 230 231 f_print(fout, "{\n"); 232 233 if (!mtflag) { 234 f_print(fout, "\tstatic "); 235 if ((!streq(proc->res_type, "void")) && 236 (!streq(proc->res_type, "oneway"))) 237 return_type(proc); 238 else 239 f_print(fout, "char *"); 240 /* cannot have void type */ 241 f_print(fout, " result;\n"); 242 } 243 244 f_print(fout, "\n\t/*\n\t * insert server code " 245 "here\n\t */\n\n"); 246 247 if (!mtflag) 248 if (!streq(proc->res_type, "void")) 249 f_print(fout, 250 "\treturn (&result);\n}\n"); 251 else /* cast back to void * */ 252 f_print(fout, "\treturn((void *) " 253 "&result);\n}\n"); 254 else 255 f_print(fout, "\treturn (retval);\n}\n"); 256 } 257 /* put in sample freeing routine */ 258 if (mtflag) { 259 f_print(fout, "\nint\n"); 260 pvname(def->def_name, vp->vers_num); 261 if (Cflag) 262 f_print(fout, "_freeresult(SVCXPRT *transp," 263 " xdrproc_t xdr_result," 264 " caddr_t result)\n"); 265 else { 266 f_print(fout, "_freeresult(transp, xdr_result," 267 " result)\n"); 268 f_print(fout, "\tSVCXPRT *transp;\n"); 269 f_print(fout, "\txdrproc_t xdr_result;\n"); 270 f_print(fout, "\tcaddr_t result;\n"); 271 } 272 f_print(fout, "{\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"); 277 } 278 } 279 } 280 281 static void 282 return_type(proc_list *plist) 283 { 284 ptype(plist->res_prefix, plist->res_type, 1); 285 } 286 287 void 288 add_sample_msg(void) 289 { 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"); 295 } 296 297 void 298 write_sample_clnt_main(void) 299 { 300 list *l; 301 definition *def; 302 version_list *vp; 303 304 f_print(fout, "\n\n"); 305 if (Cflag) 306 f_print(fout, "int\nmain(int argc, char *argv[])\n{\n"); 307 else 308 f_print(fout, "int\nmain(argc, argv)\n\tint argc;\n" 309 "\tchar *argv[];\n{\n"); 310 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\"," 314 " argv[0]);\n"); 315 f_print(fout, "\t\texit(1);\n\t}"); 316 f_print(fout, "\n\thost = argv[1];\n"); 317 318 for (l = defined; l != NULL; l = l->next) { 319 def = l->val; 320 if (def->def_kind != DEF_PROGRAM) 321 continue; 322 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 323 f_print(fout, "\t"); 324 pvname(def->def_name, vp->vers_num); 325 f_print(fout, "(host);\n"); 326 } 327 } 328 f_print(fout, "}\n"); 329 } 330