rpc_svcout.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. /*
  2. * From: @(#)rpc_svcout.c 1.29 89/03/30
  3. *
  4. * Copyright (c) 2010, Oracle America, Inc.
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are
  7. * met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above
  12. * copyright notice, this list of conditions and the following
  13. * disclaimer in the documentation and/or other materials
  14. * provided with the distribution.
  15. * * Neither the name of the "Oracle America, Inc." nor the names of its
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  24. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  26. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  28. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. /*
  33. * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
  34. */
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include "rpc_parse.h"
  38. #include "rpc_util.h"
  39. #include "proto.h"
  40. static const char RQSTP[] = "rqstp";
  41. static const char TRANSP[] = "transp";
  42. static const char ARG[] = "argument";
  43. static const char RESULT[] = "result";
  44. static const char ROUTINE[] = "local";
  45. static char RETVAL[] = "retval";
  46. char _errbuf[256]; /* For all messages */
  47. static void internal_proctype (const proc_list * plist);
  48. static void p_xdrfunc (const char *rname, const char *typename);
  49. static void write_real_program (const definition * def);
  50. static void write_program (const definition * def, const char *storage);
  51. static void printerr (const char *err, const char *transp);
  52. static void printif (const char *proc, const char *transp, const char *arg);
  53. static void write_inetmost (const char *infile);
  54. static void print_return (const char *space);
  55. static void print_pmapunset (const char *space);
  56. static void print_err_message (const char *space);
  57. static void write_timeout_func (void);
  58. static void write_pm_most (const char *infile, int netflag);
  59. static void write_rpc_svc_fg (const char *infile, const char *sp);
  60. static void open_log_file (const char *infile, const char *sp);
  61. static void
  62. p_xdrfunc (const char *rname, const char *typename)
  63. {
  64. if (Cflag)
  65. f_print (fout, "\t\t_xdr_%s = (xdrproc_t) xdr_%s;\n", rname,
  66. stringfix (typename));
  67. else
  68. f_print (fout, "\t\t_xdr_%s = xdr_%s;\n", rname, stringfix (typename));
  69. }
  70. void
  71. internal_proctype (const proc_list * plist)
  72. {
  73. f_print (fout, "static ");
  74. ptype (plist->res_prefix, plist->res_type, 1);
  75. f_print (fout, "*");
  76. }
  77. /*
  78. * write most of the service, that is, everything but the registrations.
  79. */
  80. void
  81. write_most (const char *infile /* our name */ , int netflag, int nomain)
  82. {
  83. if (inetdflag || pmflag)
  84. {
  85. const char *var_type;
  86. /* WHY? */
  87. var_type = (nomain ? "extern" : "");
  88. f_print (fout, "%s int _rpcpmstart;", var_type);
  89. f_print (fout, "\t\t/* Started by a port monitor ? */\n");
  90. if (!tirpcflag)
  91. {
  92. f_print (fout, "%s int _rpcfdtype;", var_type);
  93. f_print (fout, "\t\t/* Whether Stream or Datagram ? */\n");
  94. }
  95. if (timerflag)
  96. {
  97. #if 0
  98. f_print (fout, "%s int _rpcsvcdirty;", var_type);
  99. f_print (fout, "\t/* Still serving ? */\n");
  100. #else
  101. f_print(fout, " /* States a server can be in wrt request */\n\n");
  102. f_print(fout, "#define\t_IDLE 0\n");
  103. f_print(fout, "#define\t_SERVED 1\n");
  104. f_print(fout, "#define\t_SERVING 2\n\n");
  105. f_print(fout, "static int _rpcsvcstate = _IDLE;");
  106. f_print(fout, "\t /* Set when a request is serviced */\n");
  107. if (mtflag)
  108. {
  109. f_print (fout, "mutex_t _svcstate_lock;");
  110. f_print (fout,
  111. "\t\t\t/* Mutex lock for variable_rpcsvcstate */\n");
  112. }
  113. #endif
  114. }
  115. write_svc_aux (nomain);
  116. }
  117. /* write out dispatcher and stubs */
  118. write_programs (nomain ? NULL : "static");
  119. if (nomain)
  120. return;
  121. if (Cflag)
  122. f_print (fout, "\nint\nmain (int argc, char **argv)\n");
  123. else
  124. {
  125. f_print (fout, "\nint\nmain (argc, argv)\n");
  126. f_print (fout, "\tint argc;\n");
  127. f_print (fout, "\tchar **argv;\n");
  128. }
  129. f_print (fout, "{\n");
  130. if (inetdflag)
  131. {
  132. write_inetmost (infile); /* Includes call to write_rpc_svc_fg() */
  133. }
  134. else
  135. {
  136. if (tirpcflag)
  137. {
  138. if (netflag)
  139. {
  140. f_print (fout, "\tregister SVCXPRT *%s;\n", TRANSP);
  141. f_print (fout, "\tstruct netconfig *nconf = NULL;\n");
  142. }
  143. f_print (fout, "\tpid_t pid;\n");
  144. f_print (fout, "\tint i;\n");
  145. f_print (fout, "\tchar mname[FMNAMESZ + 1];\n\n");
  146. if (mtflag & timerflag)
  147. f_print (fout,
  148. "\tmutex_init (&_svcstate_lock, USYNC_THREAD, NULL);\n");
  149. write_pm_most (infile, netflag);
  150. f_print (fout, "\telse {\n");
  151. write_rpc_svc_fg (infile, "\t\t");
  152. f_print (fout, "\t}\n");
  153. }
  154. else
  155. {
  156. f_print (fout, "\tregister SVCXPRT *%s;\n", TRANSP);
  157. f_print (fout, "\n");
  158. print_pmapunset ("\t");
  159. }
  160. }
  161. if (logflag && !inetdflag)
  162. {
  163. open_log_file (infile, "\t");
  164. }
  165. }
  166. /*
  167. * write a registration for the given transport
  168. */
  169. void
  170. write_netid_register (const char *transp)
  171. {
  172. list *l;
  173. definition *def;
  174. version_list *vp;
  175. const char *sp;
  176. char tmpbuf[32];
  177. sp = "";
  178. f_print (fout, "\n");
  179. f_print (fout, "%s\tnconf = getnetconfigent (\"%s\");\n", sp, transp);
  180. f_print (fout, "%s\tif (nconf == NULL) {\n", sp);
  181. (void) sprintf (_errbuf, "cannot find %s netid.", transp);
  182. sprintf (tmpbuf, "%s\t\t", sp);
  183. print_err_message (tmpbuf);
  184. f_print (fout, "%s\t\texit (1);\n", sp);
  185. f_print (fout, "%s\t}\n", sp);
  186. f_print (fout, "%s\t%s = svc_tli_create (RPC_ANYFD, nconf, 0, 0, 0);\n",
  187. sp, TRANSP /*, transp *//* ?!?... */ );
  188. f_print (fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
  189. sprintf (_errbuf, "cannot create %s service.", transp);
  190. print_err_message (tmpbuf);
  191. f_print (fout, "%s\t\texit (1);\n", sp);
  192. f_print (fout, "%s\t}\n", sp);
  193. for (l = defined; l != NULL; l = l->next)
  194. {
  195. def = (definition *) l->val;
  196. if (def->def_kind != DEF_PROGRAM)
  197. {
  198. continue;
  199. }
  200. for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
  201. {
  202. f_print (fout, "%s\t(void) rpcb_unset (%s, %s, nconf);\n",
  203. sp, def->def_name, vp->vers_name);
  204. f_print (fout, "%s\tif (!svc_reg (%s, %s, %s, ",
  205. sp, TRANSP, def->def_name, vp->vers_name);
  206. pvname (def->def_name, vp->vers_num);
  207. f_print (fout, ", nconf)) {\n");
  208. (void) sprintf (_errbuf, "unable to register (%s, %s, %s).",
  209. def->def_name, vp->vers_name, transp);
  210. print_err_message (tmpbuf);
  211. f_print (fout, "%s\t\texit (1);\n", sp);
  212. f_print (fout, "%s\t}\n", sp);
  213. }
  214. }
  215. f_print (fout, "%s\tfreenetconfigent (nconf);\n", sp);
  216. }
  217. /*
  218. * write a registration for the given transport for TLI
  219. */
  220. void
  221. write_nettype_register (const char *transp)
  222. {
  223. list *l;
  224. definition *def;
  225. version_list *vp;
  226. for (l = defined; l != NULL; l = l->next)
  227. {
  228. def = (definition *) l->val;
  229. if (def->def_kind != DEF_PROGRAM)
  230. {
  231. continue;
  232. }
  233. for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
  234. {
  235. f_print (fout, "\tif (!svc_create (");
  236. pvname (def->def_name, vp->vers_num);
  237. f_print (fout, ", %s, %s, \"%s\")) {\n ",
  238. def->def_name, vp->vers_name, transp);
  239. (void) sprintf (_errbuf,
  240. "unable to create (%s, %s) for %s.",
  241. def->def_name, vp->vers_name, transp);
  242. print_err_message ("\t\t");
  243. f_print (fout, "\t\texit (1);\n");
  244. f_print (fout, "\t}\n");
  245. }
  246. }
  247. }
  248. /*
  249. * write the rest of the service
  250. */
  251. void
  252. write_rest (void)
  253. {
  254. f_print (fout, "\n");
  255. if (inetdflag)
  256. {
  257. f_print (fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
  258. (void) sprintf (_errbuf, "could not create a handle");
  259. print_err_message ("\t\t");
  260. f_print (fout, "\t\texit (1);\n");
  261. f_print (fout, "\t}\n");
  262. if (timerflag)
  263. {
  264. f_print (fout, "\tif (_rpcpmstart) {\n");
  265. f_print (fout,
  266. "\t\t(void) signal (SIGALRM, %s closedown);\n",
  267. Cflag ? "(SIG_PF)" : "(void(*)())");
  268. f_print (fout, "\t\t(void) alarm (_RPCSVC_CLOSEDOWN);\n");
  269. f_print (fout, "\t}\n");
  270. }
  271. }
  272. f_print (fout, "\tsvc_run ();\n");
  273. (void) sprintf (_errbuf, "svc_run returned");
  274. print_err_message ("\t");
  275. f_print (fout, "\texit (1);\n");
  276. f_print (fout, "\t/* NOTREACHED */\n");
  277. f_print (fout, "}\n");
  278. }
  279. void
  280. write_programs (const char *storage)
  281. {
  282. list *l;
  283. definition *def;
  284. /* write out stubs for procedure definitions */
  285. for (l = defined; l != NULL; l = l->next)
  286. {
  287. def = (definition *) l->val;
  288. if (def->def_kind == DEF_PROGRAM)
  289. {
  290. write_real_program (def);
  291. }
  292. }
  293. /* write out dispatcher for each program */
  294. for (l = defined; l != NULL; l = l->next)
  295. {
  296. def = (definition *) l->val;
  297. if (def->def_kind == DEF_PROGRAM)
  298. {
  299. write_program (def, storage);
  300. }
  301. }
  302. }
  303. /* write out definition of internal function (e.g. _printmsg_1(...))
  304. which calls server's defintion of actual function (e.g. printmsg_1(...)).
  305. Unpacks single user argument of printmsg_1 to call-by-value format
  306. expected by printmsg_1. */
  307. static void
  308. write_real_program (const definition * def)
  309. {
  310. version_list *vp;
  311. proc_list *proc;
  312. decl_list *l;
  313. if (!newstyle)
  314. return; /* not needed for old style */
  315. for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
  316. {
  317. for (proc = vp->procs; proc != NULL; proc = proc->next)
  318. {
  319. fprintf (fout, "\n");
  320. if (!mtflag)
  321. internal_proctype (proc);
  322. else
  323. f_print (fout, "int");
  324. f_print (fout, "\n_");
  325. pvname (proc->proc_name, vp->vers_num);
  326. if (Cflag)
  327. {
  328. f_print (fout, " (");
  329. /* arg name */
  330. if (proc->arg_num > 1)
  331. f_print (fout, "%s", proc->args.argname);
  332. else
  333. ptype (proc->args.decls->decl.prefix,
  334. proc->args.decls->decl.type, 0);
  335. if (mtflag)
  336. {
  337. f_print(fout, " *argp, void *%s, struct svc_req *%s)\n",
  338. RESULT, RQSTP);
  339. }
  340. else
  341. f_print (fout, " *argp, struct svc_req *%s)\n",
  342. RQSTP);
  343. }
  344. else
  345. {
  346. if (mtflag)
  347. f_print(fout, " (argp, %s, %s)\n", RESULT, RQSTP);
  348. else
  349. f_print (fout, " (argp, %s)\n", RQSTP);
  350. /* arg name */
  351. if (proc->arg_num > 1)
  352. f_print (fout, "\t%s *argp;\n", proc->args.argname);
  353. else
  354. {
  355. f_print (fout, "\t");
  356. ptype (proc->args.decls->decl.prefix,
  357. proc->args.decls->decl.type, 0);
  358. f_print (fout, " *argp;\n");
  359. }
  360. f_print (fout, " struct svc_req *%s;\n", RQSTP);
  361. }
  362. f_print (fout, "{\n");
  363. f_print (fout, "\treturn (");
  364. if (Cflag || mtflag)
  365. pvname_svc (proc->proc_name, vp->vers_num);
  366. else
  367. pvname (proc->proc_name, vp->vers_num);
  368. f_print (fout, "(");
  369. if (proc->arg_num < 2)
  370. { /* single argument */
  371. if (!streq (proc->args.decls->decl.type, "void"))
  372. f_print (fout, "*argp, "); /* non-void */
  373. }
  374. else
  375. {
  376. for (l = proc->args.decls; l != NULL; l = l->next)
  377. f_print (fout, "argp->%s, ", l->decl.name);
  378. }
  379. if (mtflag)
  380. f_print (fout, "%s, ", RESULT);
  381. f_print (fout, "%s));\n}\n", RQSTP);
  382. }
  383. }
  384. }
  385. static void
  386. write_program (const definition * def, const char *storage)
  387. {
  388. version_list *vp;
  389. proc_list *proc;
  390. int filled;
  391. for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
  392. {
  393. f_print (fout, "\n");
  394. if (storage != NULL)
  395. {
  396. f_print (fout, "%s ", storage);
  397. }
  398. f_print (fout, "void\n");
  399. pvname (def->def_name, vp->vers_num);
  400. if (Cflag)
  401. {
  402. f_print (fout, "(struct svc_req *%s, ", RQSTP);
  403. f_print (fout, "register SVCXPRT *%s)\n", TRANSP);
  404. }
  405. else
  406. {
  407. f_print (fout, "(%s, %s)\n", RQSTP, TRANSP);
  408. f_print (fout, " struct svc_req *%s;\n", RQSTP);
  409. f_print (fout, " register SVCXPRT *%s;\n", TRANSP);
  410. }
  411. f_print (fout, "{\n");
  412. filled = 0;
  413. f_print (fout, "\tunion {\n");
  414. for (proc = vp->procs; proc != NULL; proc = proc->next)
  415. {
  416. if (proc->arg_num < 2)
  417. { /* single argument */
  418. if (streq (proc->args.decls->decl.type,
  419. "void"))
  420. {
  421. continue;
  422. }
  423. filled = 1;
  424. f_print (fout, "\t\t");
  425. ptype (proc->args.decls->decl.prefix,
  426. proc->args.decls->decl.type, 0);
  427. pvname (proc->proc_name, vp->vers_num);
  428. f_print (fout, "_arg;\n");
  429. }
  430. else
  431. {
  432. filled = 1;
  433. f_print (fout, "\t\t%s", proc->args.argname);
  434. f_print (fout, " ");
  435. pvname (proc->proc_name, vp->vers_num);
  436. f_print (fout, "_arg;\n");
  437. }
  438. }
  439. if (!filled)
  440. {
  441. f_print (fout, "\t\tint fill;\n");
  442. }
  443. f_print (fout, "\t} %s;\n", ARG);
  444. if (mtflag)
  445. {
  446. f_print(fout, "\tunion {\n");
  447. for (proc = vp->procs; proc != NULL; proc = proc->next)
  448. if (!streq (proc->res_type, "void"))
  449. {
  450. f_print(fout, "\t\t");
  451. ptype(proc->res_prefix, proc->res_type, 0);
  452. pvname(proc->proc_name, vp->vers_num);
  453. f_print(fout, "_res;\n");
  454. }
  455. f_print(fout, "\t} %s;\n", RESULT);
  456. f_print(fout, "\tbool_t %s;\n", RETVAL);
  457. } else
  458. f_print (fout, "\tchar *%s;\n", RESULT);
  459. if (Cflag)
  460. {
  461. f_print (fout, "\txdrproc_t _xdr_%s, _xdr_%s;\n", ARG, RESULT);
  462. if (mtflag)
  463. f_print(fout,
  464. "\tbool_t (*%s)(char *, void *, struct svc_req *);\n",
  465. ROUTINE);
  466. else
  467. f_print (fout, "\tchar *(*%s)(char *, struct svc_req *);\n",
  468. ROUTINE);
  469. }
  470. else
  471. {
  472. f_print (fout, "\tbool_t (*_xdr_%s)(), (*_xdr_%s)();\n", ARG, RESULT);
  473. if (mtflag)
  474. f_print(fout, "\tbool_t (*%s)();\n", ROUTINE);
  475. else
  476. f_print (fout, "\tchar *(*%s)();\n", ROUTINE);
  477. }
  478. f_print (fout, "\n");
  479. if (timerflag)
  480. #if 0
  481. f_print (fout, "\t_rpcsvcdirty = 1;\n");
  482. #else
  483. {
  484. if (mtflag)
  485. f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
  486. f_print(fout, "\t_rpcsvcstate = _SERVING;\n");
  487. if (mtflag)
  488. f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
  489. }
  490. #endif
  491. f_print (fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
  492. if (!nullproc (vp->procs))
  493. {
  494. f_print (fout, "\tcase NULLPROC:\n");
  495. f_print (fout,
  496. "\t\t(void) svc_sendreply (%s, (xdrproc_t) xdr_void, (char *)NULL);\n",
  497. TRANSP);
  498. print_return ("\t\t");
  499. f_print (fout, "\n");
  500. }
  501. for (proc = vp->procs; proc != NULL; proc = proc->next)
  502. {
  503. f_print (fout, "\tcase %s:\n", proc->proc_name);
  504. if (proc->arg_num < 2)
  505. { /* single argument */
  506. p_xdrfunc (ARG, proc->args.decls->decl.type);
  507. }
  508. else
  509. {
  510. p_xdrfunc (ARG, proc->args.argname);
  511. }
  512. p_xdrfunc (RESULT, proc->res_type);
  513. if (Cflag)
  514. {
  515. if (mtflag)
  516. f_print(fout,
  517. "\t\t%s = (bool_t (*) (char *, void *, struct svc_req *))",
  518. ROUTINE);
  519. else
  520. f_print (fout,
  521. "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
  522. ROUTINE);
  523. }
  524. else
  525. if (mtflag)
  526. f_print(fout, "\t\t%s = (bool_t (*)()) ", ROUTINE);
  527. else
  528. f_print (fout, "\t\t%s = (char *(*)()) ", ROUTINE);
  529. if (newstyle)
  530. { /* new style: calls internal routine */
  531. f_print (fout, "_");
  532. }
  533. if ((Cflag || mtflag) && !newstyle)
  534. pvname_svc (proc->proc_name, vp->vers_num);
  535. else
  536. pvname (proc->proc_name, vp->vers_num);
  537. f_print (fout, ";\n");
  538. f_print (fout, "\t\tbreak;\n\n");
  539. }
  540. f_print (fout, "\tdefault:\n");
  541. printerr ("noproc", TRANSP);
  542. print_return ("\t\t");
  543. f_print (fout, "\t}\n");
  544. f_print (fout, "\tmemset ((char *)&%s, 0, sizeof (%s));\n", ARG, ARG);
  545. printif ("getargs", TRANSP, ARG);
  546. printerr ("decode", TRANSP);
  547. print_return ("\t\t");
  548. f_print (fout, "\t}\n");
  549. if (!mtflag)
  550. {
  551. if (Cflag)
  552. f_print (fout, "\t%s = (*%s)((char *)&%s, %s);\n",
  553. RESULT, ROUTINE, ARG, RQSTP);
  554. else
  555. f_print (fout, "\t%s = (*%s)(&%s, %s);\n",
  556. RESULT, ROUTINE, ARG, RQSTP);
  557. }
  558. else
  559. if (Cflag)
  560. f_print(fout, "\t%s = (bool_t) (*%s)((char *)&%s, (void *)&%s, %s);\n",
  561. RETVAL, ROUTINE, ARG, RESULT, RQSTP);
  562. else
  563. f_print(fout, "\t%s = (bool_t) (*%s)(&%s, &%s, %s);\n",
  564. RETVAL, ROUTINE, ARG, RESULT, RQSTP);
  565. if (mtflag)
  566. f_print(fout,
  567. "\tif (%s > 0 && !svc_sendreply(%s, (xdrproc_t) _xdr_%s, (char *)&%s)) {\n",
  568. RETVAL, TRANSP, RESULT, RESULT);
  569. else
  570. f_print(fout,
  571. "\tif (%s != NULL && !svc_sendreply(%s, (xdrproc_t) _xdr_%s, %s)) {\n",
  572. RESULT, TRANSP, RESULT, RESULT);
  573. printerr ("systemerr", TRANSP);
  574. f_print (fout, "\t}\n");
  575. printif ("freeargs", TRANSP, ARG);
  576. sprintf (_errbuf, "unable to free arguments");
  577. print_err_message ("\t\t");
  578. f_print (fout, "\t\texit (1);\n");
  579. f_print (fout, "\t}\n");
  580. /* print out free routine */
  581. if (mtflag)
  582. {
  583. f_print(fout,"\tif (!");
  584. pvname(def->def_name, vp->vers_num);
  585. f_print(fout,"_freeresult (%s, _xdr_%s, (caddr_t) &%s))\n",
  586. TRANSP, RESULT, RESULT);
  587. (void) sprintf(_errbuf, "unable to free results");
  588. print_err_message("\t\t");
  589. f_print(fout, "\n");
  590. }
  591. print_return ("\t");
  592. f_print (fout, "}\n");
  593. }
  594. }
  595. static void
  596. printerr (const char *err, const char *transp)
  597. {
  598. f_print (fout, "\t\tsvcerr_%s (%s);\n", err, transp);
  599. }
  600. static void
  601. printif (const char *proc, const char *transp, const char *arg)
  602. {
  603. f_print (fout, "\tif (!svc_%s (%s, (xdrproc_t) _xdr_%s, (caddr_t) &%s)) {\n",
  604. proc, transp, arg, arg);
  605. }
  606. int
  607. nullproc (const proc_list * proc)
  608. {
  609. for (; proc != NULL; proc = proc->next)
  610. {
  611. if (streq (proc->proc_num, "0"))
  612. {
  613. return 1;
  614. }
  615. }
  616. return 0;
  617. }
  618. static void
  619. write_inetmost (const char *infile)
  620. {
  621. f_print (fout, "\tregister SVCXPRT *%s;\n", TRANSP);
  622. f_print (fout, "\tint sock;\n");
  623. f_print (fout, "\tint proto;\n");
  624. f_print (fout, "\tstruct sockaddr_in saddr;\n");
  625. f_print (fout, "\tint asize = sizeof (saddr);\n");
  626. f_print (fout, "\n");
  627. f_print (fout,
  628. "\tif (getsockname (0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
  629. f_print (fout, "\t\tint ssize = sizeof (int);\n\n");
  630. f_print (fout, "\t\tif (saddr.sin_family != AF_INET)\n");
  631. f_print (fout, "\t\t\texit (1);\n");
  632. f_print (fout, "\t\tif (getsockopt (0, SOL_SOCKET, SO_TYPE,\n");
  633. f_print (fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
  634. f_print (fout, "\t\t\texit (1);\n");
  635. f_print (fout, "\t\tsock = 0;\n");
  636. f_print (fout, "\t\t_rpcpmstart = 1;\n");
  637. f_print (fout, "\t\tproto = 0;\n");
  638. open_log_file (infile, "\t\t");
  639. f_print (fout, "\t} else {\n");
  640. write_rpc_svc_fg (infile, "\t\t");
  641. f_print (fout, "\t\tsock = RPC_ANYSOCK;\n");
  642. print_pmapunset ("\t\t");
  643. f_print (fout, "\t}\n");
  644. }
  645. static void
  646. print_return (const char *space)
  647. {
  648. if (exitnow)
  649. f_print (fout, "%sexit (0);\n", space);
  650. else
  651. {
  652. if (timerflag)
  653. {
  654. #if 0
  655. f_print (fout, "%s_rpcsvcdirty = 0;\n", space);
  656. #else
  657. if (mtflag)
  658. f_print(fout, "%smutex_lock(&_svcstate_lock);\n", space);
  659. f_print(fout, "%s_rpcsvcstate = _SERVED;\n", space);
  660. if (mtflag)
  661. f_print(fout, "%smutex_unlock(&_svcstate_lock);\n", space);
  662. #endif
  663. }
  664. f_print (fout, "%sreturn;\n", space);
  665. }
  666. }
  667. static void
  668. print_pmapunset (const char *space)
  669. {
  670. list *l;
  671. definition *def;
  672. version_list *vp;
  673. for (l = defined; l != NULL; l = l->next)
  674. {
  675. def = (definition *) l->val;
  676. if (def->def_kind == DEF_PROGRAM)
  677. {
  678. for (vp = def->def.pr.versions; vp != NULL;
  679. vp = vp->next)
  680. {
  681. f_print (fout, "%spmap_unset (%s, %s);\n",
  682. space, def->def_name, vp->vers_name);
  683. }
  684. }
  685. }
  686. }
  687. static void
  688. print_err_message (const char *space)
  689. {
  690. if (logflag)
  691. f_print (fout, "%ssyslog (LOG_ERR, \"%%s\", \"%s\");\n", space, _errbuf);
  692. else if (inetdflag || pmflag)
  693. f_print (fout, "%s_msgout (\"%s\");\n", space, _errbuf);
  694. else
  695. f_print (fout, "%sfprintf (stderr, \"%%s\", \"%s\");\n", space, _errbuf);
  696. }
  697. /*
  698. * Write the server auxiliary function ( _msgout, timeout)
  699. */
  700. void
  701. write_svc_aux (int nomain)
  702. {
  703. if (!logflag)
  704. write_msg_out ();
  705. if (!nomain)
  706. write_timeout_func ();
  707. }
  708. /*
  709. * Write the _msgout function
  710. */
  711. void
  712. write_msg_out (void)
  713. {
  714. f_print (fout, "\n");
  715. f_print (fout, "static\n");
  716. if (!Cflag)
  717. {
  718. f_print (fout, "void _msgout (msg)\n");
  719. f_print (fout, "\tchar *msg;\n");
  720. }
  721. else
  722. {
  723. f_print (fout, "void _msgout (char* msg)\n");
  724. }
  725. f_print (fout, "{\n");
  726. f_print (fout, "#ifdef RPC_SVC_FG\n");
  727. if (inetdflag || pmflag)
  728. f_print (fout, "\tif (_rpcpmstart)\n");
  729. f_print (fout, "\t\tsyslog (LOG_ERR, \"%%s\", msg);\n");
  730. f_print (fout, "\telse\n");
  731. f_print (fout, "\t\tfprintf (stderr, \"%%s\\n\", msg);\n");
  732. f_print (fout, "#else\n");
  733. f_print (fout, "\tsyslog (LOG_ERR, \"%%s\", msg);\n");
  734. f_print (fout, "#endif\n");
  735. f_print (fout, "}\n");
  736. }
  737. /*
  738. * Write the timeout function
  739. */
  740. static void
  741. write_timeout_func (void)
  742. {
  743. if (!timerflag)
  744. return;
  745. f_print (fout, "\n");
  746. f_print (fout, "static void\n");
  747. if (Cflag)
  748. f_print (fout, "closedown (int sig)\n");
  749. else
  750. f_print (fout, "closedown (sig)\n\tint sig;\n");
  751. f_print (fout, "{\n");
  752. #if 0
  753. f_print (fout, "\t(void) signal (sig, %s closedown);\n",
  754. Cflag ? "(SIG_PF)" : "(void(*)())");
  755. #endif
  756. if (mtflag)
  757. f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
  758. #if 0
  759. f_print (fout, "\tif (_rpcsvcdirty == 0) {\n");
  760. #else
  761. f_print(fout, "\tif (_rpcsvcstate == _IDLE) {\n");
  762. #endif
  763. f_print (fout, "\t\textern fd_set svc_fdset;\n");
  764. f_print (fout, "\t\tstatic int size;\n");
  765. f_print (fout, "\t\tint i, openfd;\n");
  766. if (tirpcflag && pmflag)
  767. {
  768. f_print (fout, "\t\tstruct t_info tinfo;\n\n");
  769. f_print (fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
  770. }
  771. else
  772. {
  773. f_print (fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
  774. }
  775. f_print (fout, "\t\t\texit (0);\n");
  776. f_print (fout, "\t\tif (size == 0) {\n");
  777. if (tirpcflag)
  778. {
  779. f_print (fout, "\t\t\tstruct rlimit rl;\n\n");
  780. f_print (fout, "\t\t\trl.rlim_max = 0;\n");
  781. f_print (fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
  782. f_print (fout, "\t\t\tif ((size = rl.rlim_max) == 0) {\n");
  783. if (mtflag)
  784. f_print(fout, "\t\t\t\tmutex_unlock(&_svcstate_lock);\n");
  785. f_print (fout, "\t\t\t\treturn;\n\t\t\t}\n");
  786. }
  787. else
  788. {
  789. f_print (fout, "\t\t\tsize = getdtablesize();\n");
  790. }
  791. f_print (fout, "\t\t}\n");
  792. f_print (fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
  793. f_print (fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
  794. f_print (fout, "\t\t\t\topenfd++;\n");
  795. f_print (fout, "\t\tif (openfd <= 1)\n");
  796. f_print (fout, "\t\t\texit (0);\n");
  797. f_print (fout, "\t}\n");
  798. f_print(fout, "\tif (_rpcsvcstate == _SERVED)\n");
  799. f_print(fout, "\t\t_rpcsvcstate = _IDLE;\n\n");
  800. if (mtflag)
  801. f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
  802. f_print(fout, "\t(void) signal(SIGALRM, %s closedown);\n",
  803. Cflag? "(SIG_PF)" : "(void(*)())");
  804. f_print (fout, "\talarm (_RPCSVC_CLOSEDOWN);\n");
  805. f_print (fout, "}\n");
  806. }
  807. /*
  808. * Write the most of port monitor support
  809. */
  810. static void
  811. write_pm_most (const char *infile, int netflag)
  812. {
  813. list *l;
  814. definition *def;
  815. version_list *vp;
  816. f_print (fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
  817. f_print (fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
  818. f_print (fout, " !strcmp(mname, \"timod\"))) {\n");
  819. f_print (fout, "\t\tchar *netid;\n");
  820. if (!netflag)
  821. { /* Not included by -n option */
  822. f_print (fout, "\t\tstruct netconfig *nconf = NULL;\n");
  823. f_print (fout, "\t\tSVCXPRT *%s;\n", TRANSP);
  824. }
  825. if (timerflag)
  826. f_print (fout, "\t\tint pmclose;\n");
  827. /* not necessary, defined in /usr/include/stdlib */
  828. /* f_print(fout, "\t\textern char *getenv();\n"); */
  829. f_print (fout, "\n");
  830. f_print (fout, "\t\t_rpcpmstart = 1;\n");
  831. if (logflag)
  832. open_log_file (infile, "\t\t");
  833. f_print (fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
  834. sprintf (_errbuf, "cannot get transport name");
  835. print_err_message ("\t\t\t");
  836. f_print (fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
  837. sprintf (_errbuf, "cannot get transport info");
  838. print_err_message ("\t\t\t");
  839. f_print (fout, "\t\t}\n");
  840. /*
  841. * A kludgy support for inetd services. Inetd only works with
  842. * sockmod, and RPC works only with timod, hence all this jugglery
  843. */
  844. f_print (fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
  845. f_print (fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
  846. sprintf (_errbuf, "could not get the right module");
  847. print_err_message ("\t\t\t\t");
  848. f_print (fout, "\t\t\t\texit(1);\n");
  849. f_print (fout, "\t\t\t}\n");
  850. f_print (fout, "\t\t}\n");
  851. if (timerflag)
  852. f_print (fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
  853. f_print (fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
  854. TRANSP);
  855. sprintf (_errbuf, "cannot create server handle");
  856. print_err_message ("\t\t\t");
  857. f_print (fout, "\t\t\texit(1);\n");
  858. f_print (fout, "\t\t}\n");
  859. f_print (fout, "\t\tif (nconf)\n");
  860. f_print (fout, "\t\t\tfreenetconfigent(nconf);\n");
  861. for (l = defined; l != NULL; l = l->next)
  862. {
  863. def = (definition *) l->val;
  864. if (def->def_kind != DEF_PROGRAM)
  865. {
  866. continue;
  867. }
  868. for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
  869. {
  870. f_print (fout,
  871. "\t\tif (!svc_reg(%s, %s, %s, ",
  872. TRANSP, def->def_name, vp->vers_name);
  873. pvname (def->def_name, vp->vers_num);
  874. f_print (fout, ", 0)) {\n");
  875. (void) sprintf (_errbuf, "unable to register (%s, %s).",
  876. def->def_name, vp->vers_name);
  877. print_err_message ("\t\t\t");
  878. f_print (fout, "\t\t\texit(1);\n");
  879. f_print (fout, "\t\t}\n");
  880. }
  881. }
  882. if (timerflag)
  883. {
  884. f_print (fout, "\t\tif (pmclose) {\n");
  885. f_print (fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
  886. Cflag ? "(SIG_PF)" : "(void(*)())");
  887. f_print (fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
  888. f_print (fout, "\t\t}\n");
  889. }
  890. f_print (fout, "\t\tsvc_run();\n");
  891. f_print (fout, "\t\texit(1);\n");
  892. f_print (fout, "\t\t/* NOTREACHED */\n");
  893. f_print (fout, "\t}\n");
  894. }
  895. /*
  896. * Support for backgrounding the server if self started.
  897. */
  898. static void
  899. write_rpc_svc_fg (const char *infile, const char *sp)
  900. {
  901. f_print (fout, "#ifndef RPC_SVC_FG\n");
  902. f_print (fout, "%sint size;\n", sp);
  903. if (tirpcflag)
  904. f_print (fout, "%sstruct rlimit rl;\n", sp);
  905. if (inetdflag)
  906. f_print (fout, "%sint pid, i;\n\n", sp);
  907. f_print (fout, "%spid = fork();\n", sp);
  908. f_print (fout, "%sif (pid < 0) {\n", sp);
  909. f_print (fout, "%s\tperror(\"cannot fork\");\n", sp);
  910. f_print (fout, "%s\texit(1);\n", sp);
  911. f_print (fout, "%s}\n", sp);
  912. f_print (fout, "%sif (pid)\n", sp);
  913. f_print (fout, "%s\texit(0);\n", sp);
  914. /* get number of file descriptors */
  915. if (tirpcflag)
  916. {
  917. f_print (fout, "%srl.rlim_max = 0;\n", sp);
  918. f_print (fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
  919. f_print (fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
  920. f_print (fout, "%s\texit(1);\n", sp);
  921. }
  922. else
  923. {
  924. f_print (fout, "%ssize = getdtablesize();\n", sp);
  925. }
  926. f_print (fout, "%sfor (i = 0; i < size; i++)\n", sp);
  927. f_print (fout, "%s\t(void) close(i);\n", sp);
  928. /* Redirect stderr and stdout to console */
  929. f_print (fout, "%si = open(\"/dev/console\", 2);\n", sp);
  930. f_print (fout, "%s(void) dup2(i, 1);\n", sp);
  931. f_print (fout, "%s(void) dup2(i, 2);\n", sp);
  932. /* This removes control of the controlling terminal */
  933. if (tirpcflag)
  934. f_print (fout, "%ssetsid();\n", sp);
  935. else
  936. {
  937. f_print (fout, "%si = open(\"/dev/tty\", 2);\n", sp);
  938. f_print (fout, "%sif (i >= 0) {\n", sp);
  939. f_print (fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);;
  940. f_print (fout, "%s\t(void) close(i);\n", sp);
  941. f_print (fout, "%s}\n", sp);
  942. }
  943. if (!logflag)
  944. open_log_file (infile, sp);
  945. f_print (fout, "#endif\n");
  946. if (logflag)
  947. open_log_file (infile, sp);
  948. }
  949. static void
  950. open_log_file (const char *infile, const char *sp)
  951. {
  952. char *s;
  953. s = strrchr (infile, '.');
  954. if (s)
  955. *s = '\0';
  956. f_print (fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
  957. if (s)
  958. *s = '.';
  959. }
  960. /*
  961. * write a registration for the given transport for Inetd
  962. */
  963. void
  964. write_inetd_register (const char *transp)
  965. {
  966. list *l;
  967. definition *def;
  968. version_list *vp;
  969. const char *sp;
  970. int isudp;
  971. char tmpbuf[32];
  972. if (inetdflag)
  973. sp = "\t";
  974. else
  975. sp = "";
  976. if (streq (transp, "udp") || streq (transp, "udp6"))
  977. isudp = 1;
  978. else
  979. isudp = 0;
  980. f_print (fout, "\n");
  981. if (inetdflag)
  982. {
  983. f_print (fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
  984. isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
  985. }
  986. f_print (fout, "%s\t%s = svc%s_create(%s",
  987. sp, TRANSP, transp, inetdflag ? "sock" : "RPC_ANYSOCK");
  988. if (!isudp)
  989. f_print (fout, ", 0, 0");
  990. f_print (fout, ");\n");
  991. f_print (fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
  992. (void) sprintf (_errbuf, "cannot create %s service.", transp);
  993. (void) sprintf (tmpbuf, "%s\t\t", sp);
  994. print_err_message (tmpbuf);
  995. f_print (fout, "%s\t\texit(1);\n", sp);
  996. f_print (fout, "%s\t}\n", sp);
  997. if (inetdflag)
  998. {
  999. f_print (fout, "%s\tif (!_rpcpmstart)\n\t", sp);
  1000. f_print (fout, "%s\tproto = IPPROTO_%s;\n",
  1001. sp, isudp ? "UDP" : "TCP");
  1002. }
  1003. for (l = defined; l != NULL; l = l->next)
  1004. {
  1005. def = (definition *) l->val;
  1006. if (def->def_kind != DEF_PROGRAM)
  1007. {
  1008. continue;
  1009. }
  1010. for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
  1011. {
  1012. f_print (fout, "%s\tif (!svc_register(%s, %s, %s, ",
  1013. sp, TRANSP, def->def_name, vp->vers_name);
  1014. pvname (def->def_name, vp->vers_num);
  1015. if (inetdflag)
  1016. f_print (fout, ", proto)) {\n");
  1017. else
  1018. f_print (fout, ", IPPROTO_%s)) {\n",
  1019. isudp ? "UDP" : "TCP");
  1020. (void) sprintf (_errbuf, "unable to register (%s, %s, %s).",
  1021. def->def_name, vp->vers_name, transp);
  1022. print_err_message (tmpbuf);
  1023. f_print (fout, "%s\t\texit(1);\n", sp);
  1024. f_print (fout, "%s\t}\n", sp);
  1025. }
  1026. }
  1027. if (inetdflag)
  1028. f_print (fout, "\t}\n");
  1029. }