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