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