Back to index

glibc  2.9
rpc_main.c
Go to the documentation of this file.
00001 /*
00002  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00003  * unrestricted use provided that this legend is included on all tape
00004  * media and as a part of the software program in whole or part.  Users
00005  * may copy or modify Sun RPC without charge, but are not authorized
00006  * to license or distribute it to anyone else except as part of a product or
00007  * program developed by the user or with the express written consent of
00008  * Sun Microsystems, Inc.
00009  *
00010  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00011  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00012  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00013  *
00014  * Sun RPC is provided with no support and without any obligation on the
00015  * part of Sun Microsystems, Inc. to assist in its use, correction,
00016  * modification or enhancement.
00017  *
00018  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00019  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00020  * OR ANY PART THEREOF.
00021  *
00022  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00023  * or profits or other special, indirect and consequential damages, even if
00024  * Sun has been advised of the possibility of such damages.
00025  *
00026  * Sun Microsystems, Inc.
00027  * 2550 Garcia Avenue
00028  * Mountain View, California  94043
00029  */
00030 
00031 /*
00032  * From @(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI;
00033  */
00034 
00035 /*
00036  * rpc_main.c, Top level of the RPC protocol compiler.
00037  */
00038 
00039 #include <errno.h>
00040 #include <stdio.h>
00041 #include <string.h>
00042 #include <unistd.h>
00043 #include <libintl.h>
00044 #include <ctype.h>
00045 #include <sys/types.h>
00046 #include <sys/param.h>
00047 #include <sys/file.h>
00048 #include <sys/stat.h>
00049 #include <sys/wait.h>
00050 #include "rpc_parse.h"
00051 #include "rpc_util.h"
00052 #include "rpc_scan.h"
00053 #include "proto.h"
00054 
00055 #define EXTEND       1             /* alias for TRUE */
00056 #define DONT_EXTEND  0      /* alias for FALSE */
00057 
00058 struct commandline
00059   {
00060     int cflag;                     /* xdr C routines */
00061     int hflag;                     /* header file */
00062     int lflag;                     /* client side stubs */
00063     int mflag;                     /* server side stubs */
00064     int nflag;                     /* netid flag */
00065     int sflag;                     /* server stubs for the given transport */
00066     int tflag;                     /* dispatch Table file */
00067     int Ssflag;                    /* produce server sample code */
00068     int Scflag;                    /* produce client sample code */
00069     int makefileflag;              /* Generate a template Makefile */
00070     const char *infile;            /* input module name */
00071     const char *outfile;    /* output module name */
00072   };
00073 
00074 
00075 static const char *cmdname;
00076 
00077 #define SVR4_CPP "/usr/ccs/lib/cpp"
00078 #define SUNOS_CPP "/lib/cpp"
00079 
00080 static const char *svcclosetime = "120";
00081 static int cppDefined;      /* explicit path for C preprocessor */
00082 static const char *CPP = SUNOS_CPP;
00083 static const char CPPFLAGS[] = "-C";
00084 static char *pathbuf;
00085 static int cpp_pid;
00086 static const char *allv[] =
00087 {
00088   "rpcgen", "-s", "udp", "-s", "tcp"
00089 };
00090 static int allc = sizeof (allv) / sizeof (allv[0]);
00091 static const char *allnv[] =
00092 {
00093   "rpcgen", "-s", "netpath",
00094 };
00095 static int allnc = sizeof (allnv) / sizeof (allnv[0]);
00096 
00097 /*
00098  * machinations for handling expanding argument list
00099  */
00100 static void addarg (const char *); /* add another argument to the list */
00101 static void putarg (int, const char *);          /* put argument at specified location */
00102 static void clear_args (void);     /* clear argument list */
00103 static void checkfiles (const char *, const char *);
00104                                    /* check if out file already exists */
00105 
00106 static void clear_args (void);
00107 static char *extendfile (const char *file, const char *ext);
00108 static void open_output (const char *infile, const char *outfile);
00109 static void add_warning (void);
00110 static void clear_args (void);
00111 static void find_cpp (void);
00112 static void open_input (const char *infile, const char *define);
00113 static int check_nettype (const char *name, const char *list_to_check[]);
00114 static void c_output (const char *infile, const char *define,
00115                     int extend, const char *outfile);
00116 static void h_output (const char *infile, const char *define,
00117                     int extend, const char *outfile);
00118 static void s_output (int argc, const char *argv[], const char *infile,
00119                     const char *define, int extend,
00120                     const char *outfile, int nomain, int netflag);
00121 static void l_output (const char *infile, const char *define,
00122                     int extend, const char *outfile);
00123 static void t_output (const char *infile, const char *define,
00124                     int extend, const char *outfile);
00125 static void svc_output (const char *infile, const char *define,
00126                      int extend, const char *outfile);
00127 static void clnt_output (const char *infile, const char *define,
00128                       int extend, const char *outfile);
00129 static void mkfile_output (struct commandline *cmd);
00130 static int do_registers (int argc, const char *argv[]);
00131 static void addarg (const char *cp);
00132 static void putarg (int whereto, const char *cp);
00133 static void checkfiles (const char *infile, const char *outfile);
00134 static int parseargs (int argc, const char *argv[], struct commandline *cmd);
00135 static void usage (void) __attribute__ ((noreturn));
00136 static void options_usage (void) __attribute__ ((noreturn));
00137 static void c_initialize (void);
00138 static char *generate_guard (const char *pathname);
00139 
00140 
00141 #define ARGLISTLEN   20
00142 #define FIXEDARGS         2
00143 
00144 static const char *arglist[ARGLISTLEN];
00145 static int argcount = FIXEDARGS;
00146 
00147 
00148 int nonfatalerrors;         /* errors */
00149 int inetdflag /* = 1 */ ;   /* Support for inetd *//* is now the default */
00150 int pmflag;                 /* Support for port monitors */
00151 int logflag;                /* Use syslog instead of fprintf for errors */
00152 int tblflag;                /* Support for dispatch table file */
00153 int mtflag;                 /* Support for MT */
00154 
00155 #define INLINE 3
00156 /*length at which to start doing an inline */
00157 
00158 int inlineflag = INLINE;    /* length at which to start doing an inline. 3 = default
00159                                if 0, no xdr_inline code */
00160 
00161 int indefinitewait;         /* If started by port monitors, hang till it wants */
00162 int exitnow;                /* If started by port monitors, exit after the call */
00163 int timerflag;                     /* TRUE if !indefinite && !exitnow */
00164 int newstyle;               /* newstyle of passing arguments (by value) */
00165 #ifdef __GNU_LIBRARY__
00166 int Cflag = 1;                     /* ANSI C syntax */
00167 #else
00168 int Cflag;                  /* ANSI C/C++ syntax */
00169 #endif
00170 int CCflag;                 /* C++ files */
00171 static int allfiles;        /* generate all files */
00172 #ifdef __GNU_LIBRARY__
00173 int tirpcflag;                     /* generating code for tirpc, by default */
00174 #else
00175 int tirpcflag = 1;          /* generating code for tirpc, by default */
00176 #endif
00177 xdrfunc *xdrfunc_head;             /* xdr function list */
00178 xdrfunc *xdrfunc_tail;             /* xdr function list */
00179 
00180 int
00181 main (int argc, const char *argv[])
00182 {
00183   struct commandline cmd;
00184 
00185   (void) memset ((char *) &cmd, 0, sizeof (struct commandline));
00186   clear_args ();
00187   if (!parseargs (argc, argv, &cmd))
00188     usage ();
00189 
00190   if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
00191       cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag)
00192     {
00193       checkfiles (cmd.infile, cmd.outfile);
00194     }
00195   else
00196     checkfiles (cmd.infile, NULL);
00197 
00198   if (cmd.cflag)
00199     c_output (cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
00200   else if (cmd.hflag)
00201     h_output (cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile);
00202   else if (cmd.lflag)
00203     l_output (cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
00204   else if (cmd.sflag || cmd.mflag || (cmd.nflag))
00205     s_output (argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
00206              cmd.outfile, cmd.mflag, cmd.nflag);
00207   else if (cmd.tflag)
00208     t_output (cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
00209   else if (cmd.Ssflag)
00210     svc_output (cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
00211   else if (cmd.Scflag)
00212     clnt_output (cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
00213   else if (cmd.makefileflag)
00214     mkfile_output (&cmd);
00215   else
00216     {
00217       /* the rescans are required, since cpp may effect input */
00218       c_output (cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
00219       reinitialize ();
00220       h_output (cmd.infile, "-DRPC_HDR", EXTEND, ".h");
00221       reinitialize ();
00222       l_output (cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
00223       reinitialize ();
00224       if (inetdflag || !tirpcflag)
00225        s_output (allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
00226                 "_svc.c", cmd.mflag, cmd.nflag);
00227       else
00228        s_output (allnc, allnv, cmd.infile, "-DRPC_SVC",
00229                 EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
00230       if (tblflag)
00231        {
00232          reinitialize ();
00233          t_output (cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
00234        }
00235       if (allfiles)
00236        {
00237          reinitialize ();
00238          svc_output (cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
00239          reinitialize ();
00240          clnt_output (cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
00241        }
00242       if (allfiles || (cmd.makefileflag == 1))
00243        {
00244          reinitialize ();
00245          mkfile_output (&cmd);
00246        }
00247     }
00248 
00249   return nonfatalerrors;
00250 }
00251 
00252 /*
00253  * add extension to filename
00254  */
00255 static char *
00256 extendfile (const char *file, const char *ext)
00257 {
00258   char *res;
00259   const char *p;
00260 
00261   res = alloc (strlen (file) + strlen (ext) + 1);
00262   if (res == NULL)
00263     abort ();
00264   p = strrchr (file, '.');
00265   if (p == NULL)
00266     p = file + strlen (file);
00267   strcpy (res, file);
00268   strcpy (res + (p - file), ext);
00269   return res;
00270 }
00271 
00272 /*
00273  * Open output file with given extension
00274  */
00275 static void
00276 open_output (const char *infile, const char *outfile)
00277 {
00278   if (outfile == NULL)
00279     {
00280       fout = stdout;
00281       return;
00282     }
00283 
00284   if (infile != NULL && streq (outfile, infile))
00285     {
00286       fprintf (stderr, _ ("%s: output would overwrite %s\n"), cmdname,
00287               infile);
00288       crash ();
00289     }
00290   fout = fopen (outfile, "w");
00291   if (fout == NULL)
00292     {
00293       fprintf (stderr, _ ("%s: unable to open %s: %m\n"), cmdname, outfile);
00294       crash ();
00295     }
00296   record_open (outfile);
00297 }
00298 
00299 /* Close the output file and check for write errors.  */
00300 static void
00301 close_output (const char *outfile)
00302 {
00303   if (fclose (fout) == EOF)
00304     {
00305       fprintf (stderr, _("%s: while writing output %s: %m"), cmdname,
00306               outfile ?: "<stdout>");
00307       crash ();
00308     }
00309 }
00310 
00311 static void
00312 add_warning (void)
00313 {
00314   fprintf (fout, "/*\n");
00315   fprintf (fout, " * Please do not edit this file.\n");
00316   fprintf (fout, " * It was generated using rpcgen.\n");
00317   fprintf (fout, " */\n\n");
00318 }
00319 
00320 /* clear list of arguments */
00321 static void
00322 clear_args (void)
00323 {
00324   int i;
00325   for (i = FIXEDARGS; i < ARGLISTLEN; ++i)
00326     arglist[i] = NULL;
00327   argcount = FIXEDARGS;
00328 }
00329 
00330 /* make sure that a CPP exists */
00331 static void
00332 find_cpp (void)
00333 {
00334   struct stat buf;
00335 
00336   if (stat (CPP, &buf) < 0)
00337     {                       /* /lib/cpp or explicit cpp does not exist */
00338       if (cppDefined)
00339        {
00340          fprintf (stderr, _ ("cannot find C preprocessor: %s \n"), CPP);
00341          crash ();
00342        }
00343       else
00344        {                    /* try the other one */
00345          CPP = SVR4_CPP;
00346          if (stat (CPP, &buf) < 0)
00347            {                /* can't find any cpp */
00348              fputs (_ ("cannot find any C preprocessor (cpp)\n"), stdout);
00349              crash ();
00350            }
00351        }
00352     }
00353 }
00354 
00355 /*
00356  * Open input file with given define for C-preprocessor
00357  */
00358 static void
00359 open_input (const char *infile, const char *define)
00360 {
00361   int pd[2];
00362 
00363   infilename = (infile == NULL) ? "<stdin>" : infile;
00364   if (pipe (pd) != 0)
00365     {
00366       perror ("pipe");
00367       exit (1);
00368     }
00369   cpp_pid = fork ();
00370   switch (cpp_pid)
00371     {
00372     case 0:
00373       find_cpp ();
00374       putarg (0, CPP);
00375       putarg (1, CPPFLAGS);
00376       addarg (define);
00377       if (infile)
00378        addarg (infile);
00379       addarg ((char *) NULL);
00380       close (1);
00381       dup2 (pd[1], 1);
00382       close (pd[0]);
00383       execv (arglist[0], (char **) arglist);
00384       perror ("execv");
00385       exit (1);
00386     case -1:
00387       perror ("fork");
00388       exit (1);
00389     }
00390   close (pd[1]);
00391   fin = fdopen (pd[0], "r");
00392   if (fin == NULL)
00393     {
00394       fprintf (stderr, "%s: ", cmdname);
00395       perror (infilename);
00396       crash ();
00397     }
00398 }
00399 
00400 /* Close the connection to the C-preprocessor and check for successfull
00401    termination.  */
00402 static void
00403 close_input (void)
00404 {
00405   int status;
00406 
00407   fclose (fin);
00408   /* Check the termination status.  */
00409   if (waitpid (cpp_pid, &status, 0) < 0)
00410     {
00411       perror ("waitpid");
00412       crash ();
00413     }
00414   if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0)
00415     {
00416       if (WIFSIGNALED (status))
00417        fprintf (stderr, _("%s: C preprocessor failed with signal %d\n"),
00418                cmdname, WTERMSIG (status));
00419       else
00420        fprintf (stderr, _("%s: C preprocessor failed with exit code %d\n"),
00421                cmdname, WEXITSTATUS (status));
00422       crash ();
00423     }
00424 }
00425 
00426 /* valid tirpc nettypes */
00427 static const char *valid_ti_nettypes[] =
00428 {
00429   "netpath",
00430   "visible",
00431   "circuit_v",
00432   "datagram_v",
00433   "circuit_n",
00434   "datagram_n",
00435   "udp",
00436   "tcp",
00437   "raw",
00438   NULL
00439 };
00440 
00441 /* valid inetd nettypes */
00442 static const char *valid_i_nettypes[] =
00443 {
00444   "udp",
00445   "tcp",
00446   NULL
00447 };
00448 
00449 static int
00450 check_nettype (const char *name, const char *list_to_check[])
00451 {
00452   int i;
00453   for (i = 0; list_to_check[i] != NULL; i++)
00454     {
00455       if (strcmp (name, list_to_check[i]) == 0)
00456        {
00457          return 1;
00458        }
00459     }
00460   fprintf (stderr, _ ("illegal nettype: `%s'\n"), name);
00461   return 0;
00462 }
00463 
00464 /*
00465  * Compile into an XDR routine output file
00466  */
00467 
00468 static void
00469 c_output (const char *infile, const char *define, int extend,
00470          const char *outfile)
00471 {
00472   definition *def;
00473   char *include;
00474   const char *outfilename;
00475   long tell;
00476 
00477   c_initialize ();
00478   open_input (infile, define);
00479   outfilename = extend ? extendfile (infile, outfile) : outfile;
00480   open_output (infile, outfilename);
00481   add_warning ();
00482   if (infile && (include = extendfile (infile, ".h")))
00483     {
00484       fprintf (fout, "#include \"%s\"\n", include);
00485       free (include);
00486       /* .h file already contains rpc/rpc.h */
00487     }
00488   else
00489     fprintf (fout, "#include <rpc/rpc.h>\n");
00490   tell = ftell (fout);
00491   while ((def = get_definition ()) != NULL)
00492     emit (def);
00493 
00494   if (extend && tell == ftell (fout))
00495     unlink (outfilename);
00496   close_input ();
00497   close_output (outfilename);
00498 }
00499 
00500 void
00501 c_initialize (void)
00502 {
00503 
00504   /* add all the starting basic types */
00505 
00506   add_type (1, "int");
00507   add_type (1, "long");
00508   add_type (1, "short");
00509   add_type (1, "bool");
00510 
00511   add_type (1, "u_int");
00512   add_type (1, "u_long");
00513   add_type (1, "u_short");
00514 
00515 }
00516 
00517 char rpcgen_table_dcl[] = "struct rpcgen_table {\n\
00518        char   *(*proc)();\n\
00519        xdrproc_t     xdr_arg;\n\
00520        unsigned      len_arg;\n\
00521        xdrproc_t     xdr_res;\n\
00522        unsigned      len_res;\n\
00523 };\n";
00524 
00525 
00526 static char *
00527 generate_guard (const char *pathname)
00528 {
00529   const char *filename;
00530   char *guard, *tmp;
00531 
00532   filename = strrchr (pathname, '/');     /* find last component */
00533   filename = ((filename == NULL) ? pathname : filename + 1);
00534   guard = extendfile (filename, "_H_RPCGEN");
00535   /* convert to upper case */
00536   tmp = guard;
00537   while (*tmp)
00538     {
00539       if (islower (*tmp))
00540        *tmp = toupper (*tmp);
00541       tmp++;
00542     }
00543 
00544   return guard;
00545 }
00546 
00547 /*
00548  * Compile into an XDR header file
00549  */
00550 
00551 
00552 static void
00553 h_output (const char *infile, const char *define, int extend,
00554          const char *outfile)
00555 {
00556   xdrfunc *xdrfuncp;
00557   definition *def;
00558   const char *ifilename;
00559   const char *outfilename;
00560   long tell;
00561   char *guard;
00562   list *l;
00563 
00564   open_input (infile, define);
00565   outfilename = extend ? extendfile (infile, outfile) : outfile;
00566   open_output (infile, outfilename);
00567   add_warning ();
00568   ifilename = (infile == NULL) ? "STDIN" : infile;
00569   guard = generate_guard (outfilename ? outfilename : ifilename);
00570 
00571   fprintf (fout, "#ifndef _%s\n#define _%s\n\n", guard,
00572           guard);
00573 
00574   fprintf (fout, "#include <rpc/rpc.h>\n\n");
00575 
00576   if (mtflag)
00577     {
00578       fprintf (fout, "#include <pthread.h>\n");
00579     }
00580 
00581   /* put the C++ support */
00582   if (Cflag && !CCflag)
00583     {
00584       fprintf (fout, "\n#ifdef __cplusplus\n");
00585       fprintf (fout, "extern \"C\" {\n");
00586       fprintf (fout, "#endif\n\n");
00587     }
00588 
00589   tell = ftell (fout);
00590   /* print data definitions */
00591   while ((def = get_definition ()) != NULL)
00592     {
00593       print_datadef (def);
00594     }
00595 
00596   /* print function declarations.
00597      Do this after data definitions because they might be used as
00598      arguments for functions */
00599   for (l = defined; l != NULL; l = l->next)
00600     {
00601       print_funcdef (l->val);
00602     }
00603   /* Now  print all xdr func declarations */
00604   if (xdrfunc_head != NULL)
00605     {
00606       fprintf (fout, "\n/* the xdr functions */\n");
00607       if (CCflag)
00608        {
00609          fprintf (fout, "\n#ifdef __cplusplus\n");
00610          fprintf (fout, "extern \"C\" {\n");
00611          fprintf (fout, "#endif\n");
00612        }
00613       if (!Cflag)
00614        {
00615          xdrfuncp = xdrfunc_head;
00616          while (xdrfuncp != NULL)
00617            {
00618              print_xdr_func_def (xdrfuncp->name,
00619                               xdrfuncp->pointerp, 2);
00620              xdrfuncp = xdrfuncp->next;
00621            }
00622        }
00623       else
00624        {
00625          int i;
00626 
00627          for (i = 1; i < 3; ++i)
00628            {
00629              if (i == 1)
00630               fprintf (fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
00631              else
00632               fprintf (fout, "\n#else /* K&R C */\n");
00633 
00634              xdrfuncp = xdrfunc_head;
00635              while (xdrfuncp != NULL)
00636               {
00637                 print_xdr_func_def (xdrfuncp->name,
00638                                   xdrfuncp->pointerp, i);
00639                 xdrfuncp = xdrfuncp->next;
00640               }
00641            }
00642          fprintf (fout, "\n#endif /* K&R C */\n");
00643        }
00644     }
00645 
00646   if (extend && tell == ftell (fout))
00647     {
00648       unlink (outfilename);
00649     }
00650   else if (tblflag)
00651     {
00652       fprintf (fout, rpcgen_table_dcl);
00653     }
00654 
00655   if (Cflag)
00656     {
00657       fprintf (fout, "\n#ifdef __cplusplus\n");
00658       fprintf (fout, "}\n");
00659       fprintf (fout, "#endif\n");
00660     }
00661 
00662   fprintf (fout, "\n#endif /* !_%s */\n", guard);
00663   free (guard);
00664   close_input ();
00665   close_output (outfilename);
00666 }
00667 
00668 /*
00669  * Compile into an RPC service
00670  */
00671 static void
00672 s_output (int argc, const char *argv[], const char *infile, const char *define,
00673          int extend, const char *outfile, int nomain, int netflag)
00674 {
00675   char *include;
00676   definition *def;
00677   int foundprogram = 0;
00678   const char *outfilename;
00679 
00680   open_input (infile, define);
00681   outfilename = extend ? extendfile (infile, outfile) : outfile;
00682   open_output (infile, outfilename);
00683   add_warning ();
00684   if (infile && (include = extendfile (infile, ".h")))
00685     {
00686       fprintf (fout, "#include \"%s\"\n", include);
00687       free (include);
00688     }
00689   else
00690     fprintf (fout, "#include <rpc/rpc.h>\n");
00691 
00692   fprintf (fout, "#include <stdio.h>\n");
00693   fprintf (fout, "#include <stdlib.h>\n");
00694   fprintf (fout, "#include <rpc/pmap_clnt.h>\n");
00695   if (Cflag)
00696     fprintf (fout, "#include <string.h>\n");
00697   if (strcmp (svcclosetime, "-1") == 0)
00698     indefinitewait = 1;
00699   else if (strcmp (svcclosetime, "0") == 0)
00700     exitnow = 1;
00701   else if (inetdflag || pmflag)
00702     {
00703       fprintf (fout, "#include <signal.h>\n");
00704       timerflag = 1;
00705     }
00706 
00707   if (!tirpcflag && inetdflag)
00708 #ifdef __GNU_LIBRARY__
00709     fprintf (fout, "#include <sys/ioctl.h> /* ioctl, TIOCNOTTY */\n");
00710 #else
00711     fprintf (fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n");
00712 #endif
00713   if (Cflag && (inetdflag || pmflag))
00714     {
00715 #ifdef __GNU_LIBRARY__
00716       fprintf (fout, "#include <sys/types.h> /* open */\n");
00717       fprintf (fout, "#include <sys/stat.h> /* open */\n");
00718       fprintf (fout, "#include <fcntl.h> /* open */\n");
00719       fprintf (fout, "#include <unistd.h> /* getdtablesize */\n");
00720 #else
00721       fprintf (fout, "#ifdef __cplusplus\n");
00722       fprintf (fout, "#include <sysent.h> /* getdtablesize, open */\n");
00723       fprintf (fout, "#endif /* __cplusplus */\n");
00724       if (tirpcflag)
00725        fprintf (fout, "#include <unistd.h> /* setsid */\n");
00726 #endif
00727     }
00728 #ifdef __GNU_LIBRARY__
00729   if (tirpcflag && !(Cflag && (inetdflag || pmflag)))
00730 #else
00731   if (tirpcflag)
00732 #endif
00733     fprintf (fout, "#include <sys/types.h>\n");
00734 
00735   fprintf (fout, "#include <memory.h>\n");
00736 #ifndef __GNU_LIBRARY__
00737   fprintf (fout, "#include <stropts.h>\n");
00738 #endif
00739   if (inetdflag || !tirpcflag)
00740     {
00741       fprintf (fout, "#include <sys/socket.h>\n");
00742       fprintf (fout, "#include <netinet/in.h>\n");
00743     }
00744 
00745   if ((netflag || pmflag) && tirpcflag && !nomain)
00746     {
00747       fprintf (fout, "#include <netconfig.h>\n");
00748     }
00749   if ( /*timerflag && */ tirpcflag)
00750     fprintf (fout, "#include <sys/resource.h> /* rlimit */\n");
00751   if (logflag || inetdflag || pmflag)
00752     {
00753 #ifdef __GNU_LIBRARY__
00754       fprintf (fout, "#include <syslog.h>\n");
00755 #else
00756       fprintf (fout, "#ifdef SYSLOG\n");
00757       fprintf (fout, "#include <syslog.h>\n");
00758       fprintf (fout, "#else\n");
00759       fprintf (fout, "#define LOG_ERR 1\n");
00760       fprintf (fout, "#define openlog(a, b, c)\n");
00761       fprintf (fout, "#endif\n");
00762 #endif
00763     }
00764 
00765   /* for ANSI-C */
00766   if (Cflag)
00767     fprintf (fout, "\n#ifndef SIG_PF\n#define SIG_PF void(*)(int)\n#endif\n");
00768 
00769 #ifndef __GNU_LIBRARY__
00770   fprintf (fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
00771 #endif
00772   if (timerflag)
00773     fprintf (fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime);
00774   while ((def = get_definition ()) != NULL)
00775     {
00776       foundprogram |= (def->def_kind == DEF_PROGRAM);
00777     }
00778   if (extend && !foundprogram)
00779     {
00780       unlink (outfilename);
00781       return;
00782     }
00783   write_most (infile, netflag, nomain);
00784   if (!nomain)
00785     {
00786       if (!do_registers (argc, argv))
00787        {
00788          if (outfilename)
00789            unlink (outfilename);
00790          usage ();
00791        }
00792       write_rest ();
00793     }
00794   close_input ();
00795   close_output (outfilename);
00796 }
00797 
00798 /*
00799  * generate client side stubs
00800  */
00801 static void
00802 l_output (const char *infile, const char *define, int extend,
00803          const char *outfile)
00804 {
00805   char *include;
00806   definition *def;
00807   int foundprogram = 0;
00808   const char *outfilename;
00809 
00810   open_input (infile, define);
00811   outfilename = extend ? extendfile (infile, outfile) : outfile;
00812   open_output (infile, outfilename);
00813   add_warning ();
00814   if (Cflag)
00815     fprintf (fout, "#include <memory.h> /* for memset */\n");
00816   if (infile && (include = extendfile (infile, ".h")))
00817     {
00818       fprintf (fout, "#include \"%s\"\n", include);
00819       free (include);
00820     }
00821   else
00822     fprintf (fout, "#include <rpc/rpc.h>\n");
00823   while ((def = get_definition ()) != NULL)
00824     {
00825       foundprogram |= (def->def_kind == DEF_PROGRAM);
00826     }
00827   if (extend && !foundprogram)
00828     {
00829       unlink (outfilename);
00830       return;
00831     }
00832   write_stubs ();
00833   close_input ();
00834   close_output (outfilename);
00835 }
00836 
00837 /*
00838  * generate the dispatch table
00839  */
00840 static void
00841 t_output (const char *infile, const char *define, int extend,
00842          const char *outfile)
00843 {
00844   definition *def;
00845   int foundprogram = 0;
00846   const char *outfilename;
00847 
00848   open_input (infile, define);
00849   outfilename = extend ? extendfile (infile, outfile) : outfile;
00850   open_output (infile, outfilename);
00851   add_warning ();
00852   while ((def = get_definition ()) != NULL)
00853     {
00854       foundprogram |= (def->def_kind == DEF_PROGRAM);
00855     }
00856   if (extend && !foundprogram)
00857     {
00858       unlink (outfilename);
00859       return;
00860     }
00861   write_tables ();
00862   close_input ();
00863   close_output (outfilename);
00864 }
00865 
00866 /* sample routine for the server template */
00867 static void
00868 svc_output (const char *infile, const char *define, int extend,
00869            const char *outfile)
00870 {
00871   definition *def;
00872   char *include;
00873   const char *outfilename;
00874   long tell;
00875 
00876   open_input (infile, define);
00877   outfilename = extend ? extendfile (infile, outfile) : outfile;
00878   checkfiles (infile, outfilename);
00879   /*check if outfile already exists.
00880      if so, print an error message and exit */
00881   open_output (infile, outfilename);
00882   add_sample_msg ();
00883 
00884   if (infile && (include = extendfile (infile, ".h")))
00885     {
00886       fprintf (fout, "#include \"%s\"\n", include);
00887       free (include);
00888     }
00889   else
00890     fprintf (fout, "#include <rpc/rpc.h>\n");
00891 
00892   tell = ftell (fout);
00893   while ((def = get_definition ()) != NULL)
00894     {
00895       write_sample_svc (def);
00896     }
00897   if (extend && tell == ftell (fout))
00898     {
00899       unlink (outfilename);
00900     }
00901   close_input ();
00902   close_output (outfilename);
00903 }
00904 
00905 
00906 /* sample main routine for client */
00907 static void
00908 clnt_output (const char *infile, const char *define, int extend,
00909             const char *outfile)
00910 {
00911   definition *def;
00912   char *include;
00913   const char *outfilename;
00914   long tell;
00915   int has_program = 0;
00916 
00917   open_input (infile, define);
00918   outfilename = extend ? extendfile (infile, outfile) : outfile;
00919   checkfiles (infile, outfilename);
00920   /*check if outfile already exists.
00921      if so, print an error message and exit */
00922 
00923   open_output (infile, outfilename);
00924   add_sample_msg ();
00925   if (infile && (include = extendfile (infile, ".h")))
00926     {
00927       fprintf (fout, "#include \"%s\"\n", include);
00928       free (include);
00929     }
00930   else
00931     fprintf (fout, "#include <rpc/rpc.h>\n");
00932   tell = ftell (fout);
00933   while ((def = get_definition ()) != NULL)
00934     {
00935       has_program += write_sample_clnt (def);
00936     }
00937 
00938   if (has_program)
00939     write_sample_clnt_main ();
00940 
00941   if (extend && tell == ftell (fout))
00942     {
00943       unlink (outfilename);
00944     }
00945   close_input ();
00946   close_output (outfilename);
00947 }
00948 
00949 static const char space[] = " ";
00950 
00951 static char *
00952 file_name (const char *file, const char *ext)
00953 {
00954   char *temp;
00955   temp = extendfile (file, ext);
00956 
00957   if (access (temp, F_OK) != -1)
00958     return (temp);
00959 
00960   free (temp);
00961   return (char *) space;
00962 }
00963 
00964 static void
00965 mkfile_output (struct commandline *cmd)
00966 {
00967   char *mkfilename;
00968   char *clientname, *clntname, *xdrname, *hdrname;
00969   char *servername, *svcname, *servprogname, *clntprogname;
00970 
00971   svcname = file_name (cmd->infile, "_svc.c");
00972   clntname = file_name (cmd->infile, "_clnt.c");
00973   xdrname = file_name (cmd->infile, "_xdr.c");
00974   hdrname = file_name (cmd->infile, ".h");
00975 
00976   if (allfiles)
00977     {
00978       servername = extendfile (cmd->infile, "_server.c");
00979       clientname = extendfile (cmd->infile, "_client.c");
00980     }
00981   else
00982     {
00983       servername = (char *) space;
00984       clientname = (char *) space;
00985     }
00986   servprogname = extendfile (cmd->infile, "_server");
00987   clntprogname = extendfile (cmd->infile, "_client");
00988 
00989   if (allfiles)
00990     {
00991       char *cp, *temp;
00992 
00993       mkfilename = alloc (strlen ("Makefile.") + strlen (cmd->infile) + 1);
00994       if (mkfilename == NULL)
00995        abort ();
00996       temp = rindex (cmd->infile, '.');
00997       cp = stpcpy (mkfilename, "Makefile.");
00998       if (temp != NULL)
00999        *((char *) stpncpy (cp, cmd->infile, temp - cmd->infile)) = '\0';
01000       else
01001        stpcpy (cp, cmd->infile);
01002 
01003     }
01004   else
01005     mkfilename = (char *) cmd->outfile;
01006 
01007   checkfiles (NULL, mkfilename);
01008   open_output (NULL, mkfilename);
01009 
01010   fprintf (fout, "\n# This is a template Makefile generated by rpcgen\n");
01011 
01012   f_print (fout, "\n# Parameters\n\n");
01013 
01014   f_print (fout, "CLIENT = %s\nSERVER = %s\n\n", clntprogname, servprogname);
01015   f_print (fout, "SOURCES_CLNT.c = \nSOURCES_CLNT.h = \n");
01016   f_print (fout, "SOURCES_SVC.c = \nSOURCES_SVC.h = \n");
01017   f_print (fout, "SOURCES.x = %s\n\n", cmd->infile);
01018   f_print (fout, "TARGETS_SVC.c = %s %s %s \n",
01019           svcname, servername, xdrname);
01020   f_print (fout, "TARGETS_CLNT.c = %s %s %s \n",
01021           clntname, clientname, xdrname);
01022   f_print (fout, "TARGETS = %s %s %s %s %s %s\n\n",
01023           hdrname, xdrname, clntname,
01024           svcname, clientname, servername);
01025 
01026   f_print (fout, "OBJECTS_CLNT = $(SOURCES_CLNT.c:%%.c=%%.o) \
01027 $(TARGETS_CLNT.c:%%.c=%%.o)");
01028 
01029   f_print (fout, "\nOBJECTS_SVC = $(SOURCES_SVC.c:%%.c=%%.o) \
01030 $(TARGETS_SVC.c:%%.c=%%.o)");
01031 
01032   f_print (fout, "\n# Compiler flags \n");
01033   if (mtflag)
01034     fprintf (fout, "\nCPPFLAGS += -D_REENTRANT\nCFLAGS += -g \nLDLIBS \
01035 += -lnsl -lpthread \n ");
01036   else
01037     f_print (fout, "\nCFLAGS += -g \nLDLIBS += -lnsl\n");
01038   f_print (fout, "RPCGENFLAGS = \n");
01039 
01040   f_print (fout, "\n# Targets \n\n");
01041 
01042   f_print (fout, "all : $(CLIENT) $(SERVER)\n\n");
01043   f_print (fout, "$(TARGETS) : $(SOURCES.x) \n");
01044   f_print (fout, "\trpcgen $(RPCGENFLAGS) $(SOURCES.x)\n\n");
01045   f_print (fout, "$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) \
01046 $(TARGETS_CLNT.c) \n\n");
01047 
01048   f_print (fout, "$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) \
01049 $(TARGETS_SVC.c) \n\n");
01050   f_print (fout, "$(CLIENT) : $(OBJECTS_CLNT) \n");
01051   f_print (fout, "\t$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) \
01052 $(LDLIBS) \n\n");
01053   f_print (fout, "$(SERVER) : $(OBJECTS_SVC) \n");
01054   f_print (fout, "\t$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)\n\n ");
01055   f_print (fout, "clean:\n\t $(RM) core $(TARGETS) $(OBJECTS_CLNT) \
01056 $(OBJECTS_SVC) $(CLIENT) $(SERVER)\n\n");
01057   close_output (mkfilename);
01058 
01059   free (clntprogname);
01060   free (servprogname);
01061   if (servername != space)
01062     free (servername);
01063   if (clientname != space)
01064     free (clientname);
01065   if (mkfilename != (char *) cmd->outfile)
01066     free (mkfilename);
01067   if (svcname != space)
01068     free (svcname);
01069   if (clntname != space)
01070     free (clntname);
01071   if (xdrname != space)
01072     free (xdrname);
01073   if (hdrname != space)
01074     free (hdrname);
01075 }
01076 
01077 /*
01078  * Perform registrations for service output
01079  * Return 0 if failed; 1 otherwise.
01080  */
01081 static int
01082 do_registers (int argc, const char *argv[])
01083 {
01084   int i;
01085 
01086   if (inetdflag || !tirpcflag)
01087     {
01088       for (i = 1; i < argc; i++)
01089        {
01090          if (streq (argv[i], "-s"))
01091            {
01092              if (!check_nettype (argv[i + 1], valid_i_nettypes))
01093               return 0;
01094              write_inetd_register (argv[i + 1]);
01095              i++;
01096            }
01097        }
01098     }
01099   else
01100     {
01101       for (i = 1; i < argc; i++)
01102        if (streq (argv[i], "-s"))
01103          {
01104            if (!check_nettype (argv[i + 1], valid_ti_nettypes))
01105              return 0;
01106            write_nettype_register (argv[i + 1]);
01107            i++;
01108          }
01109        else if (streq (argv[i], "-n"))
01110          {
01111            write_netid_register (argv[i + 1]);
01112            i++;
01113          }
01114     }
01115   return 1;
01116 }
01117 
01118 /*
01119  * Add another argument to the arg list
01120  */
01121 static void
01122 addarg (const char *cp)
01123 {
01124   if (argcount >= ARGLISTLEN)
01125     {
01126       fprintf (stderr, _("rpcgen: too many defines\n"));
01127       crash ();
01128       /*NOTREACHED */
01129     }
01130   arglist[argcount++] = cp;
01131 }
01132 
01133 static void
01134 putarg (int whereto, const char *cp)
01135 {
01136   if (whereto >= ARGLISTLEN)
01137     {
01138       fprintf (stderr, _("rpcgen: arglist coding error\n"));
01139       crash ();
01140       /*NOTREACHED */
01141     }
01142   arglist[whereto] = cp;
01143 }
01144 
01145 /*
01146  * if input file is stdin and an output file is specified then complain
01147  * if the file already exists. Otherwise the file may get overwritten
01148  * If input file does not exist, exit with an error
01149  */
01150 
01151 static void
01152 checkfiles (const char *infile, const char *outfile)
01153 {
01154   struct stat buf;
01155 
01156   if (infile)               /* infile ! = NULL */
01157     if (stat (infile, &buf) < 0)
01158       {
01159        perror (infile);
01160        crash ();
01161       }
01162   if (outfile)
01163     {
01164       if (stat (outfile, &buf) < 0)
01165        return;                     /* file does not exist */
01166       else
01167        {
01168          fprintf (stderr,
01169                  /* TRANS: the file will not be removed; this is an
01170                     TRANS: informative message.  */
01171                  _("file `%s' already exists and may be overwritten\n"),
01172                  outfile);
01173          crash ();
01174        }
01175     }
01176 }
01177 
01178 /*
01179  * Parse command line arguments
01180  */
01181 static int
01182 parseargs (int argc, const char *argv[], struct commandline *cmd)
01183 {
01184   int i;
01185   int j;
01186   int c;
01187   char flag[(1 << 8 * sizeof (char))];
01188   int nflags;
01189 
01190   cmdname = argv[0];
01191   cmd->infile = cmd->outfile = NULL;
01192   if (argc < 2)
01193     {
01194       return (0);
01195     }
01196   allfiles = 0;
01197   flag['c'] = 0;
01198   flag['h'] = 0;
01199   flag['l'] = 0;
01200   flag['m'] = 0;
01201   flag['o'] = 0;
01202   flag['s'] = 0;
01203   flag['n'] = 0;
01204   flag['t'] = 0;
01205   flag['S'] = 0;
01206   flag['C'] = 0;
01207   flag['M'] = 0;
01208 
01209   for (i = 1; i < argc; i++)
01210     {
01211       if (argv[i][0] != '-')
01212        {
01213          if (cmd->infile)
01214            {
01215              fprintf (stderr,
01216                      _("Cannot specify more than one input file!\n"));
01217              return 0;
01218            }
01219          cmd->infile = argv[i];
01220        }
01221       else
01222        {
01223          for (j = 1; argv[i][j] != 0; j++)
01224            {
01225              c = argv[i][j];
01226              switch (c)
01227               {
01228               case 'a':
01229                 allfiles = 1;
01230                 break;
01231               case 'c':
01232               case 'h':
01233               case 'l':
01234               case 'm':
01235               case 't':
01236                 if (flag[c])
01237                   return 0;
01238                 flag[c] = 1;
01239                 break;
01240               case 'S':
01241                 /* sample flag: Ss or Sc.
01242                    Ss means set flag['S'];
01243                    Sc means set flag['C'];
01244                    Sm means set flag['M']; */
01245                 c = argv[i][++j];  /* get next char */
01246                 if (c == 's')
01247                   c = 'S';
01248                 else if (c == 'c')
01249                   c = 'C';
01250                 else if (c == 'm')
01251                   c = 'M';
01252                 else
01253                   return 0;
01254 
01255                 if (flag[c])
01256                   return 0;
01257                 flag[c] = 1;
01258                 break;
01259               case 'C':     /* ANSI C syntax */
01260                 Cflag = 1;
01261                 break;
01262 
01263 #ifdef __GNU_LIBRARY__
01264               case 'k':  /* K&R C syntax */
01265                 Cflag = 0;
01266                 break;
01267 
01268 #endif
01269               case 'b':  /* turn TIRPC flag off for
01270                            generating backward compatible
01271                         */
01272                 tirpcflag = 0;
01273                 break;
01274 
01275 #ifdef __GNU_LIBRARY__
01276               case '5':  /* turn TIRPC flag on for
01277                            generating SysVr4 compatible
01278                         */
01279                 tirpcflag = 1;
01280                 break;
01281 #endif
01282               case 'I':
01283                 inetdflag = 1;
01284                 break;
01285               case 'N':
01286                 newstyle = 1;
01287                 break;
01288               case 'L':
01289                 logflag = 1;
01290                 break;
01291               case 'K':
01292                 if (++i == argc)
01293                   {
01294                     return (0);
01295                   }
01296                 svcclosetime = argv[i];
01297                 goto nextarg;
01298               case 'T':
01299                 tblflag = 1;
01300                 break;
01301               case 'M':
01302                 mtflag = 1;
01303                 break;
01304               case 'i':
01305                 if (++i == argc)
01306                   {
01307                     return (0);
01308                   }
01309                 inlineflag = atoi (argv[i]);
01310                 goto nextarg;
01311               case 'n':
01312               case 'o':
01313               case 's':
01314                 if (argv[i][j - 1] != '-' ||
01315                     argv[i][j + 1] != 0)
01316                   {
01317                     return (0);
01318                   }
01319                 flag[c] = 1;
01320                 if (++i == argc)
01321                   {
01322                     return (0);
01323                   }
01324                 if (c == 's')
01325                   {
01326                     if (!streq (argv[i], "udp") &&
01327                        !streq (argv[i], "tcp"))
01328                      return 0;
01329                   }
01330                 else if (c == 'o')
01331                   {
01332                     if (cmd->outfile)
01333                      return 0;
01334                     cmd->outfile = argv[i];
01335                   }
01336                 goto nextarg;
01337               case 'D':
01338                 if (argv[i][j - 1] != '-')
01339                   return 0;
01340                 addarg (argv[i]);
01341                 goto nextarg;
01342               case 'Y':
01343                 if (++i == argc)
01344                   return 0;
01345                 {
01346                   size_t len = strlen (argv[i]);
01347                   pathbuf = malloc (len + 5);
01348                   if (pathbuf == NULL)
01349                     {
01350                      perror (cmdname);
01351                      crash ();
01352                     }
01353                   stpcpy (stpcpy (pathbuf,
01354                                 argv[i]),
01355                          "/cpp");
01356                   CPP = pathbuf;
01357                   cppDefined = 1;
01358                   goto nextarg;
01359                 }
01360 
01361               default:
01362                 return 0;
01363               }
01364              }
01365        nextarg:
01366          ;
01367        }
01368     }
01369 
01370   cmd->cflag = flag['c'];
01371   cmd->hflag = flag['h'];
01372   cmd->lflag = flag['l'];
01373   cmd->mflag = flag['m'];
01374   cmd->nflag = flag['n'];
01375   cmd->sflag = flag['s'];
01376   cmd->tflag = flag['t'];
01377   cmd->Ssflag = flag['S'];
01378   cmd->Scflag = flag['C'];
01379   cmd->makefileflag = flag['M'];
01380 
01381 #ifndef _RPC_THREAD_SAFE_
01382   if (mtflag || newstyle)
01383     {
01384       /* glibc doesn't support these flags.  */
01385       f_print (stderr,
01386               _("This implementation doesn't support newstyle or MT-safe code!\n"));
01387       return (0);
01388     }
01389 #endif
01390   if (tirpcflag)
01391     {
01392       pmflag = inetdflag ? 0 : 1;    /* pmflag or inetdflag is always TRUE */
01393       if ((inetdflag && cmd->nflag))
01394        {                    /* netid not allowed with inetdflag */
01395          fprintf (stderr, _("Cannot use netid flag with inetd flag!\n"));
01396          return 0;
01397        }
01398     }
01399   else
01400     {                       /* 4.1 mode */
01401       pmflag = 0;           /* set pmflag only in tirpcmode */
01402 #ifndef __GNU_LIBRARY__
01403       inetdflag = 1;            /* inetdflag is TRUE by default */
01404 #endif
01405       if (cmd->nflag)
01406        {                    /* netid needs TIRPC */
01407          f_print (stderr, _("Cannot use netid flag without TIRPC!\n"));
01408          return (0);
01409        }
01410     }
01411 
01412   if (newstyle && (tblflag || cmd->tflag))
01413     {
01414       f_print (stderr, _("Cannot use table flags with newstyle!\n"));
01415       return (0);
01416     }
01417 
01418   /* check no conflicts with file generation flags */
01419   nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag +
01420     cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag;
01421 
01422   if (nflags == 0)
01423     {
01424       if (cmd->outfile != NULL || cmd->infile == NULL)
01425        {
01426          return (0);
01427        }
01428     }
01429   else if (cmd->infile == NULL &&
01430           (cmd->Ssflag || cmd->Scflag || cmd->makefileflag))
01431     {
01432       fprintf (stderr,
01433               _("\"infile\" is required for template generation flags.\n"));
01434       return 0;
01435     }
01436   if (nflags > 1)
01437     {
01438       fprintf (stderr, _("Cannot have more than one file generation flag!\n"));
01439       return 0;
01440     }
01441   return 1;
01442 }
01443 
01444 static void
01445 usage (void)
01446 {
01447   fprintf (stderr, _("usage: %s infile\n"), cmdname);
01448   fprintf (stderr, _("\t%s [-abkCLNTM][-Dname[=value]] [-i size] \
01449 [-I [-K seconds]] [-Y path] infile\n"), cmdname);
01450   fprintf (stderr, _("\t%s [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] \
01451 [-o outfile] [infile]\n"), cmdname);
01452   fprintf (stderr, _("\t%s [-s nettype]* [-o outfile] [infile]\n"), cmdname);
01453   fprintf (stderr, _("\t%s [-n netid]* [-o outfile] [infile]\n"), cmdname);
01454   options_usage ();
01455   exit (1);
01456 }
01457 
01458 static void
01459 options_usage (void)
01460 {
01461   f_print (stderr, "options:\n");
01462   f_print (stderr, "-a\t\tgenerate all files, including samples\n");
01463   f_print (stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n");
01464   f_print (stderr, "-c\t\tgenerate XDR routines\n");
01465   f_print (stderr, "-C\t\tANSI C mode\n");
01466   f_print (stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n");
01467   f_print (stderr, "-h\t\tgenerate header file\n");
01468   f_print (stderr, "-i size\t\tsize at which to start generating inline code\n");
01469   f_print (stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n");
01470   f_print (stderr, "-K seconds\tserver exits after K seconds of inactivity\n");
01471   f_print (stderr, "-l\t\tgenerate client side stubs\n");
01472   f_print (stderr, "-L\t\tserver errors will be printed to syslog\n");
01473   f_print (stderr, "-m\t\tgenerate server side stubs\n");
01474   f_print (stderr, "-M\t\tgenerate MT-safe code\n");
01475   f_print (stderr, "-n netid\tgenerate server code that supports named netid\n");
01476   f_print (stderr, "-N\t\tsupports multiple arguments and call-by-value\n");
01477   f_print (stderr, "-o outfile\tname of the output file\n");
01478   f_print (stderr, "-s nettype\tgenerate server code that supports named nettype\n");
01479   f_print (stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n");
01480   f_print (stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n");
01481   f_print (stderr, "-Sm \t\tgenerate makefile template \n");
01482   f_print (stderr, "-t\t\tgenerate RPC dispatch table\n");
01483   f_print (stderr, "-T\t\tgenerate code to support RPC dispatch tables\n");
01484   f_print (stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n");
01485 
01486   exit (1);
01487 }