Commit | Line | Data |
---|---|---|
9a4767d3 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[] = "from: @(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI";*/ | |
32 | static char rcsid[] = "$Id: rpc_main.c,v 1.4 1993/08/01 18:09:20 mycroft 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 | } |