initial-freebsd-port-work-20010414
[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, "#ifdef AFS_64BIT_ENV\n");
250         f_print(fout, "#define xdr_afs_int32 xdr_int\n");
251         f_print(fout, "#else\n");
252         f_print(fout, "#define xdr_afs_int32 xdr_long\n");
253         f_print(fout, "#endif\n");
254         f_print(fout, "#endif\n");
255         f_print(fout, "#ifndef xdr_afs_uint32\n");
256         f_print(fout, "#define xdr_afs_uint32 xdr_u_int\n");
257         f_print(fout, "#endif\n");
258         f_print(fout, "#ifndef xdr_afs_int64\n");
259         f_print(fout, "#define xdr_afs_int64 xdr_int64\n");
260         f_print(fout, "#endif\n");
261         f_print(fout, "#ifndef xdr_afs_uint64\n");
262         f_print(fout, "#define xdr_afs_uint64 xdr_uint64\n");
263         f_print(fout, "#endif\n");
264 #else
265 #error Need to do some work here...
266 #endif
267 }
268
269 /*
270  * add extension to filename 
271  */
272 static char *
273 extendfile(file, ext)
274         char *file;
275         char *ext;
276 {
277         char *res;
278         char *p;
279         char *sname;
280
281         res = alloc(strlen(file) + strlen(ext) + 1);
282         if (res == NULL) {
283                 abort();
284         }
285         p = (char *) rindex(file, '.');
286         if (p == NULL) {
287                 p = file + strlen(file);
288         }
289         sname = (char *) rindex(file,'/');
290         if (sname == NULL)
291             sname = file;
292         else
293             sname++;
294         strcpy(res,sname);
295         strcpy(res + (p - sname),ext);
296         return (res);
297 }
298
299 /*
300  * Open output file with given extension 
301  */
302 static
303 open_output(infile, outfile)
304         char *infile;
305         char *outfile;
306 {
307         if (outfile == NULL) {
308                 fout = stdout;
309                 return;
310         }
311         if (infile != NULL && streq(outfile, infile)) {
312                 f_print(stderr, "%s: output would overwrite %s\n", cmdname,
313                         infile);
314                 crash();
315         }
316         fout = fopen(outfile, "w");
317         if (fout == NULL) {
318                 f_print(stderr, "%s: unable to open ", cmdname);
319                 perror(outfile);
320                 crash();
321         }
322         record_open(outfile);
323 }
324
325 /*
326  * Open input file with given define for C-preprocessor 
327  */
328 static
329 open_input(infile, define)
330         char *infile;
331         char *define;
332 {
333         char *exec_args[MAXCPPARGS+10];
334         int nargs = 0;
335         char **args;
336         char cpp_cmdline[MAXCMDLINE];
337
338         int i;
339         if (debug == 0) {
340             infilename = (infile == NULL) ? "<stdin>" : infile;
341             strcpy(cpp_cmdline, CPP);
342             strcat(cpp_cmdline, " ");
343             strcat(cpp_cmdline, CPPFLAGS);
344             strcat(cpp_cmdline, " ");
345             strcat(cpp_cmdline, define);
346
347 #ifdef  AFS_ALPHA_ENV
348             for (i = 0;
349                  i < (sizeof(XTRA_CPPFLAGS)/
350                       sizeof(XTRA_CPPFLAGS[0])) - 1;
351                  i++) {
352               strcat(cpp_cmdline, " ");
353               strcat(cpp_cmdline, XTRA_CPPFLAGS[i]);
354             }
355 #endif
356             for (i = 0; i < nincludes; i++) {
357               strcat(cpp_cmdline, " ");
358               strcat(cpp_cmdline, IncludeDir[i]);
359             }
360
361             strcat(cpp_cmdline, " ");
362             strcat(cpp_cmdline, infile);
363
364             fin = popen(cpp_cmdline, "r");
365             if (fin == NULL)
366               perror("popen");
367               
368         } else {
369             if (infile == NULL) {       
370                 fin = stdin;
371                 return;
372             }
373             fin = fopen(infile, "r");
374         }
375         if (fin == NULL) {
376             f_print(stderr, "%s: ", cmdname);
377             perror(infilename);
378             crash();
379         }
380 }
381
382 /*
383  * Compile into an XDR routine output file
384  */
385 static
386 c_output(infile, define, extend, outfile, append)
387         char *infile;
388         char *define;
389         int extend;
390         char *outfile;
391         int append;
392 {
393     definition *def;
394     char *include;
395     char *outfilename;
396     long tell;
397     char fullname[1024];
398     char *currfile = (OutFileFlag ? OutFile : infile);
399     int i,j;
400
401     open_input(infile, define); 
402     cflag = 1;
403     bzero(fullname, sizeof(fullname));
404     if (append) {
405         strcpy(fullname, prefix);
406         strcat(fullname, infile);
407     } else
408         strcpy(fullname, infile);
409     outfilename = extend ? extendfile(fullname, outfile) : outfile;
410     open_output(infile, outfilename);
411     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
412     if (xflag) {
413         if (kflag) {
414             f_print(fout, "#include \"../afs/param.h\"\n");
415         } else {
416             f_print(fout, "#include <afs/param.h>\n");
417         }
418         f_print(fout, "#ifdef AFS_NT40_ENV\n");
419         f_print(fout, "#define AFS_RXGEN_EXPORT __declspec(dllexport)\n");
420         f_print(fout, "#endif /* AFS_NT40_ENV */\n");
421     }
422     if (currfile && (include = extendfile(currfile,".h"))) {
423         if (kflag) {
424             f_print(fout, "#include \"../afsint/%s\"\n\n",include);
425         } else
426             f_print(fout, "#include \"%s\"\n\n", include);
427         free(include);
428     } else {
429         /* In case we can't include the interface's own header file... */
430         if (kflag) {
431             f_print(fout, "#include \"../h/types.h\"\n");
432             f_print(fout, "#include \"../h/socket.h\"\n");
433             f_print(fout, "#include \"../h/file.h\"\n");
434             f_print(fout, "#include \"../h/stat.h\"\n");
435             f_print(fout, "#include \"../netinet/in.h\"\n");
436             f_print(fout, "#include \"../h/time.h\"\n");
437             f_print(fout, "#ifndef AFS_LINUX22_ENV\n");
438             f_print(fout, "#include \"../rpc/types.h\"\n");
439             f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
440             f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
441             f_print(fout, "#include \"../rx/xdr.h\"\n");
442             f_print(fout, "#else /* AFS_LINUX22_ENV */\n");
443             f_print(fout, "#include \"../rpc/xdr.h\"\n");
444             f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
445             f_print(fout, "#include \"../afsint/rxgen_consts.h\"\n");
446         } else {
447             f_print(fout, "#include <rx/xdr.h>\n");
448         }
449     }
450
451     write_int32_macros(fout);
452
453     tell = ftell(fout);
454     while (def = get_definition()) {
455         extern int IsRxgenDefinition();
456
457         if (!yflag) {
458             if ((!IsRxgenDefinition(def)) && def->def_kind != DEF_CUSTOMIZED)
459                 emit(def);
460         }
461     }
462
463     /*
464      * Print out array containing list of all functions in the interface
465      * in order
466      */
467
468     if (xflag) {
469         for(j=0;j<=PackageIndex;j++) {
470             f_print(fout, "AFS_RXGEN_EXPORT\n");
471             f_print(fout, "const char *%sfunction_names[] = {\n",
472                     PackagePrefix[j]);
473
474             for(i=0;i<no_of_stat_funcs_header[j];i++) {
475                 if (i == 0) {
476                     f_print(fout, "\t\"%s\"",
477                             &function_list[j][i]);
478                 } else {
479                     f_print(fout, ",\n\t\"%s\"",
480                             &function_list[j][i]);
481                 }
482             }
483
484             f_print(fout, "\n};\n");
485         }
486     }
487
488     if (extend && tell == ftell(fout)) {
489             (void) unlink(outfilename);
490     }
491     cflag = 0;
492 }
493
494 /*
495  * Compile into an XDR header file
496  */
497 static
498 h_output(infile, define, extend, outfile, append)
499         char *infile;
500         char *define;
501         int extend;
502         char *outfile;
503         int append;
504 {
505         definition *def;
506         char *outfilename;
507         long tell;
508         extern char *uppercase();
509         char fullname[1024], *p;
510         extern int h_opcode_stats();
511
512
513         open_input(infile, define);
514         hflag = 1;
515         bzero(fullname, sizeof(fullname));
516         if (append) {
517             strcpy(fullname, prefix);
518             strcat(fullname, infile);
519         } else
520             strcpy(fullname, infile);
521         outfilename = extend ? extendfile(fullname, outfile) : outfile;
522         open_output(infile, outfilename);
523         strcpy(fullname, outfilename);
524         if (p = (char *)index(fullname, '.')) *p = '\0';
525         f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
526         f_print(fout, "#ifndef  _RXGEN_%s_\n", uppercase(fullname));
527         f_print(fout, "#define  _RXGEN_%s_\n\n", uppercase(fullname));
528         f_print(fout, "#ifdef   KERNEL\n");
529         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");
530         f_print(fout, "#include \"../afs/param.h\"\n");
531         f_print(fout, "#ifdef   UKERNEL\n");
532         f_print(fout, "#include \"../afs/sysincludes.h\"\n");
533         f_print(fout, "#include \"../rx/xdr.h\"\n");
534         f_print(fout, "#include \"../rx/rx.h\"\n");
535         if (xflag) {
536             f_print(fout, "#include \"../rx/rx_globals.h\"\n");
537         }
538         f_print(fout, "#else    /* UKERNEL */\n");
539         f_print(fout, "#include \"../h/types.h\"\n");
540         f_print(fout, "#ifndef  SOCK_DGRAM  /* XXXXX */\n");
541         f_print(fout, "#include \"../h/socket.h\"\n");
542         f_print(fout, "#endif\n");
543         f_print(fout, "#ifndef  DTYPE_SOCKET  /* XXXXX */\n");
544         f_print(fout, "#ifdef AFS_DEC_ENV\n");
545         f_print(fout, "#include \"../h/smp_lock.h\"\n");
546         f_print(fout, "#endif\n");
547         f_print(fout, "#ifndef AFS_LINUX22_ENV\n");
548         f_print(fout, "#include \"../h/file.h\"\n");
549         f_print(fout, "#endif\n");
550         f_print(fout, "#endif\n");
551         f_print(fout, "#ifndef  S_IFMT  /* XXXXX */\n");
552         f_print(fout, "#include \"../h/stat.h\"\n");
553         f_print(fout, "#endif\n");
554         f_print(fout, "#ifndef  IPPROTO_UDP /* XXXXX */\n");
555         f_print(fout, "#include \"../netinet/in.h\"\n");
556         f_print(fout, "#endif\n");
557         f_print(fout, "#ifndef  DST_USA  /* XXXXX */\n");
558         f_print(fout, "#include \"../h/time.h\"\n");
559         f_print(fout, "#endif\n");
560         f_print(fout, "#ifndef AFS_LINUX22_ENV\n");
561         f_print(fout, "#include \"../rpc/types.h\"\n");
562         f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
563         f_print(fout, "#ifndef  XDR_GETLONG /* XXXXX */\n");
564         f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
565         f_print(fout, "#ifndef quad_t\n");
566         f_print(fout, "#define quad_t __quad_t\n");
567         f_print(fout, "#define u_quad_t __u_quad_t\n");
568         f_print(fout, "#endif\n");
569         f_print(fout, "#endif\n");
570         f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
571         f_print(fout, "#include \"../rx/xdr.h\"\n");
572         f_print(fout, "#else /* AFS_LINUX22_ENV */\n");
573         f_print(fout, "extern bool_t xdr_int64();\n");
574         f_print(fout, "extern bool_t xdr_uint64();\n");
575         f_print(fout, "#include \"../rpc/xdr.h\"\n");
576         f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
577         f_print(fout, "#endif /* XDR_GETLONG */\n");
578         f_print(fout, "#endif   /* UKERNEL */\n");
579         f_print(fout, "#include \"../afsint/rxgen_consts.h\"\n");
580         f_print(fout, "#include \"../afs/afs_osi.h\"\n");
581         f_print(fout, "#include \"../rx/rx.h\"\n");
582         if (xflag) {
583             f_print(fout, "#include \"../rx/rx_globals.h\"\n");
584         }
585         f_print(fout, "#else    /* KERNEL */\n");
586         f_print(fout, "#include <afs/param.h>\n");
587         f_print(fout, "#include <afs/stds.h>\n");
588         f_print(fout, "#include <sys/types.h>\n");
589         f_print(fout, "#include <rx/xdr.h>\n");
590         f_print(fout, "#include <rx/rx.h>\n");
591         if (xflag) {
592             f_print(fout, "#include <rx/rx_globals.h>\n");
593         }
594         f_print(fout, "#include <afs/rxgen_consts.h>\n");
595         f_print(fout, "#endif   /* KERNEL */\n\n");
596         f_print(fout, "#ifdef AFS_NT40_ENV\n");
597         f_print(fout, "#ifndef AFS_RXGEN_EXPORT\n");
598         f_print(fout, "#define AFS_RXGEN_EXPORT __declspec(dllimport)\n");
599         f_print(fout, "#endif /* AFS_RXGEN_EXPORT */\n");
600         f_print(fout, "#else /* AFS_NT40_ENV */\n");
601         f_print(fout, "#define AFS_RXGEN_EXPORT\n");
602         f_print(fout, "#endif /* AFS_NT40_ENV */\n\n");
603         tell = ftell(fout);
604         while (def = get_definition()) {
605                 print_datadef(def);
606         }
607         h_opcode_stats();
608         hflag = 0;
609         f_print(fout, "#endif   /* _RXGEN_%s_ */\n", uppercase(fullname));
610         if (extend && tell == ftell(fout)) {
611                 (void) unlink(outfilename);
612         }
613 }
614
615 /*
616  * Compile into an RPC service
617  */
618 static
619 s_output(argc, argv, infile, define, extend, outfile, nomain)
620         int argc;
621         char *argv[];
622         char *infile;
623         char *define;
624         int extend;
625         char *outfile;
626         int nomain;
627 {
628         char *include;
629         definition *def;
630         int foundprogram;
631         char *outfilename;
632
633         open_input(infile, define);
634         outfilename = extend ? extendfile(infile, outfile) : outfile;
635         open_output(infile, outfilename);
636         f_print(fout, "#include <stdio.h>\n");
637         f_print(fout, "#include <rpc/rpc.h>\n");
638         if (infile && (include = extendfile(infile, ".h"))) {
639                 f_print(fout, "#include \"%s\"\n", include);
640                 free(include);
641         }
642         foundprogram = 0;
643         while (def = get_definition()) {
644                 foundprogram |= (def->def_kind == DEF_PROGRAM);
645         }
646         if (extend && !foundprogram) {
647                 (void) unlink(outfilename);
648                 return;
649         }
650         if (nomain) {
651                 write_programs((char *)NULL);
652         } else {
653                 write_most();
654                 do_registers(argc, argv);
655                 write_rest();
656                 write_programs("static");
657         }
658 }
659
660 static
661 l_output(infile, define, extend, outfile)
662         char *infile;
663         char *define;
664         int extend;
665         char *outfile;
666 {
667         char *include;
668         definition *def;
669         int foundprogram;
670         char *outfilename;
671
672         open_input(infile, define);
673         outfilename = extend ? extendfile(infile, outfile) : outfile;
674         open_output(infile, outfilename);
675         f_print(fout, "#include <rpc/rpc.h>\n");
676         f_print(fout, "#include <sys/time.h>\n");
677         if (infile && (include = extendfile(infile, ".h"))) {
678                 f_print(fout, "#include \"%s\"\n", include);
679                 free(include);
680         }
681         foundprogram = 0;
682         while (def = get_definition()) {
683                 foundprogram |= (def->def_kind == DEF_PROGRAM);
684         }
685         if (extend && !foundprogram) {
686                 (void) unlink(outfilename);
687                 return;
688         }
689         write_stubs();
690 }
691
692 /*
693  * Perform registrations for service output 
694  */
695 static
696 do_registers(argc, argv)
697         int argc;
698         char *argv[];
699
700 {
701         int i;
702
703         for (i = 1; i < argc; i++) {
704                 if (streq(argv[i], "-s")) {
705                         write_register(argv[i + 1]);
706                         i++;
707                 }
708         }
709 }
710
711
712 C_output(infile, define, extend, outfile, append)
713 char *infile;
714 char *define;
715 int extend;
716 char *outfile;
717 int append;
718 {
719     char *include;
720     char *outfilename;
721     char fullname[1024];
722     long tell;
723     char *currfile = (OutFileFlag ? OutFile : infile);
724    
725     Cflag = 1;
726     open_input(infile, define); 
727     bzero(fullname, sizeof(fullname));
728     if (append) {
729         strcpy(fullname, prefix);
730         strcat(fullname, infile);
731     } else
732         strcpy(fullname, infile);
733     outfilename = extend ? extendfile(fullname, outfile) : outfile;
734     open_output(infile, outfilename);
735     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
736     if (currfile && (include = extendfile(currfile,".h"))) {
737         if (kflag) {
738             f_print(fout, "#include \"../afsint/%s\"\n\n",include);
739         } else {
740             f_print(fout,"#include \"%s\"\n\n",include);
741         }
742         free(include);
743     } else {
744         if (kflag) {
745             f_print(fout, "#include \"../h/types.h\"\n");
746             f_print(fout, "#include \"../h/socket.h\"\n");
747             f_print(fout, "#include \"../h/file.h\"\n");
748             f_print(fout, "#include \"../h/stat.h\"\n");
749             f_print(fout, "#include \"../netinet/in.h\"\n");
750             f_print(fout, "#include \"../h/time.h\"\n");
751             f_print(fout, "#include \"../rpc/types.h\"\n");
752             f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
753             f_print(fout, "#include \"../rx/xdr.h\"\n");
754             f_print(fout, "#else /* AFS_LINUX22_ENV */\n");
755             f_print(fout, "#include \"../rpc/xdr.h\"\n");
756             f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
757             f_print(fout, "#include \"../afsint/rxgen_consts.h\"\n");
758             f_print(fout, "#include \"../afs/afs_osi.h\"\n");
759             f_print(fout, "#include \"../rx/rx.h\"\n");
760             if (xflag) {
761                 f_print(fout, "#include \"../rx/rx_globals.h\"\n");
762             }
763         } else {
764             f_print(fout, "#include <sys/types.h>\n");
765             f_print(fout, "#include <rx/xdr.h>\n");
766             f_print(fout, "#include <rx/rx.h>\n");
767             if (xflag) {
768                 f_print(fout, "#include <rx/rx_globals.h>\n");
769             }
770             f_print(fout, "#include <afs/rxgen_consts.h>\n");
771         }
772     }
773
774     write_int32_macros(fout);
775
776     tell = ftell(fout);
777     while (get_definition()) continue;
778     if (extend && tell == ftell(fout)) {
779         (void) unlink(outfilename);
780     }
781
782     Cflag = 0;
783 }
784
785 S_output(infile, define, extend, outfile, append)
786 char *infile;
787 char *define;
788 int extend;
789 char *outfile;
790 int append;
791 {
792     char *include;
793     char *outfilename;
794     char fullname[1024];
795     definition *def;
796     long tell;
797     extern int er_Proc_CodeGeneration();
798     char *currfile = (OutFileFlag ? OutFile : infile);
799    
800     Sflag = 1;
801     open_input(infile, define); 
802     bzero(fullname, sizeof(fullname));
803     if (append) {
804         strcpy(fullname, prefix);
805         strcat(fullname, infile);
806     } else
807         strcpy(fullname, infile);
808     outfilename = extend ? extendfile(fullname, outfile) : outfile;
809     open_output(infile, outfilename);
810     f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n");
811     if (currfile && (include = extendfile(currfile,".h"))) {
812         if (kflag) {
813             f_print(fout, "#include \"../afsint/%s\"\n",include);
814         } else {
815             f_print(fout,"#include \"%s\"\n\n",include);
816         }
817         free(include);
818     } else {
819         if (kflag) {
820             f_print(fout, "#include \"../h/types.h\"\n");
821             f_print(fout, "#include \"../h/socket.h\"\n");
822             f_print(fout, "#include \"../h/file.h\"\n");
823             f_print(fout, "#include \"../h/stat.h\"\n");
824             f_print(fout, "#include \"../netinet/in.h\"\n");
825             f_print(fout, "#include \"../h/time.h\"\n");
826             f_print(fout, "#include \"../rpc/types.h\"\n");
827             f_print(fout, "#ifdef AFS_LINUX22_ENV\n");
828             f_print(fout, "#include \"../rx/xdr.h\"\n");
829             f_print(fout, "#else /* AFS_LINUX22_ENV */\n");
830             f_print(fout, "#include \"../rpc/xdr.h\"\n");
831             f_print(fout, "#endif /* AFS_LINUX22_ENV */\n");
832             f_print(fout, "#include \"../afsint/rxgen_consts.h\"\n");
833             f_print(fout, "#include \"../afs/afs_osi.h\"\n");
834             f_print(fout, "#include \"../rx/rx.h\"\n");
835             if (xflag) {
836                 f_print(fout, "#include \"../rx/rx_globals.h\"\n");
837             }
838         } else {
839             f_print(fout, "#include <sys/types.h>\n");
840             f_print(fout, "#include <rx/xdr.h>\n");
841             f_print(fout, "#include <rx/rx.h>\n");
842             if (xflag) {
843                 f_print(fout, "#include <rx/rx_globals.h>\n");
844             }
845             f_print(fout, "#include <afs/rxgen_consts.h>\n");
846         }
847     }
848
849     write_int32_macros(fout);
850
851     tell = ftell(fout);
852     fflush(fout);
853     while (def = get_definition()) {
854         fflush(fout);
855         print_datadef(def);
856     }
857
858     er_Proc_CodeGeneration();
859
860     if (extend && tell == ftell(fout)) {
861         (void) unlink(outfilename);
862     }
863     Sflag = 0;
864 }
865
866 char *uppercase(str)
867 char *str;
868 {
869     static char max_size[100];
870     char *pnt;
871     int len = strlen(str);
872
873     for (pnt = max_size; len > 0; len--, str++) {
874         *pnt++ = (islower(*str) ? toupper(*str) : *str);
875     }
876     *pnt = '\0';
877     return max_size;
878 }
879
880 /*
881  * Parse command line arguments 
882  */
883 static
884 parseargs(argc, argv, cmd)
885         int argc;
886         char *argv[];
887         struct commandline *cmd;
888
889 {
890         int i;
891         int j;
892         char c;
893         char flag[(1 << 8 * sizeof(char))];
894         int nflags;
895
896         cmdname = argv[0];
897         cmd->infile = cmd->outfile = NULL;
898         if (argc < 2) {
899                 return (0);
900         }
901         bzero(flag, sizeof(flag));
902         cmd->outfile = NULL;
903         for (i = 1; i < argc; i++) {
904                 if (argv[i][0] != '-') {
905                         if (cmd->infile) {
906                                 return (0);
907                         }
908                         cmd->infile = argv[i];
909                 } else {
910                         for (j = 1; argv[i][j] != 0; j++) {
911                                 c = argv[i][j];
912                                 switch (c) {
913                                 case 'c':
914                                 case 'h':
915                                 case 'l':
916                                 case 'm':
917                                 case 'C':
918                                 case 'S':
919                                 case 'r':
920                                 case 'R':
921                                 case 'k':
922                                 case 'p':
923                                 case 'd':
924                                 case 'x':
925                                 case 'y':
926                                 case 'z':
927                                         if (flag[c]) {
928                                                 return (0);
929                                         }
930                                         flag[c] = 1;
931                                         break;
932                                 case 'o':
933                                 case 's':
934                                         if (argv[i][j - 1] != '-' || 
935                                             argv[i][j + 1] != 0) {
936                                                 return (0);
937                                         }
938                                         flag[c] = 1;
939                                         if (++i == argc) {
940                                                 return (0);
941                                         }
942                                         if (c == 's') {
943                                                 if (!streq(argv[i], "udp") &&
944                                                     !streq(argv[i], "tcp")) {
945                                                         return (0);
946                                                 }
947                                         } else if (c == 'o') {
948                                                 if (cmd->outfile) {
949                                                         return (0);
950                                                 }
951                                                 cmd->outfile = argv[i];
952                                         }
953                                         goto nextarg;
954                                 case 'P':
955                                         if (argv[i][j-1] != '-')
956                                             return(0);
957                                         prefix = &argv[i][j+1];
958                                         goto nextarg;
959                                 case 'I':
960                                         if (argv[i][j-1] != '-')
961                                             return(0);
962                                         IncludeDir[nincludes++]= &argv[i][j-1];
963                                         goto nextarg;
964                                 default:
965                                         return (0);
966                                 }
967                         }
968         nextarg:
969                         ;
970                 }
971         }
972         cmd->cflag = cflag = flag['c'];
973         cmd->hflag = hflag = flag['h'];
974         cmd->sflag = flag['s'];
975         cmd->lflag = flag['l'];
976         cmd->mflag = flag['m'];
977         cmd->xflag = xflag = flag['x'];
978         cmd->yflag = yflag = flag['y'];
979         cmd->Cflag = Cflag = flag['C'];
980         cmd->Sflag = Sflag = flag['S'];
981         cmd->rflag = flag['r'];
982         cmd->kflag = kflag = flag['k'];
983         cmd->pflag = flag['p'];
984         cmd->dflag = debug = flag['d'];
985         zflag = flag['z'];
986         if (cmd->pflag) combinepackages = 1;
987         nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag + cmd->Cflag + cmd->Sflag + cmd->rflag;
988         if (nflags == 0) {
989                 if (cmd->outfile != NULL || cmd->infile == NULL) {
990                         return (0);
991                 }
992         } else if (nflags > 1) {
993                 return (0);
994         }
995         return (1);
996 }