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