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