]>
Commit | Line | Data |
---|---|---|
28f540f4 RM |
1 | /* |
2 | * Sun RPC is a product of Sun Microsystems, Inc. and is provided for | |
3 | * unrestricted use provided that this legend is included on all tape | |
4 | * media and as a part of the software program in whole or part. Users | |
5 | * may copy or modify Sun RPC without charge, but are not authorized | |
6 | * to license or distribute it to anyone else except as part of a product or | |
0d204b0a UD |
7 | * program developed by the user or with the express written consent of |
8 | * Sun Microsystems, Inc. | |
cbd3dceb | 9 | * |
28f540f4 RM |
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. | |
cbd3dceb | 13 | * |
28f540f4 RM |
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. | |
cbd3dceb | 17 | * |
28f540f4 RM |
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. | |
cbd3dceb | 21 | * |
28f540f4 RM |
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. | |
cbd3dceb | 25 | * |
28f540f4 RM |
26 | * Sun Microsystems, Inc. |
27 | * 2550 Garcia Avenue | |
28 | * Mountain View, California 94043 | |
29 | */ | |
0d204b0a UD |
30 | |
31 | /* | |
32 | * From @(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI; | |
33 | */ | |
880f421f | 34 | const char main_rcsid[] = |
0d204b0a | 35 | "$Id$"; |
28f540f4 RM |
36 | |
37 | /* | |
cbd3dceb | 38 | * rpc_main.c, Top level of the RPC protocol compiler. |
28f540f4 RM |
39 | */ |
40 | ||
9756dfe1 | 41 | #include <errno.h> |
28f540f4 | 42 | #include <stdio.h> |
0d204b0a UD |
43 | #include <string.h> |
44 | #include <unistd.h> | |
4360eafd | 45 | #include <libintl.h> |
0d204b0a UD |
46 | #include <ctype.h> |
47 | #include <sys/types.h> | |
48 | #include <sys/param.h> | |
28f540f4 | 49 | #include <sys/file.h> |
0d204b0a | 50 | #include <sys/stat.h> |
0dee6738 | 51 | #include <sys/wait.h> |
28f540f4 | 52 | #include "rpc_parse.h" |
0d204b0a | 53 | #include "rpc_util.h" |
28f540f4 | 54 | #include "rpc_scan.h" |
0d204b0a UD |
55 | #include "proto.h" |
56 | ||
28f540f4 | 57 | #define EXTEND 1 /* alias for TRUE */ |
880f421f UD |
58 | #define DONT_EXTEND 0 /* alias for FALSE */ |
59 | ||
60 | struct commandline | |
61 | { | |
62 | int cflag; /* xdr C routines */ | |
63 | int hflag; /* header file */ | |
64 | int lflag; /* client side stubs */ | |
65 | int mflag; /* server side stubs */ | |
66 | int nflag; /* netid flag */ | |
67 | int sflag; /* server stubs for the given transport */ | |
68 | int tflag; /* dispatch Table file */ | |
69 | int Ssflag; /* produce server sample code */ | |
70 | int Scflag; /* produce client sample code */ | |
71 | int makefileflag; /* Generate a template Makefile */ | |
72 | const char *infile; /* input module name */ | |
73 | const char *outfile; /* output module name */ | |
74 | }; | |
28f540f4 | 75 | |
0d204b0a UD |
76 | |
77 | static const char *cmdname; | |
78 | ||
880f421f UD |
79 | #define SVR4_CPP "/usr/ccs/lib/cpp" |
80 | #define SUNOS_CPP "/lib/cpp" | |
81 | ||
0d204b0a | 82 | static const char *svcclosetime = "120"; |
880f421f UD |
83 | static int cppDefined = 0; /* explicit path for C preprocessor */ |
84 | static const char *CPP = SUNOS_CPP; | |
28f540f4 | 85 | static char CPPFLAGS[] = "-C"; |
9756dfe1 | 86 | static char *pathbuf; |
0dee6738 | 87 | static int cpp_pid; |
880f421f UD |
88 | static const char *allv[] = |
89 | { | |
90 | "rpcgen", "-s", "udp", "-s", "tcp", | |
28f540f4 | 91 | }; |
880f421f UD |
92 | static int allc = sizeof (allv) / sizeof (allv[0]); |
93 | static const char *allnv[] = | |
94 | { | |
95 | "rpcgen", "-s", "netpath", | |
0d204b0a | 96 | }; |
880f421f | 97 | static int allnc = sizeof (allnv) / sizeof (allnv[0]); |
0d204b0a UD |
98 | |
99 | /* | |
100 | * machinations for handling expanding argument list | |
101 | */ | |
880f421f UD |
102 | static void addarg (const char *); /* add another argument to the list */ |
103 | static void putarg (int, const char *); /* put argument at specified location */ | |
104 | static void clear_args (void); /* clear argument list */ | |
105 | static void checkfiles (const char *, const char *); | |
106 | /* check if out file already exists */ | |
107 | ||
108 | static void clear_args (void); | |
109 | static char *extendfile (const char *file, const char *ext); | |
110 | static void open_output (const char *infile, const char *outfile); | |
111 | static void add_warning (void); | |
112 | static void clear_args (void); | |
113 | static void find_cpp (void); | |
114 | static void open_input (const char *infile, const char *define); | |
115 | static int check_nettype (const char *name, const char *list_to_check[]); | |
116 | static void c_output (const char *infile, const char *define, | |
117 | int extend, const char *outfile); | |
118 | static void h_output (const char *infile, const char *define, | |
119 | int extend, const char *outfile); | |
120 | static void s_output (int argc, const char *argv[], const char *infile, | |
121 | const char *define, int extend, | |
122 | const char *outfile, int nomain, int netflag); | |
123 | static void l_output (const char *infile, const char *define, | |
124 | int extend, const char *outfile); | |
125 | static void t_output (const char *infile, const char *define, | |
126 | int extend, const char *outfile); | |
127 | static void svc_output (const char *infile, const char *define, | |
0d204b0a | 128 | int extend, const char *outfile); |
880f421f UD |
129 | static void clnt_output (const char *infile, const char *define, |
130 | int extend, const char *outfile); | |
131 | static void mkfile_output (struct commandline *cmd); | |
132 | static int do_registers (int argc, const char *argv[]); | |
133 | static void addarg (const char *cp); | |
134 | static void putarg (int whereto, const char *cp); | |
135 | static void checkfiles (const char *infile, const char *outfile); | |
136 | static int parseargs (int argc, const char *argv[], struct commandline *cmd); | |
137 | static void usage (void); | |
138 | static void options_usage (void); | |
139 | static void c_initialize (void); | |
140 | static char *generate_guard (const char *pathname); | |
0d204b0a UD |
141 | |
142 | ||
143 | #define ARGLISTLEN 20 | |
144 | #define FIXEDARGS 2 | |
145 | ||
146 | static const char *arglist[ARGLISTLEN]; | |
147 | static int argcount = FIXEDARGS; | |
148 | ||
149 | ||
880f421f UD |
150 | int nonfatalerrors; /* errors */ |
151 | int inetdflag /* = 1 */ ; /* Support for inetd *//* is now the default */ | |
152 | int pmflag; /* Support for port monitors */ | |
153 | int logflag; /* Use syslog instead of fprintf for errors */ | |
154 | int tblflag; /* Support for dispatch table file */ | |
155 | int mtflag; /* Support for MT */ | |
28f540f4 | 156 | |
0d204b0a UD |
157 | #define INLINE 3 |
158 | /*length at which to start doing an inline */ | |
28f540f4 | 159 | |
880f421f UD |
160 | int inlineflag = INLINE; /* length at which to start doing an inline. 3 = default |
161 | if 0, no xdr_inline code */ | |
0d204b0a | 162 | |
880f421f UD |
163 | int indefinitewait; /* If started by port monitors, hang till it wants */ |
164 | int exitnow; /* If started by port monitors, exit after the call */ | |
165 | int timerflag; /* TRUE if !indefinite && !exitnow */ | |
166 | int newstyle; /* newstyle of passing arguments (by value) */ | |
0d204b0a | 167 | #ifdef __GNU_LIBRARY__ |
880f421f | 168 | int Cflag = 1; /* ANSI C syntax */ |
0d204b0a | 169 | #else |
880f421f | 170 | int Cflag = 0; /* ANSI C/C++ syntax */ |
0d204b0a | 171 | #endif |
880f421f UD |
172 | int CCflag = 0; /* C++ files */ |
173 | static int allfiles; /* generate all files */ | |
0d204b0a | 174 | #ifdef __GNU_LIBRARY__ |
880f421f | 175 | int tirpcflag = 0; /* generating code for tirpc, by default */ |
0d204b0a | 176 | #else |
880f421f | 177 | int tirpcflag = 1; /* generating code for tirpc, by default */ |
9756dfe1 | 178 | #endif |
880f421f UD |
179 | xdrfunc *xdrfunc_head = NULL; /* xdr function list */ |
180 | xdrfunc *xdrfunc_tail = NULL; /* xdr function list */ | |
9756dfe1 | 181 | |
0d204b0a | 182 | int |
880f421f | 183 | main (int argc, const char *argv[]) |
28f540f4 | 184 | { |
880f421f | 185 | struct commandline cmd; |
28f540f4 | 186 | |
880f421f UD |
187 | (void) memset ((char *) &cmd, 0, sizeof (struct commandline)); |
188 | clear_args (); | |
189 | if (!parseargs (argc, argv, &cmd)) | |
190 | usage (); | |
c475b8f5 | 191 | |
880f421f UD |
192 | if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag || |
193 | cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) | |
194 | { | |
195 | checkfiles (cmd.infile, cmd.outfile); | |
196 | } | |
197 | else | |
198 | checkfiles (cmd.infile, NULL); | |
199 | ||
200 | if (cmd.cflag) | |
201 | c_output (cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile); | |
202 | else if (cmd.hflag) | |
203 | h_output (cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile); | |
204 | else if (cmd.lflag) | |
205 | l_output (cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile); | |
206 | else if (cmd.sflag || cmd.mflag || (cmd.nflag)) | |
207 | s_output (argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND, | |
208 | cmd.outfile, cmd.mflag, cmd.nflag); | |
209 | else if (cmd.tflag) | |
210 | t_output (cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile); | |
211 | else if (cmd.Ssflag) | |
212 | svc_output (cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile); | |
213 | else if (cmd.Scflag) | |
214 | clnt_output (cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile); | |
215 | else if (cmd.makefileflag) | |
216 | mkfile_output (&cmd); | |
217 | else | |
218 | { | |
219 | /* the rescans are required, since cpp may effect input */ | |
220 | c_output (cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); | |
221 | reinitialize (); | |
222 | h_output (cmd.infile, "-DRPC_HDR", EXTEND, ".h"); | |
223 | reinitialize (); | |
224 | l_output (cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); | |
225 | reinitialize (); | |
226 | if (inetdflag || !tirpcflag) | |
227 | s_output (allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, | |
228 | "_svc.c", cmd.mflag, cmd.nflag); | |
229 | else | |
230 | s_output (allnc, allnv, cmd.infile, "-DRPC_SVC", | |
231 | EXTEND, "_svc.c", cmd.mflag, cmd.nflag); | |
232 | if (tblflag) | |
233 | { | |
234 | reinitialize (); | |
235 | t_output (cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i"); | |
28f540f4 | 236 | } |
880f421f UD |
237 | if (allfiles) |
238 | { | |
239 | reinitialize (); | |
240 | svc_output (cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c"); | |
241 | reinitialize (); | |
242 | clnt_output (cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c"); | |
28f540f4 | 243 | } |
880f421f UD |
244 | if (allfiles || (cmd.makefileflag == 1)) |
245 | { | |
246 | reinitialize (); | |
247 | mkfile_output (&cmd); | |
248 | } | |
249 | } | |
250 | exit (nonfatalerrors); | |
251 | /* NOTREACHED */ | |
28f540f4 RM |
252 | } |
253 | ||
254 | /* | |
cbd3dceb | 255 | * add extension to filename |
28f540f4 RM |
256 | */ |
257 | static char * | |
880f421f | 258 | extendfile (const char *file, const char *ext) |
28f540f4 | 259 | { |
880f421f UD |
260 | char *res; |
261 | const char *p; | |
262 | ||
263 | res = alloc (strlen (file) + strlen (ext) + 1); | |
264 | if (res == NULL) | |
265 | abort (); | |
266 | p = strrchr (file, '.'); | |
267 | if (p == NULL) | |
268 | p = file + strlen (file); | |
269 | strcpy (res, file); | |
270 | strcpy (res + (p - file), ext); | |
271 | return res; | |
28f540f4 RM |
272 | } |
273 | ||
274 | /* | |
cbd3dceb | 275 | * Open output file with given extension |
28f540f4 | 276 | */ |
0d204b0a | 277 | static void |
880f421f | 278 | open_output (const char *infile, const char *outfile) |
28f540f4 | 279 | { |
880f421f UD |
280 | if (outfile == NULL) |
281 | { | |
282 | fout = stdout; | |
283 | return; | |
284 | } | |
0d204b0a | 285 | |
880f421f UD |
286 | if (infile != NULL && streq (outfile, infile)) |
287 | { | |
288 | fprintf (stderr, _ ("%s: output would overwrite %s\n"), cmdname, | |
289 | infile); | |
290 | crash (); | |
291 | } | |
292 | fout = fopen (outfile, "w"); | |
293 | if (fout == NULL) | |
294 | { | |
d74e76f9 | 295 | fprintf (stderr, _ ("%s: unable to open %s: %m\n"), cmdname, outfile); |
880f421f UD |
296 | crash (); |
297 | } | |
298 | record_open (outfile); | |
0d204b0a UD |
299 | } |
300 | ||
0dee6738 UD |
301 | /* Close the output file and check for write errors. */ |
302 | static void | |
303 | close_output (const char *outfile) | |
304 | { | |
305 | if (fclose (fout) == EOF) | |
306 | { | |
d74e76f9 UD |
307 | fprintf (stderr, _("%s: while writing output %s: %m"), cmdname, |
308 | outfile ?: "<stdout>"); | |
0dee6738 UD |
309 | crash (); |
310 | } | |
311 | } | |
312 | ||
0d204b0a | 313 | static void |
880f421f | 314 | add_warning (void) |
0d204b0a | 315 | { |
880f421f UD |
316 | fprintf (fout, "/*\n"); |
317 | fprintf (fout, " * Please do not edit this file.\n"); | |
318 | fprintf (fout, " * It was generated using rpcgen.\n"); | |
319 | fprintf (fout, " */\n\n"); | |
0d204b0a UD |
320 | } |
321 | ||
322 | /* clear list of arguments */ | |
880f421f UD |
323 | static void |
324 | clear_args (void) | |
0d204b0a UD |
325 | { |
326 | int i; | |
880f421f | 327 | for (i = FIXEDARGS; i < ARGLISTLEN; ++i) |
0d204b0a UD |
328 | arglist[i] = NULL; |
329 | argcount = FIXEDARGS; | |
330 | } | |
331 | ||
332 | /* make sure that a CPP exists */ | |
880f421f UD |
333 | static void |
334 | find_cpp (void) | |
0d204b0a UD |
335 | { |
336 | struct stat buf; | |
337 | ||
880f421f UD |
338 | if (stat (CPP, &buf) < 0) |
339 | { /* /lib/cpp or explicit cpp does not exist */ | |
340 | if (cppDefined) | |
341 | { | |
342 | fprintf (stderr, _ ("cannot find C preprocessor: %s \n"), CPP); | |
343 | crash (); | |
344 | } | |
345 | else | |
346 | { /* try the other one */ | |
347 | CPP = SVR4_CPP; | |
348 | if (stat (CPP, &buf) < 0) | |
349 | { /* can't find any cpp */ | |
350 | fputs (_ ("cannot find any C preprocessor (cpp)\n"), stdout); | |
351 | crash (); | |
352 | } | |
353 | } | |
0d204b0a | 354 | } |
0d204b0a UD |
355 | } |
356 | ||
28f540f4 | 357 | /* |
cbd3dceb | 358 | * Open input file with given define for C-preprocessor |
28f540f4 | 359 | */ |
0d204b0a | 360 | static void |
880f421f | 361 | open_input (const char *infile, const char *define) |
28f540f4 | 362 | { |
880f421f UD |
363 | int pd[2]; |
364 | ||
365 | infilename = (infile == NULL) ? "<stdin>" : infile; | |
9eb2730e UD |
366 | if (pipe (pd) != 0) |
367 | { | |
368 | perror ("pipe"); | |
369 | exit (1); | |
370 | } | |
0dee6738 UD |
371 | cpp_pid = fork (); |
372 | switch (cpp_pid) | |
880f421f UD |
373 | { |
374 | case 0: | |
375 | find_cpp (); | |
376 | putarg (0, CPP); | |
377 | putarg (1, CPPFLAGS); | |
378 | addarg (define); | |
379 | if (infile) | |
380 | addarg (infile); | |
381 | addarg ((char *) NULL); | |
382 | close (1); | |
383 | dup2 (pd[1], 1); | |
384 | close (pd[0]); | |
385 | execv (arglist[0], (char **) arglist); | |
386 | perror ("execv"); | |
387 | exit (1); | |
388 | case -1: | |
389 | perror ("fork"); | |
390 | exit (1); | |
391 | } | |
392 | close (pd[1]); | |
393 | fin = fdopen (pd[0], "r"); | |
394 | if (fin == NULL) | |
395 | { | |
396 | fprintf (stderr, "%s: ", cmdname); | |
397 | perror (infilename); | |
398 | crash (); | |
399 | } | |
28f540f4 RM |
400 | } |
401 | ||
0dee6738 UD |
402 | /* Close the connection to the C-preprocessor and check for successfull |
403 | termination. */ | |
404 | static void | |
405 | close_input (void) | |
406 | { | |
407 | int status; | |
408 | ||
409 | fclose (fin); | |
410 | /* Check the termination status. */ | |
411 | if (waitpid (cpp_pid, &status, 0) < 0) | |
412 | { | |
413 | perror ("waitpid"); | |
414 | crash (); | |
415 | } | |
416 | if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0) | |
417 | { | |
418 | if (WIFSIGNALED (status)) | |
419 | fprintf (stderr, _("%s: C preprocessor failed with signal %d\n"), | |
420 | cmdname, WTERMSIG (status)); | |
421 | else | |
422 | fprintf (stderr, _("%s: C preprocessor failed with exit code %d\n"), | |
423 | cmdname, WEXITSTATUS (status)); | |
424 | crash (); | |
425 | } | |
426 | } | |
427 | ||
0d204b0a UD |
428 | /* valid tirpc nettypes */ |
429 | static const char *valid_ti_nettypes[] = | |
430 | { | |
431 | "netpath", | |
432 | "visible", | |
433 | "circuit_v", | |
434 | "datagram_v", | |
435 | "circuit_n", | |
436 | "datagram_n", | |
437 | "udp", | |
438 | "tcp", | |
439 | "raw", | |
440 | NULL | |
880f421f | 441 | }; |
0d204b0a UD |
442 | |
443 | /* valid inetd nettypes */ | |
444 | static const char *valid_i_nettypes[] = | |
445 | { | |
446 | "udp", | |
447 | "tcp", | |
448 | NULL | |
449 | }; | |
450 | ||
880f421f UD |
451 | static int |
452 | check_nettype (const char *name, const char *list_to_check[]) | |
453 | { | |
0d204b0a | 454 | int i; |
880f421f UD |
455 | for (i = 0; list_to_check[i] != NULL; i++) |
456 | { | |
457 | if (strcmp (name, list_to_check[i]) == 0) | |
458 | { | |
459 | return 1; | |
460 | } | |
461 | } | |
db276fa1 | 462 | fprintf (stderr, _ ("illegal nettype :`%s'\n"), name); |
0d204b0a UD |
463 | return 0; |
464 | } | |
465 | ||
28f540f4 RM |
466 | /* |
467 | * Compile into an XDR routine output file | |
468 | */ | |
0d204b0a UD |
469 | |
470 | static void | |
880f421f UD |
471 | c_output (const char *infile, const char *define, int extend, |
472 | const char *outfile) | |
28f540f4 | 473 | { |
880f421f UD |
474 | definition *def; |
475 | char *include; | |
476 | const char *outfilename; | |
477 | long tell; | |
478 | ||
479 | c_initialize (); | |
480 | open_input (infile, define); | |
481 | outfilename = extend ? extendfile (infile, outfile) : outfile; | |
482 | open_output (infile, outfilename); | |
483 | add_warning (); | |
484 | if (infile && (include = extendfile (infile, ".h"))) | |
485 | { | |
486 | fprintf (fout, "#include \"%s\"\n", include); | |
487 | free (include); | |
488 | /* .h file already contains rpc/rpc.h */ | |
489 | } | |
490 | else | |
491 | fprintf (fout, "#include <rpc/rpc.h>\n"); | |
492 | tell = ftell (fout); | |
493 | while ((def = get_definition ()) != NULL) | |
494 | emit (def); | |
495 | ||
496 | if (extend && tell == ftell (fout)) | |
497 | unlink (outfilename); | |
0dee6738 UD |
498 | close_input (); |
499 | close_output (outfilename); | |
28f540f4 RM |
500 | } |
501 | ||
0d204b0a | 502 | void |
880f421f | 503 | c_initialize (void) |
0d204b0a UD |
504 | { |
505 | ||
506 | /* add all the starting basic types */ | |
507 | ||
880f421f UD |
508 | add_type (1, "int"); |
509 | add_type (1, "long"); | |
510 | add_type (1, "short"); | |
511 | add_type (1, "bool"); | |
0d204b0a | 512 | |
880f421f UD |
513 | add_type (1, "u_int"); |
514 | add_type (1, "u_long"); | |
515 | add_type (1, "u_short"); | |
0d204b0a UD |
516 | |
517 | } | |
518 | ||
519 | char rpcgen_table_dcl[] = "struct rpcgen_table {\n\ | |
520 | char *(*proc)();\n\ | |
521 | xdrproc_t xdr_arg;\n\ | |
522 | unsigned len_arg;\n\ | |
523 | xdrproc_t xdr_res;\n\ | |
524 | unsigned len_res;\n\ | |
525 | };\n"; | |
526 | ||
527 | ||
880f421f UD |
528 | static char * |
529 | generate_guard (const char *pathname) | |
530 | { | |
531 | const char *filename; | |
532 | char *guard, *tmp; | |
533 | ||
534 | filename = strrchr (pathname, '/'); /* find last component */ | |
535 | filename = ((filename == NULL) ? pathname : filename + 1); | |
536 | guard = strdup (filename); | |
537 | /* convert to upper case */ | |
538 | tmp = guard; | |
539 | while (*tmp) | |
540 | { | |
541 | if (islower (*tmp)) | |
542 | *tmp = toupper (*tmp); | |
543 | tmp++; | |
544 | } | |
0d204b0a | 545 | |
880f421f UD |
546 | guard = extendfile (guard, "_H_RPCGEN"); |
547 | return guard; | |
0d204b0a UD |
548 | } |
549 | ||
28f540f4 RM |
550 | /* |
551 | * Compile into an XDR header file | |
552 | */ | |
0d204b0a UD |
553 | |
554 | ||
555 | static void | |
880f421f UD |
556 | h_output (const char *infile, const char *define, int extend, |
557 | const char *outfile) | |
28f540f4 | 558 | { |
880f421f UD |
559 | xdrfunc *xdrfuncp; |
560 | definition *def; | |
561 | const char *ifilename; | |
562 | const char *outfilename; | |
563 | long tell; | |
564 | char *guard; | |
565 | list *l; | |
0d204b0a | 566 | |
880f421f UD |
567 | open_input (infile, define); |
568 | outfilename = extend ? extendfile (infile, outfile) : outfile; | |
569 | open_output (infile, outfilename); | |
570 | add_warning (); | |
571 | ifilename = (infile == NULL) ? "STDIN" : infile; | |
572 | guard = generate_guard (outfilename ? outfilename : ifilename); | |
573 | ||
574 | fprintf (fout, "#ifndef _%s\n#define _%s\n\n", guard, | |
575 | guard); | |
576 | ||
577 | fprintf (fout, "#include <rpc/rpc.h>\n\n"); | |
578 | ||
579 | if (mtflag) | |
580 | { | |
581 | fprintf (fout, "#include <pthread.h>\n"); | |
582 | } | |
583 | ||
584 | /* put the C++ support */ | |
585 | if (Cflag && !CCflag) | |
586 | { | |
587 | fprintf (fout, "\n#ifdef __cplusplus\n"); | |
588 | fprintf (fout, "extern \"C\" {\n"); | |
589 | fprintf (fout, "#endif\n\n"); | |
590 | } | |
591 | ||
592 | tell = ftell (fout); | |
593 | /* print data definitions */ | |
594 | while ((def = get_definition ()) != NULL) | |
595 | { | |
596 | print_datadef (def); | |
597 | } | |
598 | ||
599 | /* print function declarations. | |
600 | Do this after data definitions because they might be used as | |
601 | arguments for functions */ | |
602 | for (l = defined; l != NULL; l = l->next) | |
603 | { | |
604 | print_funcdef (l->val); | |
605 | } | |
606 | /* Now print all xdr func declarations */ | |
607 | if (xdrfunc_head != NULL) | |
608 | { | |
609 | fprintf (fout, "\n/* the xdr functions */\n"); | |
610 | if (CCflag) | |
611 | { | |
612 | fprintf (fout, "\n#ifdef __cplusplus\n"); | |
613 | fprintf (fout, "extern \"C\" {\n"); | |
614 | fprintf (fout, "#endif\n"); | |
615 | } | |
616 | if (!Cflag) | |
617 | { | |
618 | xdrfuncp = xdrfunc_head; | |
619 | while (xdrfuncp != NULL) | |
620 | { | |
621 | print_xdr_func_def (xdrfuncp->name, | |
622 | xdrfuncp->pointerp, 2); | |
623 | xdrfuncp = xdrfuncp->next; | |
624 | } | |
0d204b0a | 625 | } |
880f421f UD |
626 | else |
627 | { | |
628 | int i; | |
629 | ||
630 | for (i = 1; i < 3; ++i) | |
631 | { | |
632 | if (i == 1) | |
633 | fprintf (fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n"); | |
634 | else | |
635 | fprintf (fout, "\n#else /* K&R C */\n"); | |
636 | ||
637 | xdrfuncp = xdrfunc_head; | |
638 | while (xdrfuncp != NULL) | |
639 | { | |
640 | print_xdr_func_def (xdrfuncp->name, | |
641 | xdrfuncp->pointerp, i); | |
642 | xdrfuncp = xdrfuncp->next; | |
643 | } | |
644 | } | |
645 | fprintf (fout, "\n#endif /* K&R C */\n"); | |
28f540f4 | 646 | } |
880f421f UD |
647 | } |
648 | ||
649 | if (extend && tell == ftell (fout)) | |
650 | { | |
651 | unlink (outfilename); | |
652 | } | |
653 | else if (tblflag) | |
654 | { | |
655 | fprintf (fout, rpcgen_table_dcl); | |
656 | } | |
657 | ||
658 | if (Cflag) | |
659 | { | |
660 | fprintf (fout, "\n#ifdef __cplusplus\n"); | |
661 | fprintf (fout, "}\n"); | |
662 | fprintf (fout, "#endif\n"); | |
663 | } | |
664 | ||
665 | fprintf (fout, "\n#endif /* !_%s */\n", guard); | |
0dee6738 UD |
666 | close_input (); |
667 | close_output (outfilename); | |
28f540f4 RM |
668 | } |
669 | ||
670 | /* | |
671 | * Compile into an RPC service | |
672 | */ | |
0d204b0a | 673 | static void |
880f421f UD |
674 | s_output (int argc, const char *argv[], const char *infile, const char *define, |
675 | int extend, const char *outfile, int nomain, int netflag) | |
28f540f4 | 676 | { |
880f421f UD |
677 | char *include; |
678 | definition *def; | |
679 | int foundprogram = 0; | |
680 | const char *outfilename; | |
681 | ||
682 | open_input (infile, define); | |
683 | outfilename = extend ? extendfile (infile, outfile) : outfile; | |
684 | open_output (infile, outfilename); | |
685 | add_warning (); | |
686 | if (infile && (include = extendfile (infile, ".h"))) | |
687 | { | |
688 | fprintf (fout, "#include \"%s\"\n", include); | |
689 | free (include); | |
690 | } | |
691 | else | |
692 | fprintf (fout, "#include <rpc/rpc.h>\n"); | |
693 | ||
694 | fprintf (fout, "#include <stdio.h>\n"); | |
695 | fprintf (fout, "#include <stdlib.h>\n"); | |
696 | if (Cflag) | |
697 | { | |
698 | fprintf (fout, "#include <rpc/pmap_clnt.h>\n"); | |
699 | fprintf (fout, "#include <string.h>\n"); | |
700 | } | |
701 | if (strcmp (svcclosetime, "-1") == 0) | |
702 | indefinitewait = 1; | |
703 | else if (strcmp (svcclosetime, "0") == 0) | |
704 | exitnow = 1; | |
705 | else if (inetdflag || pmflag) | |
706 | { | |
707 | fprintf (fout, "#include <signal.h>\n"); | |
708 | timerflag = 1; | |
709 | } | |
0d204b0a | 710 | |
880f421f | 711 | if (!tirpcflag && inetdflag) |
0d204b0a | 712 | #ifdef __GNU_LIBRARY__ |
880f421f | 713 | fprintf (fout, "#include <sys/ioctl.h> /* ioctl, TIOCNOTTY */\n"); |
0d204b0a | 714 | #else |
880f421f | 715 | fprintf (fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n"); |
0d204b0a | 716 | #endif |
880f421f UD |
717 | if (Cflag && (inetdflag || pmflag)) |
718 | { | |
0d204b0a | 719 | #ifdef __GNU_LIBRARY__ |
880f421f UD |
720 | fprintf (fout, "#include <sys/types.h> /* open */\n"); |
721 | fprintf (fout, "#include <sys/stat.h> /* open */\n"); | |
722 | fprintf (fout, "#include <fcntl.h> /* open */\n"); | |
723 | fprintf (fout, "#include <unistd.h> /* getdtablesize */\n"); | |
0d204b0a | 724 | #else |
880f421f UD |
725 | fprintf (fout, "#ifdef __cplusplus\n"); |
726 | fprintf (fout, "#include <sysent.h> /* getdtablesize, open */\n"); | |
727 | fprintf (fout, "#endif /* __cplusplus */\n"); | |
728 | if (tirpcflag) | |
729 | fprintf (fout, "#include <unistd.h> /* setsid */\n"); | |
0d204b0a | 730 | #endif |
880f421f UD |
731 | } |
732 | #ifdef __GNU_LIBRARY__ | |
733 | if (tirpcflag && !(Cflag && (inetdflag || pmflag))) | |
734 | #else | |
735 | if (tirpcflag) | |
736 | #endif | |
737 | fprintf (fout, "#include <sys/types.h>\n"); | |
0d204b0a | 738 | |
880f421f | 739 | fprintf (fout, "#include <memory.h>\n"); |
0d204b0a | 740 | #ifndef __GNU_LIBRARY__ |
880f421f | 741 | fprintf (fout, "#include <stropts.h>\n"); |
0d204b0a | 742 | #endif |
880f421f UD |
743 | if (inetdflag || !tirpcflag) |
744 | { | |
745 | fprintf (fout, "#include <sys/socket.h>\n"); | |
746 | fprintf (fout, "#include <netinet/in.h>\n"); | |
747 | } | |
0d204b0a | 748 | |
880f421f UD |
749 | if ((netflag || pmflag) && tirpcflag && !nomain) |
750 | { | |
751 | fprintf (fout, "#include <netconfig.h>\n"); | |
752 | } | |
753 | if ( /*timerflag && */ tirpcflag) | |
754 | fprintf (fout, "#include <sys/resource.h> /* rlimit */\n"); | |
755 | if (logflag || inetdflag || pmflag) | |
756 | { | |
0d204b0a | 757 | #ifdef __GNU_LIBRARY__ |
880f421f | 758 | fprintf (fout, "#include <syslog.h>\n"); |
0d204b0a | 759 | #else |
880f421f UD |
760 | fprintf (fout, "#ifdef SYSLOG\n"); |
761 | fprintf (fout, "#include <syslog.h>\n"); | |
762 | fprintf (fout, "#else\n"); | |
763 | fprintf (fout, "#define LOG_ERR 1\n"); | |
764 | fprintf (fout, "#define openlog(a, b, c)\n"); | |
765 | fprintf (fout, "#endif\n"); | |
0d204b0a | 766 | #endif |
880f421f | 767 | } |
0d204b0a | 768 | |
880f421f UD |
769 | /* for ANSI-C */ |
770 | if (Cflag) | |
771 | fprintf (fout, "\n#ifndef SIG_PF\n#define SIG_PF void(*)(int)\n#endif\n"); | |
0d204b0a UD |
772 | |
773 | #ifndef __GNU_LIBRARY__ | |
880f421f | 774 | fprintf (fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n"); |
0d204b0a | 775 | #endif |
880f421f UD |
776 | if (timerflag) |
777 | fprintf (fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime); | |
778 | while ((def = get_definition ()) != NULL) | |
779 | { | |
780 | foundprogram |= (def->def_kind == DEF_PROGRAM); | |
781 | } | |
782 | if (extend && !foundprogram) | |
783 | { | |
784 | unlink (outfilename); | |
785 | return; | |
786 | } | |
787 | write_most (infile, netflag, nomain); | |
788 | if (!nomain) | |
789 | { | |
790 | if (!do_registers (argc, argv)) | |
791 | { | |
792 | if (outfilename) | |
793 | unlink (outfilename); | |
794 | usage (); | |
28f540f4 | 795 | } |
880f421f UD |
796 | write_rest (); |
797 | } | |
0dee6738 UD |
798 | close_input (); |
799 | close_output (outfilename); | |
28f540f4 RM |
800 | } |
801 | ||
0d204b0a UD |
802 | /* |
803 | * generate client side stubs | |
804 | */ | |
805 | static void | |
880f421f UD |
806 | l_output (const char *infile, const char *define, int extend, |
807 | const char *outfile) | |
28f540f4 | 808 | { |
880f421f UD |
809 | char *include; |
810 | definition *def; | |
811 | int foundprogram = 0; | |
812 | const char *outfilename; | |
813 | ||
814 | open_input (infile, define); | |
815 | outfilename = extend ? extendfile (infile, outfile) : outfile; | |
816 | open_output (infile, outfilename); | |
817 | add_warning (); | |
818 | if (Cflag) | |
819 | fprintf (fout, "#include <memory.h> /* for memset */\n"); | |
820 | if (infile && (include = extendfile (infile, ".h"))) | |
821 | { | |
822 | fprintf (fout, "#include \"%s\"\n", include); | |
823 | free (include); | |
824 | } | |
825 | else | |
826 | fprintf (fout, "#include <rpc/rpc.h>\n"); | |
827 | while ((def = get_definition ()) != NULL) | |
828 | { | |
829 | foundprogram |= (def->def_kind == DEF_PROGRAM); | |
830 | } | |
831 | if (extend && !foundprogram) | |
832 | { | |
833 | unlink (outfilename); | |
834 | return; | |
835 | } | |
836 | write_stubs (); | |
0dee6738 UD |
837 | close_input (); |
838 | close_output (outfilename); | |
28f540f4 RM |
839 | } |
840 | ||
841 | /* | |
0d204b0a | 842 | * generate the dispatch table |
28f540f4 | 843 | */ |
0d204b0a | 844 | static void |
880f421f UD |
845 | t_output (const char *infile, const char *define, int extend, |
846 | const char *outfile) | |
0d204b0a | 847 | { |
880f421f UD |
848 | definition *def; |
849 | int foundprogram = 0; | |
850 | const char *outfilename; | |
851 | ||
852 | open_input (infile, define); | |
853 | outfilename = extend ? extendfile (infile, outfile) : outfile; | |
854 | open_output (infile, outfilename); | |
855 | add_warning (); | |
856 | while ((def = get_definition ()) != NULL) | |
857 | { | |
858 | foundprogram |= (def->def_kind == DEF_PROGRAM); | |
859 | } | |
860 | if (extend && !foundprogram) | |
861 | { | |
862 | unlink (outfilename); | |
863 | return; | |
864 | } | |
865 | write_tables (); | |
0dee6738 UD |
866 | close_input (); |
867 | close_output (outfilename); | |
0d204b0a UD |
868 | } |
869 | ||
870 | /* sample routine for the server template */ | |
871 | static void | |
880f421f UD |
872 | svc_output (const char *infile, const char *define, int extend, |
873 | const char *outfile) | |
0d204b0a UD |
874 | { |
875 | definition *def; | |
876 | char *include; | |
877 | const char *outfilename; | |
878 | long tell; | |
879 | ||
880f421f UD |
880 | open_input (infile, define); |
881 | outfilename = extend ? extendfile (infile, outfile) : outfile; | |
882 | checkfiles (infile, outfilename); | |
883 | /*check if outfile already exists. | |
884 | if so, print an error message and exit */ | |
885 | open_output (infile, outfilename); | |
886 | add_sample_msg (); | |
887 | ||
888 | if (infile && (include = extendfile (infile, ".h"))) | |
889 | { | |
890 | fprintf (fout, "#include \"%s\"\n", include); | |
891 | free (include); | |
892 | } | |
893 | else | |
894 | fprintf (fout, "#include <rpc/rpc.h>\n"); | |
895 | ||
896 | tell = ftell (fout); | |
897 | while ((def = get_definition ()) != NULL) | |
898 | { | |
899 | write_sample_svc (def); | |
900 | } | |
901 | if (extend && tell == ftell (fout)) | |
902 | { | |
903 | unlink (outfilename); | |
904 | } | |
0dee6738 UD |
905 | close_input (); |
906 | close_output (outfilename); | |
0d204b0a UD |
907 | } |
908 | ||
909 | ||
910 | /* sample main routine for client */ | |
911 | static void | |
880f421f UD |
912 | clnt_output (const char *infile, const char *define, int extend, |
913 | const char *outfile) | |
0d204b0a UD |
914 | { |
915 | definition *def; | |
916 | char *include; | |
917 | const char *outfilename; | |
918 | long tell; | |
919 | int has_program = 0; | |
28f540f4 | 920 | |
880f421f UD |
921 | open_input (infile, define); |
922 | outfilename = extend ? extendfile (infile, outfile) : outfile; | |
923 | checkfiles (infile, outfilename); | |
924 | /*check if outfile already exists. | |
925 | if so, print an error message and exit */ | |
926 | ||
927 | open_output (infile, outfilename); | |
928 | add_sample_msg (); | |
929 | if (infile && (include = extendfile (infile, ".h"))) | |
930 | { | |
931 | fprintf (fout, "#include \"%s\"\n", include); | |
932 | free (include); | |
933 | } | |
934 | else | |
935 | fprintf (fout, "#include <rpc/rpc.h>\n"); | |
936 | tell = ftell (fout); | |
937 | while ((def = get_definition ()) != NULL) | |
938 | { | |
939 | has_program += write_sample_clnt (def); | |
940 | } | |
941 | ||
942 | if (has_program) | |
943 | write_sample_clnt_main (); | |
944 | ||
945 | if (extend && tell == ftell (fout)) | |
946 | { | |
947 | unlink (outfilename); | |
948 | } | |
0dee6738 UD |
949 | close_input (); |
950 | close_output (outfilename); | |
880f421f UD |
951 | } |
952 | ||
953 | static char * | |
954 | file_name (const char *file, const char *ext) | |
955 | { | |
956 | char *temp; | |
957 | temp = extendfile (file, ext); | |
958 | ||
959 | if (access (temp, F_OK) != -1) | |
960 | return (temp); | |
961 | else | |
962 | return ((char *) " "); | |
963 | } | |
964 | ||
965 | static void | |
966 | mkfile_output (struct commandline *cmd) | |
967 | { | |
968 | char *mkfilename; | |
969 | const char *clientname, *clntname, *xdrname, *hdrname; | |
970 | const char *servername, *svcname, *servprogname, *clntprogname; | |
880f421f UD |
971 | |
972 | svcname = file_name (cmd->infile, "_svc.c"); | |
973 | clntname = file_name (cmd->infile, "_clnt.c"); | |
974 | xdrname = file_name (cmd->infile, "_xdr.c"); | |
975 | hdrname = file_name (cmd->infile, ".h"); | |
976 | ||
977 | if (allfiles) | |
978 | { | |
979 | servername = extendfile (cmd->infile, "_server.c"); | |
980 | clientname = extendfile (cmd->infile, "_client.c"); | |
981 | } | |
982 | else | |
983 | { | |
984 | servername = " "; | |
985 | clientname = " "; | |
986 | } | |
987 | servprogname = extendfile (cmd->infile, "_server"); | |
988 | clntprogname = extendfile (cmd->infile, "_client"); | |
989 | ||
990 | if (allfiles) | |
991 | { | |
ee586e0e UD |
992 | char *cp, *temp; |
993 | ||
994 | mkfilename = alloc (strlen ("Makefile.") + strlen (cmd->infile) + 1); | |
995 | temp = rindex (cmd->infile, '.'); | |
996 | cp = stpcpy (mkfilename, "Makefile."); | |
997 | strncpy (cp, cmd->infile, (temp - cmd->infile)); | |
880f421f UD |
998 | } |
999 | else | |
1000 | mkfilename = (char *) cmd->outfile; | |
1001 | ||
1002 | checkfiles (NULL, mkfilename); | |
1003 | open_output (NULL, mkfilename); | |
1004 | ||
1005 | fprintf (fout, "\n# This is a template Makefile generated by rpcgen\n"); | |
1006 | ||
1007 | f_print (fout, "\n# Parameters\n\n"); | |
1008 | ||
1009 | f_print (fout, "CLIENT = %s\nSERVER = %s\n\n", clntprogname, servprogname); | |
1010 | f_print (fout, "SOURCES_CLNT.c = \nSOURCES_CLNT.h = \n"); | |
1011 | f_print (fout, "SOURCES_SVC.c = \nSOURCES_SVC.h = \n"); | |
1012 | f_print (fout, "SOURCES.x = %s\n\n", cmd->infile); | |
1013 | f_print (fout, "TARGETS_SVC.c = %s %s %s \n", | |
1014 | svcname, servername, xdrname); | |
1015 | f_print (fout, "TARGETS_CLNT.c = %s %s %s \n", | |
1016 | clntname, clientname, xdrname); | |
1017 | f_print (fout, "TARGETS = %s %s %s %s %s %s\n\n", | |
1018 | hdrname, xdrname, clntname, | |
1019 | svcname, clientname, servername); | |
1020 | ||
1021 | f_print (fout, "OBJECTS_CLNT = $(SOURCES_CLNT.c:%%.c=%%.o) \ | |
1022 | $(TARGETS_CLNT.c:%%.c=%%.o)"); | |
1023 | ||
1024 | f_print (fout, "\nOBJECTS_SVC = $(SOURCES_SVC.c:%%.c=%%.o) \ | |
1025 | $(TARGETS_SVC.c:%%.c=%%.o)"); | |
1026 | ||
1027 | f_print (fout, "\n# Compiler flags \n"); | |
1028 | if (mtflag) | |
1029 | fprintf (fout, "\nCPPFLAGS += -D_REENTRANT\nCFLAGS += -g \nLDLIBS \ | |
1030 | += -lnsl -lpthread \n "); | |
1031 | else | |
1032 | f_print (fout, "\nCFLAGS += -g \nLDLIBS += -lnsl\n"); | |
1033 | f_print (fout, "RPCGENFLAGS = \n"); | |
1034 | ||
1035 | f_print (fout, "\n# Targets \n\n"); | |
1036 | ||
1037 | f_print (fout, "all : $(CLIENT) $(SERVER)\n\n"); | |
1038 | f_print (fout, "$(TARGETS) : $(SOURCES.x) \n"); | |
1039 | f_print (fout, "\trpcgen $(RPCGENFLAGS) $(SOURCES.x)\n\n"); | |
1040 | f_print (fout, "$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) \ | |
1041 | $(TARGETS_CLNT.c) \n\n"); | |
1042 | ||
1043 | f_print (fout, "$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) \ | |
1044 | $(TARGETS_SVC.c) \n\n"); | |
1045 | f_print (fout, "$(CLIENT) : $(OBJECTS_CLNT) \n"); | |
1046 | f_print (fout, "\t$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) \ | |
1047 | $(LDLIBS) \n\n"); | |
1048 | f_print (fout, "$(SERVER) : $(OBJECTS_SVC) \n"); | |
1049 | f_print (fout, "\t$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)\n\n "); | |
1050 | f_print (fout, "clean:\n\t $(RM) core $(TARGETS) $(OBJECTS_CLNT) \ | |
1051 | $(OBJECTS_SVC) $(CLIENT) $(SERVER)\n\n"); | |
0dee6738 | 1052 | close_output (mkfilename); |
0d204b0a UD |
1053 | } |
1054 | ||
1055 | /* | |
1056 | * Perform registrations for service output | |
1057 | * Return 0 if failed; 1 otherwise. | |
1058 | */ | |
880f421f UD |
1059 | static int |
1060 | do_registers (int argc, const char *argv[]) | |
28f540f4 | 1061 | { |
880f421f UD |
1062 | int i; |
1063 | ||
1064 | if (inetdflag || !tirpcflag) | |
1065 | { | |
1066 | for (i = 1; i < argc; i++) | |
1067 | { | |
1068 | if (streq (argv[i], "-s")) | |
1069 | { | |
1070 | if (!check_nettype (argv[i + 1], valid_i_nettypes)) | |
1071 | return 0; | |
1072 | write_inetd_register (argv[i + 1]); | |
1073 | i++; | |
1074 | } | |
28f540f4 | 1075 | } |
880f421f UD |
1076 | } |
1077 | else | |
1078 | { | |
1079 | for (i = 1; i < argc; i++) | |
1080 | if (streq (argv[i], "-s")) | |
1081 | { | |
1082 | if (!check_nettype (argv[i + 1], valid_ti_nettypes)) | |
1083 | return 0; | |
1084 | write_nettype_register (argv[i + 1]); | |
1085 | i++; | |
1086 | } | |
1087 | else if (streq (argv[i], "-n")) | |
1088 | { | |
1089 | write_netid_register (argv[i + 1]); | |
1090 | i++; | |
1091 | } | |
1092 | } | |
1093 | return 1; | |
28f540f4 RM |
1094 | } |
1095 | ||
1096 | /* | |
0d204b0a | 1097 | * Add another argument to the arg list |
28f540f4 | 1098 | */ |
0d204b0a | 1099 | static void |
880f421f | 1100 | addarg (const char *cp) |
0d204b0a | 1101 | { |
880f421f UD |
1102 | if (argcount >= ARGLISTLEN) |
1103 | { | |
1104 | fprintf (stderr, _("rpcgen: too many defines\n")); | |
1105 | crash (); | |
1106 | /*NOTREACHED */ | |
1107 | } | |
1108 | arglist[argcount++] = cp; | |
0d204b0a UD |
1109 | } |
1110 | ||
1111 | static void | |
880f421f | 1112 | putarg (int whereto, const char *cp) |
0d204b0a | 1113 | { |
880f421f UD |
1114 | if (whereto >= ARGLISTLEN) |
1115 | { | |
1116 | fprintf (stderr, _("rpcgen: arglist coding error\n")); | |
1117 | crash (); | |
1118 | /*NOTREACHED */ | |
1119 | } | |
1120 | arglist[whereto] = cp; | |
0d204b0a | 1121 | } |
28f540f4 | 1122 | |
0d204b0a UD |
1123 | /* |
1124 | * if input file is stdin and an output file is specified then complain | |
1125 | * if the file already exists. Otherwise the file may get overwritten | |
1126 | * If input file does not exist, exit with an error | |
1127 | */ | |
1128 | ||
1129 | static void | |
880f421f | 1130 | checkfiles (const char *infile, const char *outfile) |
0d204b0a | 1131 | { |
0d204b0a UD |
1132 | struct stat buf; |
1133 | ||
880f421f UD |
1134 | if (infile) /* infile ! = NULL */ |
1135 | if (stat (infile, &buf) < 0) | |
0d204b0a | 1136 | { |
880f421f UD |
1137 | perror (infile); |
1138 | crash (); | |
1139 | } | |
1140 | if (outfile) | |
1141 | { | |
1142 | if (stat (outfile, &buf) < 0) | |
1143 | return; /* file does not exist */ | |
1144 | else | |
1145 | { | |
1146 | fprintf (stderr, | |
db276fa1 | 1147 | _("file `%s' already exists and may be overwritten\n"), |
880f421f UD |
1148 | outfile); |
1149 | crash (); | |
1150 | } | |
0d204b0a | 1151 | } |
0d204b0a UD |
1152 | } |
1153 | ||
1154 | /* | |
1155 | * Parse command line arguments | |
1156 | */ | |
1157 | static int | |
880f421f | 1158 | parseargs (int argc, const char *argv[], struct commandline *cmd) |
28f540f4 | 1159 | { |
880f421f UD |
1160 | int i; |
1161 | int j; | |
1162 | int c; | |
1163 | char flag[(1 << 8 * sizeof (char))]; | |
1164 | int nflags; | |
1165 | ||
1166 | cmdname = argv[0]; | |
1167 | cmd->infile = cmd->outfile = NULL; | |
1168 | if (argc < 2) | |
1169 | { | |
1170 | return (0); | |
1171 | } | |
1172 | allfiles = 0; | |
1173 | flag['c'] = 0; | |
1174 | flag['h'] = 0; | |
1175 | flag['l'] = 0; | |
1176 | flag['m'] = 0; | |
1177 | flag['o'] = 0; | |
1178 | flag['s'] = 0; | |
1179 | flag['n'] = 0; | |
1180 | flag['t'] = 0; | |
1181 | flag['S'] = 0; | |
1182 | flag['C'] = 0; | |
1183 | flag['M'] = 0; | |
1184 | ||
1185 | for (i = 1; i < argc; i++) | |
1186 | { | |
1187 | if (argv[i][0] != '-') | |
1188 | { | |
1189 | if (cmd->infile) | |
1190 | { | |
1191 | fprintf (stderr, | |
1192 | _("Cannot specify more than one input file!\n")); | |
1193 | return 0; | |
1194 | } | |
1195 | cmd->infile = argv[i]; | |
28f540f4 | 1196 | } |
880f421f UD |
1197 | else |
1198 | { | |
1199 | for (j = 1; argv[i][j] != 0; j++) | |
1200 | { | |
1201 | c = argv[i][j]; | |
1202 | switch (c) | |
1203 | { | |
1204 | case 'a': | |
1205 | allfiles = 1; | |
1206 | break; | |
1207 | case 'c': | |
1208 | case 'h': | |
1209 | case 'l': | |
1210 | case 'm': | |
1211 | case 't': | |
1212 | if (flag[c]) | |
1213 | return 0; | |
1214 | flag[c] = 1; | |
1215 | break; | |
1216 | case 'S': | |
1217 | /* sample flag: Ss or Sc. | |
1218 | Ss means set flag['S']; | |
1219 | Sc means set flag['C']; | |
1220 | Sm means set flag['M']; */ | |
1221 | c = argv[i][++j]; /* get next char */ | |
1222 | if (c == 's') | |
1223 | c = 'S'; | |
1224 | else if (c == 'c') | |
1225 | c = 'C'; | |
1226 | else if (c == 'm') | |
1227 | c = 'M'; | |
1228 | else | |
1229 | return 0; | |
1230 | ||
1231 | if (flag[c]) | |
1232 | return 0; | |
1233 | flag[c] = 1; | |
1234 | break; | |
1235 | case 'C': /* ANSI C syntax */ | |
1236 | Cflag = 1; | |
1237 | break; | |
0d204b0a UD |
1238 | |
1239 | #ifdef __GNU_LIBRARY__ | |
880f421f UD |
1240 | case 'k': /* K&R C syntax */ |
1241 | Cflag = 0; | |
1242 | break; | |
0d204b0a UD |
1243 | |
1244 | #endif | |
880f421f UD |
1245 | case 'b': /* turn TIRPC flag off for |
1246 | generating backward compatible | |
1247 | */ | |
1248 | tirpcflag = 0; | |
1249 | break; | |
0d204b0a UD |
1250 | |
1251 | #ifdef __GNU_LIBRARY__ | |
880f421f UD |
1252 | case '5': /* turn TIRPC flag on for |
1253 | generating SysVr4 compatible | |
1254 | */ | |
1255 | tirpcflag = 1; | |
1256 | break; | |
0d204b0a | 1257 | #endif |
880f421f UD |
1258 | case 'I': |
1259 | inetdflag = 1; | |
1260 | break; | |
1261 | case 'N': | |
1262 | newstyle = 1; | |
1263 | break; | |
1264 | case 'L': | |
1265 | logflag = 1; | |
1266 | break; | |
1267 | case 'K': | |
1268 | if (++i == argc) | |
1269 | { | |
1270 | return (0); | |
1271 | } | |
1272 | svcclosetime = argv[i]; | |
1273 | goto nextarg; | |
1274 | case 'T': | |
1275 | tblflag = 1; | |
1276 | break; | |
1277 | case 'M': | |
1278 | mtflag = 1; | |
1279 | break; | |
1280 | case 'i': | |
1281 | if (++i == argc) | |
1282 | { | |
1283 | return (0); | |
1284 | } | |
1285 | inlineflag = atoi (argv[i]); | |
1286 | goto nextarg; | |
1287 | case 'n': | |
1288 | case 'o': | |
1289 | case 's': | |
1290 | if (argv[i][j - 1] != '-' || | |
1291 | argv[i][j + 1] != 0) | |
1292 | { | |
1293 | return (0); | |
1294 | } | |
1295 | flag[c] = 1; | |
1296 | if (++i == argc) | |
1297 | { | |
1298 | return (0); | |
1299 | } | |
1300 | if (c == 's') | |
1301 | { | |
1302 | if (!streq (argv[i], "udp") && | |
1303 | !streq (argv[i], "tcp")) | |
1304 | return 0; | |
1305 | } | |
1306 | else if (c == 'o') | |
1307 | { | |
1308 | if (cmd->outfile) | |
1309 | return 0; | |
1310 | cmd->outfile = argv[i]; | |
1311 | } | |
1312 | goto nextarg; | |
1313 | case 'D': | |
1314 | if (argv[i][j - 1] != '-') | |
1315 | return 0; | |
1316 | addarg (argv[i]); | |
1317 | goto nextarg; | |
1318 | case 'Y': | |
1319 | if (++i == argc) | |
1320 | return 0; | |
1321 | { | |
1322 | size_t len = strlen (argv[i]); | |
1323 | pathbuf = malloc (len + 5); | |
1324 | if (pathbuf == NULL) | |
1325 | { | |
1326 | perror (cmdname); | |
1327 | crash (); | |
1328 | } | |
1329 | stpcpy (stpcpy (pathbuf, | |
1330 | argv[i]), | |
1331 | "/cpp"); | |
1332 | CPP = pathbuf; | |
1333 | cppDefined = 1; | |
1334 | goto nextarg; | |
1335 | } | |
1336 | ||
1337 | default: | |
1338 | return 0; | |
28f540f4 | 1339 | } |
880f421f UD |
1340 | } |
1341 | nextarg: | |
1342 | ; | |
28f540f4 | 1343 | } |
880f421f | 1344 | } |
0d204b0a | 1345 | |
880f421f UD |
1346 | cmd->cflag = flag['c']; |
1347 | cmd->hflag = flag['h']; | |
1348 | cmd->lflag = flag['l']; | |
1349 | cmd->mflag = flag['m']; | |
1350 | cmd->nflag = flag['n']; | |
1351 | cmd->sflag = flag['s']; | |
1352 | cmd->tflag = flag['t']; | |
1353 | cmd->Ssflag = flag['S']; | |
1354 | cmd->Scflag = flag['C']; | |
1355 | cmd->makefileflag = flag['M']; | |
1356 | ||
1357 | if (tirpcflag) | |
1358 | { | |
1359 | pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is always TRUE */ | |
1360 | if ((inetdflag && cmd->nflag)) | |
1361 | { /* netid not allowed with inetdflag */ | |
1362 | fprintf (stderr, _("Cannot use netid flag with inetd flag!\n")); | |
1363 | return 0; | |
1364 | } | |
1365 | } | |
1366 | else | |
1367 | { /* 4.1 mode */ | |
1368 | pmflag = 0; /* set pmflag only in tirpcmode */ | |
0d204b0a | 1369 | #ifndef __GNU_LIBRARY__ |
880f421f | 1370 | inetdflag = 1; /* inetdflag is TRUE by default */ |
0d204b0a | 1371 | #endif |
880f421f UD |
1372 | if (cmd->nflag) |
1373 | { /* netid needs TIRPC */ | |
1374 | f_print (stderr, _("Cannot use netid flag without TIRPC!\n")); | |
1375 | return (0); | |
0d204b0a | 1376 | } |
880f421f | 1377 | } |
0d204b0a | 1378 | |
880f421f UD |
1379 | if (newstyle && (tblflag || cmd->tflag)) |
1380 | { | |
1381 | f_print (stderr, _("Cannot use table flags with newstyle!\n")); | |
1382 | return (0); | |
1383 | } | |
0d204b0a | 1384 | |
880f421f UD |
1385 | /* check no conflicts with file generation flags */ |
1386 | nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag + | |
1387 | cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag; | |
0d204b0a | 1388 | |
880f421f UD |
1389 | if (nflags == 0) |
1390 | { | |
1391 | if (cmd->outfile != NULL || cmd->infile == NULL) | |
1392 | { | |
1393 | return (0); | |
28f540f4 | 1394 | } |
880f421f UD |
1395 | } |
1396 | else if (cmd->infile == NULL && | |
1397 | (cmd->Ssflag || cmd->Scflag || cmd->makefileflag)) | |
1398 | { | |
1399 | fprintf (stderr, | |
1400 | _("\"infile\" is required for template generation flags.\n")); | |
1401 | return 0; | |
1402 | } | |
1403 | if (nflags > 1) | |
1404 | { | |
1405 | fprintf (stderr, _("Cannot have more than one file generation flag!\n")); | |
1406 | return 0; | |
1407 | } | |
1408 | return 1; | |
28f540f4 | 1409 | } |
0d204b0a UD |
1410 | |
1411 | static void | |
880f421f | 1412 | usage (void) |
0d204b0a | 1413 | { |
db276fa1 | 1414 | fprintf (stderr, _("usage: %s infile\n"), cmdname); |
880f421f UD |
1415 | fprintf (stderr, _("\t%s [-abkCLNTM][-Dname[=value]] [-i size] \ |
1416 | [-I [-K seconds]] [-Y path] infile\n"), cmdname); | |
1417 | fprintf (stderr, _("\t%s [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] \ | |
1418 | [-o outfile] [infile]\n"), cmdname); | |
1419 | fprintf (stderr, _("\t%s [-s nettype]* [-o outfile] [infile]\n"), cmdname); | |
1420 | fprintf (stderr, _("\t%s [-n netid]* [-o outfile] [infile]\n"), cmdname); | |
1421 | options_usage (); | |
1422 | exit (1); | |
0d204b0a UD |
1423 | } |
1424 | ||
1425 | static void | |
880f421f | 1426 | options_usage (void) |
0d204b0a | 1427 | { |
880f421f UD |
1428 | f_print (stderr, "options:\n"); |
1429 | f_print (stderr, "-a\t\tgenerate all files, including samples\n"); | |
1430 | f_print (stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n"); | |
1431 | f_print (stderr, "-c\t\tgenerate XDR routines\n"); | |
1432 | f_print (stderr, "-C\t\tANSI C mode\n"); | |
1433 | f_print (stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n"); | |
1434 | f_print (stderr, "-h\t\tgenerate header file\n"); | |
1435 | f_print (stderr, "-i size\t\tsize at which to start generating inline code\n"); | |
1436 | f_print (stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n"); | |
1437 | f_print (stderr, "-K seconds\tserver exits after K seconds of inactivity\n"); | |
1438 | f_print (stderr, "-l\t\tgenerate client side stubs\n"); | |
1439 | f_print (stderr, "-L\t\tserver errors will be printed to syslog\n"); | |
1440 | f_print (stderr, "-m\t\tgenerate server side stubs\n"); | |
1441 | f_print (stderr, "-M\t\tgenerate MT-safe code\n"); | |
1442 | f_print (stderr, "-n netid\tgenerate server code that supports named netid\n"); | |
1443 | f_print (stderr, "-N\t\tsupports multiple arguments and call-by-value\n"); | |
1444 | f_print (stderr, "-o outfile\tname of the output file\n"); | |
1445 | f_print (stderr, "-s nettype\tgenerate server code that supports named nettype\n"); | |
1446 | f_print (stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n"); | |
1447 | f_print (stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n"); | |
1448 | f_print (stderr, "-Sm \t\tgenerate makefile template \n"); | |
1449 | f_print (stderr, "-t\t\tgenerate RPC dispatch table\n"); | |
1450 | f_print (stderr, "-T\t\tgenerate code to support RPC dispatch tables\n"); | |
1451 | f_print (stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n"); | |
1452 | ||
1453 | exit (1); | |
0d204b0a | 1454 | } |