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 #include <sys/cdefs.h> 33 #if defined(__RCSID) && !defined(lint) 34 #if 0 35 static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI"; 36 #else 37 __RCSID("$NetBSD: rpc_clntout.c,v 1.12 2002/01/31 19:36:48 tv Exp $"); 38 #endif 39 #endif 40 41 /* 42 * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler 43 * Copyright (C) 1987, Sun Microsytsems, Inc. 44 */ 45 #include <stdio.h> 46 #include <string.h> 47 #include <rpc/types.h> 48 #include "rpc_scan.h" 49 #include "rpc_parse.h" 50 #include "rpc_util.h" 51 52 static void write_program __P((definition *)); 53 static char *ampr __P((char *)); 54 static char *aster __P((char *)); 55 static void printbody __P((proc_list *)); 56 57 #define DEFAULT_TIMEOUT 25 /* in seconds */ 58 static char RESULT[] = "clnt_res"; 59 60 61 void 62 write_stubs() 63 { 64 list *l; 65 definition *def; 66 67 f_print(fout, 68 "\n/* Default timeout can be changed using clnt_control() */\n"); 69 f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n", 70 DEFAULT_TIMEOUT); 71 for (l = defined; l != NULL; l = l->next) { 72 def = (definition *) l->val; 73 if (def->def_kind == DEF_PROGRAM) { 74 write_program(def); 75 } 76 } 77 } 78 79 static void 80 write_program(def) 81 definition *def; 82 { 83 version_list *vp; 84 proc_list *proc; 85 86 for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { 87 for (proc = vp->procs; proc != NULL; proc = proc->next) { 88 f_print(fout, "\n"); 89 if (Mflag) 90 f_print(fout, "enum clnt_stat\n"); 91 else { 92 ptype(proc->res_prefix, proc->res_type, 1); 93 f_print(fout, "*\n"); 94 } 95 pvname(proc->proc_name, vp->vers_num); 96 printarglist(proc, RESULT, "clnt", "CLIENT *"); 97 f_print(fout, "{\n"); 98 printbody(proc); 99 f_print(fout, "}\n"); 100 } 101 } 102 } 103 /* Writes out declarations of procedure's argument list. 104 In either ANSI C style, in one of old rpcgen style (pass by reference), 105 or new rpcgen style (multiple arguments, pass by value); 106 */ 107 108 /* sample addargname = "clnt"; sample addargtype = "CLIENT * " */ 109 110 void 111 printarglist(proc, result, addargname, addargtype) 112 proc_list *proc; 113 char *result, *addargname, *addargtype; 114 { 115 116 decl_list *l; 117 118 if (!newstyle) { /* old style: always pass argument by 119 * reference */ 120 if (Cflag) { /* C++ style heading */ 121 f_print(fout, "("); 122 ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); 123 f_print(fout, "*argp, "); 124 if (Mflag) { 125 if (streq(proc->res_type, "void")) 126 f_print(fout, "char "); 127 else 128 ptype(proc->res_prefix, proc->res_type, 0); 129 f_print(fout, "%s%s, ", aster(proc->res_type), 130 result); 131 } 132 f_print(fout, "%s%s)\n", addargtype, addargname); 133 } else { 134 f_print(fout, "(argp, "); 135 if (Mflag) 136 f_print(fout, "%s, ", result); 137 f_print(fout, "%s)\n", addargname); 138 f_print(fout, "\t"); 139 ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1); 140 f_print(fout, "*argp;\n"); 141 if (Mflag) { 142 f_print(fout, "\t"); 143 if (streq(proc->res_type, "void")) 144 f_print(fout, "char "); 145 else 146 ptype(proc->res_prefix, proc->res_type, 0); 147 f_print(fout, "%s%s;\n", aster(proc->res_type), 148 result); 149 } 150 } 151 } else { 152 f_print(fout, "("); 153 if (!streq(proc->args.decls->decl.type, "void")) { 154 /* new style, 1 or multiple arguments */ 155 if (!Cflag) { 156 for (l = proc->args.decls; l != NULL; 157 l = l->next) 158 f_print(fout, "%s, ", l->decl.name); 159 } else {/* C++ style header */ 160 for (l = proc->args.decls; l != NULL; 161 l = l->next) 162 pdeclaration(proc->args.argname, 163 &l->decl, 0, ", "); 164 } 165 } 166 if (!Cflag) { 167 if (Mflag) { 168 f_print(fout, "\t"); 169 if (streq(proc->res_type, "void")) 170 f_print(fout, "char "); 171 else 172 ptype(proc->res_prefix, proc->res_type, 0); 173 f_print(fout, "%s%s;\n", aster(proc->res_type), 174 result); 175 } 176 f_print(fout, "%s)\n", addargname); 177 if (!streq(proc->args.decls->decl.type, "void")) { 178 for (l = proc->args.decls; l != NULL; 179 l = l->next) 180 pdeclaration(proc->args.argname, 181 &l->decl, 1, ";\n"); 182 } 183 } else { 184 if (Mflag) { 185 if (streq(proc->res_type, "void")) 186 f_print(fout, "char "); 187 else 188 ptype(proc->res_prefix, proc->res_type, 0); 189 f_print(fout, "%s%s, ", aster(proc->res_type), 190 result); 191 } 192 f_print(fout, "%s%s)\n", addargtype, addargname); 193 } 194 } 195 196 if (!Cflag) 197 f_print(fout, "\t%s%s;\n", addargtype, addargname); 198 } 199 200 201 static char * 202 ampr(type) 203 char *type; 204 { 205 if (isvectordef(type, REL_ALIAS)) { 206 return (""); 207 } else { 208 return ("&"); 209 } 210 } 211 212 static char * 213 aster(type) 214 char *type; 215 { 216 if (isvectordef(type, REL_ALIAS)) { 217 return (""); 218 } else { 219 return ("*"); 220 } 221 } 222 223 static void 224 printbody(proc) 225 proc_list *proc; 226 { 227 decl_list *l; 228 bool_t args2 = (proc->arg_num > 1); 229 230 /* For new style with multiple arguments, need a structure in which to 231 * stuff the arguments. */ 232 if (newstyle && args2) { 233 f_print(fout, "\t%s", proc->args.argname); 234 f_print(fout, " arg;\n"); 235 } 236 if (!Mflag) { 237 f_print(fout, "\tstatic "); 238 if (streq(proc->res_type, "void")) 239 f_print(fout, "char "); 240 else 241 ptype(proc->res_prefix, proc->res_type, 0); 242 f_print(fout, "%s;\n", RESULT); 243 } 244 f_print(fout, "\n"); 245 if (!Mflag) 246 f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n", 247 ampr(proc->res_type), RESULT, RESULT); 248 if (newstyle && !args2 && (streq(proc->args.decls->decl.type, "void"))) { 249 /* newstyle, 0 arguments */ 250 if (Mflag) { 251 f_print(fout, "\treturn (clnt_call(clnt, %s, xdr_void", 252 proc->proc_name); 253 f_print(fout, ", NULL, xdr_%s, %s, TIMEOUT));\n", 254 stringfix(proc->res_type), RESULT); 255 } else { 256 f_print(fout, "\tif (clnt_call(clnt, %s, xdr_void, ", 257 proc->proc_name); 258 f_print(fout, 259 "NULL, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n", 260 stringfix(proc->res_type), ampr(proc->res_type), 261 RESULT); 262 } 263 } else { 264 if (newstyle && args2) { 265 /* newstyle, multiple arguments: stuff arguments into 266 * structure */ 267 for (l = proc->args.decls; l != NULL; l = l->next) { 268 f_print(fout, "\targ.%s = %s;\n", 269 l->decl.name, l->decl.name); 270 } 271 if (Mflag) { 272 f_print(fout, 273 "\treturn (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s, TIMEOUT));\n", 274 proc->proc_name, proc->args.argname, 275 stringfix(proc->res_type), RESULT); 276 } else { 277 f_print(fout, 278 "\tif (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n", 279 proc->proc_name, proc->args.argname, 280 stringfix(proc->res_type), 281 ampr(proc->res_type), RESULT); 282 } 283 } else { /* single argument, new or old style */ 284 if (Mflag) { 285 f_print(fout, 286 "\treturn (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s, TIMEOUT));\n", 287 proc->proc_name, 288 stringfix(proc->args.decls->decl.type), 289 (newstyle ? "&" : ""), 290 (newstyle ? proc->args.decls->decl.name : "argp"), 291 stringfix(proc->res_type), RESULT); 292 } else { 293 f_print(fout, 294 "\tif (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n", 295 proc->proc_name, 296 stringfix(proc->args.decls->decl.type), 297 (newstyle ? "&" : ""), 298 (newstyle ? proc->args.decls->decl.name : "argp"), 299 stringfix(proc->res_type), 300 ampr(proc->res_type), RESULT); 301 } 302 } 303 } 304 if (!Mflag) { 305 f_print(fout, "\t\treturn (NULL);\n"); 306 if (streq(proc->res_type, "void")) 307 f_print(fout, "\treturn ((void *)%s%s);\n", 308 ampr(proc->res_type), RESULT); 309 else 310 f_print(fout, "\treturn (%s%s);\n", 311 ampr(proc->res_type), RESULT); 312 } 313 } 314