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