1 /* @(#)rpc_main.c 2.2 88/08/01 4.0 RPCSRC */ 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. 9 * 10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13 * 14 * Sun RPC is provided with no support and without any obligation on the 15 * part of Sun Microsystems, Inc. to assist in its use, correction, 16 * modification or enhancement. 17 * 18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20 * OR ANY PART THEREOF. 21 * 22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23 * or profits or other special, indirect and consequential damages, even if 24 * Sun has been advised of the possibility of such damages. 25 * 26 * Sun Microsystems, Inc. 27 * 2550 Garcia Avenue 28 * Mountain View, California 94043 29 */ 30 #ifndef lint 31 /*static char sccsid[] = "from: @(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI";*/ 32 static char rcsid[] = "$Id: rpc_main.c,v 1.1 1993/09/13 23:20:15 jtc Exp $"; 33 #endif 34 35 /* 36 * rpc_main.c, Top level of the RPC protocol compiler. 37 * Copyright (C) 1987, Sun Microsystems, Inc. 38 */ 39 40 #include <stdio.h> 41 #include <strings.h> 42 #include <sys/file.h> 43 #include "rpc_util.h" 44 #include "rpc_parse.h" 45 #include "rpc_scan.h" 46 47 #define EXTEND 1 /* alias for TRUE */ 48 49 struct commandline { 50 int cflag; 51 int hflag; 52 int lflag; 53 int sflag; 54 int mflag; 55 char *infile; 56 char *outfile; 57 }; 58 59 static char *cmdname; 60 static char CPP[] = "/usr/bin/cpp"; 61 static char CPPFLAGS[] = "-C"; 62 static char *allv[] = { 63 "rpcgen", "-s", "udp", "-s", "tcp", 64 }; 65 static int allc = sizeof(allv)/sizeof(allv[0]); 66 67 68 static int h_output(), c_output(), s_output(), l_output(), do_registers(), 69 parseargs(); 70 71 main(argc, argv) 72 int argc; 73 char *argv[]; 74 75 { 76 struct commandline cmd; 77 78 if (!parseargs(argc, argv, &cmd)) { 79 f_print(stderr, 80 "usage: %s infile\n", cmdname); 81 f_print(stderr, 82 " %s [-c | -h | -l | -m] [-o outfile] [infile]\n", 83 cmdname); 84 f_print(stderr, 85 " %s [-s udp|tcp]* [-o outfile] [infile]\n", 86 cmdname); 87 exit(1); 88 } 89 if (cmd.cflag) { 90 c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile); 91 } else if (cmd.hflag) { 92 h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile); 93 } else if (cmd.lflag) { 94 l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile); 95 } else if (cmd.sflag || cmd.mflag) { 96 s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND, 97 cmd.outfile, cmd.mflag); 98 } else { 99 c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); 100 reinitialize(); 101 h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h"); 102 reinitialize(); 103 l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); 104 reinitialize(); 105 s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, 106 "_svc.c", cmd.mflag); 107 } 108 exit(0); 109 } 110 111 /* 112 * add extension to filename 113 */ 114 static char * 115 extendfile(file, ext) 116 char *file; 117 char *ext; 118 { 119 char *res; 120 char *p; 121 122 res = alloc(strlen(file) + strlen(ext) + 1); 123 if (res == NULL) { 124 abort(); 125 } 126 p = rindex(file, '.'); 127 if (p == NULL) { 128 p = file + strlen(file); 129 } 130 (void) strcpy(res, file); 131 (void) strcpy(res + (p - file), ext); 132 return (res); 133 } 134 135 /* 136 * Open output file with given extension 137 */ 138 static 139 open_output(infile, outfile) 140 char *infile; 141 char *outfile; 142 { 143 if (outfile == NULL) { 144 fout = stdout; 145 return; 146 } 147 if (infile != NULL && streq(outfile, infile)) { 148 f_print(stderr, "%s: output would overwrite %s\n", cmdname, 149 infile); 150 crash(); 151 } 152 fout = fopen(outfile, "w"); 153 if (fout == NULL) { 154 f_print(stderr, "%s: unable to open ", cmdname); 155 perror(outfile); 156 crash(); 157 } 158 record_open(outfile); 159 } 160 161 /* 162 * Open input file with given define for C-preprocessor 163 */ 164 static 165 open_input(infile, define) 166 char *infile; 167 char *define; 168 { 169 int pd[2]; 170 171 infilename = (infile == NULL) ? "<stdin>" : infile; 172 (void) pipe(pd); 173 switch (fork()) { 174 case 0: 175 (void) close(1); 176 (void) dup2(pd[1], 1); 177 (void) close(pd[0]); 178 execl(CPP, CPP, CPPFLAGS, define, infile, NULL); 179 perror("execl"); 180 exit(1); 181 case -1: 182 perror("fork"); 183 exit(1); 184 } 185 (void) close(pd[1]); 186 fin = fdopen(pd[0], "r"); 187 if (fin == NULL) { 188 f_print(stderr, "%s: ", cmdname); 189 perror(infilename); 190 crash(); 191 } 192 } 193 194 /* 195 * Compile into an XDR routine output file 196 */ 197 static 198 c_output(infile, define, extend, outfile) 199 char *infile; 200 char *define; 201 int extend; 202 char *outfile; 203 { 204 definition *def; 205 char *include; 206 char *outfilename; 207 long tell; 208 209 open_input(infile, define); 210 outfilename = extend ? extendfile(infile, outfile) : outfile; 211 open_output(infile, outfilename); 212 f_print(fout, "#include <rpc/rpc.h>\n"); 213 if (infile && (include = extendfile(infile, ".h"))) { 214 f_print(fout, "#include \"%s\"\n", include); 215 free(include); 216 } 217 tell = ftell(fout); 218 while (def = get_definition()) { 219 emit(def); 220 } 221 if (extend && tell == ftell(fout)) { 222 (void) unlink(outfilename); 223 } 224 } 225 226 /* 227 * Compile into an XDR header file 228 */ 229 static 230 h_output(infile, define, extend, outfile) 231 char *infile; 232 char *define; 233 int extend; 234 char *outfile; 235 { 236 definition *def; 237 char *outfilename; 238 long tell; 239 240 open_input(infile, define); 241 outfilename = extend ? extendfile(infile, outfile) : outfile; 242 open_output(infile, outfilename); 243 tell = ftell(fout); 244 while (def = get_definition()) { 245 print_datadef(def); 246 } 247 if (extend && tell == ftell(fout)) { 248 (void) unlink(outfilename); 249 } 250 } 251 252 /* 253 * Compile into an RPC service 254 */ 255 static 256 s_output(argc, argv, infile, define, extend, outfile, nomain) 257 int argc; 258 char *argv[]; 259 char *infile; 260 char *define; 261 int extend; 262 char *outfile; 263 int nomain; 264 { 265 char *include; 266 definition *def; 267 int foundprogram; 268 char *outfilename; 269 270 open_input(infile, define); 271 outfilename = extend ? extendfile(infile, outfile) : outfile; 272 open_output(infile, outfilename); 273 f_print(fout, "#include <stdio.h>\n"); 274 f_print(fout, "#include <rpc/rpc.h>\n"); 275 if (infile && (include = extendfile(infile, ".h"))) { 276 f_print(fout, "#include \"%s\"\n", include); 277 free(include); 278 } 279 foundprogram = 0; 280 while (def = get_definition()) { 281 foundprogram |= (def->def_kind == DEF_PROGRAM); 282 } 283 if (extend && !foundprogram) { 284 (void) unlink(outfilename); 285 return; 286 } 287 if (nomain) { 288 write_programs((char *)NULL); 289 } else { 290 write_most(); 291 do_registers(argc, argv); 292 write_rest(); 293 write_programs("static"); 294 } 295 } 296 297 static 298 l_output(infile, define, extend, outfile) 299 char *infile; 300 char *define; 301 int extend; 302 char *outfile; 303 { 304 char *include; 305 definition *def; 306 int foundprogram; 307 char *outfilename; 308 309 open_input(infile, define); 310 outfilename = extend ? extendfile(infile, outfile) : outfile; 311 open_output(infile, outfilename); 312 f_print(fout, "#include <rpc/rpc.h>\n"); 313 if (infile && (include = extendfile(infile, ".h"))) { 314 f_print(fout, "#include \"%s\"\n", include); 315 free(include); 316 } 317 foundprogram = 0; 318 while (def = get_definition()) { 319 foundprogram |= (def->def_kind == DEF_PROGRAM); 320 } 321 if (extend && !foundprogram) { 322 (void) unlink(outfilename); 323 return; 324 } 325 write_stubs(); 326 } 327 328 /* 329 * Perform registrations for service output 330 */ 331 static 332 do_registers(argc, argv) 333 int argc; 334 char *argv[]; 335 336 { 337 int i; 338 339 for (i = 1; i < argc; i++) { 340 if (streq(argv[i], "-s")) { 341 write_register(argv[i + 1]); 342 i++; 343 } 344 } 345 } 346 347 /* 348 * Parse command line arguments 349 */ 350 static 351 parseargs(argc, argv, cmd) 352 int argc; 353 char *argv[]; 354 struct commandline *cmd; 355 356 { 357 int i; 358 int j; 359 char c; 360 char flag[(1 << 8 * sizeof(char))]; 361 int nflags; 362 363 cmdname = argv[0]; 364 cmd->infile = cmd->outfile = NULL; 365 if (argc < 2) { 366 return (0); 367 } 368 flag['c'] = 0; 369 flag['h'] = 0; 370 flag['s'] = 0; 371 flag['o'] = 0; 372 flag['l'] = 0; 373 flag['m'] = 0; 374 for (i = 1; i < argc; i++) { 375 if (argv[i][0] != '-') { 376 if (cmd->infile) { 377 return (0); 378 } 379 cmd->infile = argv[i]; 380 } else { 381 for (j = 1; argv[i][j] != 0; j++) { 382 c = argv[i][j]; 383 switch (c) { 384 case 'c': 385 case 'h': 386 case 'l': 387 case 'm': 388 if (flag[c]) { 389 return (0); 390 } 391 flag[c] = 1; 392 break; 393 case 'o': 394 case 's': 395 if (argv[i][j - 1] != '-' || 396 argv[i][j + 1] != 0) { 397 return (0); 398 } 399 flag[c] = 1; 400 if (++i == argc) { 401 return (0); 402 } 403 if (c == 's') { 404 if (!streq(argv[i], "udp") && 405 !streq(argv[i], "tcp")) { 406 return (0); 407 } 408 } else if (c == 'o') { 409 if (cmd->outfile) { 410 return (0); 411 } 412 cmd->outfile = argv[i]; 413 } 414 goto nextarg; 415 416 default: 417 return (0); 418 } 419 } 420 nextarg: 421 ; 422 } 423 } 424 cmd->cflag = flag['c']; 425 cmd->hflag = flag['h']; 426 cmd->sflag = flag['s']; 427 cmd->lflag = flag['l']; 428 cmd->mflag = flag['m']; 429 nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag; 430 if (nflags == 0) { 431 if (cmd->outfile != NULL || cmd->infile == NULL) { 432 return (0); 433 } 434 } else if (nflags > 1) { 435 return (0); 436 } 437 return (1); 438 } 439