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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 /* 30 * University Copyright- Copyright (c) 1982, 1986, 1988 31 * The Regents of the University of California 32 * All Rights Reserved 33 * 34 * University Acknowledgment- Portions of this document are derived from 35 * software developed by the University of California, Berkeley, and its 36 * contributors. 37 */ 38 39 #pragma ident "%Z%%M% %I% %E% SMI" 40 41 /* 42 * rpc_sample.c, Sample client-server code outputter 43 * for the RPC protocol compiler 44 */ 45 46 #include <stdio.h> 47 #include <string.h> 48 #include "rpc_parse.h" 49 #include "rpc_util.h" 50 51 52 static char RQSTP[] = "rqstp"; 53 54 extern void printarglist(proc_list *, char *, char *, char *); 55 56 static void write_sample_client(char *, version_list *); 57 static void write_sample_server(definition *); 58 static void return_type(proc_list *); 59 60 void 61 write_sample_svc(definition *def) 62 { 63 if (def->def_kind != DEF_PROGRAM) 64 return; 65 write_sample_server(def); 66 } 67 68 int 69 write_sample_clnt(definition *def) 70 { 71 version_list *vp; 72 int count = 0; 73 74 if (def->def_kind != DEF_PROGRAM) 75 return (0); 76 /* generate sample code for each version */ 77 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 78 write_sample_client(def->def_name, vp); 79 ++count; 80 } 81 return (count); 82 } 83 84 static void 85 write_sample_client(char *program_name, version_list *vp) 86 { 87 proc_list *proc; 88 int i; 89 decl_list *l; 90 91 f_print(fout, "\n\nvoid\n"); 92 pvname(program_name, vp->vers_num); 93 if (Cflag) 94 f_print(fout, "(char *host)\n{\n"); 95 else 96 f_print(fout, "(host)\n\tchar *host;\n{\n"); 97 f_print(fout, "\tCLIENT *clnt;\n"); 98 99 i = 0; 100 for (proc = vp->procs; proc != NULL; proc = proc->next) { 101 f_print(fout, "\t"); 102 if (mtflag) { 103 f_print(fout, "enum clnt_stat retval_%d;\n", ++i); 104 if (!streq(proc->res_type, "oneway")) { 105 f_print(fout, "\t"); 106 if (!streq(proc->res_type, "void")) 107 ptype(proc->res_prefix, 108 proc->res_type, 1); 109 else 110 f_print(fout, "void *"); 111 f_print(fout, "result_%d;\n", i); 112 } 113 } else { 114 ptype(proc->res_prefix, proc->res_type, 1); 115 f_print(fout, " *result_%d;\n", ++i); 116 } 117 /* print out declarations for arguments */ 118 if (proc->arg_num < 2 && !newstyle) { 119 f_print(fout, "\t"); 120 if (!streq(proc->args.decls->decl.type, "void")) 121 ptype(proc->args.decls->decl.prefix, 122 proc->args.decls->decl.type, 1); 123 else 124 /* cannot have "void" type */ 125 f_print(fout, "char * "); 126 f_print(fout, " "); 127 pvname(proc->proc_name, vp->vers_num); 128 f_print(fout, "_arg;\n"); 129 } else if (!streq(proc->args.decls->decl.type, "void")) { 130 for (l = proc->args.decls; l != NULL; l = l->next) { 131 f_print(fout, "\t"); 132 ptype(l->decl.prefix, l->decl.type, 1); 133 if (strcmp(l->decl.type, "string") == 1) 134 f_print(fout, " "); 135 pvname(proc->proc_name, vp->vers_num); 136 f_print(fout, "_%s;\n", l->decl.name); 137 } 138 } 139 } 140 141 /* generate creation of client handle */ 142 f_print(fout, "\n#ifndef\tDEBUG\n"); 143 f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n", 144 program_name, vp->vers_name, tirpcflag? "netpath" : "udp"); 145 f_print(fout, "\tif (clnt == (CLIENT *) NULL) {\n"); 146 f_print(fout, "\t\tclnt_pcreateerror(host);\n"); 147 f_print(fout, "\t\texit(1);\n\t}\n"); 148 f_print(fout, "#endif\t/* DEBUG */\n\n"); 149 150 /* generate calls to procedures */ 151 i = 0; 152 for (proc = vp->procs; proc != NULL; proc = proc->next) { 153 if (mtflag) 154 f_print(fout, "\tretval_%d = ", ++i); 155 else 156 f_print(fout, "\tresult_%d = ", ++i); 157 pvname(proc->proc_name, vp->vers_num); 158 if (proc->arg_num < 2 && !newstyle) { 159 f_print(fout, "("); 160 if (streq(proc->args.decls->decl.type, "void")) 161 /* cast to void * */ 162 f_print(fout, "(void *)"); 163 f_print(fout, "&"); 164 pvname(proc->proc_name, vp->vers_num); 165 if (mtflag) { 166 if (streq(proc->res_type, "oneway")) 167 f_print(fout, "_arg, clnt);\n"); 168 else 169 f_print(fout, 170 "_arg, &result_%d, clnt);\n", i); 171 } else 172 f_print(fout, "_arg, clnt);\n"); 173 174 } else if (streq(proc->args.decls->decl.type, "void")) { 175 if (mtflag) { 176 if (streq(proc->res_type, "oneway")) 177 f_print(fout, "(clnt);\n"); 178 else 179 f_print(fout, 180 "(&result_%d, clnt);\n", i); 181 } else 182 f_print(fout, "(clnt);\n"); 183 } else { 184 f_print(fout, "("); 185 for (l = proc->args.decls; l != NULL; l = l->next) { 186 pvname(proc->proc_name, vp->vers_num); 187 f_print(fout, "_%s, ", l->decl.name); 188 } 189 if (mtflag) { 190 if (!streq(proc->res_type, "oneway")) 191 f_print(fout, "&result_%d, ", i); 192 } 193 194 f_print(fout, "clnt);\n"); 195 } 196 if (mtflag) { 197 f_print(fout, "\tif (retval_%d != RPC_SUCCESS) {\n", i); 198 } else { 199 f_print(fout, "\tif (result_%d == (", i); 200 ptype(proc->res_prefix, proc->res_type, 1); 201 f_print(fout, "*) NULL) {\n"); 202 } 203 f_print(fout, "\t\tclnt_perror(clnt, \"call failed\");\n"); 204 f_print(fout, "\t}\n"); 205 } 206 207 f_print(fout, "#ifndef\tDEBUG\n"); 208 f_print(fout, "\tclnt_destroy(clnt);\n"); 209 f_print(fout, "#endif\t /* DEBUG */\n"); 210 f_print(fout, "}\n"); 211 } 212 213 static void 214 write_sample_server(definition *def) 215 { 216 version_list *vp; 217 proc_list *proc; 218 219 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 220 for (proc = vp->procs; proc != NULL; proc = proc->next) { 221 f_print(fout, "\n"); 222 if (!mtflag) { 223 return_type(proc); 224 f_print(fout, "*\n"); 225 } else { 226 f_print(fout, "bool_t\n"); 227 } 228 if (Cflag || mtflag) 229 pvname_svc(proc->proc_name, vp->vers_num); 230 else 231 pvname(proc->proc_name, vp->vers_num); 232 printarglist(proc, "result", RQSTP, "struct svc_req *"); 233 234 f_print(fout, "{\n"); 235 236 if (!mtflag) { 237 f_print(fout, "\tstatic "); 238 if ((!streq(proc->res_type, "void")) && 239 (!streq(proc->res_type, "oneway"))) 240 return_type(proc); 241 else 242 f_print(fout, "char *"); 243 /* cannot have void type */ 244 f_print(fout, " result;\n"); 245 } 246 247 f_print(fout, "\n\t/*\n\t * insert server code " 248 "here\n\t */\n\n"); 249 250 if (!mtflag) 251 if (!streq(proc->res_type, "void")) 252 f_print(fout, 253 "\treturn (&result);\n}\n"); 254 else /* cast back to void * */ 255 f_print(fout, "\treturn((void *) " 256 "&result);\n}\n"); 257 else 258 f_print(fout, "\treturn (retval);\n}\n"); 259 } 260 /* put in sample freeing routine */ 261 if (mtflag) { 262 f_print(fout, "\nint\n"); 263 pvname(def->def_name, vp->vers_num); 264 if (Cflag) 265 f_print(fout, "_freeresult(SVCXPRT *transp," 266 " xdrproc_t xdr_result," 267 " caddr_t result)\n"); 268 else { 269 f_print(fout, "_freeresult(transp, xdr_result," 270 " 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 "\t(void) xdr_free(xdr_result, result);\n" 277 "\n\t/*\n\t * Insert additional freeing" 278 " code here, if needed\n\t */\n" 279 "\n\n\treturn (TRUE);\n}\n"); 280 } 281 } 282 } 283 284 static void 285 return_type(proc_list *plist) 286 { 287 ptype(plist->res_prefix, plist->res_type, 1); 288 } 289 290 void 291 add_sample_msg(void) 292 { 293 f_print(fout, "/*\n"); 294 f_print(fout, " * This is sample code generated by rpcgen.\n"); 295 f_print(fout, " * These are only templates and you can use them\n"); 296 f_print(fout, " * as a guideline for developing your own functions.\n"); 297 f_print(fout, " */\n\n"); 298 } 299 300 void 301 write_sample_clnt_main(void) 302 { 303 list *l; 304 definition *def; 305 version_list *vp; 306 307 f_print(fout, "\n\n"); 308 if (Cflag) 309 f_print(fout, "int\nmain(int argc, char *argv[])\n{\n"); 310 else 311 f_print(fout, "int\nmain(argc, argv)\n\tint argc;\n" 312 "\tchar *argv[];\n{\n"); 313 314 f_print(fout, "\tchar *host;"); 315 f_print(fout, "\n\n\tif (argc < 2) {"); 316 f_print(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\"," 317 " 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 def = l->val; 323 if (def->def_kind != DEF_PROGRAM) 324 continue; 325 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 326 f_print(fout, "\t"); 327 pvname(def->def_name, vp->vers_num); 328 f_print(fout, "(host);\n"); 329 } 330 } 331 f_print(fout, "}\n"); 332 } 333