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