1 |
|
|
/* $OpenBSD: rpc_svcout.c,v 1.27 2012/12/05 23:20:26 deraadt Exp $ */ |
2 |
|
|
/* $NetBSD: rpc_svcout.c,v 1.7 1995/06/24 14:59:59 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_svcout.c, Server-skeleton outputter for the RPC protocol compiler |
37 |
|
|
*/ |
38 |
|
|
#include <stdio.h> |
39 |
|
|
#include <string.h> |
40 |
|
|
#include "rpc_parse.h" |
41 |
|
|
#include "rpc_util.h" |
42 |
|
|
|
43 |
|
|
static char RQSTP[] = "rqstp"; |
44 |
|
|
static char TRANSP[] = "transp"; |
45 |
|
|
static char ARG[] = "argument"; |
46 |
|
|
static char RESULT[] = "result"; |
47 |
|
|
static char ROUTINE[] = "local"; |
48 |
|
|
|
49 |
|
|
char _errbuf[256]; /* For all messages */ |
50 |
|
|
|
51 |
|
|
void internal_proctype(proc_list *); |
52 |
|
|
static void write_real_program(definition *); |
53 |
|
|
static void write_program(definition *, char *); |
54 |
|
|
static void printerr(char *, char *); |
55 |
|
|
static void printif(char *, char *, char *, char *); |
56 |
|
|
static void write_inetmost(char *); |
57 |
|
|
static void print_return(char *); |
58 |
|
|
static void print_pmapunset(char *); |
59 |
|
|
static void print_err_message(char *); |
60 |
|
|
static void write_timeout_func(void); |
61 |
|
|
static void write_pm_most(char *, int); |
62 |
|
|
static void write_caller_func(void); |
63 |
|
|
static void write_rpc_svc_fg(char *, char *); |
64 |
|
|
static void write_msg_out(void); |
65 |
|
|
static void open_log_file(char *, char *); |
66 |
|
|
|
67 |
|
|
static void |
68 |
|
|
p_xdrfunc(char *rname, char *typename) |
69 |
|
|
{ |
70 |
|
|
if (Cflag) |
71 |
|
|
fprintf(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n", |
72 |
|
|
rname, stringfix(typename)); |
73 |
|
|
else |
74 |
|
|
fprintf(fout, "\t\txdr_%s = xdr_%s;\n", rname, |
75 |
|
|
stringfix(typename)); |
76 |
|
|
} |
77 |
|
|
|
78 |
|
|
void |
79 |
|
|
internal_proctype(plist) |
80 |
|
|
proc_list *plist; |
81 |
|
|
{ |
82 |
|
|
fprintf(fout, "static "); |
83 |
|
|
ptype(plist->res_prefix, plist->res_type, 1); |
84 |
|
|
fprintf(fout, "*"); |
85 |
|
|
} |
86 |
|
|
|
87 |
|
|
/* |
88 |
|
|
* write most of the service, that is, everything but the registrations. |
89 |
|
|
*/ |
90 |
|
|
void |
91 |
|
|
write_most(infile, netflag, nomain) |
92 |
|
|
char *infile; /* our name */ |
93 |
|
|
int netflag; |
94 |
|
|
int nomain; |
95 |
|
|
{ |
96 |
|
|
if (inetdflag || pmflag) { |
97 |
|
|
char *var_type; |
98 |
|
|
var_type = (nomain? "extern" : "static"); |
99 |
|
|
fprintf(fout, "%s int _rpcpmstart;", var_type); |
100 |
|
|
fprintf(fout, "\t\t/* Started by a port monitor ? */\n"); |
101 |
|
|
fprintf(fout, "%s int _rpcfdtype;", var_type); |
102 |
|
|
fprintf(fout, "\t\t/* Whether Stream or Datagram ? */\n"); |
103 |
|
|
if (timerflag) { |
104 |
|
|
fprintf(fout, "%s int _rpcsvcdirty;", var_type); |
105 |
|
|
fprintf(fout, "\t/* Still serving ? */\n"); |
106 |
|
|
} |
107 |
|
|
write_svc_aux(nomain); |
108 |
|
|
} |
109 |
|
|
/* write out dispatcher and stubs */ |
110 |
|
|
write_programs(nomain? (char *)NULL : "static"); |
111 |
|
|
|
112 |
|
|
if (nomain) |
113 |
|
|
return; |
114 |
|
|
|
115 |
|
|
fprintf(fout, "\nmain()\n"); |
116 |
|
|
fprintf(fout, "{\n"); |
117 |
|
|
if (inetdflag) { |
118 |
|
|
write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */ |
119 |
|
|
} else { |
120 |
|
|
if (tirpcflag) { |
121 |
|
|
if (netflag) { |
122 |
|
|
fprintf(fout, "\tSVCXPRT *%s;\n", TRANSP); |
123 |
|
|
fprintf(fout, "\tstruct netconfig *nconf = NULL;\n"); |
124 |
|
|
} |
125 |
|
|
fprintf(fout, "\tpid_t pid;\n"); |
126 |
|
|
fprintf(fout, "\tint i;\n"); |
127 |
|
|
fprintf(fout, "\tchar mname[FMNAMESZ + 1];\n\n"); |
128 |
|
|
write_pm_most(infile, netflag); |
129 |
|
|
fprintf(fout, "\telse {\n"); |
130 |
|
|
write_rpc_svc_fg(infile, "\t\t"); |
131 |
|
|
fprintf(fout, "\t}\n"); |
132 |
|
|
} else { |
133 |
|
|
fprintf(fout, "\tSVCXPRT *%s;\n", TRANSP); |
134 |
|
|
fprintf(fout, "\n"); |
135 |
|
|
print_pmapunset("\t"); |
136 |
|
|
} |
137 |
|
|
} |
138 |
|
|
|
139 |
|
|
if (logflag && !inetdflag) { |
140 |
|
|
open_log_file(infile, "\t"); |
141 |
|
|
} |
142 |
|
|
} |
143 |
|
|
|
144 |
|
|
/* |
145 |
|
|
* write a registration for the given transport |
146 |
|
|
*/ |
147 |
|
|
void |
148 |
|
|
write_netid_register(transp) |
149 |
|
|
char *transp; |
150 |
|
|
{ |
151 |
|
|
list *l; |
152 |
|
|
definition *def; |
153 |
|
|
version_list *vp; |
154 |
|
|
char *sp; |
155 |
|
|
char tmpbuf[32]; |
156 |
|
|
|
157 |
|
|
sp = ""; |
158 |
|
|
fprintf(fout, "\n"); |
159 |
|
|
fprintf(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp); |
160 |
|
|
fprintf(fout, "%s\tif (nconf == NULL) {\n", sp); |
161 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, "cannot find %s netid.", transp); |
162 |
|
|
snprintf(tmpbuf, sizeof tmpbuf, "%s\t\t", sp); |
163 |
|
|
print_err_message(tmpbuf); |
164 |
|
|
fprintf(fout, "%s\t\texit(1);\n", sp); |
165 |
|
|
fprintf(fout, "%s\t}\n", sp); |
166 |
|
|
fprintf(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n", |
167 |
|
|
sp, TRANSP); |
168 |
|
|
fprintf(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP); |
169 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, "cannot create %s service.", transp); |
170 |
|
|
print_err_message(tmpbuf); |
171 |
|
|
fprintf(fout, "%s\t\texit(1);\n", sp); |
172 |
|
|
fprintf(fout, "%s\t}\n", sp); |
173 |
|
|
|
174 |
|
|
for (l = defined; l != NULL; l = l->next) { |
175 |
|
|
def = (definition *) l->val; |
176 |
|
|
if (def->def_kind != DEF_PROGRAM) |
177 |
|
|
continue; |
178 |
|
|
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { |
179 |
|
|
fprintf(fout, |
180 |
|
|
"%s\t(void) rpcb_unset(%s, %s, nconf);\n", |
181 |
|
|
sp, def->def_name, vp->vers_name); |
182 |
|
|
fprintf(fout, |
183 |
|
|
"%s\tif (!svc_reg(%s, %s, %s, ", |
184 |
|
|
sp, TRANSP, def->def_name, vp->vers_name); |
185 |
|
|
pvname(def->def_name, vp->vers_num); |
186 |
|
|
fprintf(fout, ", nconf)) {\n"); |
187 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, |
188 |
|
|
"unable to register (%s, %s, %s).", |
189 |
|
|
def->def_name, vp->vers_name, transp); |
190 |
|
|
print_err_message(tmpbuf); |
191 |
|
|
fprintf(fout, "%s\t\texit(1);\n", sp); |
192 |
|
|
fprintf(fout, "%s\t}\n", sp); |
193 |
|
|
} |
194 |
|
|
} |
195 |
|
|
fprintf(fout, "%s\tfreenetconfigent(nconf);\n", sp); |
196 |
|
|
} |
197 |
|
|
|
198 |
|
|
/* |
199 |
|
|
* write a registration for the given transport for TLI |
200 |
|
|
*/ |
201 |
|
|
void |
202 |
|
|
write_nettype_register(transp) |
203 |
|
|
char *transp; |
204 |
|
|
{ |
205 |
|
|
list *l; |
206 |
|
|
definition *def; |
207 |
|
|
version_list *vp; |
208 |
|
|
|
209 |
|
|
for (l = defined; l != NULL; l = l->next) { |
210 |
|
|
def = (definition *) l->val; |
211 |
|
|
if (def->def_kind != DEF_PROGRAM) |
212 |
|
|
continue; |
213 |
|
|
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { |
214 |
|
|
fprintf(fout, "\tif (!svc_create("); |
215 |
|
|
pvname(def->def_name, vp->vers_num); |
216 |
|
|
fprintf(fout, ", %s, %s, \"%s\")) {\n", |
217 |
|
|
def->def_name, vp->vers_name, transp); |
218 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, |
219 |
|
|
"unable to create (%s, %s) for %s.", |
220 |
|
|
def->def_name, vp->vers_name, transp); |
221 |
|
|
print_err_message("\t\t"); |
222 |
|
|
fprintf(fout, "\t\texit(1);\n"); |
223 |
|
|
fprintf(fout, "\t}\n"); |
224 |
|
|
} |
225 |
|
|
} |
226 |
|
|
} |
227 |
|
|
|
228 |
|
|
/* |
229 |
|
|
* write the rest of the service |
230 |
|
|
*/ |
231 |
|
|
void |
232 |
|
|
write_rest() |
233 |
|
|
{ |
234 |
|
|
fprintf(fout, "\n"); |
235 |
|
|
if (inetdflag) { |
236 |
|
|
fprintf(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP); |
237 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, "could not create a handle"); |
238 |
|
|
print_err_message("\t\t"); |
239 |
|
|
fprintf(fout, "\t\texit(1);\n"); |
240 |
|
|
fprintf(fout, "\t}\n"); |
241 |
|
|
if (timerflag) { |
242 |
|
|
fprintf(fout, "\tif (_rpcpmstart) {\n"); |
243 |
|
|
fprintf(fout, |
244 |
|
|
"\t\t(void) signal(SIGALRM, %s closedown);\n", |
245 |
|
|
Cflag? "(SIG_PF)" : "(void(*)())"); |
246 |
|
|
fprintf(fout, "\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n"); |
247 |
|
|
fprintf(fout, "\t}\n"); |
248 |
|
|
} |
249 |
|
|
} |
250 |
|
|
fprintf(fout, "\tsvc_run();\n"); |
251 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, "svc_run returned"); |
252 |
|
|
print_err_message("\t"); |
253 |
|
|
fprintf(fout, "\texit(1);\n"); |
254 |
|
|
fprintf(fout, "\t/* NOTREACHED */\n"); |
255 |
|
|
fprintf(fout, "}\n"); |
256 |
|
|
} |
257 |
|
|
|
258 |
|
|
void |
259 |
|
|
write_programs(storage) |
260 |
|
|
char *storage; |
261 |
|
|
{ |
262 |
|
|
definition *def; |
263 |
|
|
list *l; |
264 |
|
|
|
265 |
|
|
/* write out stubs for procedure definitions */ |
266 |
|
|
for (l = defined; l != NULL; l = l->next) { |
267 |
|
|
def = (definition *) l->val; |
268 |
|
|
if (def->def_kind == DEF_PROGRAM) |
269 |
|
|
write_real_program(def); |
270 |
|
|
} |
271 |
|
|
|
272 |
|
|
/* write out dispatcher for each program */ |
273 |
|
|
for (l = defined; l != NULL; l = l->next) { |
274 |
|
|
def = (definition *) l->val; |
275 |
|
|
if (def->def_kind == DEF_PROGRAM) |
276 |
|
|
write_program(def, storage); |
277 |
|
|
} |
278 |
|
|
} |
279 |
|
|
|
280 |
|
|
/* write out definition of internal function (e.g. _printmsg_1(...)) |
281 |
|
|
which calls server's definition of actual function (e.g. printmsg_1(...)). |
282 |
|
|
Unpacks single user argument of printmsg_1 to call-by-value format |
283 |
|
|
expected by printmsg_1. */ |
284 |
|
|
static void |
285 |
|
|
write_real_program(def) |
286 |
|
|
definition *def; |
287 |
|
|
{ |
288 |
|
|
version_list *vp; |
289 |
|
|
proc_list *proc; |
290 |
|
|
decl_list *l; |
291 |
|
|
|
292 |
|
|
if (!newstyle) return; /* not needed for old style */ |
293 |
|
|
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { |
294 |
|
|
for (proc = vp->procs; proc != NULL; proc = proc->next) { |
295 |
|
|
fprintf(fout, "\n"); |
296 |
|
|
internal_proctype(proc); |
297 |
|
|
fprintf(fout, "\n_"); |
298 |
|
|
pvname(proc->proc_name, vp->vers_num); |
299 |
|
|
if (Cflag) { |
300 |
|
|
fprintf(fout, "("); |
301 |
|
|
/* arg name */ |
302 |
|
|
if (proc->arg_num > 1) |
303 |
|
|
fprintf(fout, "%s", proc->args.argname); |
304 |
|
|
else |
305 |
|
|
ptype(proc->args.decls->decl.prefix, |
306 |
|
|
proc->args.decls->decl.type, 0); |
307 |
|
|
fprintf(fout, " *argp, struct svc_req *%s)\n", |
308 |
|
|
RQSTP); |
309 |
|
|
} else { |
310 |
|
|
fprintf(fout, "(argp, %s)\n", RQSTP); |
311 |
|
|
/* arg name */ |
312 |
|
|
if (proc->arg_num > 1) |
313 |
|
|
fprintf(fout, "\t%s *argp;\n", |
314 |
|
|
proc->args.argname); |
315 |
|
|
else { |
316 |
|
|
fprintf(fout, "\t"); |
317 |
|
|
ptype(proc->args.decls->decl.prefix, |
318 |
|
|
proc->args.decls->decl.type, 0); |
319 |
|
|
fprintf(fout, " *argp;\n"); |
320 |
|
|
} |
321 |
|
|
fprintf(fout, " struct svc_req *%s;\n", RQSTP); |
322 |
|
|
} |
323 |
|
|
|
324 |
|
|
fprintf(fout, "{\n"); |
325 |
|
|
fprintf(fout, "\treturn("); |
326 |
|
|
pvname_svc(proc->proc_name, vp->vers_num); |
327 |
|
|
fprintf(fout, "("); |
328 |
|
|
if (proc->arg_num < 2) { /* single argument */ |
329 |
|
|
if (!streq(proc->args.decls->decl.type, "void")) |
330 |
|
|
fprintf(fout, "*argp, "); /* non-void */ |
331 |
|
|
} else { |
332 |
|
|
for (l = proc->args.decls; l != NULL; l = l->next) |
333 |
|
|
fprintf(fout, "argp->%s, ", l->decl.name); |
334 |
|
|
} |
335 |
|
|
fprintf(fout, "%s));\n}\n", RQSTP); |
336 |
|
|
} |
337 |
|
|
} |
338 |
|
|
} |
339 |
|
|
|
340 |
|
|
static void |
341 |
|
|
write_program(def, storage) |
342 |
|
|
definition *def; |
343 |
|
|
char *storage; |
344 |
|
|
{ |
345 |
|
|
version_list *vp; |
346 |
|
|
proc_list *proc; |
347 |
|
|
int filled; |
348 |
|
|
|
349 |
|
|
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { |
350 |
|
|
fprintf(fout, "\n"); |
351 |
|
|
if (storage != NULL) |
352 |
|
|
fprintf(fout, "%s ", storage); |
353 |
|
|
fprintf(fout, "void\t"); |
354 |
|
|
pvname(def->def_name, vp->vers_num); |
355 |
|
|
|
356 |
|
|
if (Cflag) { |
357 |
|
|
fprintf(fout, "(struct svc_req *%s, ", RQSTP); |
358 |
|
|
fprintf(fout, "SVCXPRT *%s);\n", TRANSP); |
359 |
|
|
} else { |
360 |
|
|
fprintf(fout, "();\n"); |
361 |
|
|
} |
362 |
|
|
fprintf(fout, "\n"); |
363 |
|
|
|
364 |
|
|
if (storage != NULL) |
365 |
|
|
fprintf(fout, "%s ", storage); |
366 |
|
|
fprintf(fout, "void\n"); |
367 |
|
|
pvname(def->def_name, vp->vers_num); |
368 |
|
|
|
369 |
|
|
if (Cflag) { |
370 |
|
|
fprintf(fout, "(struct svc_req *%s, ", RQSTP); |
371 |
|
|
fprintf(fout, "SVCXPRT *%s)\n", TRANSP); |
372 |
|
|
} else { |
373 |
|
|
fprintf(fout, "(%s, %s)\n", RQSTP, TRANSP); |
374 |
|
|
fprintf(fout, " struct svc_req *%s;\n", RQSTP); |
375 |
|
|
fprintf(fout, " SVCXPRT *%s;\n", TRANSP); |
376 |
|
|
} |
377 |
|
|
fprintf(fout, "{\n"); |
378 |
|
|
|
379 |
|
|
filled = 0; |
380 |
|
|
fprintf(fout, "\tunion {\n"); |
381 |
|
|
for (proc = vp->procs; proc != NULL; proc = proc->next) { |
382 |
|
|
if (proc->arg_num < 2) { /* single argument */ |
383 |
|
|
if (streq(proc->args.decls->decl.type, |
384 |
|
|
"void")) |
385 |
|
|
continue; |
386 |
|
|
filled = 1; |
387 |
|
|
fprintf(fout, "\t\t"); |
388 |
|
|
ptype(proc->args.decls->decl.prefix, |
389 |
|
|
proc->args.decls->decl.type, 0); |
390 |
|
|
pvname(proc->proc_name, vp->vers_num); |
391 |
|
|
fprintf(fout, "_arg;\n"); |
392 |
|
|
|
393 |
|
|
} else { |
394 |
|
|
filled = 1; |
395 |
|
|
fprintf(fout, "\t\t%s", proc->args.argname); |
396 |
|
|
fprintf(fout, " "); |
397 |
|
|
pvname(proc->proc_name, vp->vers_num); |
398 |
|
|
fprintf(fout, "_arg;\n"); |
399 |
|
|
} |
400 |
|
|
} |
401 |
|
|
if (!filled) |
402 |
|
|
fprintf(fout, "\t\tint fill;\n"); |
403 |
|
|
fprintf(fout, "\t} %s;\n", ARG); |
404 |
|
|
fprintf(fout, "\tchar *%s;\n", RESULT); |
405 |
|
|
|
406 |
|
|
if (Cflag) { |
407 |
|
|
fprintf(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT); |
408 |
|
|
fprintf(fout, |
409 |
|
|
"\tchar *(*%s)(char *, struct svc_req *);\n", |
410 |
|
|
ROUTINE); |
411 |
|
|
} else { |
412 |
|
|
fprintf(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", |
413 |
|
|
ARG, RESULT); |
414 |
|
|
fprintf(fout, "\tchar *(*%s)();\n", ROUTINE); |
415 |
|
|
} |
416 |
|
|
fprintf(fout, "\n"); |
417 |
|
|
|
418 |
|
|
if (callerflag) |
419 |
|
|
fprintf(fout, "\tcaller = transp;\n"); /*EVAS*/ |
420 |
|
|
if (timerflag) |
421 |
|
|
fprintf(fout, "\t_rpcsvcdirty = 1;\n"); |
422 |
|
|
fprintf(fout, "\tswitch (%s->rq_proc) {\n", RQSTP); |
423 |
|
|
if (!nullproc(vp->procs)) { |
424 |
|
|
fprintf(fout, "\tcase NULLPROC:\n"); |
425 |
|
|
fprintf(fout, |
426 |
|
|
Cflag |
427 |
|
|
? "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n" |
428 |
|
|
: "\t\t(void) svc_sendreply(%s, xdr_void, (char *)NULL);\n", |
429 |
|
|
TRANSP); |
430 |
|
|
print_return("\t\t"); |
431 |
|
|
fprintf(fout, "\n"); |
432 |
|
|
} |
433 |
|
|
for (proc = vp->procs; proc != NULL; proc = proc->next) { |
434 |
|
|
fprintf(fout, "\tcase %s:\n", proc->proc_name); |
435 |
|
|
if (proc->arg_num < 2) { /* single argument */ |
436 |
|
|
p_xdrfunc(ARG, proc->args.decls->decl.type); |
437 |
|
|
} else { |
438 |
|
|
p_xdrfunc(ARG, proc->args.argname); |
439 |
|
|
} |
440 |
|
|
p_xdrfunc(RESULT, proc->res_type); |
441 |
|
|
if (Cflag) |
442 |
|
|
fprintf(fout, |
443 |
|
|
"\t\t%s = (char *(*)(char *, struct svc_req *)) ", |
444 |
|
|
ROUTINE); |
445 |
|
|
else |
446 |
|
|
fprintf(fout, "\t\t%s = (char *(*)()) ", ROUTINE); |
447 |
|
|
|
448 |
|
|
if (newstyle) { /* new style: calls internal routine */ |
449 |
|
|
fprintf(fout,"_"); |
450 |
|
|
} |
451 |
|
|
if (!newstyle) |
452 |
|
|
pvname_svc(proc->proc_name, vp->vers_num); |
453 |
|
|
else |
454 |
|
|
pvname(proc->proc_name, vp->vers_num); |
455 |
|
|
fprintf(fout, ";\n"); |
456 |
|
|
fprintf(fout, "\t\tbreak;\n\n"); |
457 |
|
|
} |
458 |
|
|
fprintf(fout, "\tdefault:\n"); |
459 |
|
|
printerr("noproc", TRANSP); |
460 |
|
|
print_return("\t\t"); |
461 |
|
|
fprintf(fout, "\t}\n"); |
462 |
|
|
|
463 |
|
|
fprintf(fout, "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", ARG, ARG); |
464 |
|
|
printif ("getargs", TRANSP, "(caddr_t) &", ARG); |
465 |
|
|
printerr("decode", TRANSP); |
466 |
|
|
print_return("\t\t"); |
467 |
|
|
fprintf(fout, "\t}\n"); |
468 |
|
|
|
469 |
|
|
if (Cflag) |
470 |
|
|
fprintf(fout, "\t%s = (*%s)((char *)&%s, %s);\n", |
471 |
|
|
RESULT, ROUTINE, ARG, RQSTP); |
472 |
|
|
else |
473 |
|
|
fprintf(fout, "\t%s = (*%s)(&%s, %s);\n", |
474 |
|
|
RESULT, ROUTINE, ARG, RQSTP); |
475 |
|
|
fprintf(fout, |
476 |
|
|
"\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n", |
477 |
|
|
RESULT, TRANSP, RESULT, RESULT); |
478 |
|
|
printerr("systemerr", TRANSP); |
479 |
|
|
fprintf(fout, "\t}\n"); |
480 |
|
|
|
481 |
|
|
printif ("freeargs", TRANSP, "(caddr_t) &", ARG); |
482 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, "unable to free arguments"); |
483 |
|
|
print_err_message("\t\t"); |
484 |
|
|
fprintf(fout, "\t\texit(1);\n"); |
485 |
|
|
fprintf(fout, "\t}\n"); |
486 |
|
|
print_return("\t"); |
487 |
|
|
fprintf(fout, "}\n"); |
488 |
|
|
} |
489 |
|
|
} |
490 |
|
|
|
491 |
|
|
static void |
492 |
|
|
printerr(err, transp) |
493 |
|
|
char *err; |
494 |
|
|
char *transp; |
495 |
|
|
{ |
496 |
|
|
fprintf(fout, "\t\tsvcerr_%s(%s);\n", err, transp); |
497 |
|
|
} |
498 |
|
|
|
499 |
|
|
static void |
500 |
|
|
printif(proc, transp, prefix, arg) |
501 |
|
|
char *proc; |
502 |
|
|
char *transp; |
503 |
|
|
char *prefix; |
504 |
|
|
char *arg; |
505 |
|
|
{ |
506 |
|
|
fprintf(fout, "\tif (!svc_%s(%s, xdr_%s, %s%s)) {\n", |
507 |
|
|
proc, transp, arg, prefix, arg); |
508 |
|
|
} |
509 |
|
|
|
510 |
|
|
int |
511 |
|
|
nullproc(proc) |
512 |
|
|
proc_list *proc; |
513 |
|
|
{ |
514 |
|
|
for (; proc != NULL; proc = proc->next) { |
515 |
|
|
if (streq(proc->proc_num, "0")) |
516 |
|
|
return (1); |
517 |
|
|
} |
518 |
|
|
return (0); |
519 |
|
|
} |
520 |
|
|
|
521 |
|
|
static void |
522 |
|
|
write_inetmost(infile) |
523 |
|
|
char *infile; |
524 |
|
|
{ |
525 |
|
|
fprintf(fout, "\tSVCXPRT *%s;\n", TRANSP); |
526 |
|
|
fprintf(fout, "\tint sock;\n"); |
527 |
|
|
fprintf(fout, "\tint proto;\n"); |
528 |
|
|
fprintf(fout, "\tstruct sockaddr_in saddr;\n"); |
529 |
|
|
fprintf(fout, "\tint asize = sizeof (saddr);\n"); |
530 |
|
|
fprintf(fout, "\n"); |
531 |
|
|
fprintf(fout, |
532 |
|
|
"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n"); |
533 |
|
|
fprintf(fout, "\t\tint ssize = sizeof (int);\n\n"); |
534 |
|
|
fprintf(fout, "\t\tif (saddr.sin_family != AF_INET)\n"); |
535 |
|
|
fprintf(fout, "\t\t\texit(1);\n"); |
536 |
|
|
fprintf(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n"); |
537 |
|
|
fprintf(fout, "\t\t (char *)&_rpcfdtype, &ssize) == -1)\n"); |
538 |
|
|
fprintf(fout, "\t\t\texit(1);\n"); |
539 |
|
|
fprintf(fout, "\t\tsock = 0;\n"); |
540 |
|
|
fprintf(fout, "\t\t_rpcpmstart = 1;\n"); |
541 |
|
|
fprintf(fout, "\t\tproto = 0;\n"); |
542 |
|
|
open_log_file(infile, "\t\t"); |
543 |
|
|
fprintf(fout, "\t} else {\n"); |
544 |
|
|
write_rpc_svc_fg(infile, "\t\t"); |
545 |
|
|
fprintf(fout, "\t\tsock = RPC_ANYSOCK;\n"); |
546 |
|
|
print_pmapunset("\t\t"); |
547 |
|
|
fprintf(fout, "\t}\n"); |
548 |
|
|
} |
549 |
|
|
|
550 |
|
|
static void |
551 |
|
|
print_return(space) |
552 |
|
|
char *space; |
553 |
|
|
{ |
554 |
|
|
if (exitnow) |
555 |
|
|
fprintf(fout, "%sexit(0);\n", space); |
556 |
|
|
else { |
557 |
|
|
if (timerflag) |
558 |
|
|
fprintf(fout, "%s_rpcsvcdirty = 0;\n", space); |
559 |
|
|
fprintf(fout, "%sreturn;\n", space); |
560 |
|
|
} |
561 |
|
|
} |
562 |
|
|
|
563 |
|
|
static void |
564 |
|
|
print_pmapunset(space) |
565 |
|
|
char *space; |
566 |
|
|
{ |
567 |
|
|
version_list *vp; |
568 |
|
|
definition *def; |
569 |
|
|
list *l; |
570 |
|
|
|
571 |
|
|
for (l = defined; l != NULL; l = l->next) { |
572 |
|
|
def = (definition *) l->val; |
573 |
|
|
if (def->def_kind == DEF_PROGRAM) { |
574 |
|
|
for (vp = def->def.pr.versions; vp != NULL; |
575 |
|
|
vp = vp->next) { |
576 |
|
|
fprintf(fout, "%s(void) pmap_unset(%s, %s);\n", |
577 |
|
|
space, def->def_name, vp->vers_name); |
578 |
|
|
} |
579 |
|
|
} |
580 |
|
|
} |
581 |
|
|
} |
582 |
|
|
|
583 |
|
|
static void |
584 |
|
|
print_err_message(space) |
585 |
|
|
char *space; |
586 |
|
|
{ |
587 |
|
|
if (logflag) |
588 |
|
|
fprintf(fout, "%ssyslog(LOG_ERR, \"%%s\", \"%s\");\n", space, _errbuf); |
589 |
|
|
else if (inetdflag || pmflag) |
590 |
|
|
fprintf(fout, "%s_msgout(\"%s\");\n", space, _errbuf); |
591 |
|
|
else |
592 |
|
|
fprintf(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf); |
593 |
|
|
} |
594 |
|
|
|
595 |
|
|
/* |
596 |
|
|
* Write the server auxiliary function (_msgout, timeout) |
597 |
|
|
*/ |
598 |
|
|
void |
599 |
|
|
write_svc_aux(nomain) |
600 |
|
|
int nomain; |
601 |
|
|
{ |
602 |
|
|
if (!logflag) |
603 |
|
|
write_msg_out(); |
604 |
|
|
if (!nomain) |
605 |
|
|
write_timeout_func(); |
606 |
|
|
if (callerflag) /*EVAS*/ |
607 |
|
|
write_caller_func(); /*EVAS*/ |
608 |
|
|
} |
609 |
|
|
|
610 |
|
|
/* |
611 |
|
|
* Write the _msgout function |
612 |
|
|
*/ |
613 |
|
|
|
614 |
|
|
void |
615 |
|
|
write_msg_out() |
616 |
|
|
{ |
617 |
|
|
fprintf(fout, "\n"); |
618 |
|
|
fprintf(fout, "static\n"); |
619 |
|
|
if (!Cflag) { |
620 |
|
|
fprintf(fout, "void _msgout(msg)\n"); |
621 |
|
|
fprintf(fout, "\tchar *msg;\n"); |
622 |
|
|
} else { |
623 |
|
|
fprintf(fout, "void _msgout(char *msg)\n"); |
624 |
|
|
} |
625 |
|
|
fprintf(fout, "{\n"); |
626 |
|
|
fprintf(fout, "#ifdef RPC_SVC_FG\n"); |
627 |
|
|
if (inetdflag || pmflag) |
628 |
|
|
fprintf(fout, "\tif (_rpcpmstart)\n"); |
629 |
|
|
fprintf(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n"); |
630 |
|
|
fprintf(fout, "\telse {\n"); |
631 |
|
|
fprintf(fout, "\t\t(void) write(STDERR_FILENO, msg, strlen(msg));\n"); |
632 |
|
|
fprintf(fout, "\t\t(void) write(STDERR_FILENO, \"\\n\", 1);\n"); |
633 |
|
|
fprintf(fout, "\t}\n#else\n"); |
634 |
|
|
fprintf(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n"); |
635 |
|
|
fprintf(fout, "#endif\n"); |
636 |
|
|
fprintf(fout, "}\n"); |
637 |
|
|
} |
638 |
|
|
|
639 |
|
|
/* |
640 |
|
|
* Write the timeout function |
641 |
|
|
*/ |
642 |
|
|
static void |
643 |
|
|
write_timeout_func() |
644 |
|
|
{ |
645 |
|
|
if (!timerflag) |
646 |
|
|
return; |
647 |
|
|
fprintf(fout, "\n"); |
648 |
|
|
fprintf(fout, "static void\n"); |
649 |
|
|
fprintf(fout, "closedown()\n"); |
650 |
|
|
fprintf(fout, "{\n"); |
651 |
|
|
fprintf(fout, "\tint save_errno = errno;\n\n"); |
652 |
|
|
fprintf(fout, "\tif (_rpcsvcdirty == 0) {\n"); |
653 |
|
|
fprintf(fout, "\t\textern fd_set *__svc_fdset;\n"); |
654 |
|
|
fprintf(fout, "\t\textern int __svc_fdsetsize;\n"); |
655 |
|
|
fprintf(fout, "\t\tint i, openfd;\n"); |
656 |
|
|
if (tirpcflag && pmflag) { |
657 |
|
|
fprintf(fout, "\t\tstruct t_info tinfo;\n\n"); |
658 |
|
|
fprintf(fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n"); |
659 |
|
|
} else { |
660 |
|
|
fprintf(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n"); |
661 |
|
|
} |
662 |
|
|
fprintf(fout, "\t\t\t_exit(0);\n"); |
663 |
|
|
fprintf(fout, "\t\tfor (i = 0, openfd = 0; i < __svc_fdsetsize && openfd < 2; i++)\n"); |
664 |
|
|
fprintf(fout, "\t\t\tif (FD_ISSET(i, __svc_fdset))\n"); |
665 |
|
|
fprintf(fout, "\t\t\t\topenfd++;\n"); |
666 |
|
|
fprintf(fout, "\t\tif (openfd <= (_rpcpmstart?0:1))\n"); |
667 |
|
|
fprintf(fout, "\t\t\t_exit(0);\n"); |
668 |
|
|
fprintf(fout, "\t}\n"); |
669 |
|
|
fprintf(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n"); |
670 |
|
|
fprintf(fout, "\terrno = save_errno;\n"); |
671 |
|
|
fprintf(fout, "}\n"); |
672 |
|
|
} |
673 |
|
|
|
674 |
|
|
static void |
675 |
|
|
write_caller_func() /*EVAS*/ |
676 |
|
|
{ |
677 |
|
|
#define P(s) fprintf(fout, s); |
678 |
|
|
|
679 |
|
|
P("\n"); |
680 |
|
|
P("char *svc_caller()\n"); |
681 |
|
|
P("{\n"); |
682 |
|
|
P(" struct sockaddr_in actual;\n"); |
683 |
|
|
P(" struct hostent *hp;\n"); |
684 |
|
|
P(" static struct in_addr prev;\n"); |
685 |
|
|
P(" static char cname[256];\n\n"); |
686 |
|
|
|
687 |
|
|
P(" actual = *svc_getcaller(caller);\n\n"); |
688 |
|
|
|
689 |
|
|
P(" if (memcmp((char *)&actual.sin_addr, (char *)&prev,\n"); |
690 |
|
|
P(" sizeof(struct in_addr)) == 0)\n"); |
691 |
|
|
P(" return (cname);\n\n"); |
692 |
|
|
|
693 |
|
|
P(" prev = actual.sin_addr;\n\n"); |
694 |
|
|
|
695 |
|
|
P(" hp = gethostbyaddr((char *) &actual.sin_addr, sizeof(actual.sin_addr), AF_INET);\n"); |
696 |
|
|
P(" if (hp == NULL) { /* dummy one up */\n"); |
697 |
|
|
P(" extern char *inet_ntoa();\n"); |
698 |
|
|
P(" strlcpy(cname, inet_ntoa(actual.sin_addr), sizeof cname);\n"); |
699 |
|
|
P(" } else {\n"); |
700 |
|
|
P(" strlcpy(cname, hp->h_name, sizeof cname);\n"); |
701 |
|
|
P(" }\n\n"); |
702 |
|
|
|
703 |
|
|
P(" return (cname);\n"); |
704 |
|
|
P("}\n"); |
705 |
|
|
|
706 |
|
|
#undef P |
707 |
|
|
} |
708 |
|
|
|
709 |
|
|
/* |
710 |
|
|
* Write the most of port monitor support |
711 |
|
|
*/ |
712 |
|
|
static void |
713 |
|
|
write_pm_most(infile, netflag) |
714 |
|
|
char *infile; |
715 |
|
|
int netflag; |
716 |
|
|
{ |
717 |
|
|
list *l; |
718 |
|
|
definition *def; |
719 |
|
|
version_list *vp; |
720 |
|
|
|
721 |
|
|
fprintf(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n"); |
722 |
|
|
fprintf(fout, "\t\t(!strcmp(mname, \"sockmod\") ||"); |
723 |
|
|
fprintf(fout, " !strcmp(mname, \"timod\"))) {\n"); |
724 |
|
|
fprintf(fout, "\t\tchar *netid;\n"); |
725 |
|
|
if (!netflag) { /* Not included by -n option */ |
726 |
|
|
fprintf(fout, "\t\tstruct netconfig *nconf = NULL;\n"); |
727 |
|
|
fprintf(fout, "\t\tSVCXPRT *%s;\n", TRANSP); |
728 |
|
|
} |
729 |
|
|
if (timerflag) |
730 |
|
|
fprintf(fout, "\t\tint pmclose;\n"); |
731 |
|
|
/* not necessary, defined in /usr/include/stdlib */ |
732 |
|
|
/* fprintf(fout, "\t\textern char *getenv();\n");*/ |
733 |
|
|
fprintf(fout, "\n"); |
734 |
|
|
fprintf(fout, "\t\t_rpcpmstart = 1;\n"); |
735 |
|
|
if (logflag) |
736 |
|
|
open_log_file(infile, "\t\t"); |
737 |
|
|
fprintf(fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n"); |
738 |
|
|
snprintf(_errbuf, sizeof _errbuf, "cannot get transport name"); |
739 |
|
|
print_err_message("\t\t\t"); |
740 |
|
|
fprintf(fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n"); |
741 |
|
|
snprintf(_errbuf, sizeof _errbuf, "cannot get transport info"); |
742 |
|
|
print_err_message("\t\t\t"); |
743 |
|
|
fprintf(fout, "\t\t}\n"); |
744 |
|
|
/* |
745 |
|
|
* A kludgy support for inetd services. Inetd only works with |
746 |
|
|
* sockmod, and RPC works only with timod, hence all this jugglery |
747 |
|
|
*/ |
748 |
|
|
fprintf(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n"); |
749 |
|
|
fprintf(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n"); |
750 |
|
|
snprintf(_errbuf, sizeof _errbuf, "could not get the right module"); |
751 |
|
|
print_err_message("\t\t\t\t"); |
752 |
|
|
fprintf(fout, "\t\t\t\texit(1);\n"); |
753 |
|
|
fprintf(fout, "\t\t\t}\n"); |
754 |
|
|
fprintf(fout, "\t\t}\n"); |
755 |
|
|
if (timerflag) |
756 |
|
|
fprintf(fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n"); |
757 |
|
|
fprintf(fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n", |
758 |
|
|
TRANSP); |
759 |
|
|
snprintf(_errbuf, sizeof _errbuf, "cannot create server handle"); |
760 |
|
|
print_err_message("\t\t\t"); |
761 |
|
|
fprintf(fout, "\t\t\texit(1);\n"); |
762 |
|
|
fprintf(fout, "\t\t}\n"); |
763 |
|
|
fprintf(fout, "\t\tif (nconf)\n"); |
764 |
|
|
fprintf(fout, "\t\t\tfreenetconfigent(nconf);\n"); |
765 |
|
|
for (l = defined; l != NULL; l = l->next) { |
766 |
|
|
def = (definition *) l->val; |
767 |
|
|
if (def->def_kind != DEF_PROGRAM) { |
768 |
|
|
continue; |
769 |
|
|
} |
770 |
|
|
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { |
771 |
|
|
fprintf(fout, |
772 |
|
|
"\t\tif (!svc_reg(%s, %s, %s, ", |
773 |
|
|
TRANSP, def->def_name, vp->vers_name); |
774 |
|
|
pvname(def->def_name, vp->vers_num); |
775 |
|
|
fprintf(fout, ", 0)) {\n"); |
776 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, "unable to register (%s, %s).", |
777 |
|
|
def->def_name, vp->vers_name); |
778 |
|
|
print_err_message("\t\t\t"); |
779 |
|
|
fprintf(fout, "\t\t\texit(1);\n"); |
780 |
|
|
fprintf(fout, "\t\t}\n"); |
781 |
|
|
} |
782 |
|
|
} |
783 |
|
|
if (timerflag) { |
784 |
|
|
fprintf(fout, "\t\tif (pmclose) {\n"); |
785 |
|
|
fprintf(fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n", |
786 |
|
|
Cflag? "(SIG_PF)" : "(void(*)())"); |
787 |
|
|
fprintf(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n"); |
788 |
|
|
fprintf(fout, "\t\t}\n"); |
789 |
|
|
} |
790 |
|
|
fprintf(fout, "\t\tsvc_run();\n"); |
791 |
|
|
fprintf(fout, "\t\texit(1);\n"); |
792 |
|
|
fprintf(fout, "\t\t/* NOTREACHED */\n"); |
793 |
|
|
fprintf(fout, "\t}\n"); |
794 |
|
|
} |
795 |
|
|
|
796 |
|
|
/* |
797 |
|
|
* Support for backgrounding the server if self started. |
798 |
|
|
*/ |
799 |
|
|
static void |
800 |
|
|
write_rpc_svc_fg(infile, sp) |
801 |
|
|
char *infile; |
802 |
|
|
char *sp; |
803 |
|
|
{ |
804 |
|
|
fprintf(fout, "#ifndef RPC_SVC_FG\n"); |
805 |
|
|
fprintf(fout, "%sint size;\n", sp); |
806 |
|
|
if (tirpcflag) |
807 |
|
|
fprintf(fout, "%sstruct rlimit rl;\n", sp); |
808 |
|
|
if (inetdflag) { |
809 |
|
|
fprintf(fout, "%sint i;\n\n", sp); |
810 |
|
|
fprintf(fout, "%spid_t pid;\n\n", sp); |
811 |
|
|
} |
812 |
|
|
fprintf(fout, "%spid = fork();\n", sp); |
813 |
|
|
fprintf(fout, "%sif (pid < 0) {\n", sp); |
814 |
|
|
fprintf(fout, "%s\tperror(\"cannot fork\");\n", sp); |
815 |
|
|
fprintf(fout, "%s\texit(1);\n", sp); |
816 |
|
|
fprintf(fout, "%s}\n", sp); |
817 |
|
|
fprintf(fout, "%sif (pid)\n", sp); |
818 |
|
|
fprintf(fout, "%s\texit(0);\n", sp); |
819 |
|
|
/* get number of file descriptors */ |
820 |
|
|
if (tirpcflag) { |
821 |
|
|
fprintf(fout, "%srl.rlim_max = 0;\n", sp); |
822 |
|
|
fprintf(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp); |
823 |
|
|
fprintf(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp); |
824 |
|
|
fprintf(fout, "%s\texit(1);\n", sp); |
825 |
|
|
} else { |
826 |
|
|
fprintf(fout, "%ssize = getdtablesize();\n", sp); |
827 |
|
|
} |
828 |
|
|
|
829 |
|
|
fprintf(fout, "%sfor (i = 0; i < size; i++)\n", sp); |
830 |
|
|
fprintf(fout, "%s\t(void) close(i);\n", sp); |
831 |
|
|
/* Redirect stderr and stdout to console */ |
832 |
|
|
fprintf(fout, "%si = open(\"/dev/console\", 2);\n", sp); |
833 |
|
|
fprintf(fout, "%s(void) dup2(i, 1);\n", sp); |
834 |
|
|
fprintf(fout, "%s(void) dup2(i, 2);\n", sp); |
835 |
|
|
/* This removes control of the controlling terminal */ |
836 |
|
|
if (tirpcflag) |
837 |
|
|
fprintf(fout, "%ssetsid();\n", sp); |
838 |
|
|
else { |
839 |
|
|
fprintf(fout, "%si = open(\"/dev/tty\", 2);\n", sp); |
840 |
|
|
fprintf(fout, "%sif (i >= 0) {\n", sp); |
841 |
|
|
fprintf(fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp); |
842 |
|
|
fprintf(fout, "%s\t(void) close(i);\n", sp); |
843 |
|
|
fprintf(fout, "%s}\n", sp); |
844 |
|
|
} |
845 |
|
|
if (!logflag) |
846 |
|
|
open_log_file(infile, sp); |
847 |
|
|
fprintf(fout, "#endif\n"); |
848 |
|
|
if (logflag) |
849 |
|
|
open_log_file(infile, sp); |
850 |
|
|
} |
851 |
|
|
|
852 |
|
|
static void |
853 |
|
|
open_log_file(infile, sp) |
854 |
|
|
char *infile; |
855 |
|
|
char *sp; |
856 |
|
|
{ |
857 |
|
|
char *s; |
858 |
|
|
|
859 |
|
|
s = strrchr(infile, '.'); |
860 |
|
|
if (s) |
861 |
|
|
*s = '\0'; |
862 |
|
|
fprintf(fout,"%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile); |
863 |
|
|
if (s) |
864 |
|
|
*s = '.'; |
865 |
|
|
} |
866 |
|
|
|
867 |
|
|
/* |
868 |
|
|
* write a registration for the given transport for Inetd |
869 |
|
|
*/ |
870 |
|
|
void |
871 |
|
|
write_inetd_register(transp) |
872 |
|
|
char *transp; |
873 |
|
|
{ |
874 |
|
|
list *l; |
875 |
|
|
definition *def; |
876 |
|
|
version_list *vp; |
877 |
|
|
char *sp; |
878 |
|
|
int isudp; |
879 |
|
|
char tmpbuf[32]; |
880 |
|
|
|
881 |
|
|
if (inetdflag) |
882 |
|
|
sp = "\t"; |
883 |
|
|
else |
884 |
|
|
sp = ""; |
885 |
|
|
if (streq(transp, "udp")) |
886 |
|
|
isudp = 1; |
887 |
|
|
else |
888 |
|
|
isudp = 0; |
889 |
|
|
fprintf(fout, "\n"); |
890 |
|
|
if (inetdflag) { |
891 |
|
|
fprintf(fout, "\tif (_rpcfdtype == 0 || _rpcfdtype == %s) {\n", |
892 |
|
|
isudp ? "SOCK_DGRAM" : "SOCK_STREAM"); |
893 |
|
|
} |
894 |
|
|
if (inetdflag && streq(transp, "tcp")) { |
895 |
|
|
fprintf(fout, "%s\tif (_rpcpmstart)\n", sp); |
896 |
|
|
|
897 |
|
|
fprintf(fout, "%s\t\t%s = svc%s_create(%s", |
898 |
|
|
sp, TRANSP, "fd", inetdflag? "sock": "RPC_ANYSOCK"); |
899 |
|
|
if (!isudp) |
900 |
|
|
fprintf(fout, ", 0, 0"); |
901 |
|
|
fprintf(fout, ");\n"); |
902 |
|
|
|
903 |
|
|
fprintf(fout, "%s\telse\n", sp); |
904 |
|
|
|
905 |
|
|
fprintf(fout, "%s\t\t%s = svc%s_create(%s", |
906 |
|
|
sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK"); |
907 |
|
|
if (!isudp) |
908 |
|
|
fprintf(fout, ", 0, 0"); |
909 |
|
|
fprintf(fout, ");\n"); |
910 |
|
|
|
911 |
|
|
} else { |
912 |
|
|
fprintf(fout, "%s\t%s = svc%s_create(%s", |
913 |
|
|
sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK"); |
914 |
|
|
if (!isudp) |
915 |
|
|
fprintf(fout, ", 0, 0"); |
916 |
|
|
fprintf(fout, ");\n"); |
917 |
|
|
} |
918 |
|
|
fprintf(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP); |
919 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, "cannot create %s service.", transp); |
920 |
|
|
(void) snprintf(tmpbuf, sizeof tmpbuf, "%s\t\t", sp); |
921 |
|
|
print_err_message(tmpbuf); |
922 |
|
|
fprintf(fout, "%s\t\texit(1);\n", sp); |
923 |
|
|
fprintf(fout, "%s\t}\n", sp); |
924 |
|
|
|
925 |
|
|
if (inetdflag) { |
926 |
|
|
fprintf(fout, "%s\tif (!_rpcpmstart)\n\t", sp); |
927 |
|
|
fprintf(fout, "%s\tproto = IPPROTO_%s;\n", |
928 |
|
|
sp, isudp ? "UDP": "TCP"); |
929 |
|
|
} |
930 |
|
|
for (l = defined; l != NULL; l = l->next) { |
931 |
|
|
def = (definition *) l->val; |
932 |
|
|
if (def->def_kind != DEF_PROGRAM) { |
933 |
|
|
continue; |
934 |
|
|
} |
935 |
|
|
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { |
936 |
|
|
fprintf(fout, "%s\tif (!svc_register(%s, %s, %s, ", |
937 |
|
|
sp, TRANSP, def->def_name, vp->vers_name); |
938 |
|
|
pvname(def->def_name, vp->vers_num); |
939 |
|
|
if (inetdflag) |
940 |
|
|
fprintf(fout, ", proto)) {\n"); |
941 |
|
|
else |
942 |
|
|
fprintf(fout, ", IPPROTO_%s)) {\n", |
943 |
|
|
isudp ? "UDP": "TCP"); |
944 |
|
|
(void) snprintf(_errbuf, sizeof _errbuf, "unable to register (%s, %s, %s).", |
945 |
|
|
def->def_name, vp->vers_name, transp); |
946 |
|
|
print_err_message(tmpbuf); |
947 |
|
|
fprintf(fout, "%s\t\texit(1);\n", sp); |
948 |
|
|
fprintf(fout, "%s\t}\n", sp); |
949 |
|
|
} |
950 |
|
|
} |
951 |
|
|
if (inetdflag) |
952 |
|
|
fprintf(fout, "\t}\n"); |
953 |
|
|
} |