Thu Mar 28 14:22:51 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
[kopensolaris-gnu/glibc.git] / sunrpc / rpc_main.c
1 /* @(#)rpc_main.c       2.2 88/08/01 4.0 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 #ifndef lint
31 static char sccsid[] = "@(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI";
32 #endif
33
34 /*
35  * rpc_main.c, Top level of the RPC protocol compiler.
36  * Copyright (C) 1987, Sun Microsystems, Inc.
37  */
38
39 #include <stdio.h>
40 #include <strings.h>
41 #include <sys/file.h>
42 #include "rpc_util.h"
43 #include "rpc_parse.h"
44 #include "rpc_scan.h"
45
46 #define EXTEND  1               /* alias for TRUE */
47
48 struct commandline {
49         int cflag;
50         int hflag;
51         int lflag;
52         int sflag;
53         int mflag;
54         char *infile;
55         char *outfile;
56 };
57
58 static char *cmdname;
59 static char CPP[] = "/lib/cpp";
60 static char CPPFLAGS[] = "-C";
61 static char *allv[] = {
62         "rpcgen", "-s", "udp", "-s", "tcp",
63 };
64 static int allc = sizeof(allv)/sizeof(allv[0]);
65
66 main(argc, argv)
67         int argc;
68         char *argv[];
69
70 {
71         struct commandline cmd;
72
73         /* Use the libc message catalog for translations.  */
74         textdomain (_libc_intl_domainname);
75
76         if (!parseargs(argc, argv, &cmd)) {
77                 f_print(stderr,
78                         _("usage: %s infile\n"), cmdname);
79                 f_print(stderr,
80                         _("       %s [-c | -h | -l | -m] [-o outfile] [infile]\n"),
81                         cmdname);
82                 f_print(stderr,
83                         _("       %s [-s udp|tcp]* [-o outfile] [infile]\n"),
84                         cmdname);
85                 exit(1);
86         }
87         if (cmd.cflag) {
88                 c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile);
89         } else if (cmd.hflag) {
90                 h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile);
91         } else if (cmd.lflag) {
92                 l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile);
93         } else if (cmd.sflag || cmd.mflag) {
94                 s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND,
95                          cmd.outfile, cmd.mflag);
96         } else {
97                 c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
98                 reinitialize();
99                 h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
100                 reinitialize();
101                 l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
102                 reinitialize();
103                 s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
104                          "_svc.c", cmd.mflag);
105         }
106         exit(0);
107 }
108
109 /*
110  * add extension to filename
111  */
112 static char *
113 extendfile(file, ext)
114         char *file;
115         char *ext;
116 {
117         char *res;
118         char *p;
119
120         res = alloc(strlen(file) + strlen(ext) + 1);
121         if (res == NULL) {
122                 abort();
123         }
124         p = rindex(file, '.');
125         if (p == NULL) {
126                 p = file + strlen(file);
127         }
128         (void) strcpy(res, file);
129         (void) strcpy(res + (p - file), ext);
130         return (res);
131 }
132
133 /*
134  * Open output file with given extension
135  */
136 static
137 open_output(infile, outfile)
138         char *infile;
139         char *outfile;
140 {
141         if (outfile == NULL) {
142                 fout = stdout;
143                 return;
144         }
145         if (infile != NULL && streq(outfile, infile)) {
146                 f_print(stderr, _("%s: output would overwrite %s\n"), cmdname,
147                         infile);
148                 crash();
149         }
150         fout = fopen(outfile, "w");
151         if (fout == NULL) {
152                 f_print(stderr, _("%s: unable to open "), cmdname);
153                 perror(outfile);
154                 crash();
155         }
156         record_open(outfile);
157 }
158
159 /*
160  * Open input file with given define for C-preprocessor
161  */
162 static
163 open_input(infile, define)
164         char *infile;
165         char *define;
166 {
167         int pd[2];
168
169         infilename = (infile == NULL) ? "<stdin>" : infile;
170         (void) pipe(pd);
171         switch (fork()) {
172         case 0:
173                 (void) close(1);
174                 (void) dup2(pd[1], 1);
175                 (void) close(pd[0]);
176                 execl(CPP, CPP, CPPFLAGS, define, infile, NULL);
177                 perror("execl");
178                 exit(1);
179         case -1:
180                 perror("fork");
181                 exit(1);
182         }
183         (void) close(pd[1]);
184         fin = fdopen(pd[0], "r");
185         if (fin == NULL) {
186                 f_print(stderr, "%s: ", cmdname);
187                 perror(infilename);
188                 crash();
189         }
190 }
191
192 /*
193  * Compile into an XDR routine output file
194  */
195 static
196 c_output(infile, define, extend, outfile)
197         char *infile;
198         char *define;
199         int extend;
200         char *outfile;
201 {
202         definition *def;
203         char *include;
204         char *outfilename;
205         long tell;
206
207         open_input(infile, define);
208         outfilename = extend ? extendfile(infile, outfile) : outfile;
209         open_output(infile, outfilename);
210         f_print(fout, "#include <rpc/rpc.h>\n");
211         if (infile && (include = extendfile(infile, ".h"))) {
212                 f_print(fout, "#include \"%s\"\n", include);
213                 free(include);
214         }
215         tell = ftell(fout);
216         while (def = get_definition()) {
217                 emit(def);
218         }
219         if (extend && tell == ftell(fout)) {
220                 (void) unlink(outfilename);
221         }
222 }
223
224 /*
225  * Compile into an XDR header file
226  */
227 static
228 h_output(infile, define, extend, outfile)
229         char *infile;
230         char *define;
231         int extend;
232         char *outfile;
233 {
234         definition *def;
235         char *outfilename;
236         long tell;
237
238         open_input(infile, define);
239         outfilename =  extend ? extendfile(infile, outfile) : outfile;
240         open_output(infile, outfilename);
241         tell = ftell(fout);
242         while (def = get_definition()) {
243                 print_datadef(def);
244         }
245         if (extend && tell == ftell(fout)) {
246                 (void) unlink(outfilename);
247         }
248 }
249
250 /*
251  * Compile into an RPC service
252  */
253 static
254 s_output(argc, argv, infile, define, extend, outfile, nomain)
255         int argc;
256         char *argv[];
257         char *infile;
258         char *define;
259         int extend;
260         char *outfile;
261         int nomain;
262 {
263         char *include;
264         definition *def;
265         int foundprogram;
266         char *outfilename;
267
268         open_input(infile, define);
269         outfilename = extend ? extendfile(infile, outfile) : outfile;
270         open_output(infile, outfilename);
271         f_print(fout, "#include <stdio.h>\n");
272         f_print(fout, "#include <rpc/rpc.h>\n");
273         if (infile && (include = extendfile(infile, ".h"))) {
274                 f_print(fout, "#include \"%s\"\n", include);
275                 free(include);
276         }
277         foundprogram = 0;
278         while (def = get_definition()) {
279                 foundprogram |= (def->def_kind == DEF_PROGRAM);
280         }
281         if (extend && !foundprogram) {
282                 (void) unlink(outfilename);
283                 return;
284         }
285         if (nomain) {
286                 write_programs((char *)NULL);
287         } else {
288                 write_most();
289                 do_registers(argc, argv);
290                 write_rest();
291                 write_programs("static");
292         }
293 }
294
295 static
296 l_output(infile, define, extend, outfile)
297         char *infile;
298         char *define;
299         int extend;
300         char *outfile;
301 {
302         char *include;
303         definition *def;
304         int foundprogram;
305         char *outfilename;
306
307         open_input(infile, define);
308         outfilename = extend ? extendfile(infile, outfile) : outfile;
309         open_output(infile, outfilename);
310         f_print(fout, "#include <rpc/rpc.h>\n");
311         if (infile && (include = extendfile(infile, ".h"))) {
312                 f_print(fout, "#include \"%s\"\n", include);
313                 free(include);
314         }
315         foundprogram = 0;
316         while (def = get_definition()) {
317                 foundprogram |= (def->def_kind == DEF_PROGRAM);
318         }
319         if (extend && !foundprogram) {
320                 (void) unlink(outfilename);
321                 return;
322         }
323         write_stubs();
324 }
325
326 /*
327  * Perform registrations for service output
328  */
329 static
330 do_registers(argc, argv)
331         int argc;
332         char *argv[];
333
334 {
335         int i;
336
337         for (i = 1; i < argc; i++) {
338                 if (streq(argv[i], "-s")) {
339                         write_register(argv[i + 1]);
340                         i++;
341                 }
342         }
343 }
344
345 /*
346  * Parse command line arguments
347  */
348 static
349 parseargs(argc, argv, cmd)
350         int argc;
351         char *argv[];
352         struct commandline *cmd;
353
354 {
355         int i;
356         int j;
357         char c;
358         char flag[(1 << 8 * sizeof(char))];
359         int nflags;
360
361         cmdname = argv[0];
362         cmd->infile = cmd->outfile = NULL;
363         if (argc < 2) {
364                 return (0);
365         }
366         flag['c'] = 0;
367         flag['h'] = 0;
368         flag['s'] = 0;
369         flag['o'] = 0;
370         flag['l'] = 0;
371         flag['m'] = 0;
372         for (i = 1; i < argc; i++) {
373                 if (argv[i][0] != '-') {
374                         if (cmd->infile) {
375                                 return (0);
376                         }
377                         cmd->infile = argv[i];
378                 } else {
379                         for (j = 1; argv[i][j] != 0; j++) {
380                                 c = argv[i][j];
381                                 switch (c) {
382                                 case 'c':
383                                 case 'h':
384                                 case 'l':
385                                 case 'm':
386                                         if (flag[c]) {
387                                                 return (0);
388                                         }
389                                         flag[c] = 1;
390                                         break;
391                                 case 'o':
392                                 case 's':
393                                         if (argv[i][j - 1] != '-' ||
394                                             argv[i][j + 1] != 0) {
395                                                 return (0);
396                                         }
397                                         flag[c] = 1;
398                                         if (++i == argc) {
399                                                 return (0);
400                                         }
401                                         if (c == 's') {
402                                                 if (!streq(argv[i], "udp") &&
403                                                     !streq(argv[i], "tcp")) {
404                                                         return (0);
405                                                 }
406                                         } else if (c == 'o') {
407                                                 if (cmd->outfile) {
408                                                         return (0);
409                                                 }
410                                                 cmd->outfile = argv[i];
411                                         }
412                                         goto nextarg;
413
414                                 default:
415                                         return (0);
416                                 }
417                         }
418         nextarg:
419                         ;
420                 }
421         }
422         cmd->cflag = flag['c'];
423         cmd->hflag = flag['h'];
424         cmd->sflag = flag['s'];
425         cmd->lflag = flag['l'];
426         cmd->mflag = flag['m'];
427         nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag;
428         if (nflags == 0) {
429                 if (cmd->outfile != NULL || cmd->infile == NULL) {
430                         return (0);
431                 }
432         } else if (nflags > 1) {
433                 return (0);
434         }
435         return (1);
436 }