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