71a27879f09c0228539540f867c386a62fa1a069
[openafs.git] / src / rxgen / rpc_main.c
1 /* @(#)rpc_main.c       1.4 87/11/30 3.9 RPCSRC */
2 /*
3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4  * unrestricted use provided that this legend is included on all tape
5  * media and as a part of the software program in whole or part.  Users
6  * may copy or modify Sun RPC without charge, but are not authorized
7  * to license or distribute it to anyone else except as part of a product or
8  * program developed by the user.
9  * 
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  * 
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  * 
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  * 
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  * 
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30
31 /*
32  * rpc_main.c, Top level of the RPC protocol compiler. 
33  * Copyright (C) 1987, Sun Microsystems, Inc. 
34  */
35
36 #include <afsconfig.h>
37 #include <afs/param.h>
38
39 RCSID("$Header$");
40
41 #include <limits.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <ctype.h>
45 #ifdef HAVE_STRING_H
46 #include <string.h>
47 #else
48 #ifdef HAVE_STRINGS_H
49 #include <strings.h>
50 #endif
51 #endif
52 #ifdef HAVE_SIGNAL_H
53 #include <signal.h>
54 #endif
55 #ifdef HAVE_SYS_FILE_H
56 #include <sys/file.h>
57 #endif
58 #include "rpc_util.h"
59 #include "rpc_parse.h"
60 #include "rpc_scan.h"
61
62 #define EXTEND  1               /* alias for TRUE */
63
64 struct commandline {
65         int cflag;
66         int hflag;
67         int lflag;
68         int sflag;
69         int mflag;
70         int Cflag;
71         int Sflag;
72         int rflag;
73         int kflag;
74         int pflag;
75         int dflag;
76         int xflag;
77         int yflag;
78         char *infile;
79         char *outfile;
80 };
81
82 #define MAXCPPARGS      256     /* maximum number of arguments to cpp */
83 #define MAXCMDLINE      1024    /* MAX chars on a single  cmd line */
84
85 char *prefix="";
86 static char *IncludeDir[MAXCPPARGS];
87 int nincludes = 0;
88 char *OutFileFlag="";
89 char OutFile[256];
90 char Sflag = 0, Cflag = 0, hflag = 0, cflag = 0, kflag = 0;
91 char zflag = 0; /* If set, abort server stub if rpc call returns non-zero */
92 char xflag = 0; /* if set, add stats code to stubs */
93 char yflag = 0; /* if set, only emit function name arrays to xdr file */
94 int debug = 0;
95 static char *cmdname;
96 #ifdef  AFS_SUN5_ENV
97 static char CPP[] = "/usr/ccs/lib/cpp";
98 #elif defined(AFS_FBSD_ENV)
99 static char CPP[] = "/usr/bin/cpp";
100 #elif defined(AFS_NT40_ENV)
101 static char CPP[MAXCMDLINE];
102 #elif defined(AFS_DARWIN_ENV)
103 static char CPP[] = "cc -E";
104 #else
105 static char CPP[] = "/lib/cpp";
106 #endif
107 static char CPPFLAGS[] = "-C";
108 static char *allv[] = {
109         "rpcgen", "-s", "udp", "-s", "tcp",
110 };
111
112 #ifdef  AFS_ALPHA_ENV
113 /*
114  * Running "cpp" directly on DEC OSF/1 does not define anything; the "cc"
115  * driver is responsible.  To compensate (and allow for other definitions
116  * which should always be passed to "cpp"), place definitions which whould
117  * always be passed to "rxgen" in this table.
118  */
119 static char *XTRA_CPPFLAGS[] = {
120 #ifdef  __alpha
121     "-D__alpha",
122 #endif  /* __alpha */
123 #ifdef  OSF
124     "-DOSF",
125 #endif  /* OSF */
126     NULL
127 };
128 #endif
129
130 static int c_output();
131 static int h_output();
132 static int s_output();
133 static int l_output();
134 static int do_registers();
135 static int parseargs();
136
137 static int allc = sizeof(allv)/sizeof(allv[0]);
138
139 #include "AFS_component_version_number.c"
140
141 int
142 main(argc, argv)
143         int argc;
144         char *argv[];
145
146 {
147         struct commandline cmd;
148         char *ep;
149
150         /* initialize CPP with the correct pre-processor on NT */
151 #ifdef AFS_NT40_ENV
152         ep = getenv("RXGEN_CPPCMD");
153         if (ep)
154           strcpy(CPP, ep);
155         else
156           strcpy(CPP, "cl /EP /C /nologo"); 
157 #endif
158 #ifdef  AFS_AIX32_ENV
159         /*
160          * The following signal action for AIX is necessary so that in case of a 
161          * crash (i.e. core is generated) we can include the user's data section 
162          * in the core dump. Unfortunately, by default, only a partial core is
163          * generated which, in many cases, isn't too useful.
164          */
165         struct sigaction nsa;
166     
167         sigemptyset(&nsa.sa_mask);
168         nsa.sa_handler = SIG_DFL;
169         nsa.sa_flags = SA_FULLDUMP;
170         sigaction(SIGSEGV, &nsa, NULL);
171 #endif
172         reinitialize();
173         if (!parseargs(argc, argv, &cmd)) {
174                 f_print(stderr,
175                         "usage: %s infile\n", cmdname);
176                 f_print(stderr,
177                         "       %s [-c | -h | -l | -m | -C | -S | -r | -k | -R | -p | -d | -z] [-Pprefix] [-Idir] [-o outfile] [infile]\n",
178                         cmdname);
179                 f_print(stderr,
180                         "       %s [-s udp|tcp]* [-o outfile] [infile]\n",
181                         cmdname);
182                 exit(1);
183         }
184         OutFileFlag = cmd.outfile;
185         if (OutFileFlag)
186             strcpy(OutFile, cmd.outfile);
187         if (cmd.cflag) {
188             OutFileFlag = NULL;
189             c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile, 0);
190         } else if (cmd.hflag) {
191                 h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile);
192         } else if (cmd.lflag) {
193                 l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile);
194         } else if (cmd.sflag || cmd.mflag) {
195                 s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND,
196                          cmd.outfile, cmd.mflag);
197         } else if (cmd.Cflag) {
198             OutFileFlag = NULL;
199             C_output(cmd.infile, "-DRPC_CLIENT", !EXTEND, cmd.outfile, 1);
200         } else if (cmd.Sflag) {
201             OutFileFlag = NULL;
202             S_output(cmd.infile, "-DRPC_SERVER", !EXTEND, cmd.outfile, 1);
203         } else {
204             if (OutFileFlag && (strrchr(OutFile,'.') == NULL))
205                 strcat(OutFile, ".");
206             if (cmd.rflag) {
207                 C_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_CLIENT", EXTEND, ".cs.c", 1);
208                 reinitialize();
209                 S_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_SERVER", EXTEND, ".ss.c", 1);
210                 reinitialize();
211             } else {
212                 reinitialize();
213                 c_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_XDR", EXTEND, ".xdr.c", 0);
214                 reinitialize();
215                 h_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_HDR", EXTEND, ".h", 0);
216                 reinitialize();
217                 C_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_CLIENT", EXTEND, ".cs.c", 1);
218                 reinitialize();
219                 S_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_SERVER", EXTEND, ".ss.c", 1);
220                 reinitialize();
221             }
222         }
223         exit(0);
224 }
225
226 static void
227 write_int32_macros(fout)
228         FILE *fout;
229 {
230         /*
231          * Note that rxgen writes code that uses xdr_afs_int32() and
232          * xdr_afs_uint32().  Systems do not provide these natively, so we
233          * #define them to locally provided equivalents.
234          *
235          * Some systems do come with native xdr_int32() and xdr_uint32()
236          * functions, but the prototypes are not always in the same
237          * place and are not always consistent so it is less trouble to
238          * use the original int and u_int functions.  We do check that
239          * an int is 32 bits...
240          *
241          * A cleaner solution than these #defines would be to make rxgen
242          * emit calls to xdr_int() and xdr_u_int() to process the types
243          * afs_int32 and afs_uint32 (if, of course, an int is 32 bits).
244          *
245          * Note that to avoid compiler warnings we need to keep
246          * the types of the native xdr_* routines in sync with the
247          * definitions of afs_int32 and afs_uint32 in config/stds.h.
248          */
249
250         /*
251          * If you change the definitions of xdr_afs_int32 and xdr_afs_uint32,
252          * be sure to change them in BOTH rx/xdr.h and rxgen/rpc_main.c.
253          */
254
255 #if (INT_MAX == 0x7FFFFFFF) && (UINT_MAX == 0xFFFFFFFFu)
256         f_print(fout, "#ifndef xdr_afs_int32\n");
257         f_print(fout, "#define xdr_afs_int32 xdr_int\n");
258         f_print(fout, "#endif\n");
259         f_print(fout, "#ifndef xdr_afs_uint32\n");
260         f_print(fout, "#define xdr_afs_uint32 xdr_u_int\n");
261         f_print(fout, "#endif\n");
262         f_print(fout, "#ifndef xdr_afs_int64\n");
263         f_print(fout, "#define xdr_afs_int64 xdr_int64\n");
264         f_print(fout, "#endif\n");
265         f_print(fout, "#ifndef xdr_afs_uint64\n");
266         f_print(fout, "#define xdr_afs_uint64 xdr_uint64\n");
267         f_print(fout, "#endif\n");
268 #else
269 #error Need to do some work here...
270 #endif
271 }
272
273 /*
274  * add extension to filename 
275  */
276 static char *
277 extendfile(file, ext)
278         char *file;
279         char *ext;
280 {
281         char *res;
282         char *p;
283         char *sname;
284
285         res = alloc(strlen(file) + strlen(ext) + 1);
286         if (res == NULL) {
287                 abort();
288         }
289         p = (char *) strrchr(file, '.');
290         if (p == NULL) {
291                 p = file + strlen(file);
292         }
293         sname = (char *) strrchr(file, '/');
294         if (sname == NULL)
295             sname = file;
296         else
297             sname++;
298         strcpy(res,sname);
299         strcpy(res + (p - sname),ext);
300         return (res);
301 }
302
303 /*
304  * Open output file with given extension 
305  */
306 static
307 open_output(infile, outfile)
308         char *infile;
309         char *outfile;
310 {
311         if (outfile == NULL) {
312                 fout = stdout;
313                 return;
314         }
315         if (infile != NULL && streq(outfile, infile)) {
316                 f_print(stderr, "%s: output would overwrite %s\n", cmdname,
317                         infile);
318                 crash();
319         }
320         fout = fopen(outfile, "w");
321         if (fout == NULL) {
322                 f_print(stderr, "%s: unable to open ", cmdname);
323                 perror(outfile);
324                 crash();
325         }
326         record_open(outfile);
327 }
328
329 /*
330  * Open input file with given define for C-preprocessor 
331  */
332 static
333 open_input(infile, define)
334         char *infile;
335         char *define;
336 {
337         char *exec_args[MAXCPPARGS+10];
338         int nargs = 0;
339         char **args;
340         char cpp_cmdline[MAXCMDLINE];
341
342         int i;
343         if (debug == 0) {
344             infilename = (infile == NULL) ? "<stdin>" : infile;
345             strcpy(cpp_cmdline, CPP);
346             strcat(cpp_cmdline, " ");
347             strcat(cpp_cmdline, CPPFLAGS);
348             strcat(cpp_cmdline, " ");
349             strcat(cpp_cmdline, define);
350
351 #ifdef  AFS_ALPHA_ENV
352             for (i = 0;
353                  i < (sizeof(XTRA_CPPFLAGS)/
354                       sizeof(XTRA_CPPFLAGS[0])) - 1;
355                  i++) {
356               strcat(cpp_cmdline, " ");
357               strcat(cpp_cmdline, XTRA_CPPFLAGS[i]);
358             }
359 #endif
360             for (i = 0; i < nincludes; i++) {
361               strcat(cpp_cmdline, " ");
362               strcat(cpp_cmdline, IncludeDir[i]);
363             }
364
365             strcat(cpp_cmdline, " ");
366             strcat(cpp_cmdline, infile);
367
368             fin = popen(cpp_cmdline, "r");
369             if (fin == NULL)
370               perror("popen");
371               
372         } else {
373             if (infile == NULL) {       
374                 fin = stdin;
375                 return;
376             }
377             fin = fopen(infile, "r");
378         }
379         if (fin == NULL) {
380             f_print(stderr, "%s: ", cmdname);
381             perror(infilename);
382             crash();
383         }
384 }
385
386 /*
387  * Compile into an XDR routine output file
388  */
389 static
390 c_output(infile, define, extend, outfile, append)
391         char *infile;
392         char *define;
393         int extend;
394         char *outfile;
395         int append;
396 {
397     definition *def;
398     char *include;
399     char *outfilename;
400     long tell;
401     char fullname[1024];
402     char *currfile = (OutFileFlag ? OutFile : infile);
403     int i,j;
404
405     open_input(infile, define); 
406     cflag = 1;
407     memset(fullname, 0, sizeof(fullname));
408     if (append) {
409         strcpy(fullname, prefix);
410         strcat(fullname, infile);
411     } else
412         strcpy(fullname, infile);
413     outfilename = extend ? extendfile(fullname, outfile) : outfile;
414     open_output(infile, outfilename);
415     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
416     if (xflag) {
417         if (kflag) {
418             f_print(fout, "#include \"../afs/param.h\"\n");
419         } else {
420             f_print(fout, "#include <afs/param.h>\n");
421         }
422         f_print(fout, "#ifdef AFS_NT40_ENV\n");
423         f_print(fout, "#define AFS_RXGEN_EXPORT __declspec(dllexport)\n");
424         f_print(fout, "#endif /* AFS_NT40_ENV */\n");
425     }
426     if (currfile && (include = extendfile(currfile,".h"))) {
427         if (kflag) {
428             f_print(fout, "#include \"../afsint/%s\"\n\n",include);
429         } else
430             f_print(fout, "#include \"%s\"\n\n", include);
431         free(include);
432     } else {
433         /* In case we can't include the interface's own header file... */
434         if (kflag) {
435             f_print(fout, "#include \"../h/types.h\"\n");
436             f_print(fout, "#include \"../h/socket.h\"\n");
437             f_print(fout, "#include \"../h/file.h\"\n");
438             f_print(fout, "#include \"../h/stat.h\"\n");
439             f_print(fout, "#include \"../netinet/in.h\"\n");
440             f_print(fout, "#include \"../h/time.h\"\n");
441             f_print(fout, "#ifndef AFS_LINUX22_ENV\n");
442             f_print(fout, "#include \"../rpc/types.h\"\n");
443             f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
444             f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
445             f_print(fout, "#include \"../rx/xdr.h\"\n");
446             f_print(fout, "#else /* AFS_LINUX22_ENV */\n");
447             f_print(fout, "#include \"../rpc/xdr.h\"\n");
448             f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
449             f_print(fout, "#include \"../afsint/rxgen_consts.h\"\n");
450         } else {
451             f_print(fout, "#include <rx/xdr.h>\n");
452         }
453     }
454
455     write_int32_macros(fout);
456
457     tell = ftell(fout);
458     while (def = get_definition()) {
459         extern int IsRxgenDefinition();
460
461         if (!yflag) {
462             if ((!IsRxgenDefinition(def)) && def->def_kind != DEF_CUSTOMIZED)
463                 emit(def);
464         }
465     }
466
467     /*
468      * Print out array containing list of all functions in the interface
469      * in order
470      */
471
472     if (xflag) {
473         for(j=0;j<=PackageIndex;j++) {
474             f_print(fout, "AFS_RXGEN_EXPORT\n");
475             f_print(fout, "const char *%sfunction_names[] = {\n",
476                     PackagePrefix[j]);
477
478             for(i=0;i<no_of_stat_funcs_header[j];i++) {
479                 if (i == 0) {
480                     f_print(fout, "\t\"%s\"",
481                             &function_list[j][i]);
482                 } else {
483                     f_print(fout, ",\n\t\"%s\"",
484                             &function_list[j][i]);
485                 }
486             }
487
488             f_print(fout, "\n};\n");
489         }
490     }
491
492     if (extend && tell == ftell(fout)) {
493             (void) unlink(outfilename);
494     }
495     cflag = 0;
496 }
497
498 /*
499  * Compile into an XDR header file
500  */
501 static
502 h_output(infile, define, extend, outfile, append)
503         char *infile;
504         char *define;
505         int extend;
506         char *outfile;
507         int append;
508 {
509         definition *def;
510         char *outfilename;
511         long tell;
512         extern char *uppercase();
513         char fullname[1024], *p;
514         extern int h_opcode_stats();
515
516
517         open_input(infile, define);
518         hflag = 1;
519         memset(fullname, 0, sizeof(fullname));
520         if (append) {
521             strcpy(fullname, prefix);
522             strcat(fullname, infile);
523         } else
524             strcpy(fullname, infile);
525         outfilename = extend ? extendfile(fullname, outfile) : outfile;
526         open_output(infile, outfilename);
527         strcpy(fullname, outfilename);
528         if (p = strchr(fullname, '.')) *p = '\0';
529         f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
530         f_print(fout, "#ifndef  _RXGEN_%s_\n", uppercase(fullname));
531         f_print(fout, "#define  _RXGEN_%s_\n\n", uppercase(fullname));
532         f_print(fout, "#ifdef   KERNEL\n");
533         f_print(fout, "/* The following 'ifndefs' are not a good solution to the vendor's omission of surrounding all system includes with 'ifndef's since it requires that this file is included after the system includes...*/\n");
534         f_print(fout, "#include <afsconfig.h>\n");
535         f_print(fout, "#include \"../afs/param.h\"\n");
536         f_print(fout, "#ifdef   UKERNEL\n");
537         f_print(fout, "#include \"../afs/sysincludes.h\"\n");
538         f_print(fout, "#include \"../rx/xdr.h\"\n");
539         f_print(fout, "#include \"../rx/rx.h\"\n");
540         if (xflag) {
541             f_print(fout, "#include \"../rx/rx_globals.h\"\n");
542         }
543         f_print(fout, "#else    /* UKERNEL */\n");
544         f_print(fout, "#include \"../h/types.h\"\n");
545         f_print(fout, "#ifndef  SOCK_DGRAM  /* XXXXX */\n");
546         f_print(fout, "#include \"../h/socket.h\"\n");
547         f_print(fout, "#endif\n");
548         f_print(fout, "#ifndef  DTYPE_SOCKET  /* XXXXX */\n");
549         f_print(fout, "#ifdef AFS_DEC_ENV\n");
550         f_print(fout, "#include \"../h/smp_lock.h\"\n");
551         f_print(fout, "#endif\n");
552         f_print(fout, "#ifndef AFS_LINUX22_ENV\n");
553         f_print(fout, "#include \"../h/file.h\"\n");
554         f_print(fout, "#endif\n");
555         f_print(fout, "#endif\n");
556         f_print(fout, "#ifndef  S_IFMT  /* XXXXX */\n");
557         f_print(fout, "#include \"../h/stat.h\"\n");
558         f_print(fout, "#endif\n");
559         f_print(fout, "#ifndef  IPPROTO_UDP /* XXXXX */\n");
560         f_print(fout, "#include \"../netinet/in.h\"\n");
561         f_print(fout, "#endif\n");
562         f_print(fout, "#ifndef  DST_USA  /* XXXXX */\n");
563         f_print(fout, "#include \"../h/time.h\"\n");
564         f_print(fout, "#endif\n");
565         f_print(fout, "#ifndef AFS_LINUX22_ENV\n");
566         f_print(fout, "#include \"../rpc/types.h\"\n");
567         f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
568         f_print(fout, "#ifndef  XDR_GETLONG /* XXXXX */\n");
569         f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
570         f_print(fout, "#ifndef quad_t\n");
571         f_print(fout, "#define quad_t __quad_t\n");
572         f_print(fout, "#define u_quad_t __u_quad_t\n");
573         f_print(fout, "#endif\n");
574         f_print(fout, "#endif\n");
575         f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
576         f_print(fout, "#include \"../rx/xdr.h\"\n");
577         f_print(fout, "#else /* AFS_LINUX22_ENV */\n");
578         f_print(fout, "extern bool_t xdr_int64();\n");
579         f_print(fout, "extern bool_t xdr_uint64();\n");
580         f_print(fout, "#include \"../rpc/xdr.h\"\n");
581         f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
582         f_print(fout, "#endif /* XDR_GETLONG */\n");
583         f_print(fout, "#endif   /* UKERNEL */\n");
584         f_print(fout, "#include \"../afsint/rxgen_consts.h\"\n");
585         f_print(fout, "#include \"../afs/afs_osi.h\"\n");
586         f_print(fout, "#include \"../rx/rx.h\"\n");
587         if (xflag) {
588             f_print(fout, "#include \"../rx/rx_globals.h\"\n");
589         }
590         f_print(fout, "#else    /* KERNEL */\n");
591         f_print(fout, "#include <afs/param.h>\n");
592         f_print(fout, "#include <afs/stds.h>\n");
593         f_print(fout, "#include <sys/types.h>\n");
594         f_print(fout, "#include <rx/xdr.h>\n");
595         f_print(fout, "#include <rx/rx.h>\n");
596         if (xflag) {
597             f_print(fout, "#include <rx/rx_globals.h>\n");
598         }
599         f_print(fout, "#include <afs/rxgen_consts.h>\n");
600         f_print(fout, "#endif   /* KERNEL */\n\n");
601         f_print(fout, "#ifdef AFS_NT40_ENV\n");
602         f_print(fout, "#ifndef AFS_RXGEN_EXPORT\n");
603         f_print(fout, "#define AFS_RXGEN_EXPORT __declspec(dllimport)\n");
604         f_print(fout, "#endif /* AFS_RXGEN_EXPORT */\n");
605         f_print(fout, "#else /* AFS_NT40_ENV */\n");
606         f_print(fout, "#define AFS_RXGEN_EXPORT\n");
607         f_print(fout, "#endif /* AFS_NT40_ENV */\n\n");
608         tell = ftell(fout);
609         while (def = get_definition()) {
610                 print_datadef(def);
611         }
612         h_opcode_stats();
613         hflag = 0;
614         f_print(fout, "#endif   /* _RXGEN_%s_ */\n", uppercase(fullname));
615         if (extend && tell == ftell(fout)) {
616                 (void) unlink(outfilename);
617         }
618 }
619
620 /*
621  * Compile into an RPC service
622  */
623 static
624 s_output(argc, argv, infile, define, extend, outfile, nomain)
625         int argc;
626         char *argv[];
627         char *infile;
628         char *define;
629         int extend;
630         char *outfile;
631         int nomain;
632 {
633         char *include;
634         definition *def;
635         int foundprogram;
636         char *outfilename;
637
638         open_input(infile, define);
639         outfilename = extend ? extendfile(infile, outfile) : outfile;
640         open_output(infile, outfilename);
641         f_print(fout, "#include <stdio.h>\n");
642         f_print(fout, "#include <rpc/rpc.h>\n");
643         if (infile && (include = extendfile(infile, ".h"))) {
644                 f_print(fout, "#include \"%s\"\n", include);
645                 free(include);
646         }
647         foundprogram = 0;
648         while (def = get_definition()) {
649                 foundprogram |= (def->def_kind == DEF_PROGRAM);
650         }
651         if (extend && !foundprogram) {
652                 (void) unlink(outfilename);
653                 return;
654         }
655         if (nomain) {
656                 write_programs((char *)NULL);
657         } else {
658                 write_most();
659                 do_registers(argc, argv);
660                 write_rest();
661                 write_programs("static");
662         }
663 }
664
665 static
666 l_output(infile, define, extend, outfile)
667         char *infile;
668         char *define;
669         int extend;
670         char *outfile;
671 {
672         char *include;
673         definition *def;
674         int foundprogram;
675         char *outfilename;
676
677         open_input(infile, define);
678         outfilename = extend ? extendfile(infile, outfile) : outfile;
679         open_output(infile, outfilename);
680         f_print(fout, "#include <rpc/rpc.h>\n");
681         f_print(fout, "#include <sys/time.h>\n");
682         if (infile && (include = extendfile(infile, ".h"))) {
683                 f_print(fout, "#include \"%s\"\n", include);
684                 free(include);
685         }
686         foundprogram = 0;
687         while (def = get_definition()) {
688                 foundprogram |= (def->def_kind == DEF_PROGRAM);
689         }
690         if (extend && !foundprogram) {
691                 (void) unlink(outfilename);
692                 return;
693         }
694         write_stubs();
695 }
696
697 /*
698  * Perform registrations for service output 
699  */
700 static
701 do_registers(argc, argv)
702         int argc;
703         char *argv[];
704
705 {
706         int i;
707
708         for (i = 1; i < argc; i++) {
709                 if (streq(argv[i], "-s")) {
710                         write_register(argv[i + 1]);
711                         i++;
712                 }
713         }
714 }
715
716
717 C_output(infile, define, extend, outfile, append)
718 char *infile;
719 char *define;
720 int extend;
721 char *outfile;
722 int append;
723 {
724     char *include;
725     char *outfilename;
726     char fullname[1024];
727     long tell;
728     char *currfile = (OutFileFlag ? OutFile : infile);
729    
730     Cflag = 1;
731     open_input(infile, define); 
732     memset(fullname, 0, sizeof(fullname));
733     if (append) {
734         strcpy(fullname, prefix);
735         strcat(fullname, infile);
736     } else
737         strcpy(fullname, infile);
738     outfilename = extend ? extendfile(fullname, outfile) : outfile;
739     open_output(infile, outfilename);
740     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
741     if (currfile && (include = extendfile(currfile,".h"))) {
742         if (kflag) {
743             f_print(fout, "#include \"../afsint/%s\"\n\n",include);
744         } else {
745             f_print(fout,"#include \"%s\"\n\n",include);
746         }
747         free(include);
748     } else {
749         if (kflag) {
750             f_print(fout, "#include \"../h/types.h\"\n");
751             f_print(fout, "#include \"../h/socket.h\"\n");
752             f_print(fout, "#include \"../h/file.h\"\n");
753             f_print(fout, "#include \"../h/stat.h\"\n");
754             f_print(fout, "#include \"../netinet/in.h\"\n");
755             f_print(fout, "#include \"../h/time.h\"\n");
756             f_print(fout, "#include \"../rpc/types.h\"\n");
757             f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
758             f_print(fout, "#include \"../rx/xdr.h\"\n");
759             f_print(fout, "#else /* AFS_LINUX22_ENV */\n");
760             f_print(fout, "#include \"../rpc/xdr.h\"\n");
761             f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
762             f_print(fout, "#include \"../afsint/rxgen_consts.h\"\n");
763             f_print(fout, "#include \"../afs/afs_osi.h\"\n");
764             f_print(fout, "#include \"../rx/rx.h\"\n");
765             if (xflag) {
766                 f_print(fout, "#include \"../rx/rx_globals.h\"\n");
767             }
768         } else {
769             f_print(fout, "#include <sys/types.h>\n");
770             f_print(fout, "#include <rx/xdr.h>\n");
771             f_print(fout, "#include <rx/rx.h>\n");
772             if (xflag) {
773                 f_print(fout, "#include <rx/rx_globals.h>\n");
774             }
775             f_print(fout, "#include <afs/rxgen_consts.h>\n");
776         }
777     }
778
779     write_int32_macros(fout);
780
781     tell = ftell(fout);
782     while (get_definition()) continue;
783     if (extend && tell == ftell(fout)) {
784         (void) unlink(outfilename);
785     }
786
787     Cflag = 0;
788 }
789
790 S_output(infile, define, extend, outfile, append)
791 char *infile;
792 char *define;
793 int extend;
794 char *outfile;
795 int append;
796 {
797     char *include;
798     char *outfilename;
799     char fullname[1024];
800     definition *def;
801     long tell;
802     extern int er_Proc_CodeGeneration();
803     char *currfile = (OutFileFlag ? OutFile : infile);
804    
805     Sflag = 1;
806     open_input(infile, define); 
807     memset(fullname, 0, sizeof(fullname));
808     if (append) {
809         strcpy(fullname, prefix);
810         strcat(fullname, infile);
811     } else
812         strcpy(fullname, infile);
813     outfilename = extend ? extendfile(fullname, outfile) : outfile;
814     open_output(infile, outfilename);
815     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
816     if (currfile && (include = extendfile(currfile,".h"))) {
817         if (kflag) {
818             f_print(fout, "#include \"../afsint/%s\"\n",include);
819         } else {
820             f_print(fout,"#include \"%s\"\n\n",include);
821         }
822         free(include);
823     } else {
824         if (kflag) {
825             f_print(fout, "#include \"../h/types.h\"\n");
826             f_print(fout, "#include \"../h/socket.h\"\n");
827             f_print(fout, "#include \"../h/file.h\"\n");
828             f_print(fout, "#include \"../h/stat.h\"\n");
829             f_print(fout, "#include \"../netinet/in.h\"\n");
830             f_print(fout, "#include \"../h/time.h\"\n");
831             f_print(fout, "#include \"../rpc/types.h\"\n");
832             f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
833             f_print(fout, "#include \"../rx/xdr.h\"\n");
834             f_print(fout, "#else /* AFS_LINUX22_ENV */\n");
835             f_print(fout, "#include \"../rpc/xdr.h\"\n");
836             f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
837             f_print(fout, "#include \"../afsint/rxgen_consts.h\"\n");
838             f_print(fout, "#include \"../afs/afs_osi.h\"\n");
839             f_print(fout, "#include \"../rx/rx.h\"\n");
840             if (xflag) {
841                 f_print(fout, "#include \"../rx/rx_globals.h\"\n");
842             }
843         } else {
844             f_print(fout, "#include <sys/types.h>\n");
845             f_print(fout, "#include <rx/xdr.h>\n");
846             f_print(fout, "#include <rx/rx.h>\n");
847             if (xflag) {
848                 f_print(fout, "#include <rx/rx_globals.h>\n");
849             }
850             f_print(fout, "#include <afs/rxgen_consts.h>\n");
851         }
852     }
853
854     write_int32_macros(fout);
855
856     tell = ftell(fout);
857     fflush(fout);
858     while (def = get_definition()) {
859         fflush(fout);
860         print_datadef(def);
861     }
862
863     er_Proc_CodeGeneration();
864
865     if (extend && tell == ftell(fout)) {
866         (void) unlink(outfilename);
867     }
868     Sflag = 0;
869 }
870
871 char *uppercase(str)
872 char *str;
873 {
874     static char max_size[100];
875     char *pnt;
876     int len = strlen(str);
877
878     for (pnt = max_size; len > 0; len--, str++) {
879         *pnt++ = (islower(*str) ? toupper(*str) : *str);
880     }
881     *pnt = '\0';
882     return max_size;
883 }
884
885 /*
886  * Parse command line arguments 
887  */
888 static
889 parseargs(argc, argv, cmd)
890         int argc;
891         char *argv[];
892         struct commandline *cmd;
893
894 {
895         int i;
896         int j;
897         char c;
898         char flag[(1 << 8 * sizeof(char))];
899         int nflags;
900
901         cmdname = argv[0];
902         cmd->infile = cmd->outfile = NULL;
903         if (argc < 2) {
904                 return (0);
905         }
906         memset(flag, 0, sizeof(flag));
907         cmd->outfile = NULL;
908         for (i = 1; i < argc; i++) {
909                 if (argv[i][0] != '-') {
910                         if (cmd->infile) {
911                                 return (0);
912                         }
913                         cmd->infile = argv[i];
914                 } else {
915                         for (j = 1; argv[i][j] != 0; j++) {
916                                 c = argv[i][j];
917                                 switch (c) {
918                                 case 'c':
919                                 case 'h':
920                                 case 'l':
921                                 case 'm':
922                                 case 'C':
923                                 case 'S':
924                                 case 'r':
925                                 case 'R':
926                                 case 'k':
927                                 case 'p':
928                                 case 'd':
929                                 case 'x':
930                                 case 'y':
931                                 case 'z':
932                                         if (flag[c]) {
933                                                 return (0);
934                                         }
935                                         flag[c] = 1;
936                                         break;
937                                 case 'o':
938                                 case 's':
939                                         if (argv[i][j - 1] != '-' || 
940                                             argv[i][j + 1] != 0) {
941                                                 return (0);
942                                         }
943                                         flag[c] = 1;
944                                         if (++i == argc) {
945                                                 return (0);
946                                         }
947                                         if (c == 's') {
948                                                 if (!streq(argv[i], "udp") &&
949                                                     !streq(argv[i], "tcp")) {
950                                                         return (0);
951                                                 }
952                                         } else if (c == 'o') {
953                                                 if (cmd->outfile) {
954                                                         return (0);
955                                                 }
956                                                 cmd->outfile = argv[i];
957                                         }
958                                         goto nextarg;
959                                 case 'P':
960                                         if (argv[i][j-1] != '-')
961                                             return(0);
962                                         prefix = &argv[i][j+1];
963                                         goto nextarg;
964                                 case 'I':
965                                         if (argv[i][j-1] != '-')
966                                             return(0);
967                                         IncludeDir[nincludes++]= &argv[i][j-1];
968                                         goto nextarg;
969                                 default:
970                                         return (0);
971                                 }
972                         }
973         nextarg:
974                         ;
975                 }
976         }
977         cmd->cflag = cflag = flag['c'];
978         cmd->hflag = hflag = flag['h'];
979         cmd->sflag = flag['s'];
980         cmd->lflag = flag['l'];
981         cmd->mflag = flag['m'];
982         cmd->xflag = xflag = flag['x'];
983         cmd->yflag = yflag = flag['y'];
984         cmd->Cflag = Cflag = flag['C'];
985         cmd->Sflag = Sflag = flag['S'];
986         cmd->rflag = flag['r'];
987         cmd->kflag = kflag = flag['k'];
988         cmd->pflag = flag['p'];
989         cmd->dflag = debug = flag['d'];
990         zflag = flag['z'];
991         if (cmd->pflag) combinepackages = 1;
992         nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag + cmd->Cflag + cmd->Sflag + cmd->rflag;
993         if (nflags == 0) {
994                 if (cmd->outfile != NULL || cmd->infile == NULL) {
995                         return (0);
996                 }
997         } else if (nflags > 1) {
998                 return (0);
999         }
1000         return (1);
1001 }