1 1.45 andvar /* $NetBSD: rpc_main.c,v 1.45 2022/03/04 21:12:04 andvar Exp $ */ 2 1.10 tls 3 1.1 glass /* 4 1.1 glass * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 1.1 glass * unrestricted use provided that this legend is included on all tape 6 1.1 glass * media and as a part of the software program in whole or part. Users 7 1.1 glass * may copy or modify Sun RPC without charge, but are not authorized 8 1.1 glass * to license or distribute it to anyone else except as part of a product or 9 1.6 pk * program developed by the user or with the express written consent of 10 1.6 pk * Sun Microsystems, Inc. 11 1.6 pk * 12 1.1 glass * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 13 1.1 glass * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 14 1.1 glass * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 15 1.6 pk * 16 1.1 glass * Sun RPC is provided with no support and without any obligation on the 17 1.1 glass * part of Sun Microsystems, Inc. to assist in its use, correction, 18 1.1 glass * modification or enhancement. 19 1.6 pk * 20 1.1 glass * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 21 1.1 glass * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 22 1.1 glass * OR ANY PART THEREOF. 23 1.6 pk * 24 1.1 glass * In no event will Sun Microsystems, Inc. be liable for any lost revenue 25 1.1 glass * or profits or other special, indirect and consequential damages, even if 26 1.1 glass * Sun has been advised of the possibility of such damages. 27 1.6 pk * 28 1.1 glass * Sun Microsystems, Inc. 29 1.1 glass * 2550 Garcia Avenue 30 1.1 glass * Mountain View, California 94043 31 1.1 glass */ 32 1.6 pk 33 1.26 jmc #if HAVE_NBTOOL_CONFIG_H 34 1.26 jmc #include "nbtool_config.h" 35 1.26 jmc #endif 36 1.26 jmc 37 1.12 christos #include <sys/cdefs.h> 38 1.22 tv #if defined(__RCSID) && !defined(lint) 39 1.12 christos #if 0 40 1.6 pk static char sccsid[] = "@(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI"; 41 1.12 christos #else 42 1.45 andvar __RCSID("$NetBSD: rpc_main.c,v 1.45 2022/03/04 21:12:04 andvar Exp $"); 43 1.12 christos #endif 44 1.1 glass #endif 45 1.1 glass 46 1.1 glass /* 47 1.14 lukem * rpc_main.c, Top level of the RPC protocol compiler. 48 1.1 glass */ 49 1.1 glass 50 1.14 lukem #define RPCGEN_VERSION "199506"/* This program's version (year & month) */ 51 1.9 pk 52 1.22 tv #include <sys/types.h> 53 1.22 tv #include <sys/param.h> 54 1.22 tv #include <sys/file.h> 55 1.22 tv #include <sys/stat.h> 56 1.22 tv #include <ctype.h> 57 1.22 tv #include <err.h> 58 1.1 glass #include <stdio.h> 59 1.8 cgd #include <stdlib.h> 60 1.6 pk #include <string.h> 61 1.12 christos #include <unistd.h> 62 1.12 christos #include "rpc_scan.h" 63 1.6 pk #include "rpc_parse.h" 64 1.1 glass #include "rpc_util.h" 65 1.21 tv 66 1.1 glass #define EXTEND 1 /* alias for TRUE */ 67 1.14 lukem #define DONT_EXTEND 0 /* alias for FALSE */ 68 1.6 pk 69 1.1 glass struct commandline { 70 1.14 lukem int cflag; /* xdr C routines */ 71 1.14 lukem int hflag; /* header file */ 72 1.14 lukem int lflag; /* client side stubs */ 73 1.14 lukem int mflag; /* server side stubs */ 74 1.14 lukem int nflag; /* netid flag */ 75 1.14 lukem int sflag; /* server stubs for the given transport */ 76 1.14 lukem int tflag; /* dispatch Table file */ 77 1.14 lukem int Ssflag; /* produce server sample code */ 78 1.14 lukem int Scflag; /* produce client sample code */ 79 1.14 lukem char *infile; /* input module name */ 80 1.14 lukem char *outfile; /* output module name */ 81 1.1 glass }; 82 1.1 glass 83 1.6 pk 84 1.1 glass static char *cmdname; 85 1.6 pk 86 1.36 dholland static const char *svcclosetime = "120"; 87 1.36 dholland static const char *CPP; 88 1.1 glass static char CPPFLAGS[] = "-C"; 89 1.6 pk static char pathbuf[MAXPATHLEN + 1]; 90 1.36 dholland 91 1.36 dholland /* these cannot be const */ 92 1.36 dholland static char allv0[] = "rpcgen"; 93 1.36 dholland static char allv1[] = "-s"; 94 1.36 dholland static char allv2[] = "udp"; 95 1.36 dholland static char allv3[] = "-s"; 96 1.36 dholland static char allv4[] = "tcp"; 97 1.1 glass static char *allv[] = { 98 1.36 dholland allv0, 99 1.36 dholland allv1, 100 1.36 dholland allv2, 101 1.36 dholland allv3, 102 1.36 dholland allv4, 103 1.1 glass }; 104 1.14 lukem static int allc = sizeof(allv) / sizeof(allv[0]); 105 1.36 dholland 106 1.36 dholland /* these cannot be const */ 107 1.36 dholland static char allnv0[] = "rpcgen"; 108 1.36 dholland static char allnv1[] = "-s"; 109 1.36 dholland static char allnv2[] = "netpath"; 110 1.6 pk static char *allnv[] = { 111 1.36 dholland allnv0, 112 1.36 dholland allnv1, 113 1.36 dholland allnv2, 114 1.6 pk }; 115 1.14 lukem static int allnc = sizeof(allnv) / sizeof(allnv[0]); 116 1.6 pk 117 1.6 pk #define ARGLISTLEN 20 118 1.6 pk #define FIXEDARGS 2 119 1.6 pk 120 1.36 dholland static const char *arglist[ARGLISTLEN]; 121 1.6 pk static int argcount = FIXEDARGS; 122 1.6 pk 123 1.6 pk 124 1.14 lukem int nonfatalerrors; /* errors */ 125 1.14 lukem int inetdflag /* = 1 */ ; /* Support for inetd *//* is now the default */ 126 1.14 lukem int pmflag; /* Support for port monitors */ 127 1.14 lukem int logflag; /* Use syslog instead of fprintf for errors */ 128 1.14 lukem int tblflag; /* Support for dispatch table file */ 129 1.38 christos int BSDflag; /* use BSD cplusplus macros */ 130 1.14 lukem int callerflag; /* Generate svc_caller() function */ 131 1.40 christos int docleanup = 1; /* cause atexit to remove files */ 132 1.6 pk 133 1.6 pk #define INLINE 3 134 1.6 pk /*length at which to start doing an inline */ 135 1.6 pk 136 1.14 lukem int doinline = INLINE; /* length at which to start doing an inline. 3 137 1.14 lukem * = default if 0, no xdr_inline code */ 138 1.6 pk 139 1.14 lukem int indefinitewait; /* If started by port monitors, hang till it 140 1.14 lukem * wants */ 141 1.14 lukem int exitnow; /* If started by port monitors, exit after the 142 1.14 lukem * call */ 143 1.14 lukem int timerflag; /* TRUE if !indefinite && !exitnow */ 144 1.14 lukem int newstyle; /* newstyle of passing arguments (by value) */ 145 1.19 mycroft int Mflag = 0; /* multithread safe */ 146 1.14 lukem static int allfiles; /* generate all files */ 147 1.16 fvdl int tirpcflag = 1; /* generating code for tirpc, by default */ 148 1.6 pk 149 1.6 pk #ifdef __MSDOS__ 150 1.6 pk static char *dos_cppfile = NULL; 151 1.6 pk #endif 152 1.6 pk 153 1.38 christos static char *extendfile(const char *, const char *); 154 1.38 christos static void open_output(const char *, const char *); 155 1.38 christos static void add_warning(void); 156 1.38 christos static void clear_args(void); 157 1.38 christos static void open_input(const char *, const char *); 158 1.38 christos static int check_nettype(const char *, const char *[]); 159 1.38 christos static void c_output(const char *, const char *, int, const char *); 160 1.38 christos static void c_initialize(void); 161 1.38 christos static char *generate_guard(const char *); 162 1.38 christos static void h_output(const char *, const char *, int, const char *); 163 1.38 christos static void s_output(int, char *[], char *, const char *, int, const char *, 164 1.38 christos int, int); 165 1.38 christos static void l_output(const char *, const char *, int, const char *); 166 1.38 christos static void t_output(const char *, const char *, int, const char *); 167 1.38 christos static void svc_output(const char *, const char *, int, const char *); 168 1.38 christos static void clnt_output(const char *, const char *, int, const char *); 169 1.38 christos static int do_registers(int, char *[]); 170 1.38 christos static void addarg(const char *); 171 1.38 christos static void putarg(int, const char *); 172 1.38 christos static void checkfiles(const char *, const char *); 173 1.38 christos static int parseargs(int, char *[], struct commandline *); 174 1.37 joerg static void usage(void) __dead; 175 1.37 joerg static void options_usage(void) __dead; 176 1.1 glass 177 1.12 christos int 178 1.36 dholland main(int argc, char *argv[]) 179 1.1 glass { 180 1.1 glass struct commandline cmd; 181 1.18 cgd 182 1.18 cgd setprogname(argv[0]); 183 1.35 joerg if ((CPP = getenv("RPCGEN_CPP")) == NULL) { 184 1.21 tv CPP = "/usr/bin/cpp"; 185 1.35 joerg if (access(CPP, X_OK)) 186 1.35 joerg CPP = "/usr/bin/clang-cpp"; 187 1.35 joerg } 188 1.1 glass 189 1.14 lukem (void) memset((char *) &cmd, 0, sizeof(struct commandline)); 190 1.6 pk clear_args(); 191 1.40 christos atexit(crash); 192 1.6 pk if (!parseargs(argc, argv, &cmd)) 193 1.6 pk usage(); 194 1.6 pk 195 1.14 lukem if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag || 196 1.14 lukem cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) { 197 1.14 lukem checkfiles(cmd.infile, cmd.outfile); 198 1.14 lukem } else 199 1.14 lukem checkfiles(cmd.infile, NULL); 200 1.6 pk 201 1.1 glass if (cmd.cflag) { 202 1.6 pk c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile); 203 1.14 lukem } else 204 1.14 lukem if (cmd.hflag) { 205 1.14 lukem h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile); 206 1.14 lukem } else 207 1.14 lukem if (cmd.lflag) { 208 1.14 lukem l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile); 209 1.14 lukem } else 210 1.14 lukem if (cmd.sflag || cmd.mflag || (cmd.nflag)) { 211 1.14 lukem s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND, 212 1.14 lukem cmd.outfile, cmd.mflag, cmd.nflag); 213 1.14 lukem } else 214 1.14 lukem if (cmd.tflag) { 215 1.14 lukem t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile); 216 1.14 lukem } else 217 1.14 lukem if (cmd.Ssflag) { 218 1.14 lukem svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile); 219 1.14 lukem } else 220 1.14 lukem if (cmd.Scflag) { 221 1.14 lukem clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile); 222 1.14 lukem } else { 223 1.14 lukem /* the rescans 224 1.14 lukem * are 225 1.14 lukem * required, 226 1.14 lukem * since cpp 227 1.14 lukem * may effect 228 1.14 lukem * input */ 229 1.14 lukem c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); 230 1.14 lukem reinitialize(); 231 1.14 lukem h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h"); 232 1.14 lukem reinitialize(); 233 1.14 lukem l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); 234 1.14 lukem reinitialize(); 235 1.14 lukem if (inetdflag || !tirpcflag) 236 1.14 lukem s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, 237 1.14 lukem "_svc.c", cmd.mflag, cmd.nflag); 238 1.14 lukem else 239 1.14 lukem s_output(allnc, allnv, cmd.infile, "-DRPC_SVC", 240 1.14 lukem EXTEND, "_svc.c", cmd.mflag, cmd.nflag); 241 1.14 lukem if (tblflag) { 242 1.14 lukem reinitialize(); 243 1.14 lukem t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i"); 244 1.14 lukem } 245 1.14 lukem if (allfiles) { 246 1.14 lukem reinitialize(); 247 1.14 lukem svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c"); 248 1.14 lukem } 249 1.14 lukem if (allfiles) { 250 1.14 lukem reinitialize(); 251 1.14 lukem clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c"); 252 1.14 lukem } 253 1.14 lukem } 254 1.6 pk #ifdef __MSDOS__ 255 1.6 pk if (dos_cppfile != NULL) { 256 1.6 pk (void) fclose(fin); 257 1.6 pk (void) unlink(dos_cppfile); 258 1.1 glass } 259 1.6 pk #endif 260 1.40 christos docleanup = 0; 261 1.6 pk exit(nonfatalerrors); 262 1.6 pk /* NOTREACHED */ 263 1.1 glass } 264 1.1 glass /* 265 1.14 lukem * add extension to filename 266 1.1 glass */ 267 1.1 glass static char * 268 1.36 dholland extendfile(const char *path, const char *ext) 269 1.1 glass { 270 1.36 dholland const char *file; 271 1.14 lukem char *res; 272 1.36 dholland const char *p; 273 1.5 jtc 274 1.6 pk if ((file = strrchr(path, '/')) == NULL) 275 1.5 jtc file = path; 276 1.5 jtc else 277 1.5 jtc file++; 278 1.1 glass 279 1.1 glass res = alloc(strlen(file) + strlen(ext) + 1); 280 1.1 glass if (res == NULL) { 281 1.44 kamil err(EXIT_FAILURE, "Out of memory"); 282 1.1 glass } 283 1.6 pk p = strrchr(file, '.'); 284 1.1 glass if (p == NULL) { 285 1.1 glass p = file + strlen(file); 286 1.1 glass } 287 1.1 glass (void) strcpy(res, file); 288 1.1 glass (void) strcpy(res + (p - file), ext); 289 1.1 glass return (res); 290 1.1 glass } 291 1.1 glass /* 292 1.14 lukem * Open output file with given extension 293 1.1 glass */ 294 1.12 christos static void 295 1.36 dholland open_output(const char *infile, const char *outfile) 296 1.1 glass { 297 1.6 pk 298 1.1 glass if (outfile == NULL) { 299 1.1 glass fout = stdout; 300 1.1 glass return; 301 1.1 glass } 302 1.1 glass if (infile != NULL && streq(outfile, infile)) { 303 1.42 dholland errx(EXIT_FAILURE, "Output would overwrite `%s'", infile); 304 1.1 glass } 305 1.1 glass fout = fopen(outfile, "w"); 306 1.1 glass if (fout == NULL) { 307 1.42 dholland err(EXIT_FAILURE, "Can't open `%s'", outfile); 308 1.1 glass } 309 1.1 glass record_open(outfile); 310 1.6 pk 311 1.6 pk } 312 1.6 pk 313 1.12 christos static void 314 1.36 dholland add_warning(void) 315 1.6 pk { 316 1.6 pk f_print(fout, "/*\n"); 317 1.6 pk f_print(fout, " * Please do not edit this file.\n"); 318 1.6 pk f_print(fout, " * It was generated using rpcgen.\n"); 319 1.6 pk f_print(fout, " */\n\n"); 320 1.6 pk } 321 1.36 dholland 322 1.6 pk /* clear list of arguments */ 323 1.14 lukem static void 324 1.36 dholland clear_args(void) 325 1.6 pk { 326 1.14 lukem int i; 327 1.14 lukem for (i = FIXEDARGS; i < ARGLISTLEN; i++) 328 1.14 lukem arglist[i] = NULL; 329 1.14 lukem argcount = FIXEDARGS; 330 1.6 pk } 331 1.6 pk 332 1.1 glass /* 333 1.14 lukem * Open input file with given define for C-preprocessor 334 1.1 glass */ 335 1.12 christos static void 336 1.36 dholland open_input(const char *infile, const char *define) 337 1.1 glass { 338 1.14 lukem int pd[2]; 339 1.1 glass 340 1.1 glass infilename = (infile == NULL) ? "<stdin>" : infile; 341 1.6 pk #ifdef __MSDOS__ 342 1.6 pk #define DOSCPP "\\prog\\bc31\\bin\\cpp.exe" 343 1.14 lukem { 344 1.14 lukem int retval; 345 1.14 lukem char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE], ext[MAXEXT]; 346 1.14 lukem char cppfile[MAXPATH]; 347 1.14 lukem char *cpp; 348 1.14 lukem 349 1.30 christos if ((cpp = getenv("RPCGEN_CPP")) == NULL && 350 1.30 christos (cpp = searchpath("cpp.exe")) == NULL) 351 1.14 lukem cpp = DOSCPP; 352 1.14 lukem 353 1.14 lukem putarg(0, cpp); 354 1.14 lukem putarg(1, "-P-"); 355 1.14 lukem putarg(2, CPPFLAGS); 356 1.14 lukem addarg(define); 357 1.14 lukem addarg(infile); 358 1.14 lukem addarg(NULL); 359 1.6 pk 360 1.14 lukem retval = spawnvp(P_WAIT, arglist[0], arglist); 361 1.14 lukem if (retval != 0) { 362 1.42 dholland err(EXIT_FAILURE, "C preprocessor failed"); 363 1.14 lukem } 364 1.14 lukem fnsplit(infile, drive, dir, name, ext); 365 1.14 lukem fnmerge(cppfile, drive, dir, name, ".i"); 366 1.6 pk 367 1.14 lukem fin = fopen(cppfile, "r"); 368 1.14 lukem if (fin == NULL) { 369 1.40 christos err(EXIT_FAILURE, "Can't open `%s'", cppfile); 370 1.14 lukem } 371 1.14 lukem dos_cppfile = strdup(cppfile); 372 1.14 lukem if (dos_cppfile == NULL) { 373 1.40 christos err(EXIT_FAILURE, "Can't copy `%s'", cppfile); 374 1.14 lukem } 375 1.6 pk } 376 1.6 pk #else 377 1.1 glass (void) pipe(pd); 378 1.1 glass switch (fork()) { 379 1.1 glass case 0: 380 1.6 pk putarg(0, CPP); 381 1.6 pk putarg(1, CPPFLAGS); 382 1.6 pk addarg(define); 383 1.6 pk addarg(infile); 384 1.34 plunky addarg(NULL); 385 1.1 glass (void) close(1); 386 1.1 glass (void) dup2(pd[1], 1); 387 1.1 glass (void) close(pd[0]); 388 1.36 dholland execvp(arglist[0], __UNCONST(arglist)); 389 1.40 christos err(EXIT_FAILURE, "$RPCGEN_CPP: %s", CPP); 390 1.1 glass case -1: 391 1.40 christos err(EXIT_FAILURE, "fork"); 392 1.1 glass } 393 1.1 glass (void) close(pd[1]); 394 1.1 glass fin = fdopen(pd[0], "r"); 395 1.6 pk #endif 396 1.1 glass if (fin == NULL) { 397 1.40 christos err(EXIT_FAILURE, "Can't open `%s'", infilename); 398 1.1 glass } 399 1.1 glass } 400 1.6 pk /* valid tirpc nettypes */ 401 1.36 dholland static const char *valid_ti_nettypes[] = 402 1.6 pk { 403 1.14 lukem "netpath", 404 1.14 lukem "visible", 405 1.14 lukem "circuit_v", 406 1.14 lukem "datagram_v", 407 1.14 lukem "circuit_n", 408 1.14 lukem "datagram_n", 409 1.14 lukem "udp", 410 1.14 lukem "tcp", 411 1.14 lukem "raw", 412 1.14 lukem NULL 413 1.14 lukem }; 414 1.6 pk /* valid inetd nettypes */ 415 1.36 dholland static const char *valid_i_nettypes[] = 416 1.6 pk { 417 1.14 lukem "udp", 418 1.14 lukem "tcp", 419 1.14 lukem NULL 420 1.6 pk }; 421 1.6 pk 422 1.14 lukem static int 423 1.36 dholland check_nettype(const char *name, const char *list_to_check[]) 424 1.14 lukem { 425 1.14 lukem int i; 426 1.14 lukem for (i = 0; list_to_check[i] != NULL; i++) { 427 1.14 lukem if (strcmp(name, list_to_check[i]) == 0) { 428 1.14 lukem return 1; 429 1.14 lukem } 430 1.14 lukem } 431 1.14 lukem f_print(stderr, "illegal nettype :\'%s\'\n", name); 432 1.14 lukem return 0; 433 1.6 pk } 434 1.1 glass /* 435 1.1 glass * Compile into an XDR routine output file 436 1.1 glass */ 437 1.6 pk 438 1.12 christos static void 439 1.36 dholland c_output(const char *infile, const char *define, int extend, 440 1.36 dholland const char *outfile) 441 1.1 glass { 442 1.1 glass definition *def; 443 1.14 lukem char *include; 444 1.36 dholland const char *outfilename; 445 1.14 lukem long tell; 446 1.1 glass 447 1.6 pk c_initialize(); 448 1.14 lukem open_input(infile, define); 449 1.1 glass outfilename = extend ? extendfile(infile, outfile) : outfile; 450 1.1 glass open_output(infile, outfilename); 451 1.6 pk add_warning(); 452 1.1 glass if (infile && (include = extendfile(infile, ".h"))) { 453 1.1 glass f_print(fout, "#include \"%s\"\n", include); 454 1.1 glass free(include); 455 1.6 pk /* .h file already contains rpc/rpc.h */ 456 1.6 pk } else 457 1.14 lukem f_print(fout, "#include <rpc/rpc.h>\n"); 458 1.1 glass tell = ftell(fout); 459 1.12 christos while ((def = get_definition()) != NULL) { 460 1.1 glass emit(def); 461 1.1 glass } 462 1.1 glass if (extend && tell == ftell(fout)) { 463 1.1 glass (void) unlink(outfilename); 464 1.1 glass } 465 1.1 glass } 466 1.1 glass 467 1.6 pk 468 1.12 christos static void 469 1.36 dholland c_initialize(void) 470 1.6 pk { 471 1.6 pk 472 1.14 lukem /* add all the starting basic types */ 473 1.6 pk 474 1.14 lukem add_type(1, "int"); 475 1.14 lukem add_type(1, "long"); 476 1.14 lukem add_type(1, "short"); 477 1.14 lukem add_type(1, "bool"); 478 1.6 pk 479 1.14 lukem add_type(1, "u_int"); 480 1.14 lukem add_type(1, "u_long"); 481 1.14 lukem add_type(1, "u_short"); 482 1.6 pk 483 1.6 pk } 484 1.6 pk 485 1.17 is const char rpcgen_table_dcl[] = "struct rpcgen_table {\n\ 486 1.6 pk char *(*proc)();\n\ 487 1.6 pk xdrproc_t xdr_arg;\n\ 488 1.6 pk unsigned len_arg;\n\ 489 1.6 pk xdrproc_t xdr_res;\n\ 490 1.6 pk unsigned len_res;\n\ 491 1.6 pk };\n"; 492 1.6 pk 493 1.6 pk 494 1.12 christos static char * 495 1.36 dholland generate_guard(const char *pathname) 496 1.6 pk { 497 1.36 dholland const char *filename; 498 1.43 kamil char *guard, *tmp, *tmp2, *extdot; 499 1.6 pk 500 1.14 lukem filename = strrchr(pathname, '/'); /* find last component */ 501 1.14 lukem filename = ((filename == 0) ? pathname : filename + 1); 502 1.6 pk guard = strdup(filename); 503 1.43 kamil if (guard == NULL) { 504 1.43 kamil err(EXIT_FAILURE, "strdup"); 505 1.6 pk } 506 1.43 kamil extdot = strrchr(guard, '.'); 507 1.14 lukem 508 1.43 kamil /* 509 1.43 kamil * Convert to valid C symbol name and make it upper case. 510 1.43 kamil * Map non alphanumerical characters to '_'. 511 1.43 kamil * 512 1.43 kamil * Leave extension as it is. It will be handled in extendfile(). 513 1.43 kamil */ 514 1.43 kamil for (tmp = guard; *tmp; tmp++) { 515 1.43 kamil if (islower((unsigned char)*tmp)) 516 1.43 kamil *tmp = toupper((unsigned char)*tmp); 517 1.43 kamil else if (isupper((unsigned char)*tmp)) 518 1.43 kamil continue; 519 1.43 kamil else if (isdigit((unsigned char)*tmp)) 520 1.43 kamil continue; 521 1.43 kamil else if (*tmp == '_') 522 1.43 kamil continue; 523 1.43 kamil else if (tmp == extdot) 524 1.43 kamil break; 525 1.43 kamil else 526 1.43 kamil *tmp = '_'; 527 1.43 kamil } 528 1.43 kamil 529 1.43 kamil /* 530 1.45 andvar * Can't have a '_' or '.' at the front of a symbol name, because it 531 1.43 kamil * will end up as "__". 532 1.43 kamil * 533 1.43 kamil * Prefix it with "RPCGEN_". 534 1.43 kamil */ 535 1.43 kamil if (guard[0] == '_' || guard[0] == '.') { 536 1.43 kamil if (asprintf(&tmp2, "RPCGEN_%s", guard) == -1) { 537 1.43 kamil err(EXIT_FAILURE, "asprintf"); 538 1.43 kamil } 539 1.43 kamil free(guard); 540 1.43 kamil guard = tmp2; 541 1.43 kamil } 542 1.43 kamil 543 1.43 kamil /* Replace the file extension */ 544 1.28 elad tmp2 = extendfile(guard, "_H_RPCGEN"); 545 1.28 elad free(guard); 546 1.28 elad guard = tmp2; 547 1.43 kamil 548 1.14 lukem return (guard); 549 1.6 pk } 550 1.36 dholland 551 1.1 glass /* 552 1.1 glass * Compile into an XDR header file 553 1.1 glass */ 554 1.12 christos static void 555 1.36 dholland h_output(const char *infile, const char *define, int extend, 556 1.36 dholland const char *outfile) 557 1.1 glass { 558 1.1 glass definition *def; 559 1.36 dholland const char *outfilename; 560 1.14 lukem long tell; 561 1.14 lukem char *guard; 562 1.14 lukem list *l; 563 1.38 christos int did; 564 1.1 glass 565 1.1 glass open_input(infile, define); 566 1.14 lukem outfilename = extend ? extendfile(infile, outfile) : outfile; 567 1.1 glass open_output(infile, outfilename); 568 1.6 pk add_warning(); 569 1.31 christos if (outfilename || infile) 570 1.32 christos guard = generate_guard(outfilename ? outfilename : infile); 571 1.36 dholland else { 572 1.36 dholland guard = strdup("STDIN_"); 573 1.36 dholland if (guard == NULL) { 574 1.40 christos err(EXIT_FAILURE, "strdup"); 575 1.36 dholland } 576 1.36 dholland } 577 1.6 pk 578 1.14 lukem f_print(fout, "#ifndef _%s\n#define _%s\n\n", guard, 579 1.14 lukem guard); 580 1.6 pk 581 1.9 pk f_print(fout, "#define RPCGEN_VERSION\t%s\n\n", RPCGEN_VERSION); 582 1.6 pk f_print(fout, "#include <rpc/rpc.h>\n\n"); 583 1.6 pk 584 1.1 glass tell = ftell(fout); 585 1.6 pk /* print data definitions */ 586 1.12 christos while ((def = get_definition()) != NULL) { 587 1.1 glass print_datadef(def); 588 1.1 glass } 589 1.6 pk 590 1.14 lukem /* print function declarations. Do this after data definitions 591 1.14 lukem * because they might be used as arguments for functions */ 592 1.38 christos did = 0; 593 1.6 pk for (l = defined; l != NULL; l = l->next) { 594 1.38 christos print_funcdef(l->val, &did); 595 1.6 pk } 596 1.38 christos print_funcend(did); 597 1.38 christos 598 1.38 christos for (l = defined; l != NULL; l = l->next) { 599 1.38 christos print_progdef(l->val); 600 1.38 christos } 601 1.38 christos 602 1.1 glass if (extend && tell == ftell(fout)) { 603 1.1 glass (void) unlink(outfilename); 604 1.14 lukem } else 605 1.14 lukem if (tblflag) { 606 1.14 lukem f_print(fout, rpcgen_table_dcl); 607 1.14 lukem } 608 1.6 pk f_print(fout, "\n#endif /* !_%s */\n", guard); 609 1.28 elad 610 1.28 elad free(guard); 611 1.1 glass } 612 1.36 dholland 613 1.1 glass /* 614 1.1 glass * Compile into an RPC service 615 1.1 glass */ 616 1.12 christos static void 617 1.36 dholland s_output(int argc, char *argv[], char *infile, 618 1.36 dholland const char *define, int extend, const char *outfile, int nomain, 619 1.36 dholland int netflag) 620 1.1 glass { 621 1.14 lukem char *include; 622 1.1 glass definition *def; 623 1.14 lukem int foundprogram = 0; 624 1.36 dholland const char *outfilename; 625 1.1 glass 626 1.1 glass open_input(infile, define); 627 1.1 glass outfilename = extend ? extendfile(infile, outfile) : outfile; 628 1.1 glass open_output(infile, outfilename); 629 1.6 pk add_warning(); 630 1.1 glass if (infile && (include = extendfile(infile, ".h"))) { 631 1.1 glass f_print(fout, "#include \"%s\"\n", include); 632 1.1 glass free(include); 633 1.6 pk } else 634 1.14 lukem f_print(fout, "#include <rpc/rpc.h>\n"); 635 1.6 pk 636 1.14 lukem f_print(fout, "#include <sys/ioctl.h>\n"); 637 1.14 lukem f_print(fout, "#include <fcntl.h>\n"); 638 1.6 pk f_print(fout, "#include <stdio.h>\n"); 639 1.40 christos f_print(fout, "#include <err.h>\n"); 640 1.14 lukem f_print(fout, "#include <stdlib.h>\n"); 641 1.38 christos f_print(fout, "#include <unistd.h>\n"); 642 1.38 christos f_print(fout, "#include <rpc/pmap_clnt.h>\n"); 643 1.38 christos f_print(fout, "#include <string.h>\n"); 644 1.14 lukem f_print(fout, "#include <netdb.h>\n"); 645 1.6 pk if (strcmp(svcclosetime, "-1") == 0) 646 1.6 pk indefinitewait = 1; 647 1.14 lukem else 648 1.14 lukem if (strcmp(svcclosetime, "0") == 0) 649 1.14 lukem exitnow = 1; 650 1.14 lukem else 651 1.14 lukem if (inetdflag || pmflag) { 652 1.14 lukem f_print(fout, "#include <signal.h>\n"); 653 1.14 lukem timerflag = 1; 654 1.14 lukem } 655 1.14 lukem if (!tirpcflag && inetdflag) 656 1.14 lukem f_print(fout, "#include <sys/ttycom.h>\n"); 657 1.38 christos if (inetdflag || pmflag) { 658 1.14 lukem f_print(fout, "#ifdef __cplusplus\n"); 659 1.14 lukem f_print(fout, "#include <sysent.h>\n"); 660 1.14 lukem f_print(fout, "#endif /* __cplusplus */\n"); 661 1.6 pk } 662 1.14 lukem if (tirpcflag) 663 1.14 lukem f_print(fout, "#include <sys/types.h>\n"); 664 1.6 pk 665 1.6 pk f_print(fout, "#include <memory.h>\n"); 666 1.7 pk 667 1.14 lukem if (inetdflag || !tirpcflag) { 668 1.6 pk f_print(fout, "#include <sys/socket.h>\n"); 669 1.6 pk f_print(fout, "#include <netinet/in.h>\n"); 670 1.14 lukem } 671 1.14 lukem if ((netflag || pmflag) && tirpcflag) { 672 1.6 pk f_print(fout, "#include <netconfig.h>\n"); 673 1.6 pk } 674 1.14 lukem if ( /* timerflag && */ tirpcflag) 675 1.14 lukem f_print(fout, "#include <sys/resource.h>\n"); 676 1.13 lukem if (logflag || inetdflag || pmflag) 677 1.6 pk f_print(fout, "#include <syslog.h>\n"); 678 1.6 pk 679 1.38 christos f_print(fout, "\n#define SIG_PF void(*)(int)\n"); 680 1.6 pk 681 1.6 pk f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n"); 682 1.6 pk if (timerflag) 683 1.6 pk f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime); 684 1.12 christos while ((def = get_definition()) != NULL) { 685 1.1 glass foundprogram |= (def->def_kind == DEF_PROGRAM); 686 1.1 glass } 687 1.1 glass if (extend && !foundprogram) { 688 1.1 glass (void) unlink(outfilename); 689 1.1 glass return; 690 1.1 glass } 691 1.14 lukem if (callerflag) /* EVAS */ 692 1.14 lukem f_print(fout, "\nstatic SVCXPRT *caller;\n"); /* EVAS */ 693 1.6 pk write_most(infile, netflag, nomain); 694 1.6 pk if (!nomain) { 695 1.14 lukem if (!do_registers(argc, argv)) { 696 1.14 lukem if (outfilename) 697 1.14 lukem (void) unlink(outfilename); 698 1.14 lukem usage(); 699 1.6 pk } 700 1.1 glass write_rest(); 701 1.1 glass } 702 1.1 glass } 703 1.6 pk /* 704 1.6 pk * generate client side stubs 705 1.6 pk */ 706 1.12 christos static void 707 1.36 dholland l_output(const char *infile, const char *define, int extend, 708 1.36 dholland const char *outfile) 709 1.1 glass { 710 1.14 lukem char *include; 711 1.1 glass definition *def; 712 1.14 lukem int foundprogram = 0; 713 1.36 dholland const char *outfilename; 714 1.1 glass 715 1.1 glass open_input(infile, define); 716 1.1 glass outfilename = extend ? extendfile(infile, outfile) : outfile; 717 1.1 glass open_output(infile, outfilename); 718 1.6 pk add_warning(); 719 1.38 christos f_print(fout, "#include <memory.h>\n"); 720 1.1 glass if (infile && (include = extendfile(infile, ".h"))) { 721 1.1 glass f_print(fout, "#include \"%s\"\n", include); 722 1.1 glass free(include); 723 1.6 pk } else 724 1.14 lukem f_print(fout, "#include <rpc/rpc.h>\n"); 725 1.12 christos while ((def = get_definition()) != NULL) { 726 1.6 pk foundprogram |= (def->def_kind == DEF_PROGRAM); 727 1.6 pk } 728 1.6 pk if (extend && !foundprogram) { 729 1.6 pk (void) unlink(outfilename); 730 1.6 pk return; 731 1.1 glass } 732 1.6 pk write_stubs(); 733 1.6 pk } 734 1.6 pk /* 735 1.6 pk * generate the dispatch table 736 1.6 pk */ 737 1.12 christos static void 738 1.36 dholland t_output(const char *infile, const char *define, int extend, 739 1.36 dholland const char *outfile) 740 1.6 pk { 741 1.6 pk definition *def; 742 1.14 lukem int foundprogram = 0; 743 1.36 dholland const char *outfilename; 744 1.6 pk 745 1.6 pk open_input(infile, define); 746 1.6 pk outfilename = extend ? extendfile(infile, outfile) : outfile; 747 1.6 pk open_output(infile, outfilename); 748 1.6 pk add_warning(); 749 1.12 christos while ((def = get_definition()) != NULL) { 750 1.1 glass foundprogram |= (def->def_kind == DEF_PROGRAM); 751 1.1 glass } 752 1.1 glass if (extend && !foundprogram) { 753 1.1 glass (void) unlink(outfilename); 754 1.1 glass return; 755 1.1 glass } 756 1.6 pk write_tables(); 757 1.6 pk } 758 1.6 pk /* sample routine for the server template */ 759 1.14 lukem static void 760 1.36 dholland svc_output(const char *infile, const char *define, int extend, 761 1.36 dholland const char *outfile) 762 1.14 lukem { 763 1.14 lukem definition *def; 764 1.14 lukem char *include; 765 1.36 dholland const char *outfilename; 766 1.14 lukem long tell; 767 1.14 lukem 768 1.14 lukem open_input(infile, define); 769 1.14 lukem outfilename = extend ? extendfile(infile, outfile) : outfile; 770 1.14 lukem checkfiles(infile, outfilename); /* check if outfile already 771 1.14 lukem * exists. if so, print an 772 1.14 lukem * error message and exit */ 773 1.14 lukem open_output(infile, outfilename); 774 1.14 lukem add_sample_msg(); 775 1.14 lukem 776 1.14 lukem if (infile && (include = extendfile(infile, ".h"))) { 777 1.14 lukem f_print(fout, "#include \"%s\"\n", include); 778 1.14 lukem free(include); 779 1.14 lukem } else 780 1.14 lukem f_print(fout, "#include <rpc/rpc.h>\n"); 781 1.14 lukem 782 1.14 lukem tell = ftell(fout); 783 1.14 lukem while ((def = get_definition()) != NULL) { 784 1.14 lukem write_sample_svc(def); 785 1.14 lukem } 786 1.14 lukem if (extend && tell == ftell(fout)) { 787 1.14 lukem (void) unlink(outfilename); 788 1.14 lukem } 789 1.6 pk } 790 1.6 pk 791 1.6 pk 792 1.6 pk /* sample main routine for client */ 793 1.12 christos static void 794 1.36 dholland clnt_output(const char *infile, const char *define, int extend, 795 1.36 dholland const char *outfile) 796 1.14 lukem { 797 1.14 lukem definition *def; 798 1.14 lukem char *include; 799 1.36 dholland const char *outfilename; 800 1.14 lukem long tell; 801 1.14 lukem int has_program = 0; 802 1.14 lukem 803 1.14 lukem open_input(infile, define); 804 1.14 lukem outfilename = extend ? extendfile(infile, outfile) : outfile; 805 1.14 lukem checkfiles(infile, outfilename); /* check if outfile already 806 1.14 lukem * exists. if so, print an 807 1.14 lukem * error message and exit */ 808 1.14 lukem 809 1.14 lukem open_output(infile, outfilename); 810 1.14 lukem add_sample_msg(); 811 1.38 christos f_print(fout, "#include <stdio.h>\n"); 812 1.40 christos f_print(fout, "#include <err.h>\n"); 813 1.14 lukem if (infile && (include = extendfile(infile, ".h"))) { 814 1.14 lukem f_print(fout, "#include \"%s\"\n", include); 815 1.14 lukem free(include); 816 1.14 lukem } else 817 1.14 lukem f_print(fout, "#include <rpc/rpc.h>\n"); 818 1.14 lukem tell = ftell(fout); 819 1.14 lukem while ((def = get_definition()) != NULL) { 820 1.14 lukem has_program += write_sample_clnt(def); 821 1.14 lukem } 822 1.14 lukem 823 1.14 lukem if (has_program) 824 1.14 lukem write_sample_clnt_main(); 825 1.14 lukem 826 1.14 lukem if (extend && tell == ftell(fout)) { 827 1.14 lukem (void) unlink(outfilename); 828 1.14 lukem } 829 1.1 glass } 830 1.1 glass /* 831 1.14 lukem * Perform registrations for service output 832 1.6 pk * Return 0 if failed; 1 otherwise. 833 1.1 glass */ 834 1.12 christos static int 835 1.36 dholland do_registers(int argc, char *argv[]) 836 1.1 glass { 837 1.14 lukem int i; 838 1.1 glass 839 1.14 lukem if (inetdflag || !tirpcflag) { 840 1.6 pk for (i = 1; i < argc; i++) { 841 1.6 pk if (streq(argv[i], "-s")) { 842 1.14 lukem if (!check_nettype(argv[i + 1], valid_i_nettypes)) 843 1.14 lukem return 0; 844 1.6 pk write_inetd_register(argv[i + 1]); 845 1.6 pk i++; 846 1.6 pk } 847 1.1 glass } 848 1.6 pk } else { 849 1.6 pk for (i = 1; i < argc; i++) 850 1.14 lukem if (streq(argv[i], "-s")) { 851 1.14 lukem if (!check_nettype(argv[i + 1], valid_ti_nettypes)) 852 1.14 lukem return 0; 853 1.6 pk write_nettype_register(argv[i + 1]); 854 1.6 pk i++; 855 1.14 lukem } else 856 1.14 lukem if (streq(argv[i], "-n")) { 857 1.14 lukem write_netid_register(argv[i + 1]); 858 1.14 lukem i++; 859 1.14 lukem } 860 1.6 pk } 861 1.6 pk return 1; 862 1.6 pk } 863 1.6 pk /* 864 1.6 pk * Add another argument to the arg list 865 1.6 pk */ 866 1.6 pk static void 867 1.36 dholland addarg(const char *cp) 868 1.6 pk { 869 1.6 pk if (argcount >= ARGLISTLEN) { 870 1.42 dholland errx(EXIT_FAILURE, "Internal error: too many defines"); 871 1.14 lukem /* NOTREACHED */ 872 1.1 glass } 873 1.6 pk arglist[argcount++] = cp; 874 1.6 pk 875 1.6 pk } 876 1.6 pk 877 1.6 pk static void 878 1.36 dholland putarg(int pwhere, const char *cp) 879 1.6 pk { 880 1.33 lukem if (pwhere >= ARGLISTLEN) { 881 1.42 dholland errx(EXIT_FAILURE, "Internal error: arglist coding error"); 882 1.14 lukem /* NOTREACHED */ 883 1.6 pk } 884 1.33 lukem arglist[pwhere] = cp; 885 1.14 lukem 886 1.6 pk } 887 1.6 pk /* 888 1.6 pk * if input file is stdin and an output file is specified then complain 889 1.6 pk * if the file already exists. Otherwise the file may get overwritten 890 1.14 lukem * If input file does not exist, exit with an error 891 1.6 pk */ 892 1.6 pk 893 1.6 pk static void 894 1.36 dholland checkfiles(const char *infile, const char *outfile) 895 1.6 pk { 896 1.6 pk 897 1.14 lukem struct stat buf; 898 1.14 lukem 899 1.14 lukem if (infile) /* infile ! = NULL */ 900 1.14 lukem if (stat(infile, &buf) < 0) { 901 1.40 christos err(EXIT_FAILURE, "Can't stat `%s'", infile); 902 1.14 lukem }; 903 1.6 pk #if 0 904 1.14 lukem if (outfile) { 905 1.14 lukem if (stat(outfile, &buf) < 0) 906 1.14 lukem return; /* file does not exist */ 907 1.14 lukem else { 908 1.41 dholland errx(EXIT_FAILURE, 909 1.42 dholland "`%s' already exists and would be overwritten", 910 1.40 christos outfile); 911 1.14 lukem } 912 1.14 lukem } 913 1.6 pk #endif 914 1.1 glass } 915 1.1 glass /* 916 1.14 lukem * Parse command line arguments 917 1.1 glass */ 918 1.6 pk static int 919 1.36 dholland parseargs(int argc, char *argv[], struct commandline *cmd) 920 1.1 glass { 921 1.14 lukem int i; 922 1.14 lukem int j; 923 1.14 lukem int c; 924 1.29 dholland char flag[1 << CHAR_BIT]; 925 1.14 lukem int nflags; 926 1.1 glass 927 1.1 glass cmdname = argv[0]; 928 1.1 glass cmd->infile = cmd->outfile = NULL; 929 1.1 glass if (argc < 2) { 930 1.1 glass return (0); 931 1.1 glass } 932 1.6 pk allfiles = 0; 933 1.1 glass flag['c'] = 0; 934 1.1 glass flag['h'] = 0; 935 1.1 glass flag['l'] = 0; 936 1.1 glass flag['m'] = 0; 937 1.6 pk flag['o'] = 0; 938 1.6 pk flag['s'] = 0; 939 1.6 pk flag['n'] = 0; 940 1.6 pk flag['t'] = 0; 941 1.6 pk flag['S'] = 0; 942 1.6 pk flag['C'] = 0; 943 1.1 glass for (i = 1; i < argc; i++) { 944 1.1 glass if (argv[i][0] != '-') { 945 1.1 glass if (cmd->infile) { 946 1.14 lukem f_print(stderr, "Cannot specify more than one input file!\n"); 947 1.6 pk 948 1.1 glass return (0); 949 1.1 glass } 950 1.1 glass cmd->infile = argv[i]; 951 1.1 glass } else { 952 1.1 glass for (j = 1; argv[i][j] != 0; j++) { 953 1.1 glass c = argv[i][j]; 954 1.1 glass switch (c) { 955 1.6 pk case 'A': 956 1.6 pk callerflag = 1; 957 1.6 pk break; 958 1.6 pk case 'a': 959 1.6 pk allfiles = 1; 960 1.6 pk break; 961 1.38 christos case 'B': 962 1.38 christos BSDflag = 1; 963 1.38 christos break; 964 1.1 glass case 'c': 965 1.1 glass case 'h': 966 1.1 glass case 'l': 967 1.1 glass case 'm': 968 1.6 pk case 't': 969 1.1 glass if (flag[c]) { 970 1.1 glass return (0); 971 1.1 glass } 972 1.1 glass flag[c] = 1; 973 1.1 glass break; 974 1.14 lukem case 'S': 975 1.14 lukem /* sample flag: Ss or Sc. Ss means set 976 1.14 lukem * flag['S']; Sc means set flag['C']; */ 977 1.14 lukem c = argv[i][++j]; /* get next char */ 978 1.14 lukem if (c == 's') 979 1.14 lukem c = 'S'; 980 1.6 pk else 981 1.14 lukem if (c == 'c') 982 1.14 lukem c = 'C'; 983 1.14 lukem else 984 1.14 lukem return (0); 985 1.6 pk 986 1.6 pk if (flag[c]) { 987 1.6 pk return (0); 988 1.6 pk } 989 1.6 pk flag[c] = 1; 990 1.6 pk break; 991 1.38 christos case 'C': /* deprecated ANSI C syntax */ 992 1.6 pk break; 993 1.6 pk 994 1.14 lukem case 'b': /* turn TIRPC flag off for 995 1.14 lukem * generating backward 996 1.14 lukem * compatible */ 997 1.6 pk tirpcflag = 0; 998 1.6 pk break; 999 1.6 pk 1000 1.6 pk case 'I': 1001 1.6 pk inetdflag = 1; 1002 1.6 pk break; 1003 1.19 mycroft case 'M': 1004 1.19 mycroft Mflag = 1; 1005 1.19 mycroft break; 1006 1.6 pk case 'N': 1007 1.6 pk newstyle = 1; 1008 1.6 pk break; 1009 1.6 pk case 'L': 1010 1.6 pk logflag = 1; 1011 1.6 pk break; 1012 1.6 pk case 'K': 1013 1.6 pk if (++i == argc) { 1014 1.6 pk return (0); 1015 1.6 pk } 1016 1.6 pk svcclosetime = argv[i]; 1017 1.6 pk goto nextarg; 1018 1.6 pk case 'T': 1019 1.6 pk tblflag = 1; 1020 1.6 pk break; 1021 1.14 lukem case 'i': 1022 1.14 lukem if (++i == argc) { 1023 1.6 pk return (0); 1024 1.6 pk } 1025 1.12 christos doinline = atoi(argv[i]); 1026 1.6 pk goto nextarg; 1027 1.6 pk case 'n': 1028 1.1 glass case 'o': 1029 1.1 glass case 's': 1030 1.14 lukem if (argv[i][j - 1] != '-' || 1031 1.1 glass argv[i][j + 1] != 0) { 1032 1.1 glass return (0); 1033 1.1 glass } 1034 1.1 glass flag[c] = 1; 1035 1.1 glass if (++i == argc) { 1036 1.1 glass return (0); 1037 1.1 glass } 1038 1.1 glass if (c == 's') { 1039 1.1 glass if (!streq(argv[i], "udp") && 1040 1.1 glass !streq(argv[i], "tcp")) { 1041 1.1 glass return (0); 1042 1.1 glass } 1043 1.14 lukem } else 1044 1.14 lukem if (c == 'o') { 1045 1.14 lukem if (cmd->outfile) { 1046 1.14 lukem return (0); 1047 1.14 lukem } 1048 1.14 lukem cmd->outfile = argv[i]; 1049 1.1 glass } 1050 1.1 glass goto nextarg; 1051 1.6 pk case 'D': 1052 1.6 pk if (argv[i][j - 1] != '-') { 1053 1.6 pk return (0); 1054 1.6 pk } 1055 1.6 pk (void) addarg(argv[i]); 1056 1.6 pk goto nextarg; 1057 1.6 pk case 'Y': 1058 1.6 pk if (++i == argc) { 1059 1.6 pk return (0); 1060 1.6 pk } 1061 1.23 itojun (void) strlcpy(pathbuf, argv[i], 1062 1.23 itojun sizeof(pathbuf)); 1063 1.23 itojun (void) strlcat(pathbuf, "/cpp", 1064 1.23 itojun sizeof(pathbuf)); 1065 1.6 pk CPP = pathbuf; 1066 1.6 pk goto nextarg; 1067 1.6 pk 1068 1.25 christos case 'v': 1069 1.25 christos printf("version 1.0\n"); 1070 1.25 christos exit(0); 1071 1.1 glass 1072 1.1 glass default: 1073 1.1 glass return (0); 1074 1.1 glass } 1075 1.1 glass } 1076 1.1 glass nextarg: 1077 1.1 glass ; 1078 1.1 glass } 1079 1.1 glass } 1080 1.6 pk 1081 1.1 glass cmd->cflag = flag['c']; 1082 1.1 glass cmd->hflag = flag['h']; 1083 1.1 glass cmd->lflag = flag['l']; 1084 1.1 glass cmd->mflag = flag['m']; 1085 1.6 pk cmd->nflag = flag['n']; 1086 1.6 pk cmd->sflag = flag['s']; 1087 1.6 pk cmd->tflag = flag['t']; 1088 1.6 pk cmd->Ssflag = flag['S']; 1089 1.6 pk cmd->Scflag = flag['C']; 1090 1.6 pk 1091 1.14 lukem if (tirpcflag) { 1092 1.14 lukem pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is 1093 1.14 lukem * always TRUE */ 1094 1.14 lukem if ((inetdflag && cmd->nflag)) { /* netid not allowed 1095 1.14 lukem * with inetdflag */ 1096 1.14 lukem f_print(stderr, "Cannot use netid flag with inetd flag!\n"); 1097 1.14 lukem return (0); 1098 1.14 lukem } 1099 1.14 lukem } else { /* 4.1 mode */ 1100 1.14 lukem pmflag = 0; /* set pmflag only in tirpcmode */ 1101 1.14 lukem inetdflag = 1; /* inetdflag is TRUE by default */ 1102 1.14 lukem if (cmd->nflag) { /* netid needs TIRPC */ 1103 1.14 lukem f_print(stderr, "Cannot use netid flag without TIRPC!\n"); 1104 1.14 lukem return (0); 1105 1.14 lukem } 1106 1.6 pk } 1107 1.6 pk 1108 1.14 lukem if (newstyle && (tblflag || cmd->tflag)) { 1109 1.14 lukem f_print(stderr, "Cannot use table flags with newstyle!\n"); 1110 1.14 lukem return (0); 1111 1.14 lukem } 1112 1.6 pk /* check no conflicts with file generation flags */ 1113 1.6 pk nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag + 1114 1.14 lukem cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag; 1115 1.6 pk 1116 1.1 glass if (nflags == 0) { 1117 1.1 glass if (cmd->outfile != NULL || cmd->infile == NULL) { 1118 1.1 glass return (0); 1119 1.1 glass } 1120 1.14 lukem } else 1121 1.14 lukem if (nflags > 1) { 1122 1.14 lukem f_print(stderr, "Cannot have more than one file generation flag!\n"); 1123 1.14 lukem return (0); 1124 1.14 lukem } 1125 1.1 glass return (1); 1126 1.6 pk } 1127 1.6 pk 1128 1.12 christos static void 1129 1.36 dholland usage(void) 1130 1.6 pk { 1131 1.6 pk f_print(stderr, "usage: %s infile\n", cmdname); 1132 1.39 wiz f_print(stderr, "\t%s [-AaBbILMNTv] [-Dname[=value]] [-i size] [-K seconds] [-Y pathname] infile\n", 1133 1.14 lukem cmdname); 1134 1.39 wiz f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n", 1135 1.14 lukem cmdname); 1136 1.39 wiz f_print(stderr, "\t%s [-s nettype] [-o outfile] [infile]\n", cmdname); 1137 1.39 wiz f_print(stderr, "\t%s [-n netid] [-o outfile] [infile]\n", cmdname); 1138 1.6 pk options_usage(); 1139 1.6 pk exit(1); 1140 1.6 pk } 1141 1.6 pk 1142 1.12 christos static void 1143 1.36 dholland options_usage(void) 1144 1.6 pk { 1145 1.6 pk f_print(stderr, "options:\n"); 1146 1.6 pk f_print(stderr, "-A\t\tgenerate svc_caller() function\n"); 1147 1.6 pk f_print(stderr, "-a\t\tgenerate all files, including samples\n"); 1148 1.39 wiz f_print(stderr, "-B\t\tgenerate BSD c++ macros\n"); 1149 1.6 pk f_print(stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n"); 1150 1.6 pk f_print(stderr, "-c\t\tgenerate XDR routines\n"); 1151 1.6 pk f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n"); 1152 1.6 pk f_print(stderr, "-h\t\tgenerate header file\n"); 1153 1.39 wiz f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n"); 1154 1.6 pk f_print(stderr, "-i size\t\tsize at which to start generating inline code\n"); 1155 1.6 pk f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n"); 1156 1.39 wiz f_print(stderr, "-L\t\tserver errors will be printed to syslog\n"); 1157 1.6 pk f_print(stderr, "-l\t\tgenerate client side stubs\n"); 1158 1.39 wiz f_print(stderr, "-M\t\tgenerate thread-safe stubs\n"); 1159 1.6 pk f_print(stderr, "-m\t\tgenerate server side stubs\n"); 1160 1.39 wiz f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n"); 1161 1.6 pk f_print(stderr, "-n netid\tgenerate server code that supports named netid\n"); 1162 1.6 pk f_print(stderr, "-o outfile\tname of the output file\n"); 1163 1.6 pk f_print(stderr, "-s nettype\tgenerate server code that supports named nettype\n"); 1164 1.6 pk f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n"); 1165 1.6 pk f_print(stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n"); 1166 1.39 wiz f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n"); 1167 1.6 pk f_print(stderr, "-t\t\tgenerate RPC dispatch table\n"); 1168 1.39 wiz f_print(stderr, "-v\t\tdisplay version number\n"); 1169 1.6 pk f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n"); 1170 1.6 pk 1171 1.6 pk exit(1); 1172 1.1 glass } 1173