]>
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 | */ | |
34 | char main_rcsid[] = | |
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> | |
45 | #include <ctype.h> | |
46 | #include <sys/types.h> | |
47 | #include <sys/param.h> | |
28f540f4 | 48 | #include <sys/file.h> |
0d204b0a | 49 | #include <sys/stat.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 RM |
55 | |
56 | #define EXTEND 1 /* alias for TRUE */ | |
0d204b0a UD |
57 | #define DONT_EXTEND 0 /* alias for FALSE */ |
58 | ||
59 | #define SVR4_CPP "/usr/ccs/lib/cpp" | |
60 | #define SUNOS_CPP "/lib/cpp" | |
61 | static int cppDefined = 0; /* explicit path for C preprocessor */ | |
28f540f4 RM |
62 | |
63 | struct commandline { | |
0d204b0a UD |
64 | int cflag; /* xdr C routines */ |
65 | int hflag; /* header file */ | |
66 | int lflag; /* client side stubs */ | |
67 | int mflag; /* server side stubs */ | |
68 | int nflag; /* netid flag */ | |
69 | int sflag; /* server stubs for the given transport */ | |
70 | int tflag; /* dispatch Table file */ | |
71 | int Ssflag; /* produce server sample code */ | |
72 | int Scflag; /* produce client sample code */ | |
73 | const char *infile; /* input module name */ | |
74 | const char *outfile; /* output module name */ | |
28f540f4 RM |
75 | }; |
76 | ||
0d204b0a UD |
77 | |
78 | static const char *cmdname; | |
79 | ||
80 | static const char *svcclosetime = "120"; | |
81 | static const char *CPP = SVR4_CPP; | |
28f540f4 | 82 | static char CPPFLAGS[] = "-C"; |
9756dfe1 | 83 | static char *pathbuf; |
0d204b0a | 84 | static const char *allv[] = { |
28f540f4 RM |
85 | "rpcgen", "-s", "udp", "-s", "tcp", |
86 | }; | |
87 | static int allc = sizeof(allv)/sizeof(allv[0]); | |
0d204b0a UD |
88 | static const char *allnv[] = { |
89 | "rpcgen", "-s", "netpath", | |
90 | }; | |
91 | static int allnc = sizeof(allnv)/sizeof(allnv[0]); | |
92 | ||
93 | /* | |
94 | * machinations for handling expanding argument list | |
95 | */ | |
96 | static void addarg(const char *); /* add another argument to the list */ | |
97 | static void putarg(int, const char *); /* put argument at specified location */ | |
98 | static void clear_args(void); /* clear argument list */ | |
99 | static void checkfiles(const char *, const char *); | |
100 | /* check if out file already exists */ | |
101 | ||
102 | static void clear_args(void); | |
103 | static char *extendfile(const char *file, const char *ext); | |
104 | static void open_output(const char *infile, const char *outfile); | |
105 | static void add_warning(void); | |
106 | static void clear_args(void); | |
107 | static void find_cpp(void); | |
108 | static void open_input(const char *infile, const char *define); | |
109 | static int check_nettype(const char *name, const char *list_to_check[]); | |
110 | static void c_output(const char *infile, const char *define, | |
111 | int extend, const char *outfile); | |
112 | static void h_output(const char *infile, const char *define, | |
113 | int extend, const char *outfile); | |
114 | static void s_output(int argc, const char *argv[], const char *infile, | |
115 | const char *define, int extend, | |
116 | const char *outfile, int nomain, int netflag); | |
117 | static void l_output(const char *infile, const char *define, | |
118 | int extend, const char *outfile); | |
119 | static void t_output(const char *infile, const char *define, | |
120 | int extend, const char *outfile); | |
121 | static void svc_output(const char *infile, const char *define, | |
122 | int extend, const char *outfile); | |
123 | static void clnt_output(const char *infile, const char *define, | |
124 | int extend, const char *outfile); | |
125 | static int do_registers(int argc, const char *argv[]); | |
126 | static void addarg(const char *cp); | |
127 | static void putarg(int whereto, const char *cp); | |
128 | static void checkfiles(const char *infile, const char *outfile); | |
129 | static int parseargs(int argc, const char *argv[], struct commandline *cmd); | |
130 | static void usage(void); | |
131 | static void options_usage(void); | |
132 | static void c_initialize(void); | |
133 | static char *generate_guard(const char *pathname); | |
134 | ||
135 | ||
136 | #define ARGLISTLEN 20 | |
137 | #define FIXEDARGS 2 | |
138 | ||
139 | static const char *arglist[ARGLISTLEN]; | |
140 | static int argcount = FIXEDARGS; | |
141 | ||
142 | ||
143 | int nonfatalerrors; /* errors */ | |
144 | int inetdflag/* = 1*/; /* Support for inetd */ /* is now the default */ | |
145 | int pmflag; /* Support for port monitors */ | |
146 | int logflag; /* Use syslog instead of fprintf for errors */ | |
147 | int tblflag; /* Support for dispatch table file */ | |
28f540f4 | 148 | |
0d204b0a UD |
149 | #define INLINE 3 |
150 | /*length at which to start doing an inline */ | |
28f540f4 | 151 | |
0d204b0a UD |
152 | int inlineflag=INLINE; /* length at which to start doing an inline. 3 = default |
153 | if 0, no xdr_inline code */ | |
154 | ||
155 | int indefinitewait; /* If started by port monitors, hang till it wants */ | |
156 | int exitnow; /* If started by port monitors, exit after the call */ | |
157 | int timerflag; /* TRUE if !indefinite && !exitnow */ | |
158 | int newstyle; /* newstyle of passing arguments (by value) */ | |
159 | #ifdef __GNU_LIBRARY__ | |
160 | int Cflag = 1 ; /* ANSI C syntax */ | |
161 | #else | |
162 | int Cflag = 0 ; /* ANSI C syntax */ | |
163 | #endif | |
164 | static int allfiles; /* generate all files */ | |
165 | #ifdef __GNU_LIBRARY__ | |
166 | int tirpcflag = 0; /* generating code for tirpc, by default */ | |
167 | #else | |
168 | int tirpcflag = 1; /* generating code for tirpc, by default */ | |
169 | #endif | |
170 | ||
9756dfe1 UD |
171 | #ifdef __GNU_LIBRARY__ |
172 | int building_libc = 0; /* running as part of libc built process */ | |
173 | #endif | |
174 | ||
0d204b0a UD |
175 | int |
176 | main(int argc, const char *argv[]) | |
28f540f4 RM |
177 | { |
178 | struct commandline cmd; | |
179 | ||
0d204b0a UD |
180 | (void) memset((char *)&cmd, 0, sizeof (struct commandline)); |
181 | clear_args(); | |
182 | if (!parseargs(argc, argv, &cmd)) | |
183 | usage(); | |
c475b8f5 | 184 | |
0d204b0a UD |
185 | if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag || |
186 | cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag ) { | |
187 | checkfiles(cmd.infile, cmd.outfile); | |
28f540f4 | 188 | } |
0d204b0a UD |
189 | else |
190 | checkfiles(cmd.infile,NULL); | |
191 | ||
28f540f4 | 192 | if (cmd.cflag) { |
0d204b0a | 193 | c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile); |
28f540f4 | 194 | } else if (cmd.hflag) { |
0d204b0a | 195 | h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile); |
28f540f4 | 196 | } else if (cmd.lflag) { |
0d204b0a UD |
197 | l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile); |
198 | } else if (cmd.sflag || cmd.mflag || (cmd.nflag)) { | |
199 | s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND, | |
200 | cmd.outfile, cmd.mflag, cmd.nflag); | |
201 | } else if (cmd.tflag) { | |
202 | t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile); | |
203 | } else if (cmd.Ssflag) { | |
204 | svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile); | |
205 | } else if (cmd.Scflag) { | |
206 | clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile); | |
28f540f4 | 207 | } else { |
0d204b0a | 208 | /* the rescans are required, since cpp may effect input */ |
28f540f4 RM |
209 | c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); |
210 | reinitialize(); | |
211 | h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h"); | |
212 | reinitialize(); | |
213 | l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); | |
214 | reinitialize(); | |
0d204b0a UD |
215 | if (inetdflag || !tirpcflag ) |
216 | s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, | |
217 | "_svc.c", cmd.mflag, cmd.nflag); | |
218 | else | |
219 | s_output(allnc, allnv, cmd.infile, "-DRPC_SVC", | |
220 | EXTEND, "_svc.c", cmd.mflag, cmd.nflag); | |
221 | if (tblflag) { | |
222 | reinitialize(); | |
223 | t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i"); | |
224 | } | |
225 | if (allfiles) { | |
226 | reinitialize(); | |
227 | svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c"); | |
228 | } | |
229 | if (allfiles) { | |
230 | reinitialize(); | |
231 | clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c"); | |
232 | } | |
28f540f4 | 233 | } |
0d204b0a UD |
234 | exit(nonfatalerrors); |
235 | /* NOTREACHED */ | |
28f540f4 RM |
236 | } |
237 | ||
238 | /* | |
cbd3dceb | 239 | * add extension to filename |
28f540f4 RM |
240 | */ |
241 | static char * | |
0d204b0a | 242 | extendfile(const char *file, const char *ext) |
28f540f4 RM |
243 | { |
244 | char *res; | |
0d204b0a | 245 | const char *p; |
28f540f4 RM |
246 | |
247 | res = alloc(strlen(file) + strlen(ext) + 1); | |
248 | if (res == NULL) { | |
249 | abort(); | |
250 | } | |
0d204b0a | 251 | p = strrchr(file, '.'); |
28f540f4 RM |
252 | if (p == NULL) { |
253 | p = file + strlen(file); | |
254 | } | |
255 | (void) strcpy(res, file); | |
256 | (void) strcpy(res + (p - file), ext); | |
257 | return (res); | |
258 | } | |
259 | ||
260 | /* | |
cbd3dceb | 261 | * Open output file with given extension |
28f540f4 | 262 | */ |
0d204b0a UD |
263 | static void |
264 | open_output(const char *infile, const char *outfile) | |
28f540f4 | 265 | { |
0d204b0a | 266 | |
28f540f4 RM |
267 | if (outfile == NULL) { |
268 | fout = stdout; | |
269 | return; | |
270 | } | |
0d204b0a | 271 | |
28f540f4 | 272 | if (infile != NULL && streq(outfile, infile)) { |
0d204b0a | 273 | f_print(stderr, "%s: output would overwrite %s\n", cmdname, |
28f540f4 RM |
274 | infile); |
275 | crash(); | |
276 | } | |
277 | fout = fopen(outfile, "w"); | |
278 | if (fout == NULL) { | |
0d204b0a | 279 | f_print(stderr, "%s: unable to open ", cmdname); |
28f540f4 RM |
280 | perror(outfile); |
281 | crash(); | |
282 | } | |
283 | record_open(outfile); | |
284 | } | |
285 | ||
0d204b0a UD |
286 | static void |
287 | add_warning(void) | |
288 | { | |
289 | f_print(fout, "/*\n"); | |
290 | f_print(fout, " * Please do not edit this file.\n"); | |
291 | f_print(fout, " * It was generated using rpcgen.\n"); | |
292 | f_print(fout, " */\n\n"); | |
293 | } | |
294 | ||
295 | static void | |
296 | add_stdheaders(void) | |
297 | { | |
298 | f_print(fout, "#include <rpc/types.h>\n"); | |
299 | f_print(fout, "#include <rpc/xdr.h>\n\n"); | |
300 | } | |
301 | ||
302 | /* clear list of arguments */ | |
303 | static void clear_args(void) | |
304 | { | |
305 | int i; | |
306 | for( i=FIXEDARGS; i<ARGLISTLEN; i++ ) | |
307 | arglist[i] = NULL; | |
308 | argcount = FIXEDARGS; | |
309 | } | |
310 | ||
311 | /* make sure that a CPP exists */ | |
312 | static void find_cpp(void) | |
313 | { | |
314 | struct stat buf; | |
315 | ||
316 | if (stat(CPP, &buf) < 0 ) { /* SVR4 or explicit cpp does not exist */ | |
317 | if (cppDefined) { | |
318 | fprintf( stderr, "cannot find C preprocessor: %s \n", CPP ); | |
319 | crash(); | |
320 | } else { /* try the other one */ | |
321 | CPP = SUNOS_CPP; | |
322 | if( stat( CPP, &buf ) < 0 ) { /* can't find any cpp */ | |
323 | fprintf( stderr, "cannot find any C preprocessor (cpp)\n" ); | |
324 | crash(); | |
325 | } | |
326 | } | |
327 | } | |
328 | } | |
329 | ||
28f540f4 | 330 | /* |
cbd3dceb | 331 | * Open input file with given define for C-preprocessor |
28f540f4 | 332 | */ |
0d204b0a UD |
333 | static void |
334 | open_input(const char *infile, const char *define) | |
28f540f4 RM |
335 | { |
336 | int pd[2]; | |
337 | ||
338 | infilename = (infile == NULL) ? "<stdin>" : infile; | |
339 | (void) pipe(pd); | |
340 | switch (fork()) { | |
341 | case 0: | |
9756dfe1 UD |
342 | #ifdef __GNU_LIBRARY__ |
343 | /* While building libc we don't want to use the libc from | |
344 | the build directory which may be incompatible with the | |
345 | installed dynamic linker. */ | |
346 | if (building_libc) | |
347 | unsetenv ("LD_LIBRARY_PATH"); | |
348 | #endif | |
0d204b0a UD |
349 | find_cpp(); |
350 | putarg(0, CPP); | |
351 | putarg(1, CPPFLAGS); | |
352 | addarg(define); | |
353 | addarg(infile); | |
354 | addarg((char *)NULL); | |
28f540f4 RM |
355 | (void) close(1); |
356 | (void) dup2(pd[1], 1); | |
357 | (void) close(pd[0]); | |
0d204b0a UD |
358 | execv(arglist[0], (char **)arglist); |
359 | perror("execv"); | |
28f540f4 RM |
360 | exit(1); |
361 | case -1: | |
362 | perror("fork"); | |
363 | exit(1); | |
364 | } | |
365 | (void) close(pd[1]); | |
366 | fin = fdopen(pd[0], "r"); | |
367 | if (fin == NULL) { | |
368 | f_print(stderr, "%s: ", cmdname); | |
369 | perror(infilename); | |
370 | crash(); | |
371 | } | |
372 | } | |
373 | ||
0d204b0a UD |
374 | /* valid tirpc nettypes */ |
375 | static const char *valid_ti_nettypes[] = | |
376 | { | |
377 | "netpath", | |
378 | "visible", | |
379 | "circuit_v", | |
380 | "datagram_v", | |
381 | "circuit_n", | |
382 | "datagram_n", | |
383 | "udp", | |
384 | "tcp", | |
385 | "raw", | |
386 | NULL | |
387 | }; | |
388 | ||
389 | /* valid inetd nettypes */ | |
390 | static const char *valid_i_nettypes[] = | |
391 | { | |
392 | "udp", | |
393 | "tcp", | |
394 | NULL | |
395 | }; | |
396 | ||
397 | static int check_nettype(const char *name, const char *list_to_check[]) { | |
398 | int i; | |
399 | for( i = 0; list_to_check[i] != NULL; i++ ) { | |
400 | if( strcmp( name, list_to_check[i] ) == 0 ) { | |
401 | return 1; | |
402 | } | |
403 | } | |
404 | f_print( stderr, "illegal nettype :\'%s\'\n", name ); | |
405 | return 0; | |
406 | } | |
407 | ||
28f540f4 RM |
408 | /* |
409 | * Compile into an XDR routine output file | |
410 | */ | |
0d204b0a UD |
411 | |
412 | static void | |
413 | c_output(const char *infile, const char *define, int extend, | |
414 | const char *outfile) | |
28f540f4 RM |
415 | { |
416 | definition *def; | |
417 | char *include; | |
0d204b0a | 418 | const char *outfilename; |
28f540f4 RM |
419 | long tell; |
420 | ||
0d204b0a | 421 | c_initialize(); |
cbd3dceb | 422 | open_input(infile, define); |
28f540f4 RM |
423 | outfilename = extend ? extendfile(infile, outfile) : outfile; |
424 | open_output(infile, outfilename); | |
0d204b0a UD |
425 | add_warning(); |
426 | add_stdheaders(); | |
28f540f4 RM |
427 | if (infile && (include = extendfile(infile, ".h"))) { |
428 | f_print(fout, "#include \"%s\"\n", include); | |
429 | free(include); | |
0d204b0a UD |
430 | /* .h file already contains rpc/rpc.h */ |
431 | } else | |
432 | f_print(fout, "#include <rpc/rpc.h>\n"); | |
28f540f4 | 433 | tell = ftell(fout); |
0d204b0a | 434 | while ((def = get_definition())!=NULL) { |
28f540f4 RM |
435 | emit(def); |
436 | } | |
437 | if (extend && tell == ftell(fout)) { | |
438 | (void) unlink(outfilename); | |
439 | } | |
440 | } | |
441 | ||
0d204b0a UD |
442 | void |
443 | c_initialize(void) | |
444 | { | |
445 | ||
446 | /* add all the starting basic types */ | |
447 | ||
448 | add_type(1,"int"); | |
449 | add_type(1,"long"); | |
450 | add_type(1,"short"); | |
451 | add_type(1,"bool"); | |
452 | ||
453 | add_type(1,"u_int"); | |
454 | add_type(1,"u_long"); | |
455 | add_type(1,"u_short"); | |
456 | ||
457 | } | |
458 | ||
459 | char rpcgen_table_dcl[] = "struct rpcgen_table {\n\ | |
460 | char *(*proc)();\n\ | |
461 | xdrproc_t xdr_arg;\n\ | |
462 | unsigned len_arg;\n\ | |
463 | xdrproc_t xdr_res;\n\ | |
464 | unsigned len_res;\n\ | |
465 | };\n"; | |
466 | ||
467 | ||
468 | static char *generate_guard(const char *pathname) { | |
469 | const char *filename; | |
470 | char *guard, *tmp; | |
471 | ||
472 | filename = strrchr(pathname, '/' ); /* find last component */ | |
473 | filename = ((filename == NULL) ? pathname : filename+1); | |
474 | guard = strdup(filename); | |
475 | /* convert to upper case */ | |
476 | tmp = guard; | |
477 | while (*tmp) { | |
478 | if (islower(*tmp)) | |
479 | *tmp = toupper(*tmp); | |
480 | tmp++; | |
481 | } | |
482 | ||
483 | guard = extendfile(guard, "_H_RPCGEN"); | |
484 | return guard; | |
485 | } | |
486 | ||
28f540f4 RM |
487 | /* |
488 | * Compile into an XDR header file | |
489 | */ | |
0d204b0a UD |
490 | |
491 | ||
492 | static void | |
493 | h_output(const char *infile, const char *define, int extend, | |
494 | const char *outfile) | |
28f540f4 RM |
495 | { |
496 | definition *def; | |
0d204b0a UD |
497 | const char *ifilename; |
498 | const char *outfilename; | |
28f540f4 | 499 | long tell; |
0d204b0a UD |
500 | char *guard; |
501 | list *l; | |
28f540f4 RM |
502 | |
503 | open_input(infile, define); | |
504 | outfilename = extend ? extendfile(infile, outfile) : outfile; | |
505 | open_output(infile, outfilename); | |
0d204b0a UD |
506 | add_warning(); |
507 | ifilename = (infile == NULL) ? "STDIN" : infile; | |
508 | guard = generate_guard( outfilename ? outfilename: ifilename ); | |
509 | ||
510 | f_print(fout,"#ifndef _%s\n#define _%s\n\n", guard, | |
511 | guard); | |
512 | ||
513 | f_print(fout, "#include <rpc/rpc.h>\n\n"); | |
514 | ||
28f540f4 | 515 | tell = ftell(fout); |
0d204b0a UD |
516 | /* print data definitions */ |
517 | while ((def = get_definition())!=NULL) { | |
28f540f4 RM |
518 | print_datadef(def); |
519 | } | |
0d204b0a UD |
520 | |
521 | /* print function declarations. | |
522 | Do this after data definitions because they might be used as | |
523 | arguments for functions */ | |
524 | for (l = defined; l != NULL; l = l->next) { | |
525 | print_funcdef(l->val); | |
526 | } | |
28f540f4 RM |
527 | if (extend && tell == ftell(fout)) { |
528 | (void) unlink(outfilename); | |
0d204b0a UD |
529 | } else if (tblflag) { |
530 | f_print(fout, rpcgen_table_dcl); | |
28f540f4 | 531 | } |
0d204b0a | 532 | f_print(fout, "\n#endif /* !_%s */\n", guard); |
28f540f4 RM |
533 | } |
534 | ||
535 | /* | |
536 | * Compile into an RPC service | |
537 | */ | |
0d204b0a UD |
538 | static void |
539 | s_output(int argc, const char *argv[], const char *infile, const char *define, | |
540 | int extend, const char *outfile, int nomain, int netflag) | |
28f540f4 RM |
541 | { |
542 | char *include; | |
543 | definition *def; | |
0d204b0a UD |
544 | int foundprogram = 0; |
545 | const char *outfilename; | |
28f540f4 RM |
546 | |
547 | open_input(infile, define); | |
548 | outfilename = extend ? extendfile(infile, outfile) : outfile; | |
549 | open_output(infile, outfilename); | |
0d204b0a | 550 | add_warning(); |
28f540f4 RM |
551 | if (infile && (include = extendfile(infile, ".h"))) { |
552 | f_print(fout, "#include \"%s\"\n", include); | |
553 | free(include); | |
0d204b0a UD |
554 | } else |
555 | f_print(fout, "#include <rpc/rpc.h>\n"); | |
556 | ||
557 | f_print(fout, "#include <stdio.h>\n"); | |
558 | f_print(fout, "#include <stdlib.h>/* getenv, exit */\n"); | |
559 | if (Cflag) { | |
560 | f_print (fout, "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n"); | |
561 | f_print (fout, "#include <string.h> /* strcmp */ \n"); | |
562 | } | |
563 | if (strcmp(svcclosetime, "-1") == 0) | |
564 | indefinitewait = 1; | |
565 | else if (strcmp(svcclosetime, "0") == 0) | |
566 | exitnow = 1; | |
567 | else if (inetdflag || pmflag) { | |
568 | f_print(fout, "#include <signal.h>\n"); | |
569 | timerflag = 1; | |
570 | } | |
571 | ||
572 | if( !tirpcflag && inetdflag ) | |
573 | #ifdef __GNU_LIBRARY__ | |
574 | f_print(fout, "#include <sys/ioctl.h> /* ioctl, TIOCNOTTY */\n"); | |
575 | #else | |
576 | f_print(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n"); | |
577 | #endif | |
578 | if( Cflag && (inetdflag || pmflag ) ) { | |
579 | #ifdef __GNU_LIBRARY__ | |
580 | f_print(fout, "#include <sys/types.h> /* open */\n"); | |
581 | f_print(fout, "#include <sys/stat.h> /* open */\n"); | |
582 | f_print(fout, "#include <fcntl.h> /* open */\n"); | |
583 | f_print(fout, "#include <unistd.h> /* getdtablesize */\n"); | |
584 | #else | |
585 | f_print(fout, "#ifdef __cplusplus\n"); | |
586 | f_print(fout, "#include <sysent.h> /* getdtablesize, open */\n"); | |
587 | f_print(fout, "#endif /* __cplusplus */\n"); | |
588 | #endif | |
589 | if( tirpcflag ) | |
590 | f_print(fout, "#include <unistd.h> /* setsid */\n"); | |
591 | } | |
592 | if( tirpcflag ) | |
593 | f_print(fout, "#include <sys/types.h>\n"); | |
594 | ||
595 | f_print(fout, "#include <memory.h>\n"); | |
596 | #ifndef __GNU_LIBRARY__ | |
597 | f_print(fout, "#include <stropts.h>\n"); | |
598 | #endif | |
599 | if (inetdflag || !tirpcflag ) { | |
600 | f_print(fout, "#include <sys/socket.h>\n"); | |
601 | f_print(fout, "#include <netinet/in.h>\n"); | |
602 | } | |
603 | ||
604 | if ( (netflag || pmflag) && tirpcflag ) { | |
605 | f_print(fout, "#include <netconfig.h>\n"); | |
606 | } | |
607 | if (/*timerflag &&*/ tirpcflag) | |
608 | f_print(fout, "#include <sys/resource.h> /* rlimit */\n"); | |
609 | if (logflag || inetdflag || pmflag) { | |
610 | #ifdef __GNU_LIBRARY__ | |
611 | f_print(fout, "#include <syslog.h>\n"); | |
612 | #else | |
613 | f_print(fout, "#ifdef SYSLOG\n"); | |
614 | f_print(fout, "#include <syslog.h>\n"); | |
615 | f_print(fout, "#else\n"); | |
616 | f_print(fout, "#define LOG_ERR 1\n"); | |
617 | f_print(fout, "#define openlog(a, b, c)\n"); | |
618 | f_print(fout, "#endif\n"); | |
619 | #endif | |
28f540f4 | 620 | } |
0d204b0a UD |
621 | |
622 | /* for ANSI-C */ | |
623 | f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n"); | |
624 | ||
625 | #ifndef __GNU_LIBRARY__ | |
626 | f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n"); | |
627 | #endif | |
628 | if (timerflag) | |
629 | f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime); | |
630 | while ((def = get_definition())!=NULL) { | |
28f540f4 RM |
631 | foundprogram |= (def->def_kind == DEF_PROGRAM); |
632 | } | |
633 | if (extend && !foundprogram) { | |
634 | (void) unlink(outfilename); | |
635 | return; | |
636 | } | |
0d204b0a UD |
637 | write_most(infile, netflag, nomain); |
638 | if (!nomain) { | |
639 | if( !do_registers(argc, argv) ) { | |
640 | if (outfilename) | |
641 | (void) unlink(outfilename); | |
642 | usage(); | |
643 | } | |
28f540f4 | 644 | write_rest(); |
28f540f4 RM |
645 | } |
646 | } | |
647 | ||
0d204b0a UD |
648 | /* |
649 | * generate client side stubs | |
650 | */ | |
651 | static void | |
652 | l_output(const char *infile, const char *define, int extend, | |
653 | const char *outfile) | |
28f540f4 RM |
654 | { |
655 | char *include; | |
656 | definition *def; | |
0d204b0a UD |
657 | int foundprogram = 0; |
658 | const char *outfilename; | |
28f540f4 RM |
659 | |
660 | open_input(infile, define); | |
661 | outfilename = extend ? extendfile(infile, outfile) : outfile; | |
662 | open_output(infile, outfilename); | |
0d204b0a UD |
663 | add_warning(); |
664 | if (Cflag) | |
665 | f_print (fout, "#include <memory.h> /* for memset */\n"); | |
28f540f4 RM |
666 | if (infile && (include = extendfile(infile, ".h"))) { |
667 | f_print(fout, "#include \"%s\"\n", include); | |
668 | free(include); | |
0d204b0a UD |
669 | } else |
670 | f_print(fout, "#include <rpc/rpc.h>\n"); | |
671 | while ((def = get_definition())!=NULL) { | |
28f540f4 RM |
672 | foundprogram |= (def->def_kind == DEF_PROGRAM); |
673 | } | |
674 | if (extend && !foundprogram) { | |
675 | (void) unlink(outfilename); | |
676 | return; | |
677 | } | |
678 | write_stubs(); | |
679 | } | |
680 | ||
681 | /* | |
0d204b0a | 682 | * generate the dispatch table |
28f540f4 | 683 | */ |
0d204b0a UD |
684 | static void |
685 | t_output(const char *infile, const char *define, int extend, | |
686 | const char *outfile) | |
687 | { | |
688 | definition *def; | |
689 | int foundprogram = 0; | |
690 | const char *outfilename; | |
691 | ||
692 | open_input(infile, define); | |
693 | outfilename = extend ? extendfile(infile, outfile) : outfile; | |
694 | open_output(infile, outfilename); | |
695 | add_warning(); | |
696 | while ((def = get_definition())!=NULL) { | |
697 | foundprogram |= (def->def_kind == DEF_PROGRAM); | |
698 | } | |
699 | if (extend && !foundprogram) { | |
700 | (void) unlink(outfilename); | |
701 | return; | |
702 | } | |
703 | write_tables(); | |
704 | } | |
705 | ||
706 | /* sample routine for the server template */ | |
707 | static void | |
708 | svc_output(const char *infile, const char *define, int extend, | |
709 | const char *outfile) | |
710 | { | |
711 | definition *def; | |
712 | char *include; | |
713 | const char *outfilename; | |
714 | long tell; | |
715 | ||
716 | open_input(infile, define); | |
717 | outfilename = extend ? extendfile(infile, outfile) : outfile; | |
718 | checkfiles(infile,outfilename); /*check if outfile already exists. | |
719 | if so, print an error message and exit*/ | |
720 | open_output(infile, outfilename); | |
721 | add_sample_msg(); | |
722 | ||
723 | if (infile && (include = extendfile(infile, ".h"))) { | |
724 | f_print(fout, "#include \"%s\"\n", include); | |
725 | free(include); | |
726 | } else | |
727 | f_print(fout, "#include <rpc/rpc.h>\n"); | |
728 | ||
729 | tell = ftell(fout); | |
730 | while ((def = get_definition())!=NULL) { | |
731 | write_sample_svc(def); | |
732 | } | |
733 | if (extend && tell == ftell(fout)) { | |
734 | (void) unlink(outfilename); | |
735 | } | |
736 | } | |
737 | ||
738 | ||
739 | /* sample main routine for client */ | |
740 | static void | |
741 | clnt_output(const char *infile, const char *define, int extend, | |
742 | const char *outfile) | |
743 | { | |
744 | definition *def; | |
745 | char *include; | |
746 | const char *outfilename; | |
747 | long tell; | |
748 | int has_program = 0; | |
28f540f4 | 749 | |
0d204b0a UD |
750 | open_input(infile, define); |
751 | outfilename = extend ? extendfile(infile, outfile) : outfile; | |
752 | checkfiles(infile,outfilename); /*check if outfile already exists. | |
753 | if so, print an error message and exit*/ | |
754 | ||
755 | open_output(infile, outfilename); | |
756 | add_sample_msg(); | |
757 | if (infile && (include = extendfile(infile, ".h"))) { | |
758 | f_print(fout, "#include \"%s\"\n", include); | |
759 | free(include); | |
760 | } else | |
761 | f_print(fout, "#include <rpc/rpc.h>\n"); | |
762 | tell = ftell(fout); | |
763 | while ((def = get_definition())!=NULL) { | |
764 | has_program += write_sample_clnt(def); | |
765 | } | |
766 | ||
767 | if( has_program ) | |
768 | write_sample_clnt_main(); | |
769 | ||
770 | if (extend && tell == ftell(fout)) { | |
771 | (void) unlink(outfilename); | |
772 | } | |
773 | } | |
774 | ||
775 | /* | |
776 | * Perform registrations for service output | |
777 | * Return 0 if failed; 1 otherwise. | |
778 | */ | |
779 | static int do_registers(int argc, const char *argv[]) | |
28f540f4 RM |
780 | { |
781 | int i; | |
782 | ||
0d204b0a UD |
783 | if ( inetdflag || !tirpcflag) { |
784 | for (i = 1; i < argc; i++) { | |
785 | if (streq(argv[i], "-s")) { | |
786 | if(!check_nettype( argv[i + 1], valid_i_nettypes )) | |
787 | return 0; | |
788 | write_inetd_register(argv[i + 1]); | |
789 | i++; | |
790 | } | |
28f540f4 | 791 | } |
0d204b0a UD |
792 | } else { |
793 | for (i = 1; i < argc; i++) | |
794 | if (streq(argv[i], "-s")) { | |
795 | if(!check_nettype( argv[i + 1], valid_ti_nettypes )) | |
796 | return 0; | |
797 | write_nettype_register(argv[i + 1]); | |
798 | i++; | |
799 | } else if (streq(argv[i], "-n")) { | |
800 | write_netid_register(argv[i + 1]); | |
801 | i++; | |
802 | } | |
28f540f4 | 803 | } |
0d204b0a | 804 | return 1; |
28f540f4 RM |
805 | } |
806 | ||
807 | /* | |
0d204b0a | 808 | * Add another argument to the arg list |
28f540f4 | 809 | */ |
0d204b0a UD |
810 | static void |
811 | addarg(const char *cp) | |
812 | { | |
813 | if (argcount >= ARGLISTLEN) { | |
814 | f_print(stderr, "rpcgen: too many defines\n"); | |
815 | crash(); | |
816 | /*NOTREACHED*/ | |
817 | } | |
818 | arglist[argcount++] = cp; | |
819 | ||
820 | } | |
821 | ||
822 | static void | |
823 | putarg(int whereto, const char *cp) | |
824 | { | |
825 | if (whereto >= ARGLISTLEN) { | |
826 | f_print(stderr, "rpcgen: arglist coding error\n"); | |
827 | crash(); | |
828 | /*NOTREACHED*/ | |
829 | } | |
830 | arglist[whereto] = cp; | |
831 | } | |
28f540f4 | 832 | |
0d204b0a UD |
833 | /* |
834 | * if input file is stdin and an output file is specified then complain | |
835 | * if the file already exists. Otherwise the file may get overwritten | |
836 | * If input file does not exist, exit with an error | |
837 | */ | |
838 | ||
839 | static void | |
840 | checkfiles(const char *infile, const char *outfile) | |
841 | { | |
842 | ||
843 | struct stat buf; | |
844 | ||
845 | if(infile) /* infile ! = NULL */ | |
846 | if(stat(infile,&buf) < 0) | |
847 | { | |
848 | perror(infile); | |
849 | crash(); | |
850 | }; | |
851 | if (outfile) { | |
852 | if (stat(outfile, &buf) < 0) | |
853 | return; /* file does not exist */ | |
854 | else { | |
855 | f_print(stderr, | |
856 | "file '%s' already exists and may be overwritten\n", outfile); | |
857 | crash(); | |
858 | } | |
859 | } | |
860 | } | |
861 | ||
862 | /* | |
863 | * Parse command line arguments | |
864 | */ | |
865 | static int | |
866 | parseargs(int argc, const char *argv[], struct commandline *cmd) | |
28f540f4 RM |
867 | { |
868 | int i; | |
869 | int j; | |
0d204b0a | 870 | int c; |
28f540f4 RM |
871 | char flag[(1 << 8 * sizeof(char))]; |
872 | int nflags; | |
873 | ||
874 | cmdname = argv[0]; | |
875 | cmd->infile = cmd->outfile = NULL; | |
876 | if (argc < 2) { | |
877 | return (0); | |
878 | } | |
0d204b0a | 879 | allfiles = 0; |
28f540f4 RM |
880 | flag['c'] = 0; |
881 | flag['h'] = 0; | |
28f540f4 RM |
882 | flag['l'] = 0; |
883 | flag['m'] = 0; | |
0d204b0a UD |
884 | flag['o'] = 0; |
885 | flag['s'] = 0; | |
886 | flag['n'] = 0; | |
887 | flag['t'] = 0; | |
888 | flag['S'] = 0; | |
889 | flag['C'] = 0; | |
28f540f4 RM |
890 | for (i = 1; i < argc; i++) { |
891 | if (argv[i][0] != '-') { | |
892 | if (cmd->infile) { | |
0d204b0a UD |
893 | f_print( stderr, "Cannot specify more than one input file!\n"); |
894 | ||
28f540f4 RM |
895 | return (0); |
896 | } | |
897 | cmd->infile = argv[i]; | |
898 | } else { | |
899 | for (j = 1; argv[i][j] != 0; j++) { | |
900 | c = argv[i][j]; | |
901 | switch (c) { | |
0d204b0a UD |
902 | case 'a': |
903 | allfiles = 1; | |
904 | break; | |
28f540f4 RM |
905 | case 'c': |
906 | case 'h': | |
907 | case 'l': | |
908 | case 'm': | |
0d204b0a | 909 | case 't': |
28f540f4 RM |
910 | if (flag[c]) { |
911 | return (0); | |
912 | } | |
913 | flag[c] = 1; | |
914 | break; | |
0d204b0a UD |
915 | case 'S': |
916 | /* sample flag: Ss or Sc. | |
917 | Ss means set flag['S']; | |
918 | Sc means set flag['C']; */ | |
919 | c = argv[i][++j]; /* get next char */ | |
920 | if( c == 's' ) | |
921 | c = 'S'; | |
922 | else if( c == 'c' ) | |
923 | c = 'C'; | |
924 | else | |
925 | return( 0 ); | |
926 | ||
927 | if (flag[c]) { | |
928 | return (0); | |
929 | } | |
930 | flag[c] = 1; | |
931 | break; | |
932 | case 'C': /* ANSI C syntax */ | |
933 | Cflag = 1; | |
934 | break; | |
935 | ||
936 | #ifdef __GNU_LIBRARY__ | |
937 | case 'k': /* K&R C syntax */ | |
938 | Cflag = 0; | |
939 | break; | |
940 | ||
941 | #endif | |
942 | case 'b': /* turn TIRPC flag off for | |
943 | generating backward compatible | |
944 | */ | |
945 | tirpcflag = 0; | |
946 | break; | |
947 | ||
948 | #ifdef __GNU_LIBRARY__ | |
949 | case '5': /* turn TIRPC flag on for | |
950 | generating SysVr4 compatible | |
951 | */ | |
952 | tirpcflag = 1; | |
953 | break; | |
9756dfe1 UD |
954 | case '$': |
955 | building_libc = 1; | |
956 | break; | |
0d204b0a UD |
957 | #endif |
958 | case 'I': | |
959 | inetdflag = 1; | |
960 | break; | |
961 | case 'N': | |
962 | newstyle = 1; | |
963 | break; | |
964 | case 'L': | |
965 | logflag = 1; | |
966 | break; | |
967 | case 'K': | |
968 | if (++i == argc) { | |
969 | return (0); | |
970 | } | |
971 | svcclosetime = argv[i]; | |
972 | goto nextarg; | |
973 | case 'T': | |
974 | tblflag = 1; | |
975 | break; | |
976 | case 'i' : | |
977 | if (++i == argc) { | |
978 | return (0); | |
979 | } | |
980 | inlineflag = atoi(argv[i]); | |
981 | goto nextarg; | |
982 | case 'n': | |
28f540f4 RM |
983 | case 'o': |
984 | case 's': | |
cbd3dceb | 985 | if (argv[i][j - 1] != '-' || |
28f540f4 RM |
986 | argv[i][j + 1] != 0) { |
987 | return (0); | |
988 | } | |
989 | flag[c] = 1; | |
990 | if (++i == argc) { | |
991 | return (0); | |
992 | } | |
993 | if (c == 's') { | |
994 | if (!streq(argv[i], "udp") && | |
995 | !streq(argv[i], "tcp")) { | |
996 | return (0); | |
997 | } | |
998 | } else if (c == 'o') { | |
999 | if (cmd->outfile) { | |
1000 | return (0); | |
1001 | } | |
1002 | cmd->outfile = argv[i]; | |
1003 | } | |
1004 | goto nextarg; | |
0d204b0a UD |
1005 | case 'D': |
1006 | if (argv[i][j - 1] != '-') { | |
1007 | return (0); | |
1008 | } | |
1009 | (void) addarg(argv[i]); | |
1010 | goto nextarg; | |
1011 | case 'Y': | |
1012 | if (++i == argc) { | |
1013 | return (0); | |
1014 | } | |
9756dfe1 UD |
1015 | { |
1016 | size_t len = strlen (argv[i]); | |
1017 | pathbuf = malloc (len + 5); | |
1018 | if (pathbuf == NULL) { | |
74015205 | 1019 | perror(cmdname); |
9756dfe1 UD |
1020 | crash(); |
1021 | } | |
1022 | stpcpy (stpcpy (pathbuf, | |
1023 | argv[i]), | |
1024 | "/cpp"); | |
1025 | CPP = pathbuf; | |
1026 | cppDefined = 1; | |
1027 | goto nextarg; | |
1028 | } | |
0d204b0a | 1029 | |
28f540f4 RM |
1030 | |
1031 | default: | |
1032 | return (0); | |
1033 | } | |
1034 | } | |
1035 | nextarg: | |
1036 | ; | |
1037 | } | |
1038 | } | |
0d204b0a | 1039 | |
28f540f4 RM |
1040 | cmd->cflag = flag['c']; |
1041 | cmd->hflag = flag['h']; | |
28f540f4 RM |
1042 | cmd->lflag = flag['l']; |
1043 | cmd->mflag = flag['m']; | |
0d204b0a UD |
1044 | cmd->nflag = flag['n']; |
1045 | cmd->sflag = flag['s']; | |
1046 | cmd->tflag = flag['t']; | |
1047 | cmd->Ssflag = flag['S']; | |
1048 | cmd->Scflag = flag['C']; | |
1049 | ||
1050 | if( tirpcflag ) { | |
1051 | pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is always TRUE */ | |
1052 | if( (inetdflag && cmd->nflag)) { /* netid not allowed with inetdflag */ | |
1053 | f_print(stderr, "Cannot use netid flag with inetd flag!\n"); | |
1054 | return (0); | |
1055 | } | |
1056 | } else { /* 4.1 mode */ | |
1057 | pmflag = 0; /* set pmflag only in tirpcmode */ | |
1058 | #ifndef __GNU_LIBRARY__ | |
1059 | inetdflag = 1; /* inetdflag is TRUE by default */ | |
1060 | #endif | |
1061 | if( cmd->nflag ) { /* netid needs TIRPC */ | |
1062 | f_print( stderr, "Cannot use netid flag without TIRPC!\n"); | |
1063 | return( 0 ); | |
1064 | } | |
1065 | } | |
1066 | ||
1067 | if( newstyle && ( tblflag || cmd->tflag) ) { | |
1068 | f_print( stderr, "Cannot use table flags with newstyle!\n"); | |
1069 | return( 0 ); | |
1070 | } | |
1071 | ||
1072 | /* check no conflicts with file generation flags */ | |
1073 | nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag + | |
1074 | cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag; | |
1075 | ||
28f540f4 RM |
1076 | if (nflags == 0) { |
1077 | if (cmd->outfile != NULL || cmd->infile == NULL) { | |
1078 | return (0); | |
1079 | } | |
1080 | } else if (nflags > 1) { | |
0d204b0a | 1081 | f_print( stderr, "Cannot have more than one file generation flag!\n"); |
28f540f4 RM |
1082 | return (0); |
1083 | } | |
1084 | return (1); | |
1085 | } | |
0d204b0a UD |
1086 | |
1087 | static void | |
1088 | usage(void) | |
1089 | { | |
1090 | f_print(stderr, "usage: %s infile\n", cmdname); | |
1091 | f_print(stderr, "\t%s [-a][-b][-C][-Dname[=value]] -i size [-I [-K seconds]] [-L][-N][-T] infile\n", | |
1092 | cmdname); | |
1093 | f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n", | |
1094 | cmdname); | |
1095 | f_print(stderr, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname); | |
1096 | f_print(stderr, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname); | |
1097 | options_usage(); | |
1098 | exit(1); | |
1099 | } | |
1100 | ||
1101 | static void | |
1102 | options_usage(void) | |
1103 | { | |
1104 | f_print(stderr, "options:\n"); | |
1105 | f_print(stderr, "-a\t\tgenerate all files, including samples\n"); | |
1106 | f_print(stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n"); | |
1107 | f_print(stderr, "-c\t\tgenerate XDR routines\n"); | |
1108 | f_print(stderr, "-C\t\tANSI C mode\n"); | |
1109 | f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n"); | |
1110 | f_print(stderr, "-h\t\tgenerate header file\n"); | |
1111 | f_print(stderr, "-i size\t\tsize at which to start generating inline code\n"); | |
1112 | f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n"); | |
1113 | f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n"); | |
1114 | f_print(stderr, "-l\t\tgenerate client side stubs\n"); | |
1115 | f_print(stderr, "-L\t\tserver errors will be printed to syslog\n"); | |
1116 | f_print(stderr, "-m\t\tgenerate server side stubs\n"); | |
1117 | f_print(stderr, "-n netid\tgenerate server code that supports named netid\n"); | |
1118 | f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n"); | |
1119 | f_print(stderr, "-o outfile\tname of the output file\n"); | |
1120 | f_print(stderr, "-s nettype\tgenerate server code that supports named nettype\n"); | |
1121 | f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n"); | |
1122 | f_print(stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n"); | |
1123 | f_print(stderr, "-t\t\tgenerate RPC dispatch table\n"); | |
1124 | f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n"); | |
1125 | f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n"); | |
1126 | ||
1127 | exit(1); | |
1128 | } |