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