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