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