GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: rpc_main.c,v 1.33 2017/01/21 08:33:07 krw Exp $ */ |
||
2 |
/* $NetBSD: rpc_main.c,v 1.9 1996/02/19 11:12:43 pk Exp $ */ |
||
3 |
|||
4 |
/* |
||
5 |
* Copyright (c) 2010, Oracle America, Inc. |
||
6 |
* |
||
7 |
* Redistribution and use in source and binary forms, with or without |
||
8 |
* modification, are permitted provided that the following conditions are |
||
9 |
* met: |
||
10 |
* |
||
11 |
* * Redistributions of source code must retain the above copyright |
||
12 |
* notice, this list of conditions and the following disclaimer. |
||
13 |
* * Redistributions in binary form must reproduce the above |
||
14 |
* copyright notice, this list of conditions and the following |
||
15 |
* disclaimer in the documentation and/or other materials |
||
16 |
* provided with the distribution. |
||
17 |
* * Neither the name of the "Oracle America, Inc." nor the names of its |
||
18 |
* contributors may be used to endorse or promote products derived |
||
19 |
* from this software without specific prior written permission. |
||
20 |
* |
||
21 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||
22 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||
23 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
||
24 |
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
||
25 |
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
||
26 |
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||
27 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
||
28 |
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||
29 |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||
30 |
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||
31 |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||
32 |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
33 |
*/ |
||
34 |
|||
35 |
/* |
||
36 |
* rpc_main.c, Top level of the RPC protocol compiler. |
||
37 |
*/ |
||
38 |
|||
39 |
#define RPCGEN_VERSION "199506"/* This program's version (year & month) */ |
||
40 |
|||
41 |
#include <sys/types.h> |
||
42 |
#include <sys/file.h> |
||
43 |
#include <stdio.h> |
||
44 |
#include <stdlib.h> |
||
45 |
#include <string.h> |
||
46 |
#include <unistd.h> |
||
47 |
#include <limits.h> |
||
48 |
#include <ctype.h> |
||
49 |
#include <sys/stat.h> |
||
50 |
#include "rpc_parse.h" |
||
51 |
#include "rpc_util.h" |
||
52 |
#include "rpc_scan.h" |
||
53 |
|||
54 |
#define EXTEND 1 /* alias for TRUE */ |
||
55 |
#define DONT_EXTEND 0 /* alias for FALSE */ |
||
56 |
|||
57 |
#define SVR4_CPP "/usr/ccs/lib/cpp" |
||
58 |
#define SUNOS_CPP "/lib/cpp" |
||
59 |
static int cppDefined = 0; /* explicit path for C preprocessor */ |
||
60 |
|||
61 |
struct commandline { |
||
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 |
char *infile; /* input module name */ |
||
72 |
char *outfile;/* output module name */ |
||
73 |
}; |
||
74 |
|||
75 |
static char *cmdname; |
||
76 |
|||
77 |
static char *svcclosetime = "120"; |
||
78 |
static char *CPP = "/usr/bin/cpp"; |
||
79 |
static char CPPFLAGS[] = "-C"; |
||
80 |
static char pathbuf[PATH_MAX]; |
||
81 |
static char *allv[] = { |
||
82 |
"rpcgen", "-s", "udp", "-s", "tcp", |
||
83 |
}; |
||
84 |
static int allc = sizeof(allv) / sizeof(allv[0]); |
||
85 |
static char *allnv[] = { |
||
86 |
"rpcgen", "-s", "netpath", |
||
87 |
}; |
||
88 |
static int allnc = sizeof(allnv) / sizeof(allnv[0]); |
||
89 |
|||
90 |
#define ARGLISTLEN 20 |
||
91 |
#define FIXEDARGS 2 |
||
92 |
|||
93 |
static char *arglist[ARGLISTLEN]; |
||
94 |
static int argcount = FIXEDARGS; |
||
95 |
|||
96 |
|||
97 |
int nonfatalerrors; /* errors */ |
||
98 |
int inetdflag /* = 1 */ ; /* Support for inetd *//* is now the |
||
99 |
* default */ |
||
100 |
int pmflag; /* Support for port monitors */ |
||
101 |
int logflag; /* Use syslog instead of fprintf for errors */ |
||
102 |
int tblflag; /* Support for dispatch table file */ |
||
103 |
int callerflag; /* Generate svc_caller() function */ |
||
104 |
|||
105 |
#define INLINE 3 |
||
106 |
/* length at which to start doing an inline */ |
||
107 |
|||
108 |
int doinline = INLINE; /* length at which to start doing an |
||
109 |
* inline. 3 = default if 0, no |
||
110 |
* xdr_inline code */ |
||
111 |
|||
112 |
int indefinitewait; /* If started by port monitors, hang till it |
||
113 |
* wants */ |
||
114 |
int exitnow; /* If started by port monitors, exit after |
||
115 |
* the call */ |
||
116 |
int timerflag; /* TRUE if !indefinite && !exitnow */ |
||
117 |
int newstyle; /* newstyle of passing arguments (by value) */ |
||
118 |
int Cflag = 0; /* ANSI C syntax */ |
||
119 |
static int allfiles; /* generate all files */ |
||
120 |
int tirpcflag = 0; /* generating code for tirpc, by default */ |
||
121 |
|||
122 |
static void c_output(char *, char *, int, char *); |
||
123 |
static void h_output(char *, char *, int, char *); |
||
124 |
static void s_output(int, char **, char *, char *, int, char *, int, int); |
||
125 |
static void l_output(char *, char *, int, char *); |
||
126 |
static void t_output(char *, char *, int, char *); |
||
127 |
static void svc_output(char *, char *, int, char *); |
||
128 |
static void clnt_output(char *, char *, int, char *); |
||
129 |
static int do_registers(int, char **); |
||
130 |
static void addarg(char *); |
||
131 |
static void putarg(int, char *); |
||
132 |
static void clear_args(void); |
||
133 |
static void checkfiles(char *, char *); |
||
134 |
static int parseargs(int, char **, struct commandline *); |
||
135 |
static void usage(void); |
||
136 |
void c_initialize(void); |
||
137 |
|||
138 |
int |
||
139 |
main(int argc, char *argv[]) |
||
140 |
{ |
||
141 |
120 |
struct commandline cmd; |
|
142 |
|||
143 |
✗✓ | 60 |
if (pledge("stdio rpath wpath cpath proc exec flock", NULL) == -1) { |
144 |
perror("pledge"); |
||
145 |
exit(1); |
||
146 |
} |
||
147 |
|||
148 |
60 |
(void) memset((char *) &cmd, 0, sizeof(struct commandline)); |
|
149 |
60 |
clear_args(); |
|
150 |
✗✓ | 60 |
if (!parseargs(argc, argv, &cmd)) |
151 |
usage(); |
||
152 |
|||
153 |
✓✓✗✓ ✗✗✗✗ ✗✗✗✗ |
90 |
if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag || |
154 |
cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) { |
||
155 |
60 |
checkfiles(cmd.infile, cmd.outfile); |
|
156 |
60 |
} else |
|
157 |
checkfiles(cmd.infile, NULL); |
||
158 |
|||
159 |
✓✓ | 60 |
if (cmd.cflag) { |
160 |
30 |
c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile); |
|
161 |
✓✗ | 60 |
} else if (cmd.hflag) { |
162 |
30 |
h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile); |
|
163 |
✗✗ | 30 |
} else if (cmd.lflag) { |
164 |
l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile); |
||
165 |
} else if (cmd.sflag || cmd.mflag || (cmd.nflag)) { |
||
166 |
s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND, |
||
167 |
cmd.outfile, cmd.mflag, cmd.nflag); |
||
168 |
} else if (cmd.tflag) { |
||
169 |
t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile); |
||
170 |
} else if (cmd.Ssflag) { |
||
171 |
svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile); |
||
172 |
} else if (cmd.Scflag) { |
||
173 |
clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile); |
||
174 |
} else { |
||
175 |
/* the rescans are required, since cpp may effect input */ |
||
176 |
c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); |
||
177 |
reinitialize(); |
||
178 |
h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h"); |
||
179 |
reinitialize(); |
||
180 |
l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); |
||
181 |
reinitialize(); |
||
182 |
if (inetdflag || !tirpcflag) |
||
183 |
s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, |
||
184 |
"_svc.c", cmd.mflag, cmd.nflag); |
||
185 |
else |
||
186 |
s_output(allnc, allnv, cmd.infile, "-DRPC_SVC", |
||
187 |
EXTEND, "_svc.c", cmd.mflag, cmd.nflag); |
||
188 |
if (tblflag) { |
||
189 |
reinitialize(); |
||
190 |
t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i"); |
||
191 |
} |
||
192 |
if (allfiles) { |
||
193 |
reinitialize(); |
||
194 |
svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c"); |
||
195 |
} |
||
196 |
if (allfiles) { |
||
197 |
reinitialize(); |
||
198 |
clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c"); |
||
199 |
} |
||
200 |
} |
||
201 |
exit(nonfatalerrors); |
||
202 |
/* NOTREACHED */ |
||
203 |
} |
||
204 |
|||
205 |
/* |
||
206 |
* add extension to filename |
||
207 |
*/ |
||
208 |
static char * |
||
209 |
extendfile(char *path, char *ext) |
||
210 |
{ |
||
211 |
char *file; |
||
212 |
char *res; |
||
213 |
char *p; |
||
214 |
size_t len; |
||
215 |
|||
216 |
✓✗ | 120 |
if ((file = strrchr(path, '/')) == NULL) |
217 |
60 |
file = path; |
|
218 |
else |
||
219 |
file++; |
||
220 |
|||
221 |
60 |
len = strlen(file) + strlen(ext) + 1; |
|
222 |
60 |
res = malloc(len); |
|
223 |
✗✓ | 60 |
if (res == NULL) { |
224 |
fprintf(stderr, "could not allocate memory\n"); |
||
225 |
exit(1); |
||
226 |
} |
||
227 |
60 |
p = strrchr(file, '.'); |
|
228 |
✗✓ | 60 |
if (p == NULL) |
229 |
p = file + strlen(file); |
||
230 |
60 |
(void) strlcpy(res, file, len); |
|
231 |
60 |
(void) strlcpy(res + (p - file), ext, len - (p - file)); |
|
232 |
60 |
return (res); |
|
233 |
} |
||
234 |
|||
235 |
/* |
||
236 |
* Open output file with given extension |
||
237 |
*/ |
||
238 |
static void |
||
239 |
open_output(char *infile, char *outfile) |
||
240 |
{ |
||
241 |
|||
242 |
✗✓ | 120 |
if (outfile == NULL) { |
243 |
fout = stdout; |
||
244 |
return; |
||
245 |
} |
||
246 |
✓✗✗✓ |
120 |
if (infile != NULL && streq(outfile, infile)) { |
247 |
fprintf(stderr, "%s: output would overwrite %s\n", cmdname, |
||
248 |
infile); |
||
249 |
crash(); |
||
250 |
} |
||
251 |
60 |
fout = fopen(outfile, "w"); |
|
252 |
✗✓ | 60 |
if (fout == NULL) { |
253 |
fprintf(stderr, "%s: unable to open ", cmdname); |
||
254 |
perror(outfile); |
||
255 |
crash(); |
||
256 |
} |
||
257 |
60 |
record_open(outfile); |
|
258 |
|||
259 |
120 |
} |
|
260 |
|||
261 |
static void |
||
262 |
add_warning(void) |
||
263 |
{ |
||
264 |
120 |
fprintf(fout, "/*\n"); |
|
265 |
60 |
fprintf(fout, " * Please do not edit this file.\n"); |
|
266 |
60 |
fprintf(fout, " * It was generated using rpcgen.\n"); |
|
267 |
60 |
fprintf(fout, " */\n\n"); |
|
268 |
60 |
} |
|
269 |
|||
270 |
/* clear list of arguments */ |
||
271 |
static void |
||
272 |
clear_args(void) |
||
273 |
{ |
||
274 |
int i; |
||
275 |
✓✓ | 2340 |
for (i = FIXEDARGS; i < ARGLISTLEN; i++) |
276 |
1080 |
arglist[i] = NULL; |
|
277 |
60 |
argcount = FIXEDARGS; |
|
278 |
60 |
} |
|
279 |
|||
280 |
/* make sure that a CPP exists */ |
||
281 |
static void |
||
282 |
find_cpp(void) |
||
283 |
{ |
||
284 |
struct stat buf; |
||
285 |
|||
286 |
/* SVR4 or explicit cpp does not exist */ |
||
287 |
if (stat(CPP, &buf) < 0) { |
||
288 |
if (cppDefined) { |
||
289 |
fprintf(stderr, "cannot find C preprocessor: %s \n", CPP); |
||
290 |
crash(); |
||
291 |
} else { |
||
292 |
/* try the other one */ |
||
293 |
CPP = SUNOS_CPP; |
||
294 |
if (stat(CPP, &buf) < 0) { /* can't find any cpp */ |
||
295 |
fprintf(stderr, |
||
296 |
"cannot find any C preprocessor: %s\n", CPP); |
||
297 |
crash(); |
||
298 |
} |
||
299 |
} |
||
300 |
} |
||
301 |
} |
||
302 |
|||
303 |
/* |
||
304 |
* Open input file with given define for C-preprocessor |
||
305 |
*/ |
||
306 |
static void |
||
307 |
open_input(char *infile, char *define) |
||
308 |
{ |
||
309 |
120 |
int pd[2]; |
|
310 |
|||
311 |
60 |
infilename = (infile == NULL) ? "<stdin>" : infile; |
|
312 |
60 |
(void) pipe(pd); |
|
313 |
✗✗✓ | 60 |
switch (fork()) { |
314 |
case 0: |
||
315 |
find_cpp(); |
||
316 |
putarg(0, CPP); |
||
317 |
putarg(1, CPPFLAGS); |
||
318 |
addarg(define); |
||
319 |
addarg(infile); |
||
320 |
addarg((char *) NULL); |
||
321 |
(void) close(1); |
||
322 |
(void) dup2(pd[1], 1); |
||
323 |
(void) close(pd[0]); |
||
324 |
execv(arglist[0], arglist); |
||
325 |
perror("execv"); |
||
326 |
exit(1); |
||
327 |
case -1: |
||
328 |
perror("fork"); |
||
329 |
exit(1); |
||
330 |
} |
||
331 |
60 |
(void) close(pd[1]); |
|
332 |
60 |
fin = fdopen(pd[0], "r"); |
|
333 |
✗✓ | 60 |
if (fin == NULL) { |
334 |
fprintf(stderr, "%s: ", cmdname); |
||
335 |
perror(infilename); |
||
336 |
crash(); |
||
337 |
} |
||
338 |
60 |
} |
|
339 |
|||
340 |
/* valid tirpc nettypes */ |
||
341 |
static char *valid_ti_nettypes[] = { |
||
342 |
"netpath", |
||
343 |
"visible", |
||
344 |
"circuit_v", |
||
345 |
"datagram_v", |
||
346 |
"circuit_n", |
||
347 |
"datagram_n", |
||
348 |
"udp", |
||
349 |
"tcp", |
||
350 |
"raw", |
||
351 |
NULL |
||
352 |
}; |
||
353 |
|||
354 |
/* valid inetd nettypes */ |
||
355 |
static char *valid_i_nettypes[] = { |
||
356 |
"udp", |
||
357 |
"tcp", |
||
358 |
NULL |
||
359 |
}; |
||
360 |
|||
361 |
static int |
||
362 |
check_nettype(char *name, char *list_to_check[]) |
||
363 |
{ |
||
364 |
int i; |
||
365 |
for (i = 0; list_to_check[i] != NULL; i++) { |
||
366 |
if (strcmp(name, list_to_check[i]) == 0) |
||
367 |
return 1; |
||
368 |
} |
||
369 |
fprintf(stderr, "illegal nettype :\'%s\'\n", name); |
||
370 |
return 0; |
||
371 |
} |
||
372 |
|||
373 |
/* |
||
374 |
* Compile into an XDR routine output file |
||
375 |
*/ |
||
376 |
|||
377 |
static void |
||
378 |
c_output(infile, define, extend, outfile) |
||
379 |
char *infile; |
||
380 |
char *define; |
||
381 |
int extend; |
||
382 |
char *outfile; |
||
383 |
{ |
||
384 |
definition *def; |
||
385 |
char *include; |
||
386 |
char *outfilename; |
||
387 |
long tell; |
||
388 |
|||
389 |
60 |
c_initialize(); |
|
390 |
30 |
open_input(infile, define); |
|
391 |
✗✓ | 90 |
outfilename = extend ? extendfile(infile, outfile) : outfile; |
392 |
30 |
open_output(infile, outfilename); |
|
393 |
30 |
add_warning(); |
|
394 |
✓✗✓✗ |
60 |
if (infile && (include = extendfile(infile, ".h"))) { |
395 |
30 |
fprintf(fout, "#include \"%s\"\n", include); |
|
396 |
30 |
free(include); |
|
397 |
/* .h file already contains rpc/rpc.h */ |
||
398 |
30 |
} else |
|
399 |
fprintf(fout, "#include <rpc/rpc.h>\n"); |
||
400 |
30 |
tell = ftell(fout); |
|
401 |
✓✓ | 1224 |
while ((def = get_definition())) { |
402 |
582 |
emit(def); |
|
403 |
} |
||
404 |
✗✓✗✗ |
30 |
if (extend && tell == ftell(fout)) { |
405 |
(void) unlink(outfilename); |
||
406 |
} |
||
407 |
30 |
} |
|
408 |
|||
409 |
|||
410 |
void |
||
411 |
c_initialize(void) |
||
412 |
{ |
||
413 |
|||
414 |
/* add all the starting basic types */ |
||
415 |
|||
416 |
60 |
add_type(1, "int"); |
|
417 |
30 |
add_type(1, "long"); |
|
418 |
30 |
add_type(1, "short"); |
|
419 |
30 |
add_type(1, "bool"); |
|
420 |
|||
421 |
30 |
add_type(1, "u_int"); |
|
422 |
30 |
add_type(1, "u_long"); |
|
423 |
30 |
add_type(1, "u_short"); |
|
424 |
|||
425 |
30 |
} |
|
426 |
|||
427 |
static const char rpcgen_table_dcl[] = "struct rpcgen_table {\n\ |
||
428 |
char *(*proc)();\n\ |
||
429 |
xdrproc_t xdr_arg;\n\ |
||
430 |
unsigned int len_arg;\n\ |
||
431 |
xdrproc_t xdr_res;\n\ |
||
432 |
unsigned int len_res;\n\ |
||
433 |
};\n"; |
||
434 |
|||
435 |
|||
436 |
static char * |
||
437 |
generate_guard(char *pathname) |
||
438 |
{ |
||
439 |
char *filename, *guard, *tmp, *tmp2; |
||
440 |
|||
441 |
60 |
filename = strrchr(pathname, '/'); /* find last component */ |
|
442 |
30 |
filename = ((filename == 0) ? pathname : filename + 1); |
|
443 |
30 |
guard = strdup(filename); |
|
444 |
✗✓ | 30 |
if (guard == NULL) { |
445 |
fprintf(stderr, "out of memory while processing %s\n", filename); |
||
446 |
crash(); |
||
447 |
} |
||
448 |
|||
449 |
/* convert to upper case */ |
||
450 |
tmp = guard; |
||
451 |
✓✓ | 572 |
while (*tmp) { |
452 |
✓✓ | 256 |
if (islower((unsigned char)*tmp)) |
453 |
216 |
*tmp = toupper((unsigned char)*tmp); |
|
454 |
256 |
tmp++; |
|
455 |
} |
||
456 |
|||
457 |
30 |
tmp2 = extendfile(guard, "_H_RPCGEN"); |
|
458 |
30 |
free(guard); |
|
459 |
guard = tmp2; |
||
460 |
|||
461 |
30 |
return (guard); |
|
462 |
} |
||
463 |
|||
464 |
/* |
||
465 |
* Compile into an XDR header file |
||
466 |
*/ |
||
467 |
|||
468 |
static void |
||
469 |
h_output(infile, define, extend, outfile) |
||
470 |
char *infile; |
||
471 |
char *define; |
||
472 |
int extend; |
||
473 |
char *outfile; |
||
474 |
{ |
||
475 |
definition *def; |
||
476 |
char *outfilename; |
||
477 |
long tell; |
||
478 |
char *guard; |
||
479 |
list *l; |
||
480 |
|||
481 |
60 |
open_input(infile, define); |
|
482 |
✗✓ | 90 |
outfilename = extend ? extendfile(infile, outfile) : outfile; |
483 |
30 |
open_output(infile, outfilename); |
|
484 |
30 |
add_warning(); |
|
485 |
30 |
guard = generate_guard(outfilename ? outfilename : infile); |
|
486 |
|||
487 |
30 |
fprintf(fout, "#ifndef _%s\n#define _%s\n\n", guard, |
|
488 |
guard); |
||
489 |
|||
490 |
30 |
fprintf(fout, "#define RPCGEN_VERSION\t%s\n\n", RPCGEN_VERSION); |
|
491 |
30 |
fprintf(fout, "#include <rpc/rpc.h>\n\n"); |
|
492 |
|||
493 |
30 |
tell = ftell(fout); |
|
494 |
/* print data definitions */ |
||
495 |
✓✓ | 1224 |
while ((def = get_definition())) { |
496 |
582 |
print_datadef(def); |
|
497 |
} |
||
498 |
|||
499 |
/* |
||
500 |
* print function declarations. Do this after data definitions |
||
501 |
* because they might be used as arguments for functions |
||
502 |
*/ |
||
503 |
✓✓ | 1224 |
for (l = defined; l != NULL; l = l->next) { |
504 |
582 |
print_funcdef(l->val); |
|
505 |
} |
||
506 |
✗✓✗✗ |
30 |
if (extend && tell == ftell(fout)) { |
507 |
(void) unlink(outfilename); |
||
508 |
✗✓ | 30 |
} else if (tblflag) { |
509 |
fprintf(fout, rpcgen_table_dcl); |
||
510 |
} |
||
511 |
30 |
fprintf(fout, "\n#endif /* !_%s */\n", guard); |
|
512 |
|||
513 |
30 |
free(guard); |
|
514 |
30 |
} |
|
515 |
|||
516 |
/* |
||
517 |
* Compile into an RPC service |
||
518 |
*/ |
||
519 |
static void |
||
520 |
s_output(argc, argv, infile, define, extend, outfile, nomain, netflag) |
||
521 |
int argc; |
||
522 |
char *argv[]; |
||
523 |
char *infile; |
||
524 |
char *define; |
||
525 |
int extend; |
||
526 |
char *outfile; |
||
527 |
int nomain; |
||
528 |
int netflag; |
||
529 |
{ |
||
530 |
char *include; |
||
531 |
definition *def; |
||
532 |
int foundprogram = 0; |
||
533 |
char *outfilename; |
||
534 |
|||
535 |
open_input(infile, define); |
||
536 |
outfilename = extend ? extendfile(infile, outfile) : outfile; |
||
537 |
open_output(infile, outfilename); |
||
538 |
add_warning(); |
||
539 |
if (infile && (include = extendfile(infile, ".h"))) { |
||
540 |
fprintf(fout, "#include \"%s\"\n", include); |
||
541 |
free(include); |
||
542 |
} else |
||
543 |
fprintf(fout, "#include <rpc/rpc.h>\n"); |
||
544 |
|||
545 |
fprintf(fout, "#include <unistd.h>\n"); |
||
546 |
fprintf(fout, "#include <stdio.h>\n"); |
||
547 |
fprintf(fout, "#include <stdlib.h>/* getenv, exit */\n"); |
||
548 |
if (Cflag) { |
||
549 |
fprintf(fout, |
||
550 |
"#include <rpc/pmap_clnt.h> /* for pmap_unset */\n"); |
||
551 |
fprintf(fout, "#include <string.h> /* strcmp */ \n"); |
||
552 |
} |
||
553 |
fprintf(fout, "#include <netdb.h>\n"); /* evas */ |
||
554 |
if (strcmp(svcclosetime, "-1") == 0) |
||
555 |
indefinitewait = 1; |
||
556 |
else if (strcmp(svcclosetime, "0") == 0) |
||
557 |
exitnow = 1; |
||
558 |
else if (inetdflag || pmflag) { |
||
559 |
fprintf(fout, "#include <signal.h>\n"); |
||
560 |
timerflag = 1; |
||
561 |
} |
||
562 |
if (!tirpcflag && inetdflag) |
||
563 |
fprintf(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n"); |
||
564 |
if (Cflag && (inetdflag || pmflag)) { |
||
565 |
fprintf(fout, "#ifdef __cplusplus\n"); |
||
566 |
fprintf(fout, "#include <sysent.h> /* getdtablesize, open */\n"); |
||
567 |
fprintf(fout, "#endif /* __cplusplus */\n"); |
||
568 |
|||
569 |
if (tirpcflag) |
||
570 |
fprintf(fout, "#include <unistd.h> /* setsid */\n"); |
||
571 |
} |
||
572 |
if (tirpcflag) |
||
573 |
fprintf(fout, "#include <sys/types.h>\n"); |
||
574 |
|||
575 |
fprintf(fout, "#include <memory.h>\n"); |
||
576 |
if (tirpcflag) |
||
577 |
fprintf(fout, "#include <stropts.h>\n"); |
||
578 |
|||
579 |
if (inetdflag || !tirpcflag) { |
||
580 |
fprintf(fout, "#include <sys/socket.h>\n"); |
||
581 |
fprintf(fout, "#include <netinet/in.h>\n"); |
||
582 |
} |
||
583 |
if ((netflag || pmflag) && tirpcflag) { |
||
584 |
fprintf(fout, "#include <netconfig.h>\n"); |
||
585 |
} |
||
586 |
if (/* timerflag && */ tirpcflag) |
||
587 |
fprintf(fout, "#include <sys/resource.h> /* rlimit */\n"); |
||
588 |
if (logflag || inetdflag || pmflag) { |
||
589 |
fprintf(fout, "#include <syslog.h>\n"); |
||
590 |
fprintf(fout, "#include <errno.h>\n"); |
||
591 |
} |
||
592 |
/* for ANSI-C */ |
||
593 |
fprintf(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n"); |
||
594 |
|||
595 |
fprintf(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n"); |
||
596 |
if (timerflag) |
||
597 |
fprintf(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime); |
||
598 |
while ((def = get_definition())) { |
||
599 |
foundprogram |= (def->def_kind == DEF_PROGRAM); |
||
600 |
} |
||
601 |
if (extend && !foundprogram) { |
||
602 |
(void) unlink(outfilename); |
||
603 |
return; |
||
604 |
} |
||
605 |
if (callerflag) /* EVAS */ |
||
606 |
fprintf(fout, "\nstatic SVCXPRT *caller;\n"); /* EVAS */ |
||
607 |
write_most(infile, netflag, nomain); |
||
608 |
if (!nomain) { |
||
609 |
if (!do_registers(argc, argv)) { |
||
610 |
if (outfilename) |
||
611 |
(void) unlink(outfilename); |
||
612 |
usage(); |
||
613 |
} |
||
614 |
write_rest(); |
||
615 |
} |
||
616 |
} |
||
617 |
|||
618 |
/* |
||
619 |
* generate client side stubs |
||
620 |
*/ |
||
621 |
static void |
||
622 |
l_output(infile, define, extend, outfile) |
||
623 |
char *infile; |
||
624 |
char *define; |
||
625 |
int extend; |
||
626 |
char *outfile; |
||
627 |
{ |
||
628 |
char *include; |
||
629 |
definition *def; |
||
630 |
int foundprogram = 0; |
||
631 |
char *outfilename; |
||
632 |
|||
633 |
open_input(infile, define); |
||
634 |
outfilename = extend ? extendfile(infile, outfile) : outfile; |
||
635 |
open_output(infile, outfilename); |
||
636 |
add_warning(); |
||
637 |
if (Cflag) |
||
638 |
fprintf(fout, "#include <memory.h> /* for memset */\n"); |
||
639 |
if (infile && (include = extendfile(infile, ".h"))) { |
||
640 |
fprintf(fout, "#include \"%s\"\n", include); |
||
641 |
free(include); |
||
642 |
} else |
||
643 |
fprintf(fout, "#include <rpc/rpc.h>\n"); |
||
644 |
while ((def = get_definition())) |
||
645 |
foundprogram |= (def->def_kind == DEF_PROGRAM); |
||
646 |
|||
647 |
if (extend && !foundprogram) { |
||
648 |
(void) unlink(outfilename); |
||
649 |
return; |
||
650 |
} |
||
651 |
write_stubs(); |
||
652 |
} |
||
653 |
|||
654 |
/* |
||
655 |
* generate the dispatch table |
||
656 |
*/ |
||
657 |
static void |
||
658 |
t_output(infile, define, extend, outfile) |
||
659 |
char *infile; |
||
660 |
char *define; |
||
661 |
int extend; |
||
662 |
char *outfile; |
||
663 |
{ |
||
664 |
definition *def; |
||
665 |
int foundprogram = 0; |
||
666 |
char *outfilename; |
||
667 |
|||
668 |
open_input(infile, define); |
||
669 |
outfilename = extend ? extendfile(infile, outfile) : outfile; |
||
670 |
open_output(infile, outfilename); |
||
671 |
add_warning(); |
||
672 |
while ((def = get_definition())) |
||
673 |
foundprogram |= (def->def_kind == DEF_PROGRAM); |
||
674 |
|||
675 |
if (extend && !foundprogram) { |
||
676 |
(void) unlink(outfilename); |
||
677 |
return; |
||
678 |
} |
||
679 |
write_tables(); |
||
680 |
} |
||
681 |
|||
682 |
/* sample routine for the server template */ |
||
683 |
static void |
||
684 |
svc_output(infile, define, extend, outfile) |
||
685 |
char *infile; |
||
686 |
char *define; |
||
687 |
int extend; |
||
688 |
char *outfile; |
||
689 |
{ |
||
690 |
definition *def; |
||
691 |
char *include; |
||
692 |
char *outfilename; |
||
693 |
long tell; |
||
694 |
|||
695 |
open_input(infile, define); |
||
696 |
outfilename = extend ? extendfile(infile, outfile) : outfile; |
||
697 |
checkfiles(infile, outfilename); /* check if outfile already |
||
698 |
* exists. if so, print an |
||
699 |
* error message and exit */ |
||
700 |
open_output(infile, outfilename); |
||
701 |
add_sample_msg(); |
||
702 |
|||
703 |
if (infile && (include = extendfile(infile, ".h"))) { |
||
704 |
fprintf(fout, "#include \"%s\"\n", include); |
||
705 |
free(include); |
||
706 |
} else |
||
707 |
fprintf(fout, "#include <rpc/rpc.h>\n"); |
||
708 |
|||
709 |
tell = ftell(fout); |
||
710 |
while ((def = get_definition())) |
||
711 |
write_sample_svc(def); |
||
712 |
|||
713 |
if (extend && tell == ftell(fout)) |
||
714 |
(void) unlink(outfilename); |
||
715 |
} |
||
716 |
|||
717 |
|||
718 |
/* sample main routine for client */ |
||
719 |
static void |
||
720 |
clnt_output(infile, define, extend, outfile) |
||
721 |
char *infile; |
||
722 |
char *define; |
||
723 |
int extend; |
||
724 |
char *outfile; |
||
725 |
{ |
||
726 |
definition *def; |
||
727 |
char *include, *outfilename; |
||
728 |
long tell; |
||
729 |
int has_program = 0; |
||
730 |
|||
731 |
open_input(infile, define); |
||
732 |
outfilename = extend ? extendfile(infile, outfile) : outfile; |
||
733 |
|||
734 |
/* |
||
735 |
* check if outfile already exists. if so, |
||
736 |
* print an error message and exit |
||
737 |
*/ |
||
738 |
checkfiles(infile, outfilename); |
||
739 |
|||
740 |
open_output(infile, outfilename); |
||
741 |
add_sample_msg(); |
||
742 |
if (infile && (include = extendfile(infile, ".h"))) { |
||
743 |
fprintf(fout, "#include \"%s\"\n", include); |
||
744 |
free(include); |
||
745 |
} else |
||
746 |
fprintf(fout, "#include <rpc/rpc.h>\n"); |
||
747 |
tell = ftell(fout); |
||
748 |
while ((def = get_definition())) |
||
749 |
has_program += write_sample_clnt(def); |
||
750 |
|||
751 |
if (has_program) |
||
752 |
write_sample_clnt_main(); |
||
753 |
|||
754 |
if (extend && tell == ftell(fout)) |
||
755 |
(void) unlink(outfilename); |
||
756 |
} |
||
757 |
|||
758 |
/* |
||
759 |
* Perform registrations for service output |
||
760 |
* Return 0 if failed; 1 otherwise. |
||
761 |
*/ |
||
762 |
static int |
||
763 |
do_registers(argc, argv) |
||
764 |
int argc; |
||
765 |
char *argv[]; |
||
766 |
{ |
||
767 |
int i; |
||
768 |
|||
769 |
if (inetdflag || !tirpcflag) { |
||
770 |
for (i = 1; i < argc; i++) { |
||
771 |
if (streq(argv[i], "-s")) { |
||
772 |
if (!check_nettype(argv[i + 1], valid_i_nettypes)) |
||
773 |
return 0; |
||
774 |
write_inetd_register(argv[i + 1]); |
||
775 |
i++; |
||
776 |
} |
||
777 |
} |
||
778 |
} else { |
||
779 |
for (i = 1; i < argc; i++) |
||
780 |
if (streq(argv[i], "-s")) { |
||
781 |
if (!check_nettype(argv[i + 1], valid_ti_nettypes)) |
||
782 |
return 0; |
||
783 |
write_nettype_register(argv[i + 1]); |
||
784 |
i++; |
||
785 |
} else if (streq(argv[i], "-n")) { |
||
786 |
write_netid_register(argv[i + 1]); |
||
787 |
i++; |
||
788 |
} |
||
789 |
} |
||
790 |
return 1; |
||
791 |
} |
||
792 |
|||
793 |
/* |
||
794 |
* Add another argument to the arg list |
||
795 |
*/ |
||
796 |
static void |
||
797 |
addarg(cp) |
||
798 |
char *cp; |
||
799 |
{ |
||
800 |
if (argcount >= ARGLISTLEN) { |
||
801 |
fprintf(stderr, "rpcgen: too many defines\n"); |
||
802 |
crash(); |
||
803 |
/* NOTREACHED */ |
||
804 |
} |
||
805 |
arglist[argcount++] = cp; |
||
806 |
|||
807 |
} |
||
808 |
|||
809 |
static void |
||
810 |
putarg(where, cp) |
||
811 |
char *cp; |
||
812 |
int where; |
||
813 |
{ |
||
814 |
if (where >= ARGLISTLEN) { |
||
815 |
fprintf(stderr, "rpcgen: arglist coding error\n"); |
||
816 |
crash(); |
||
817 |
/* NOTREACHED */ |
||
818 |
} |
||
819 |
arglist[where] = cp; |
||
820 |
} |
||
821 |
|||
822 |
/* |
||
823 |
* if input file is stdin and an output file is specified then complain |
||
824 |
* if the file already exists. Otherwise the file may get overwritten |
||
825 |
* If input file does not exist, exit with an error |
||
826 |
*/ |
||
827 |
static void |
||
828 |
checkfiles(infile, outfile) |
||
829 |
char *infile; |
||
830 |
char *outfile; |
||
831 |
{ |
||
832 |
120 |
struct stat buf; |
|
833 |
|||
834 |
✓✗ | 60 |
if (infile) /* infile ! = NULL */ |
835 |
✗✓ | 60 |
if (stat(infile, &buf) < 0) { |
836 |
perror(infile); |
||
837 |
crash(); |
||
838 |
} |
||
839 |
#if 0 |
||
840 |
if (outfile) { |
||
841 |
if (stat(outfile, &buf) < 0) |
||
842 |
return; /* file does not exist */ |
||
843 |
else { |
||
844 |
fprintf(stderr, |
||
845 |
"file '%s' already exists and may be overwritten\n", |
||
846 |
outfile); |
||
847 |
crash(); |
||
848 |
} |
||
849 |
} |
||
850 |
#endif |
||
851 |
60 |
} |
|
852 |
|||
853 |
/* |
||
854 |
* Parse command line arguments |
||
855 |
*/ |
||
856 |
static int |
||
857 |
parseargs(argc, argv, cmd) |
||
858 |
int argc; |
||
859 |
char *argv[]; |
||
860 |
struct commandline *cmd; |
||
861 |
{ |
||
862 |
int i, j, nflags; |
||
863 |
120 |
char c, flag[(1 << 8 * sizeof(char))]; |
|
864 |
|||
865 |
60 |
cmdname = argv[0]; |
|
866 |
60 |
cmd->infile = cmd->outfile = NULL; |
|
867 |
✗✓ | 60 |
if (argc < 2) |
868 |
return (0); |
||
869 |
|||
870 |
60 |
allfiles = 0; |
|
871 |
60 |
flag['c'] = 0; |
|
872 |
60 |
flag['h'] = 0; |
|
873 |
60 |
flag['l'] = 0; |
|
874 |
60 |
flag['m'] = 0; |
|
875 |
60 |
flag['o'] = 0; |
|
876 |
60 |
flag['s'] = 0; |
|
877 |
60 |
flag['n'] = 0; |
|
878 |
60 |
flag['t'] = 0; |
|
879 |
60 |
flag['S'] = 0; |
|
880 |
60 |
flag['C'] = 0; |
|
881 |
✓✓ | 600 |
for (i = 1; i < argc; i++) { |
882 |
✓✓ | 240 |
if (argv[i][0] != '-') { |
883 |
✗✓ | 60 |
if (cmd->infile) { |
884 |
fprintf(stderr, |
||
885 |
"Cannot specify more than one input file!\n"); |
||
886 |
return (0); |
||
887 |
} |
||
888 |
60 |
cmd->infile = argv[i]; |
|
889 |
60 |
} else { |
|
890 |
✓✓ | 600 |
for (j = 1; argv[i][j] != 0; j++) { |
891 |
c = argv[i][j]; |
||
892 |
✗✗✗✗ ✗✗✓✗ ✓✗✗✗ ✗✗✗✗ ✗✗✓✗ ✗✗ |
180 |
switch (c) { |
893 |
case 'A': |
||
894 |
callerflag = 1; |
||
895 |
break; |
||
896 |
case 'a': |
||
897 |
allfiles = 1; |
||
898 |
break; |
||
899 |
case 'c': |
||
900 |
case 'h': |
||
901 |
case 'l': |
||
902 |
case 'm': |
||
903 |
case 't': |
||
904 |
✗✓ | 60 |
if (flag[(unsigned char)c]) |
905 |
return (0); |
||
906 |
60 |
flag[(unsigned char)c] = 1; |
|
907 |
60 |
break; |
|
908 |
case 'S': |
||
909 |
/* |
||
910 |
* sample flag: Ss or Sc. Ss means |
||
911 |
* set flag['S']; Sc means set |
||
912 |
* flag['C']; |
||
913 |
*/ |
||
914 |
c = argv[i][++j]; /* get next char */ |
||
915 |
if (c == 's') |
||
916 |
c = 'S'; |
||
917 |
else if (c == 'c') |
||
918 |
c = 'C'; |
||
919 |
else |
||
920 |
return (0); |
||
921 |
|||
922 |
if (flag[(unsigned char)c]) |
||
923 |
return (0); |
||
924 |
flag[(unsigned char)c] = 1; |
||
925 |
break; |
||
926 |
case 'C': /* ANSI C syntax */ |
||
927 |
60 |
Cflag = 1; |
|
928 |
60 |
break; |
|
929 |
|||
930 |
case 'b': |
||
931 |
/* |
||
932 |
* turn TIRPC flag off for |
||
933 |
* generating backward compatible |
||
934 |
*/ |
||
935 |
tirpcflag = 0; |
||
936 |
break; |
||
937 |
|||
938 |
case 'I': |
||
939 |
inetdflag = 1; |
||
940 |
break; |
||
941 |
case 'N': |
||
942 |
newstyle = 1; |
||
943 |
break; |
||
944 |
case 'L': |
||
945 |
logflag = 1; |
||
946 |
break; |
||
947 |
case 'K': |
||
948 |
if (++i == argc) |
||
949 |
return (0); |
||
950 |
svcclosetime = argv[i]; |
||
951 |
goto nextarg; |
||
952 |
case 'T': |
||
953 |
tblflag = 1; |
||
954 |
break; |
||
955 |
case 'i': |
||
956 |
if (++i == argc) |
||
957 |
return (0); |
||
958 |
doinline = atoi(argv[i]); |
||
959 |
goto nextarg; |
||
960 |
case 'n': |
||
961 |
case 'o': |
||
962 |
case 's': |
||
963 |
✓✗✗✓ |
120 |
if (argv[i][j - 1] != '-' || |
964 |
60 |
argv[i][j + 1] != 0) |
|
965 |
return (0); |
||
966 |
60 |
flag[(unsigned char)c] = 1; |
|
967 |
✗✓ | 60 |
if (++i == argc) |
968 |
return (0); |
||
969 |
✗✓ | 60 |
if (c == 's') { |
970 |
if (!streq(argv[i], "udp") && |
||
971 |
!streq(argv[i], "tcp")) |
||
972 |
return (0); |
||
973 |
✓✗ | 60 |
} else if (c == 'o') { |
974 |
✗✓ | 60 |
if (cmd->outfile) |
975 |
return (0); |
||
976 |
60 |
cmd->outfile = argv[i]; |
|
977 |
60 |
} |
|
978 |
goto nextarg; |
||
979 |
case 'D': |
||
980 |
if (argv[i][j - 1] != '-') |
||
981 |
return (0); |
||
982 |
(void) addarg(argv[i]); |
||
983 |
goto nextarg; |
||
984 |
case 'Y': |
||
985 |
if (++i == argc) |
||
986 |
return (0); |
||
987 |
if (snprintf(pathbuf, sizeof pathbuf, |
||
988 |
"%s/cpp", argv[i]) >= sizeof pathbuf) |
||
989 |
usage(); |
||
990 |
CPP = pathbuf; |
||
991 |
cppDefined = 1; |
||
992 |
goto nextarg; |
||
993 |
default: |
||
994 |
return (0); |
||
995 |
} |
||
996 |
} |
||
997 |
nextarg: |
||
998 |
; |
||
999 |
} |
||
1000 |
} |
||
1001 |
|||
1002 |
60 |
cmd->cflag = flag['c']; |
|
1003 |
60 |
cmd->hflag = flag['h']; |
|
1004 |
60 |
cmd->lflag = flag['l']; |
|
1005 |
60 |
cmd->mflag = flag['m']; |
|
1006 |
60 |
cmd->nflag = flag['n']; |
|
1007 |
60 |
cmd->sflag = flag['s']; |
|
1008 |
60 |
cmd->tflag = flag['t']; |
|
1009 |
60 |
cmd->Ssflag = flag['S']; |
|
1010 |
60 |
cmd->Scflag = flag['C']; |
|
1011 |
|||
1012 |
✗✓ | 60 |
if (tirpcflag) { |
1013 |
pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is |
||
1014 |
* always TRUE */ |
||
1015 |
if (inetdflag && cmd->nflag) { |
||
1016 |
/* netid not allowed with inetdflag */ |
||
1017 |
fprintf(stderr, "Cannot use netid flag with inetd flag!\n"); |
||
1018 |
return (0); |
||
1019 |
} |
||
1020 |
} else { |
||
1021 |
/* 4.1 mode */ |
||
1022 |
60 |
pmflag = 0; /* set pmflag only in tirpcmode */ |
|
1023 |
60 |
inetdflag = 1; /* inetdflag is TRUE by default */ |
|
1024 |
✗✓ | 60 |
if (cmd->nflag) { |
1025 |
/* netid needs TIRPC */ |
||
1026 |
fprintf(stderr, "Cannot use netid flag without TIRPC!\n"); |
||
1027 |
return (0); |
||
1028 |
} |
||
1029 |
} |
||
1030 |
|||
1031 |
✗✓✗✗ ✗✗ |
60 |
if (newstyle && (tblflag || cmd->tflag)) { |
1032 |
fprintf(stderr, "Cannot use table flags with newstyle!\n"); |
||
1033 |
return (0); |
||
1034 |
} |
||
1035 |
/* check no conflicts with file generation flags */ |
||
1036 |
120 |
nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag + |
|
1037 |
120 |
cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag; |
|
1038 |
|||
1039 |
✗✓ | 60 |
if (nflags == 0) { |
1040 |
if (cmd->outfile != NULL || cmd->infile == NULL) |
||
1041 |
return (0); |
||
1042 |
✗✓ | 60 |
} else if (nflags > 1) { |
1043 |
fprintf(stderr, "Cannot have more than one file generation flag!\n"); |
||
1044 |
return (0); |
||
1045 |
} |
||
1046 |
60 |
return (1); |
|
1047 |
60 |
} |
|
1048 |
|||
1049 |
static void |
||
1050 |
usage(void) |
||
1051 |
{ |
||
1052 |
fprintf(stderr, "usage: %s [-abACILNT] [-Dname[=value]] [-i lines] " |
||
1053 |
"[-K seconds] infile\n", cmdname); |
||
1054 |
fprintf(stderr, " %s [-c | -h | -l | -m | -t | -Sc | -Ss] " |
||
1055 |
"[-o outfile] [infile]\n", cmdname); |
||
1056 |
fprintf(stderr, " %s [-s nettype]* [-o outfile] [infile]\n", cmdname); |
||
1057 |
exit(1); |
||
1058 |
} |
Generated by: GCOVR (Version 3.3) |