1/* $NetBSD: rpc_clntout.c,v 1.12 2002/01/31 19:36:48 tv Exp $ */ 2/* 3 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 4 * unrestricted use provided that this legend is included on all tape 5 * media and as a part of the software program in whole or part. Users 6 * may copy or modify Sun RPC without charge, but are not authorized 7 * to license or distribute it to anyone else except as part of a product or 8 * program developed by the user or with the express written consent of 9 * Sun Microsystems, Inc. 10 * 11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14 * 15 * Sun RPC is provided with no support and without any obligation on the 16 * part of Sun Microsystems, Inc. to assist in its use, correction, 17 * modification or enhancement. 18 * 19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21 * OR ANY PART THEREOF. 22 * 23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24 * or profits or other special, indirect and consequential damages, even if 25 * Sun has been advised of the possibility of such damages. 26 * 27 * Sun Microsystems, Inc. 28 * 2550 Garcia Avenue 29 * Mountain View, California 94043 30 */ 31 32#if HAVE_NBTOOL_CONFIG_H 33#include "nbtool_config.h" 34#endif 35 36#include <sys/cdefs.h> 37#if defined(__RCSID) && !defined(lint) 38#if 0 39static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI"; 40#else 41__RCSID("$NetBSD: rpc_clntout.c,v 1.12 2002/01/31 19:36:48 tv Exp $"); 42#endif 43#endif 44 45/* 46 * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler 47 * Copyright (C) 1987, Sun Microsytsems, Inc. 48 */ 49#include <stdio.h> 50#include <string.h> 51#include <rpc/types.h> 52#include "rpc_scan.h" 53#include "rpc_parse.h" 54#include "rpc_util.h" 55 56static void write_program __P((definition *)); 57static char *ampr __P((char *)); 58static char *aster __P((char *)); 59static void printbody __P((proc_list *)); 60 61#define DEFAULT_TIMEOUT 25 /* in seconds */ 62static char RESULT[] = "clnt_res"; 63 64 65void 66write_stubs() 67{ 68 list *l; 69 definition *def; 70 71 f_print(fout, 72 "\n/* Default timeout can be changed using clnt_control() */\n"); 73 f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n", 74 DEFAULT_TIMEOUT); 75 for (l = defined; l != NULL; l = l->next) { 76 def = (definition *) l->val; 77 if (def->def_kind == DEF_PROGRAM) { 78 write_program(def); 79 } 80 } 81} 82 83static void 84write_program(def) 85 definition *def; 86{ 87 version_list *vp; 88 proc_list *proc; 89 90 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 91 for (proc = vp->procs; proc != NULL; proc = proc->next) { 92 f_print(fout, "\n"); 93 if (Mflag) 94 f_print(fout, "enum clnt_stat\n"); 95 else { 96 ptype(proc->res_prefix, proc->res_type, 1); 97 f_print(fout, "*\n"); 98 } 99 pvname(proc->proc_name, vp->vers_num); 100 printarglist(proc, RESULT, "clnt", "CLIENT *"); 101 f_print(fout, "{\n"); 102 printbody(proc); 103 f_print(fout, "}\n"); 104 } 105 } 106} 107/* Writes out declarations of procedure's argument list. 108 In either ANSI C style, in one of old rpcgen style (pass by reference), 109 or new rpcgen style (multiple arguments, pass by value); 110 */ 111 112/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */ 113 114void 115printarglist(proc, result, addargname, addargtype) 116 proc_list *proc; 117 char *result, *addargname, *addargtype; 118{ 119 120 decl_list *l; 121 122 if (!newstyle) { /* old style: always pass argument by 123 * reference */ 124 if (Cflag) { /* C++ style heading */ 125 f_print(fout, "("); 126 ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); 127 f_print(fout, "*argp, "); 128 if (Mflag) { 129 if (streq(proc->res_type, "void")) 130 f_print(fout, "char "); 131 else 132 ptype(proc->res_prefix, proc->res_type, 0); 133 f_print(fout, "%s%s, ", aster(proc->res_type), 134 result); 135 } 136 f_print(fout, "%s%s)\n", addargtype, addargname); 137 } else { 138 f_print(fout, "(argp, "); 139 if (Mflag) 140 f_print(fout, "%s, ", result); 141 f_print(fout, "%s)\n", addargname); 142 f_print(fout, "\t"); 143 ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); 144 f_print(fout, "*argp;\n"); 145 if (Mflag) { 146 f_print(fout, "\t"); 147 if (streq(proc->res_type, "void")) 148 f_print(fout, "char "); 149 else 150 ptype(proc->res_prefix, proc->res_type, 0); 151 f_print(fout, "%s%s;\n", aster(proc->res_type), 152 result); 153 } 154 } 155 } else { 156 f_print(fout, "("); 157 if (!streq(proc->args.decls->decl.type, "void")) { 158 /* new style, 1 or multiple arguments */ 159 if (!Cflag) { 160 for (l = proc->args.decls; l != NULL; 161 l = l->next) 162 f_print(fout, "%s, ", l->decl.name); 163 } else {/* C++ style header */ 164 for (l = proc->args.decls; l != NULL; 165 l = l->next) 166 pdeclaration(proc->args.argname, 167 &l->decl, 0, ", "); 168 } 169 } 170 if (!Cflag) { 171 if (Mflag) { 172 f_print(fout, "\t"); 173 if (streq(proc->res_type, "void")) 174 f_print(fout, "char "); 175 else 176 ptype(proc->res_prefix, proc->res_type, 0); 177 f_print(fout, "%s%s;\n", aster(proc->res_type), 178 result); 179 } 180 f_print(fout, "%s)\n", addargname); 181 if (!streq(proc->args.decls->decl.type, "void")) { 182 for (l = proc->args.decls; l != NULL; 183 l = l->next) 184 pdeclaration(proc->args.argname, 185 &l->decl, 1, ";\n"); 186 } 187 } else { 188 if (Mflag) { 189 if (streq(proc->res_type, "void")) 190 f_print(fout, "char "); 191 else 192 ptype(proc->res_prefix, proc->res_type, 0); 193 f_print(fout, "%s%s, ", aster(proc->res_type), 194 result); 195 } 196 f_print(fout, "%s%s)\n", addargtype, addargname); 197 } 198 } 199 200 if (!Cflag) 201 f_print(fout, "\t%s%s;\n", addargtype, addargname); 202} 203 204 205static char * 206ampr(type) 207 char *type; 208{ 209 if (isvectordef(type, REL_ALIAS)) { 210 return (""); 211 } else { 212 return ("&"); 213 } 214} 215 216static char * 217aster(type) 218 char *type; 219{ 220 if (isvectordef(type, REL_ALIAS)) { 221 return (""); 222 } else { 223 return ("*"); 224 } 225} 226 227static void 228printbody(proc) 229 proc_list *proc; 230{ 231 decl_list *l; 232 bool_t args2 = (proc->arg_num > 1); 233 234 /* For new style with multiple arguments, need a structure in which to 235 * stuff the arguments. */ 236 if (newstyle && args2) { 237 f_print(fout, "\t%s", proc->args.argname); 238 f_print(fout, " arg;\n"); 239 } 240 if (!Mflag) { 241 f_print(fout, "\tstatic "); 242 if (streq(proc->res_type, "void")) 243 f_print(fout, "char "); 244 else 245 ptype(proc->res_prefix, proc->res_type, 0); 246 f_print(fout, "%s;\n", RESULT); 247 } 248 f_print(fout, "\n"); 249 if (!Mflag) 250 f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n", 251 ampr(proc->res_type), RESULT, RESULT); 252 if (newstyle && !args2 && (streq(proc->args.decls->decl.type, "void"))) { 253 /* newstyle, 0 arguments */ 254 if (Mflag) { 255 f_print(fout, "\treturn (clnt_call(clnt, %s, xdr_void", 256 proc->proc_name); 257 f_print(fout, ", NULL, xdr_%s, %s, TIMEOUT));\n", 258 stringfix(proc->res_type), RESULT); 259 } else { 260 f_print(fout, "\tif (clnt_call(clnt, %s, xdr_void, ", 261 proc->proc_name); 262 f_print(fout, 263 "NULL, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n", 264 stringfix(proc->res_type), ampr(proc->res_type), 265 RESULT); 266 } 267 } else { 268 if (newstyle && args2) { 269 /* newstyle, multiple arguments: stuff arguments into 270 * structure */ 271 for (l = proc->args.decls; l != NULL; l = l->next) { 272 f_print(fout, "\targ.%s = %s;\n", 273 l->decl.name, l->decl.name); 274 } 275 if (Mflag) { 276 f_print(fout, 277 "\treturn (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s, TIMEOUT));\n", 278 proc->proc_name, proc->args.argname, 279 stringfix(proc->res_type), RESULT); 280 } else { 281 f_print(fout, 282 "\tif (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n", 283 proc->proc_name, proc->args.argname, 284 stringfix(proc->res_type), 285 ampr(proc->res_type), RESULT); 286 } 287 } else { /* single argument, new or old style */ 288 if (Mflag) { 289 f_print(fout, 290 "\treturn (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s, TIMEOUT));\n", 291 proc->proc_name, 292 stringfix(proc->args.decls->decl.type), 293 (newstyle ? "&" : ""), 294 (newstyle ? proc->args.decls->decl.name : "argp"), 295 stringfix(proc->res_type), RESULT); 296 } else { 297 f_print(fout, 298 "\tif (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n", 299 proc->proc_name, 300 stringfix(proc->args.decls->decl.type), 301 (newstyle ? "&" : ""), 302 (newstyle ? proc->args.decls->decl.name : "argp"), 303 stringfix(proc->res_type), 304 ampr(proc->res_type), RESULT); 305 } 306 } 307 } 308 if (!Mflag) { 309 f_print(fout, "\t\treturn (NULL);\n"); 310 if (streq(proc->res_type, "void")) 311 f_print(fout, "\treturn ((void *)%s%s);\n", 312 ampr(proc->res_type), RESULT); 313 else 314 f_print(fout, "\treturn (%s%s);\n", 315 ampr(proc->res_type), RESULT); 316 } 317} 318