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