db_server_svc.C 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. //%% (c) Copyright 1993, 1994 Hewlett-Packard Company
  24. //%% (c) Copyright 1993, 1994 International Business Machines Corp.
  25. //%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  26. //%% (c) Copyright 1993, 1994 Novell, Inc.
  27. //%% $TOG: db_server_svc.C /main/9 1999/10/12 10:01:35 mgreess $
  28. /*
  29. * @(#)db_server_svc.C 1.54 95/06/07
  30. *
  31. * Tool Talk Database Server
  32. *
  33. * Copyright (c) 1992 Sun Microsystems, Inc.
  34. *
  35. * This file contains the db server main rpc program _tt_dbserver_prog_1.
  36. */
  37. #define PORTMAP
  38. #include "tt_options.h"
  39. #include "tt_db_partition_redirection_map.h"
  40. #include "util/tt_global_env.h"
  41. #include "util/tt_new.h"
  42. #include "util/copyright.h"
  43. #include "dm_access_cache.h"
  44. #include "dm/dm_enums.h"
  45. #include "db/db_server.h"
  46. #include "db/tt_db_rpc_routines.h"
  47. #include "tt_db_msg_q_lock.h"
  48. #include "util/tt_log.h"
  49. #include "util/tt_port.h"
  50. #include "util/tt_gettext.h"
  51. #include "util/tt_file_system.h"
  52. #include "db_server_globals.h"
  53. #include <fcntl.h>
  54. #include <limits.h>
  55. #include <locale.h>
  56. #include <stdlib.h>
  57. #include <stdio.h>
  58. #include <rpc/pmap_clnt.h>
  59. #include <isam.h>
  60. #include <unistd.h>
  61. #include <sys/socket.h>
  62. #include <termios.h>
  63. #include <time.h>
  64. #if defined(sgi) || defined(CSRG_BASED)
  65. #include <getopt.h>
  66. #endif
  67. #include <string.h>
  68. #include <sys/param.h>
  69. #include <sys/stat.h>
  70. #include <signal.h>
  71. #if defined(OPT_TLI)
  72. #include <stropts.h>
  73. #endif
  74. #if (OPT_GARBAGE_IN_PARALLEL==1) && !defined(OPT_GARBAGE_THREADS)
  75. #include <sys/wait.h>
  76. #endif
  77. #define _TT_TREC_INFO (sizeof(int) + sizeof(long) + sizeof(u_int))
  78. extern "C" { int isclose(int); }
  79. extern "C" { int iscntl(int, int, ...); }
  80. extern "C" { int isopen(const char*, int); }
  81. extern "C" { int isrewrec(int, long, char*); }
  82. extern "C" { int iswrite(int, char*); }
  83. extern char *optarg;
  84. extern int opterr;
  85. extern int _tt_run_garbage_collect(int in_parallel);
  86. extern int _tt_run_garbage_collect(int);
  87. static void _tt_dbserver_prog_1(struct svc_req*, SVCXPRT*);
  88. void install_signal_handler();
  89. void sig_handler(int sig);
  90. #if defined(TTDB_DEBUG)
  91. #define TTDB_DEBUG_SYSLOG(txt) _tt_syslog(errstr, LOG_ERR, txt);
  92. #else
  93. #define TTDB_DEBUG_SYSLOG(txt)
  94. #endif
  95. TT_INSERT_COPYRIGHT
  96. const char *_TT_UNIX_OPT = "unix";
  97. const char *_TT_DES_OPT = "des";
  98. const int _TT_UMASK = 0022; /* rwxr-xr-x max permissions. */
  99. /*
  100. * GLOBAL variables
  101. */
  102. uid_t _tt_uid;
  103. gid_t _tt_gid;
  104. gid_t _tt_gidlist[NGROUPS];
  105. #if defined(OPT_GARBAGE_THREADS)
  106. mutex_t rpc_client_busy; // Used to sync calls with the RPC clients.
  107. mutex_t garbage_run_in_process;
  108. #endif
  109. int _tt_auth_level;
  110. int _tt_gidlen;
  111. keydesc _tt_oid_keydesc;
  112. _Tt_oid_access_queue_ptr _tt_oa_cache;
  113. _Tt_link_access_queue_ptr _tt_la_cache;
  114. char _tt_log_file[MAXPATHLEN];
  115. /* table of NetISAM db opened */
  116. _Tt_db_info _tt_db_table[_TT_MAX_ISFD];
  117. // _tt_refclock is a "pseudo clock" that's just incremented every time
  118. // a reference is made to an fd; the resulting value is placed
  119. // the _tt_db_table[fd].reftime field, so we can figure out which
  120. // fd is Least Recently Used when it comes time to re-use one.
  121. int _tt_refclock=0;
  122. time_t _tt_mtab_last_mtime;
  123. static char _tt_log_buf[ISMAXRECLEN];
  124. static char _tt_target_db[MAXPATHLEN];
  125. int _tt_debug_mode = 0;
  126. int access_checking = 1;
  127. static bool_t msg_q_unlock_flag = FALSE;
  128. static bool_t refresh_partition_redirection_map = TRUE;
  129. // DB partition redirection map
  130. _Tt_db_partition_redirection_map * db_pr_map;
  131. // Sink for error output. If 0, output goes to syslog.
  132. FILE * errstr = stderr;
  133. extern int optind;
  134. void sig_handler(int sig);
  135. static enum {STARTED_FROM_INETD, STARTED_FROM_SHELL} start_mode;
  136. //
  137. // This is used to hold the next time the automatic garbage
  138. // collection should be run. It will be run when the current
  139. // time is greator than or equal to next_garbage_run.
  140. //
  141. time_t next_garbage_run = (time_t) 0;
  142. int
  143. isamfatalerror(char *msg)
  144. {
  145. _tt_syslog(errstr, LOG_ERR, "NetISAM: %s", msg);
  146. return 1;
  147. }
  148. void
  149. print_usage_and_exit()
  150. {
  151. static int usage_printed = 0;
  152. if (!usage_printed) {
  153. _tt_syslog(errstr, LOG_ERR, "%s",
  154. catgets(_ttcatd, 5, 7,
  155. "Usage:\n"
  156. "rpc.ttdbserverd [-S] [-n] [-m DTMOUNTPOINT]\n"
  157. "rpc.ttdbserverd [-S] [-v]\n"
  158. "rpc.ttdbserverd -G\n"));
  159. usage_printed = 1;
  160. }
  161. // we only exit when started from the shell -- if started by
  162. // inetd we're likely to just get started up again with bad options,
  163. // probably better to try to keep going.
  164. if (start_mode == STARTED_FROM_SHELL) {
  165. exit(1);
  166. }
  167. return;
  168. }
  169. int
  170. #if defined(OPT_GARBAGE_THREADS)
  171. main(int argc, char** argv)
  172. #else
  173. main(int argc, char** argv, char **envp)
  174. #endif
  175. {
  176. #if !defined(OPT_GARBAGE_THREADS)
  177. global_argv = argv;
  178. global_envp = envp;
  179. #endif
  180. char *progname;
  181. void install_signal_handler();
  182. SVCXPRT *transp;
  183. struct sockaddr_in saddr;
  184. # if defined(__linux__) || defined(CSRG_BASED) || defined(sun)
  185. socklen_t asize = sizeof(saddr);
  186. # else
  187. size_t asize = sizeof(saddr);
  188. # endif
  189. int is_aix = 0;
  190. int do_garbage_collect = 0;
  191. #if defined(OPT_TLI)
  192. char mname[FMNAMESZ + 1];
  193. struct t_info info;
  194. #endif
  195. memset(&saddr, 0, sizeof(saddr));
  196. #if defined(OPT_TLI)
  197. memset((char *)&info,0,sizeof info);
  198. #endif
  199. #ifdef _AIX
  200. is_aix = 1;
  201. #endif
  202. setlocale( LC_ALL, "" );
  203. _tt_openlog( argv[0], LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_DAEMON );
  204. // First, we have to determine if we are started from inetd or from the shell.
  205. // Normal installations would start from inetd, but we do start from the shell
  206. // when testing; also we\'d like to allow installations to start out of the
  207. // init process (rc.local, rc?.d) if they\'d rather.
  208. // The way to determine if we\'re started from inetd is to check if fd 0 is
  209. // a connection endpoint (socket or TLI). If so, that endpoint has been
  210. // set up as an RPC connection by inetd and we should use it instead of
  211. // creating our own. If fd 0 is NOT a endpoint, we assume we\'re started
  212. // from the shell, and create a new endpoint and redirect the portmapper to it.
  213. // This is complicated by the fact that the inetd.conf file in Solaris 2.3
  214. // and Solaris 2.3. specifies that rpc.ttdbserverd is rpc/tcp, not rpc/tli.
  215. // We want this version of rpc.ttdbserverd to run on Solaris 2.3, so we have
  216. // to cater to it by checking for a tcp socket being passed in; if there is
  217. // such, we do some streams magic to convert it into a TLI endpoint.
  218. // This is further complicated by having to run on systems that don\'t
  219. // have TIRPC yet.
  220. signal(SIGTTOU, SIG_IGN);
  221. if (getsockname(0, (struct sockaddr *) &saddr, &asize) == 0) {
  222. // We were given a socket. This means we were started
  223. // from inetd.
  224. if (saddr.sin_family != AF_INET) {
  225. _tt_syslog(0, LOG_ERR, "saddr.sin_family != AF_INET");
  226. exit(1);
  227. }
  228. start_mode = STARTED_FROM_INETD;
  229. errstr = 0;
  230. #if defined(OPT_TLI)
  231. // We were given a socket but need a TLI endpoint.
  232. // Fortunately STREAMS caters to folks like us by making
  233. // it dead easy to change one into another.
  234. if (!ioctl(0, I_LOOK, mname) && (!strcmp(mname, "sockmod"))) {
  235. if (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, "timod")) {
  236. _tt_syslog(errstr, LOG_ERR, "ioctl(0, I_POP, 0)"
  237. " || ioctl(0, I_PUSH, \"timod\")");
  238. exit(1);
  239. }
  240. }
  241. } else if (0==t_getinfo(0, &info)) {
  242. // We were given a TLI endpoint. This means we were started
  243. // from inetd. The TLI endpoint is suitable for later use.
  244. start_mode = STARTED_FROM_INETD;
  245. errstr = 0;
  246. #endif /* defined(OPT_TLI) */
  247. } else {
  248. // fd 0 is not a communications endpoint, so we must not
  249. // have been started from inetd.
  250. start_mode = STARTED_FROM_SHELL;
  251. }
  252. // At this point start_mode is set to tell us who started us.
  253. // If start_mode is STARTED_FROM_INETD, then fd 0 is the
  254. // endpoint to use; if OPT_TLI is defined, fd 0 is a TLI endpoint;
  255. // if OPT_TLI is not defined, fd 0 is a socket.
  256. // it might be considered appropriate to fork into the background
  257. // here if started from the shell here, but we never have before,
  258. // we are usually started from inetd. The usual reason we\'re
  259. // started from a a shell is for debugging, where forking into the
  260. // background is a big pain, and we\'d have to have an option like
  261. // the -S one on ttsession to skip the fork.
  262. _tt_global = new _Tt_global;
  263. // Create the DB parition redirection map
  264. db_pr_map = new _Tt_db_partition_redirection_map;
  265. /* set minimum authentication requirement */
  266. _tt_auth_level = AUTH_UNIX; /* default to UNIX authentication */
  267. progname = *argv;
  268. if (argc>1) {
  269. opterr = 0;
  270. int c;
  271. // remove authentication option
  272. // int c = getopt(argc, argv, "vm:t:dna:");
  273. while ((c = getopt(argc, argv, "vm:t:dnSG")) != -1) {
  274. switch (c) {
  275. case 'v':
  276. _TT_PRINT_VERSIONS(progname)
  277. exit(0);
  278. case 'm':
  279. _tt_putenv("DTMOUNTPOINT", optarg);
  280. break;
  281. case 'n':
  282. access_checking = 0;
  283. break;
  284. case 'a':
  285. // this is now disabled (see comment above)
  286. if (strcmp(optarg, _TT_DES_OPT) == 0) {
  287. _tt_auth_level = AUTH_DES;
  288. } else if (strcmp(optarg, _TT_UNIX_OPT) != 0) {
  289. print_usage_and_exit();
  290. }
  291. break;
  292. case 't':
  293. break;
  294. case 'd':
  295. break;
  296. case 'S':
  297. _tt_debug_mode = 1;
  298. break;
  299. case 'G':
  300. do_garbage_collect = 1;
  301. break;
  302. case '?':
  303. default:
  304. print_usage_and_exit();
  305. }
  306. }
  307. // The, er, unusual inetd.conf syntax on the IBM platform
  308. // makes it necessary to *not* check for extraneous
  309. // command-line args on IBM when started out of inetd.
  310. // Since I need to check the value of a cpp macro
  311. // -- _AIX -- and a program variable -- start_mode --
  312. // use another "temp" program variable -- is_aix.
  313. if (optind < argc &&
  314. !(is_aix && start_mode == STARTED_FROM_INETD))
  315. {
  316. print_usage_and_exit();
  317. }
  318. }
  319. //
  320. // Start the garbage collection running.
  321. //
  322. if (do_garbage_collect) {
  323. //
  324. // As the garbage collection flag is set, we
  325. // start the garbage cleanup only (no server-d).
  326. //
  327. _tt_run_garbage_collect(FALSE);// Not in parallel.
  328. }
  329. //
  330. // Lock down the RPC interface until we are ready.
  331. //
  332. LOCK_RPC();
  333. /* setup oid key descriptor for access control */
  334. _tt_oid_keydesc.k_flags = ISNODUPS;
  335. _tt_oid_keydesc.k_nparts = 1;
  336. _tt_oid_keydesc.k_part[0].kp_start = 0;
  337. _tt_oid_keydesc.k_part[0].kp_leng = OID_KEY_LENGTH;
  338. _tt_oid_keydesc.k_part[0].kp_type = BINTYPE;
  339. install_signal_handler();
  340. /* set NetISAM fatal error handler */
  341. if (iscntl(ALLISFD, ISCNTL_FATAL, isamfatalerror) == -1) {
  342. _tt_syslog(errstr, LOG_ERR,
  343. "iscntl(ALLISFD, ISCNTL_FATAL,) == -1");
  344. exit(1);
  345. }
  346. /* setup database file creation mask */
  347. mode_t pmask = umask(_TT_UMASK);
  348. /* initialize access control cache */
  349. _tt_oa_cache = new _Tt_oid_access_queue();
  350. _tt_la_cache = new _Tt_link_access_queue();
  351. /* initialize opened database table */
  352. for (int i = 0; i < _TT_MAX_ISFD; i++) {
  353. _tt_db_table[i].db_path = 0;
  354. _tt_db_table[i].opener_uid = (uid_t)-1;
  355. _tt_db_table[i].reftime = 0;
  356. _tt_db_table[i].server_has_open = 0;
  357. _tt_db_table[i].client_has_open = 0;
  358. }
  359. // If we were started from inetd, inetd has already done all
  360. // the negotiation with the portmapper. We simply create a RPC
  361. // connection over the endpoint that inetd handed us. If
  362. // we were started from the shell, we create a RPC connection
  363. // with RPC_ANYSOCK (to create a new endpoint) and register
  364. // that with the portmapper.
  365. switch (start_mode) {
  366. case STARTED_FROM_INETD:
  367. #if defined(OPT_TLI)
  368. transp = svc_tli_create(0,
  369. (struct netconfig *)0,
  370. (struct t_bind *)0,
  371. 0, 0);
  372. if (transp == NULL) {
  373. _tt_syslog(errstr, LOG_ERR, "svc_tli_create() == 0");
  374. exit(1);
  375. }
  376. #else
  377. transp = svctcp_create(0,0,0);
  378. if (transp == NULL) {
  379. _tt_syslog(errstr, LOG_ERR, "svctcp_create() == 0");
  380. exit(1);
  381. }
  382. #endif /*OPT_TLI*/
  383. if (!svc_register(transp, TT_DBSERVER_PROG, TT_DBSERVER_VERS,
  384. #ifdef _AIX
  385. (void(*)())
  386. #endif
  387. _tt_dbserver_prog_1,
  388. 0)) // this zero means leave portmapper alone
  389. {
  390. _tt_syslog(errstr, LOG_ERR, "svc_register() == 0");
  391. }
  392. break;
  393. case STARTED_FROM_SHELL:
  394. // Go into the background, unless the debug_mode -S
  395. // switch was set.
  396. if (!_tt_debug_mode) {
  397. if (0!=fork()) exit(0);
  398. #if defined(CSRG_BASED)
  399. setsid();
  400. #else
  401. setpgrp();
  402. #endif //CSRG_BASED
  403. close(0); close(1); close(2);
  404. }
  405. // Evict any previous user of our RPC number and tell
  406. // the portmapper we are here.
  407. (void)pmap_unset(TT_DBSERVER_PROG, TT_DBSERVER_VERS);
  408. // XXX: really ought to use svc_tli_create if OPT_TLI is set
  409. // but that requires searching for a suitable transport..
  410. transp = svctcp_create(RPC_ANYSOCK, 0, 0);
  411. if (transp == NULL) {
  412. _tt_syslog(errstr, LOG_ERR, "svctcp_create() == 0");
  413. exit(1);
  414. }
  415. if (!svc_register(transp, TT_DBSERVER_PROG, TT_DBSERVER_VERS,
  416. #ifdef _AIX
  417. (void(*)())
  418. #endif
  419. _tt_dbserver_prog_1, IPPROTO_TCP)) {
  420. _tt_syslog(errstr, LOG_ERR, "svc_register() == 0");
  421. exit(1);
  422. }
  423. break;
  424. }
  425. // Maximize the number of possible file descriptors.
  426. _tt_zoomdtablesize();
  427. UNLOCK_RPC();
  428. svc_run();
  429. _tt_syslog(errstr, LOG_ERR, "svc_run()");
  430. exit(1);
  431. return 1;
  432. }
  433. int
  434. _tt_write_trans_record(int isfd, _Tt_trans_record *trec)
  435. {
  436. LOCK_RPC();
  437. /* if new record, writes it; otherwise updates it */
  438. isreclen = trec->rec.rec_len;
  439. if (trec->newp) {
  440. if (iswrite(isfd, trec->rec.rec_val) == -1) {
  441. UNLOCK_RPC();
  442. return 0;
  443. }
  444. } else {
  445. if (isrewrec(isfd, trec->recnum, trec->rec.rec_val) == -1) {
  446. UNLOCK_RPC();
  447. return 0;
  448. }
  449. }
  450. UNLOCK_RPC();
  451. return 1;
  452. }
  453. /*
  454. * _tt_dbserver_prog_cleanup - closes the log file and the target database file
  455. * when the database transacation processing fails.
  456. */
  457. void
  458. _tt_dbserver_prog_cleanup(int log_fd, int isfd = -1)
  459. {
  460. LOCK_RPC();
  461. /* close the log file */
  462. if ((log_fd != -1) && (close(log_fd) == -1)) {
  463. _tt_syslog(errstr, LOG_ERR, "close(log_fd): %m");
  464. }
  465. /* close the target NetISAM database */
  466. if ((isfd != -1) && (cached_isclose(isfd) == -1)) {
  467. _tt_syslog(errstr, LOG_ERR, "cached_isclose() == -1");
  468. }
  469. UNLOCK_RPC();
  470. }
  471. /*
  472. * _tt_process_transaction - process the log file by reading records stored
  473. * in the log file and writing them out to the target database. If the
  474. * transaction flag is set, then the transaction was not successfully committed.
  475. * In this case, the log file is removed. If the transaction flag is clear,
  476. * then process the log file and then removes it.
  477. */
  478. void
  479. _tt_process_transaction()
  480. {
  481. int log_fd;
  482. LOCK_RPC();
  483. if (_tt_log_file[0] == '\0') {
  484. UNLOCK_RPC();
  485. return;
  486. }
  487. if ((log_fd = open(_tt_log_file, O_RDWR | O_CREAT, S_IREAD + S_IWRITE))
  488. == -1)
  489. {
  490. _tt_syslog(errstr, LOG_ERR, "open(\"%s\"): %m", _tt_log_file);
  491. UNLOCK_RPC();
  492. return;
  493. }
  494. /* Turn on close-on-exec */
  495. fcntl(log_fd, F_SETFD, 1);
  496. /* reset to beginning of log file */
  497. off_t offset;
  498. if ((offset = lseek(log_fd, 0, SEEK_SET)) == -1) {
  499. _tt_syslog(errstr, LOG_ERR, "lseek(): %m");
  500. UNLOCK_RPC();
  501. return;
  502. }
  503. /* Check the transaction flag */
  504. int nbytes = read(log_fd, _tt_log_buf, sizeof(int));
  505. if (nbytes < sizeof(int)) {
  506. _tt_syslog(errstr, LOG_ERR, "read(): %m");
  507. _tt_dbserver_prog_cleanup(log_fd);
  508. UNLOCK_RPC();
  509. return;
  510. }
  511. offset = sizeof(int);
  512. int flag = *((int *)_tt_log_buf);
  513. if (flag == 1) { /* transaction failed */
  514. _tt_dbserver_prog_cleanup(log_fd);
  515. if (unlink(_tt_log_file) == -1) { /* remove log file */
  516. _tt_syslog(errstr, LOG_ERR, "unlink(\"%s\"): %m",
  517. _tt_log_file);
  518. }
  519. UNLOCK_RPC();
  520. return;
  521. }
  522. /* get the target database's path from the log file */
  523. nbytes = read(log_fd, _tt_log_buf, MAXPATHLEN+1);
  524. if (nbytes == -1) {
  525. _tt_syslog(errstr, LOG_ERR, "read(): %m");
  526. _tt_dbserver_prog_cleanup(log_fd);
  527. UNLOCK_RPC();
  528. return;
  529. }
  530. snprintf(_tt_target_db, MAXPATHLEN, "%s", _tt_log_buf);
  531. /* open the NetISAM transaction target database */
  532. int isfd = cached_isopen(_tt_target_db, ISINOUT+ISFIXLEN+ISMANULOCK);
  533. if (isfd == -1) {
  534. _tt_syslog(errstr, LOG_ERR, "isopen(): %d", iserrno);
  535. _tt_dbserver_prog_cleanup(log_fd, isfd);
  536. UNLOCK_RPC();
  537. return;
  538. }
  539. /* set the log seek pointer to the first record */
  540. offset += strlen(_tt_target_db) + 1;
  541. if ((offset = lseek(log_fd, offset, SEEK_SET))
  542. == -1) {
  543. _tt_syslog(errstr, LOG_ERR, "lseek(): %m");
  544. _tt_dbserver_prog_cleanup(log_fd, isfd);
  545. UNLOCK_RPC();
  546. return;
  547. }
  548. /* gets the records from the log file and writes them to the
  549. target database */
  550. char *buf_rec;
  551. _Tt_trans_record trec;
  552. nbytes = read(log_fd, _tt_log_buf, _TT_TREC_INFO);
  553. while (nbytes) {
  554. if (nbytes < _TT_TREC_INFO) {
  555. _tt_syslog(errstr, LOG_ERR, "read(): %m");
  556. _tt_dbserver_prog_cleanup(log_fd, isfd);
  557. UNLOCK_RPC();
  558. return;
  559. }
  560. /* process the batch of records just read */
  561. buf_rec = _tt_log_buf;
  562. trec.newp = *((int *) buf_rec);
  563. buf_rec += sizeof(int);
  564. trec.recnum = *((long *) buf_rec);
  565. buf_rec += sizeof(long);
  566. trec.rec.rec_len = *((u_int *) buf_rec);
  567. buf_rec += sizeof(u_int);
  568. /* read the record as a whole */
  569. nbytes = read(log_fd, _tt_log_buf, trec.rec.rec_len);
  570. if (nbytes < trec.rec.rec_len) {
  571. _tt_syslog(errstr, LOG_ERR, "read(): %m");
  572. _tt_dbserver_prog_cleanup(log_fd, isfd);
  573. UNLOCK_RPC();
  574. return;
  575. }
  576. trec.rec.rec_val = _tt_log_buf;
  577. if (_tt_write_trans_record(isfd, &trec) == 0) {
  578. _tt_dbserver_prog_cleanup(log_fd, isfd);
  579. UNLOCK_RPC();
  580. return;
  581. }
  582. nbytes = read(log_fd, _tt_log_buf, _TT_TREC_INFO);
  583. }
  584. _tt_dbserver_prog_cleanup(log_fd, isfd);
  585. /* remove the log file (not until actually close it) */
  586. if (unlink(_tt_log_file) == -1) {
  587. _tt_syslog(errstr, LOG_ERR, "unlink(\"%s\"): %m", _tt_log_file);
  588. }
  589. UNLOCK_RPC();
  590. return;
  591. }
  592. /*
  593. * _tt_dbserver_prog_1 - the rpc db server program
  594. */
  595. static void
  596. _tt_dbserver_prog_1(struct svc_req *rqstp, SVCXPRT *transp)
  597. {
  598. union arg_union {
  599. char *_tt_min_auth_level_1_arg;
  600. _Tt_isaddindex_args _tt_isaddindex_1_arg;
  601. _Tt_isbuild_args _tt_isbuild_1_arg;
  602. int _tt_isclose_1_arg;
  603. _Tt_iscntl_args _tt_iscntl_1_arg;
  604. _Tt_isdelrec_args _tt_isdelrec_1_arg;
  605. char *_tt_iserase_1_arg;
  606. _Tt_isopen_args _tt_isopen_1_arg;
  607. _Tt_isread_args _tt_isread_1_arg;
  608. _Tt_isrewrec_args _tt_isrewrec_1_arg;
  609. _Tt_isstart_args _tt_isstart_1_arg;
  610. _Tt_iswrite_args _tt_iswrite_1_arg;
  611. _Tt_test_and_set_args _tt_test_and_set_1_arg;
  612. _Tt_transaction_args _tt_transaction_1_arg;
  613. char *_tt_mfs_1_arg;
  614. _Tt_oidaccess_args _tt_getoidaccess_1_arg;
  615. _Tt_oidaccess_args _tt_setoiduser_1_arg;
  616. _Tt_oidaccess_args _tt_setoidgroup_1_arg;
  617. _Tt_oidaccess_args _tt_setoidmode_1_arg;
  618. _Tt_spec_props _tt_readspec_1_arg;
  619. _Tt_spec_props _tt_writespec_1_arg;
  620. _Tt_session_args _tt_addsession_1_arg;
  621. _Tt_session_args _tt_delsession_1_arg;
  622. _Tt_spec_props _tt_gettype_1_arg;
  623. char *_tt_get_file_partition_1_arg;
  624. _tt_create_file_args _tt_create_file_1_arg;
  625. _tt_create_obj_args _tt_create_obj_1_arg;
  626. _tt_remove_file_args _tt_remove_file_1_arg;
  627. _tt_remove_obj_args _tt_remove_obj_1_arg;
  628. _tt_move_file_args _tt_move_file_1_arg;
  629. _tt_set_file_props_args _tt_set_file_props_1_arg;
  630. _tt_set_file_prop_args _tt_set_file_prop_1_arg;
  631. _tt_add_file_prop_args _tt_add_file_prop_1_arg;
  632. _tt_del_file_prop_args _tt_delete_file_prop_1_arg;
  633. _tt_get_file_prop_args _tt_get_file_prop_1_arg;
  634. _tt_get_file_props_args _tt_get_file_props_1_arg;
  635. _tt_get_file_objs_args _tt_get_file_objs_1_arg;
  636. _tt_set_file_access_args _tt_set_file_access_1_arg;
  637. _tt_get_file_access_args _tt_get_file_access_1_arg;
  638. _tt_set_obj_props_args _tt_set_obj_props_1_arg;
  639. _tt_set_obj_prop_args _tt_set_obj_prop_1_arg;
  640. _tt_add_obj_prop_args _tt_add_obj_prop_1_arg;
  641. _tt_del_obj_prop_args _tt_delete_obj_prop_1_arg;
  642. _tt_get_obj_prop_args _tt_get_obj_prop_1_arg;
  643. _tt_get_obj_props_args _tt_get_obj_props_1_arg;
  644. _tt_set_obj_type_args _tt_set_obj_type_1_arg;
  645. _tt_get_obj_type_args _tt_get_obj_type_1_arg;
  646. _tt_set_obj_file_args _tt_set_obj_file_1_arg;
  647. _tt_get_obj_file_args _tt_get_obj_file_1_arg;
  648. _tt_set_obj_access_args _tt_set_obj_access_1_arg;
  649. _tt_get_obj_access_args _tt_get_obj_access_1_arg;
  650. _tt_is_file_in_db_args _tt_is_file_in_db_1_arg;
  651. _tt_is_obj_in_db_args _tt_is_obj_in_db_1_arg;
  652. _tt_queue_msg_args _tt_queue_message_1_arg;
  653. _tt_dequeue_msgs_args _tt_dequeue_messages_1_arg;
  654. _tt_file_netfile_args _tt_file_netfile_1_arg;
  655. _tt_file_netfile_args _tt_netfile_file_1_arg;
  656. } argument;
  657. char *result;
  658. bool_t (*xdr_argument)(), (*xdr_result)();
  659. char *(*local)();
  660. struct authunix_parms *unix_cred;
  661. #if defined(OPT_SECURE_RPC)
  662. struct authdes_cred *des_cred;
  663. #endif
  664. // Increment the counter for the number of RPC calls
  665. // handled during the life of this process.
  666. _tt_global->event_counter++;
  667. LOCK_RPC();
  668. if (rqstp->rq_proc == NULLPROC) {
  669. (void)svc_sendreply(transp, (xdrproc_t)xdr_void, (caddr_t)NULL);
  670. UNLOCK_RPC();
  671. return;
  672. } else if ((rqstp->rq_proc != _TT_MIN_AUTH_LEVEL) &&
  673. (rqstp->rq_proc != _TT_MFS) &&
  674. (rqstp->rq_proc != TT_GET_MIN_AUTH_LEVEL) &&
  675. (rqstp->rq_proc != TT_GET_FILE_PARTITION) &&
  676. (rqstp->rq_proc != TT_IS_FILE_IN_DB) &&
  677. (rqstp->rq_proc != TT_IS_OBJ_IN_DB)) {
  678. /* extract the uid and gids from the client's credential */
  679. switch (rqstp->rq_cred.oa_flavor) {
  680. case AUTH_UNIX:
  681. /* Check authentication level */
  682. if (_tt_auth_level == AUTH_DES) {
  683. svcerr_weakauth(transp);
  684. UNLOCK_RPC();
  685. return;
  686. }
  687. unix_cred = (struct authunix_parms*) rqstp->rq_clntcred;
  688. _tt_uid = unix_cred->aup_uid;
  689. _tt_gid = unix_cred->aup_gid;
  690. _tt_gidlen = unix_cred->aup_len;
  691. int i;
  692. for (i = 0; i < _tt_gidlen; i++) {
  693. _tt_gidlist[i] = unix_cred->aup_gids[i];
  694. }
  695. break;
  696. #if defined(OPT_SECURE_RPC)
  697. case AUTH_DES:
  698. des_cred = (struct authdes_cred*) rqstp->rq_clntcred;
  699. #if defined(OPT_BUG_SUNOS_4) && !defined(__GNUG__)
  700. # define CAST_IN_SUNOS_4 (int *)
  701. #else
  702. # define CAST_IN_SUNOS_4
  703. #endif
  704. if (!netname2user(des_cred->adc_fullname.name,
  705. CAST_IN_SUNOS_4 &_tt_uid,
  706. CAST_IN_SUNOS_4 &_tt_gid,
  707. &_tt_gidlen,
  708. CAST_IN_SUNOS_4 _tt_gidlist))
  709. {
  710. svcerr_systemerr(transp);
  711. UNLOCK_RPC();
  712. return;
  713. }
  714. break;
  715. #endif
  716. #ifdef AUTH_NONE
  717. case AUTH_NONE:
  718. #else
  719. case AUTH_NULL:
  720. #endif
  721. default:
  722. svcerr_weakauth(transp);
  723. UNLOCK_RPC();
  724. return;
  725. }
  726. }
  727. /* Bind the service procedure */
  728. switch (rqstp->rq_proc) {
  729. case _TT_MIN_AUTH_LEVEL:
  730. TTDB_DEBUG_SYSLOG("_TT_MIN_AUTH_LEVEL");
  731. xdr_argument = (bool_t (*)()) xdr_wrapstring;
  732. xdr_result = (bool_t (*)()) xdr_int;
  733. local = (char *(*)()) _tt_min_auth_level_1;
  734. break;
  735. case _TT_ISADDINDEX:
  736. TTDB_DEBUG_SYSLOG("_TT_ISADDINDEX");
  737. xdr_argument = (bool_t (*)()) xdr_Tt_isaddindex_args;
  738. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  739. local = (char *(*)()) _tt_isaddindex_1;
  740. break;
  741. case _TT_ISBUILD:
  742. TTDB_DEBUG_SYSLOG("_TT_ISBUILD");
  743. xdr_argument = (bool_t (*)()) xdr_Tt_isbuild_args;
  744. xdr_result =(bool_t (*)()) xdr_Tt_isam_results;
  745. local = (char *(*)()) _tt_isbuild_1;
  746. break;
  747. case _TT_ISCLOSE:
  748. TTDB_DEBUG_SYSLOG("_TT_ISCLOSE");
  749. xdr_argument = (bool_t (*)()) xdr_int;
  750. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  751. local = (char *(*)()) _tt_isclose_1;
  752. break;
  753. case _TT_ISCNTL:
  754. TTDB_DEBUG_SYSLOG("_TT_ISCNTL");
  755. xdr_argument = (bool_t (*)()) xdr_Tt_iscntl_args;
  756. xdr_result = (bool_t (*)()) xdr_Tt_iscntl_results;
  757. local = (char *(*)()) _tt_iscntl_1;
  758. break;
  759. case _TT_ISDELREC:
  760. TTDB_DEBUG_SYSLOG("_TT_ISDELREC");
  761. xdr_argument = (bool_t (*)()) xdr_Tt_isdelrec_args;
  762. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  763. local = (char *(*)()) _tt_isdelrec_1;
  764. break;
  765. case _TT_ISERASE:
  766. TTDB_DEBUG_SYSLOG("_TT_ISERASE");
  767. xdr_argument = (bool_t (*)()) xdr_wrapstring;
  768. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  769. local = (char *(*)()) _tt_iserase_1;
  770. break;
  771. case _TT_ISOPEN:
  772. TTDB_DEBUG_SYSLOG("_TT_ISOPEN");
  773. xdr_argument = (bool_t (*)()) xdr_Tt_isopen_args;
  774. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  775. local = (char *(*)()) _tt_isopen_1;
  776. break;
  777. case _TT_ISREAD:
  778. TTDB_DEBUG_SYSLOG("_TT_ISREAD");
  779. xdr_argument = (bool_t (*)()) xdr_Tt_isread_args;
  780. xdr_result = (bool_t (*)()) xdr_Tt_isread_results;
  781. local = (char *(*)()) _tt_isread_1;
  782. break;
  783. case _TT_ISREWREC:
  784. TTDB_DEBUG_SYSLOG("_TT_ISREWREC");
  785. xdr_argument = (bool_t (*)()) xdr_Tt_isrewrec_args;
  786. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  787. local = (char *(*)()) _tt_isrewrec_1;
  788. break;
  789. case _TT_ISSTART:
  790. TTDB_DEBUG_SYSLOG("_TT_ISSTART");
  791. xdr_argument = (bool_t (*)()) xdr_Tt_isstart_args;
  792. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  793. local = (char *(*)()) _tt_isstart_1;
  794. break;
  795. case _TT_ISWRITE:
  796. TTDB_DEBUG_SYSLOG("_TT_ISWRITE");
  797. xdr_argument = (bool_t (*)()) xdr_Tt_iswrite_args;
  798. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  799. local = (char *(*)()) _tt_iswrite_1;
  800. break;
  801. case _TT_TEST_AND_SET:
  802. TTDB_DEBUG_SYSLOG("_TT_TEST_AND_SET");
  803. xdr_argument = (bool_t (*)()) xdr_Tt_test_and_set_args;
  804. xdr_result = (bool_t (*)()) xdr_Tt_test_and_set_results;
  805. local = (char *(*)()) _tt_test_and_set_1;
  806. break;
  807. case _TT_TRANSACTION:
  808. TTDB_DEBUG_SYSLOG("_TT_TRANSACTION");
  809. xdr_argument = (bool_t (*)()) xdr_Tt_transaction_args;
  810. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  811. local = (char *(*)()) _tt_transaction_1;
  812. break;
  813. case _TT_MFS:
  814. TTDB_DEBUG_SYSLOG("_TT_MFS");
  815. xdr_argument = (bool_t (*)()) xdr_wrapstring;
  816. xdr_result = (bool_t (*)()) xdr_wrapstring;
  817. local = (char *(*)()) _tt_mfs_1;
  818. break;
  819. case _TT_GETOIDACCESS:
  820. TTDB_DEBUG_SYSLOG("_TT_GETOIDACCESS");
  821. xdr_argument = (bool_t (*)()) xdr_Tt_oidaccess_args;
  822. xdr_result = (bool_t (*)()) xdr_Tt_oidaccess_results;
  823. local = (char *(*)()) _tt_getoidaccess_1;
  824. break;
  825. case _TT_SETOIDUSER:
  826. TTDB_DEBUG_SYSLOG("_TT_SETOIDUSER");
  827. xdr_argument = (bool_t (*)()) xdr_Tt_oidaccess_args;
  828. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  829. local = (char *(*)()) _tt_setoiduser_1;
  830. break;
  831. case _TT_SETOIDGROUP:
  832. TTDB_DEBUG_SYSLOG("_TT_SETOIDGROUP");
  833. xdr_argument = (bool_t (*)()) xdr_Tt_oidaccess_args;
  834. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  835. local = (char *(*)()) _tt_setoidgroup_1;
  836. break;
  837. case _TT_SETOIDMODE:
  838. TTDB_DEBUG_SYSLOG("_TT_SETOIDMODE");
  839. xdr_argument = (bool_t (*)()) xdr_Tt_oidaccess_args;
  840. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  841. local = (char *(*)()) _tt_setoidmode_1;
  842. break;
  843. case _TT_READSPEC:
  844. TTDB_DEBUG_SYSLOG("_TT_READSPEC");
  845. xdr_argument = (bool_t (*)()) xdr_Tt_spec_props;
  846. xdr_result = (bool_t (*)()) xdr_Tt_spec_props;
  847. local = (char *(*)()) _tt_readspec_1;
  848. break;
  849. case _TT_WRITESPEC:
  850. TTDB_DEBUG_SYSLOG("_TT_WRITESPEC");
  851. xdr_argument = (bool_t (*)()) xdr_Tt_spec_props;
  852. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  853. local = (char *(*)()) _tt_writespec_1;
  854. break;
  855. case _TT_ADDSESSION:
  856. TTDB_DEBUG_SYSLOG("_TT_ADDSESSION");
  857. xdr_argument = (bool_t (*)()) xdr_Tt_session_args;
  858. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  859. local = (char *(*)()) _tt_addsession_1;
  860. break;
  861. case _TT_DELSESSION:
  862. TTDB_DEBUG_SYSLOG("_TT_DELSESSION");
  863. xdr_argument = (bool_t (*)()) xdr_Tt_session_args;
  864. xdr_result = (bool_t (*)()) xdr_Tt_isam_results;
  865. local = (char *(*)()) _tt_delsession_1;
  866. break;
  867. case _TT_GETTYPE:
  868. TTDB_DEBUG_SYSLOG("_TT_GETTYPE");
  869. xdr_argument = (bool_t (*)()) xdr_Tt_spec_props;
  870. xdr_result = (bool_t (*)()) xdr_Tt_spec_props;
  871. local = (char *(*)()) _tt_gettype_1;
  872. break;
  873. case TT_GET_MIN_AUTH_LEVEL:
  874. TTDB_DEBUG_SYSLOG("TT_GET_MIN_AUTH_LEVEL");
  875. xdr_argument = (bool_t (*)()) xdr_void;
  876. xdr_result = (bool_t (*)()) xdr_tt_auth_level_results;
  877. local = (char *(*)()) _tt_get_min_auth_level_1;
  878. break;
  879. case TT_GET_FILE_PARTITION:
  880. TTDB_DEBUG_SYSLOG("TT_GET_FILE_PARTITION");
  881. xdr_argument = (bool_t (*)()) xdr_wrapstring;
  882. xdr_result = (bool_t (*)()) xdr_tt_file_partition_results;
  883. local = (char *(*)()) _tt_get_file_partition_1;
  884. break;
  885. case TT_CREATE_FILE:
  886. TTDB_DEBUG_SYSLOG("TT_CREATE_FILE");
  887. xdr_argument = (bool_t (*)()) xdr_tt_create_file_args;
  888. xdr_result = (bool_t (*)()) xdr_tt_db_cache_results;
  889. local = (char *(*)()) _tt_create_file_1;
  890. break;
  891. case TT_CREATE_OBJ:
  892. TTDB_DEBUG_SYSLOG("TT_CREATE_OBJ");
  893. xdr_argument = (bool_t (*)()) xdr_tt_create_obj_args;
  894. xdr_result = (bool_t (*)()) xdr_tt_db_cache_results;
  895. local = (char *(*)()) _tt_create_obj_1;
  896. break;
  897. case TT_REMOVE_FILE:
  898. TTDB_DEBUG_SYSLOG("TT_REMOVE_FILE");
  899. xdr_argument = (bool_t (*)()) xdr_tt_remove_file_args;
  900. xdr_result = (bool_t (*)()) xdr_tt_db_results;
  901. local = (char *(*)()) _tt_remove_file_1;
  902. break;
  903. case TT_REMOVE_OBJ:
  904. TTDB_DEBUG_SYSLOG("TT_REMOVE_OBJ");
  905. xdr_argument = (bool_t (*)()) xdr_tt_remove_obj_args;
  906. xdr_result = (bool_t (*)()) xdr_tt_db_results;
  907. local = (char *(*)()) _tt_remove_obj_1;
  908. break;
  909. case TT_MOVE_FILE:
  910. TTDB_DEBUG_SYSLOG("TT_MOVE_FILE");
  911. xdr_argument = (bool_t (*)()) xdr_tt_move_file_args;
  912. xdr_result = (bool_t (*)()) xdr_tt_db_results;
  913. local = (char *(*)()) _tt_move_file_1;
  914. break;
  915. case TT_SET_FILE_PROPS:
  916. TTDB_DEBUG_SYSLOG("TT_SET_FILE_PROPS");
  917. xdr_argument = (bool_t (*)()) xdr_tt_set_file_props_args;
  918. xdr_result = (bool_t (*)()) xdr_tt_db_cache_results;
  919. local = (char *(*)()) _tt_set_file_props_1;
  920. break;
  921. case TT_SET_FILE_PROP:
  922. TTDB_DEBUG_SYSLOG("TT_SET_FILE_PROP");
  923. xdr_argument = (bool_t (*)()) xdr_tt_set_file_prop_args;
  924. xdr_result = (bool_t (*)()) xdr_tt_db_cache_results;
  925. local = (char *(*)()) _tt_set_file_prop_1;
  926. break;
  927. case TT_ADD_FILE_PROP:
  928. TTDB_DEBUG_SYSLOG("TT_ADD_FILE_PROP");
  929. xdr_argument = (bool_t (*)()) xdr_tt_add_file_prop_args;
  930. xdr_result = (bool_t (*)()) xdr_tt_db_cache_results;
  931. local = (char *(*)()) _tt_add_file_prop_1;
  932. break;
  933. case TT_DELETE_FILE_PROP:
  934. TTDB_DEBUG_SYSLOG("TT_DELETE_FILE_PROP");
  935. xdr_argument = (bool_t (*)()) xdr_tt_del_file_prop_args;
  936. xdr_result = (bool_t (*)()) xdr_tt_db_cache_results;
  937. local = (char *(*)()) _tt_delete_file_prop_1;
  938. break;
  939. case TT_GET_FILE_PROP:
  940. TTDB_DEBUG_SYSLOG("TT_GET_FILE_PROP");
  941. xdr_argument = (bool_t (*)()) xdr_tt_get_file_prop_args;
  942. xdr_result = (bool_t (*)()) xdr_tt_file_prop_results;
  943. local = (char *(*)()) _tt_get_file_prop_1;
  944. break;
  945. case TT_GET_FILE_PROPS:
  946. TTDB_DEBUG_SYSLOG("TT_GET_FILE_PROPS");
  947. xdr_argument = (bool_t (*)()) xdr_tt_get_file_props_args;
  948. xdr_result = (bool_t (*)()) xdr_tt_file_props_results;
  949. local = (char *(*)()) _tt_get_file_props_1;
  950. break;
  951. case TT_GET_FILE_OBJS:
  952. TTDB_DEBUG_SYSLOG("TT_GET_FILE_OBJS");
  953. xdr_argument = (bool_t (*)()) xdr_tt_get_file_objs_args;
  954. xdr_result = (bool_t (*)()) xdr_tt_file_objs_results;
  955. local = (char *(*)()) _tt_get_file_objs_1;
  956. break;
  957. case TT_SET_FILE_ACCESS:
  958. TTDB_DEBUG_SYSLOG("TT_SET_FILE_ACCESS");
  959. xdr_argument = (bool_t (*)()) xdr_tt_set_file_access_args;
  960. xdr_result = (bool_t (*)()) xdr_tt_db_results;
  961. local = (char *(*)()) _tt_set_file_access_1;
  962. break;
  963. case TT_GET_FILE_ACCESS:
  964. TTDB_DEBUG_SYSLOG("TT_GET_FILE_ACCESS");
  965. xdr_argument = (bool_t (*)()) xdr_tt_get_file_access_args;
  966. xdr_result = (bool_t (*)()) xdr_tt_file_access_results;
  967. local = (char *(*)()) _tt_get_file_access_1;
  968. break;
  969. case TT_SET_OBJ_PROPS:
  970. TTDB_DEBUG_SYSLOG("TT_SET_OBJ_PROPS");
  971. xdr_argument = (bool_t (*)()) xdr_tt_set_obj_props_args;
  972. xdr_result = (bool_t (*)()) xdr_tt_obj_props_results;
  973. local = (char *(*)()) _tt_set_obj_props_1;
  974. break;
  975. case TT_SET_OBJ_PROP:
  976. TTDB_DEBUG_SYSLOG("TT_SET_OBJ_PROP");
  977. xdr_argument = (bool_t (*)()) xdr_tt_set_obj_prop_args;
  978. xdr_result = (bool_t (*)()) xdr_tt_obj_props_results;
  979. local = (char *(*)()) _tt_set_obj_prop_1;
  980. break;
  981. case TT_ADD_OBJ_PROP:
  982. TTDB_DEBUG_SYSLOG("TT_ADD_OBJ_PROP");
  983. xdr_argument = (bool_t (*)()) xdr_tt_add_obj_prop_args;
  984. xdr_result = (bool_t (*)()) xdr_tt_obj_props_results;
  985. local = (char *(*)()) _tt_add_obj_prop_1;
  986. break;
  987. case TT_DELETE_OBJ_PROP:
  988. TTDB_DEBUG_SYSLOG("TT_DELETE_OBJ_PROP");
  989. xdr_argument = (bool_t (*)()) xdr_tt_del_obj_prop_args;
  990. xdr_result = (bool_t (*)()) xdr_tt_obj_props_results;
  991. local = (char *(*)()) _tt_delete_obj_prop_1;
  992. break;
  993. case TT_GET_OBJ_PROP:
  994. TTDB_DEBUG_SYSLOG("TT_GET_OBJ_PROP");
  995. xdr_argument = (bool_t (*)()) xdr_tt_get_obj_prop_args;
  996. xdr_result = (bool_t (*)()) xdr_tt_obj_prop_results;
  997. local = (char *(*)()) _tt_get_obj_prop_1;
  998. break;
  999. case TT_GET_OBJ_PROPS:
  1000. TTDB_DEBUG_SYSLOG("TT_GET_OBJ_PROPS");
  1001. xdr_argument = (bool_t (*)()) xdr_tt_get_obj_props_args;
  1002. xdr_result = (bool_t (*)()) xdr_tt_obj_props_results;
  1003. local = (char *(*)()) _tt_get_obj_props_1;
  1004. break;
  1005. case TT_SET_OBJ_TYPE:
  1006. TTDB_DEBUG_SYSLOG("TT_SET_OBJ_TYPE");
  1007. xdr_argument = (bool_t (*)()) xdr_tt_set_obj_type_args;
  1008. xdr_result = (bool_t (*)()) xdr_tt_db_results;
  1009. local = (char *(*)()) _tt_set_obj_type_1;
  1010. break;
  1011. case TT_GET_OBJ_TYPE:
  1012. TTDB_DEBUG_SYSLOG("TT_GET_OBJ_TYPE");
  1013. xdr_argument = (bool_t (*)()) xdr_wrapstring;
  1014. xdr_result = (bool_t (*)()) xdr_tt_obj_type_results;
  1015. local = (char *(*)()) _tt_get_obj_type_1;
  1016. break;
  1017. case TT_SET_OBJ_FILE:
  1018. TTDB_DEBUG_SYSLOG("TT_SET_OBJ_FILE");
  1019. xdr_argument = (bool_t (*)()) xdr_tt_set_obj_file_args;
  1020. xdr_result = (bool_t (*)()) xdr_tt_db_results;
  1021. local = (char *(*)()) _tt_set_obj_file_1;
  1022. break;
  1023. case TT_GET_OBJ_FILE:
  1024. TTDB_DEBUG_SYSLOG("TT_GET_OBJ_FILE");
  1025. xdr_argument = (bool_t (*)()) xdr_tt_get_obj_file_args;
  1026. xdr_result = (bool_t (*)()) xdr_tt_obj_file_results;
  1027. local = (char *(*)()) _tt_get_obj_file_1;
  1028. break;
  1029. case TT_SET_OBJ_ACCESS:
  1030. TTDB_DEBUG_SYSLOG("TT_SET_OBJ_ACCESS");
  1031. xdr_argument = (bool_t (*)()) xdr_tt_set_obj_access_args;
  1032. xdr_result = (bool_t (*)()) xdr_tt_db_results;
  1033. local = (char *(*)()) _tt_set_obj_access_1;
  1034. break;
  1035. case TT_GET_OBJ_ACCESS:
  1036. TTDB_DEBUG_SYSLOG("TT_GET_OBJ_ACCESS");
  1037. xdr_argument = (bool_t (*)()) xdr_tt_get_obj_access_args;
  1038. xdr_result = (bool_t (*)()) xdr_tt_obj_access_results;
  1039. local = (char *(*)()) _tt_get_obj_access_1;
  1040. break;
  1041. case TT_IS_FILE_IN_DB:
  1042. TTDB_DEBUG_SYSLOG("TT_IS_FILE_IN_DB");
  1043. xdr_argument = (bool_t (*)()) xdr_tt_is_file_in_db_args;
  1044. xdr_result = (bool_t (*)()) xdr_tt_is_file_in_db_results;
  1045. local = (char *(*)()) _tt_is_file_in_db_1;
  1046. break;
  1047. case TT_IS_OBJ_IN_DB:
  1048. TTDB_DEBUG_SYSLOG("TT_IS_OBJ_IN_DB");
  1049. xdr_argument = (bool_t (*)()) xdr_tt_is_obj_in_db_args;
  1050. xdr_result = (bool_t (*)()) xdr_tt_is_obj_in_db_results;
  1051. local = (char *(*)()) _tt_is_obj_in_db_1;
  1052. break;
  1053. case TT_QUEUE_MESSAGE:
  1054. TTDB_DEBUG_SYSLOG("TT_QUEUE_MESSAGE");
  1055. xdr_argument = (bool_t (*)()) xdr_tt_queue_msg_args;
  1056. xdr_result = (bool_t (*)()) xdr_tt_db_results;
  1057. local = (char *(*)()) _tt_queue_message_1;
  1058. break;
  1059. case TT_DEQUEUE_MESSAGES:
  1060. TTDB_DEBUG_SYSLOG("TT_DEQUEUE_MESSAGES");
  1061. xdr_argument = (bool_t (*)()) xdr_tt_dequeue_msgs_args;
  1062. xdr_result = (bool_t (*)()) xdr_tt_dequeue_msgs_results;
  1063. local = (char *(*)()) _tt_dequeue_messages_1;
  1064. break;
  1065. case TTDB_FILE_NETFILE:
  1066. TTDB_DEBUG_SYSLOG("TTDB_FILE_NETFILE");
  1067. xdr_argument = (bool_t (*)()) xdr_tt_file_netfile_args;
  1068. xdr_result = (bool_t (*)()) xdr_tt_file_netfile_results;
  1069. local = (char *(*)()) _tt_file_netfile_1;
  1070. break;
  1071. case TTDB_NETFILE_FILE:
  1072. TTDB_DEBUG_SYSLOG("TTDB_NETFILE_FILE");
  1073. xdr_argument = (bool_t (*)()) xdr_tt_file_netfile_args;
  1074. xdr_result = (bool_t (*)()) xdr_tt_file_netfile_results;
  1075. local = (char *(*)()) _tt_netfile_file_1;
  1076. break;
  1077. case TT_GET_ALL_SESSIONS:
  1078. TTDB_DEBUG_SYSLOG("TT_GET_ALL_SESSIONS");
  1079. xdr_argument = (bool_t (*)())xdr_tt_get_all_sessions_args;
  1080. xdr_result = (bool_t (*)())xdr_tt_get_all_sessions_results;
  1081. local = (char *(*)()) _tt_get_all_sessions_1;
  1082. break;
  1083. case TT_GARBAGE_COLLECT:
  1084. TTDB_DEBUG_SYSLOG("TT_GARBAGE_COLLECT");
  1085. xdr_argument = (bool_t (*)())xdr_void;
  1086. xdr_result = (bool_t (*)())xdr_tt_garbage_collect_results;
  1087. local = (char *(*)()) _tt_garbage_collect_1;
  1088. break;
  1089. case TT_DELETE_SESSION:
  1090. TTDB_DEBUG_SYSLOG("TT_DELETE_SESSION");
  1091. xdr_argument = (bool_t (*)())xdr_tt_delete_session_args;
  1092. xdr_result = (bool_t (*)())xdr_tt_delete_session_results;
  1093. local = (char *(*)()) _tt_delete_session_1;
  1094. break;
  1095. default:
  1096. svcerr_noproc(transp);
  1097. UNLOCK_RPC();
  1098. return;
  1099. }
  1100. /* get the input arguments */
  1101. memset((char *)&argument, 0, sizeof(argument));
  1102. if (!svc_getargs(transp, (xdrproc_t)xdr_argument, (caddr_t)&argument)) {
  1103. svcerr_decode(transp);
  1104. UNLOCK_RPC();
  1105. return;
  1106. }
  1107. char *(*local_t)(caddr_t, SVCXPRT *) = (char *(*)(caddr_t, SVCXPRT *))
  1108. local;
  1109. /* Check global message queue unlock flag */
  1110. if (msg_q_unlock_flag == TRUE) {
  1111. msg_q_unlock_flag = FALSE;
  1112. _Tt_db_msg_q_lock locks;
  1113. locks.unsetAllLocks();
  1114. }
  1115. if (refresh_partition_redirection_map) {
  1116. refresh_partition_redirection_map = FALSE;
  1117. db_pr_map->refresh();
  1118. }
  1119. /* call the service procedure */
  1120. result = (*local_t)((caddr_t)&argument, transp);
  1121. /* return the results to client */
  1122. if ((result != NULL) && !svc_sendreply(transp,
  1123. (xdrproc_t)xdr_result,
  1124. (caddr_t)result)) {
  1125. svcerr_systemerr(transp);
  1126. }
  1127. /* free memory */
  1128. if (!svc_freeargs(transp,
  1129. (xdrproc_t)xdr_argument,
  1130. (caddr_t)&argument)) {
  1131. _tt_syslog(errstr, LOG_ERR, "svc_freeargs() == 0");
  1132. exit(1);
  1133. }
  1134. /* process the transaction log file if there were a transaction */
  1135. if (rqstp->rq_proc == _TT_TRANSACTION) {
  1136. _tt_process_transaction();
  1137. }
  1138. //
  1139. // Free the results
  1140. switch (rqstp->rq_proc) {
  1141. case TT_GET_MIN_AUTH_LEVEL:
  1142. break;
  1143. case TT_GET_FILE_PARTITION:
  1144. if (result) {
  1145. if (((_tt_file_partition_results *)result)->partition) {
  1146. free(((_tt_file_partition_results *)result)->partition);
  1147. }
  1148. if (((_tt_file_partition_results *)result)->network_path) {
  1149. free(((_tt_file_partition_results *)result)->network_path);
  1150. }
  1151. }
  1152. break;
  1153. case TT_CREATE_FILE:
  1154. break;
  1155. case TT_CREATE_OBJ:
  1156. break;
  1157. case TT_REMOVE_FILE:
  1158. break;
  1159. case TT_REMOVE_OBJ:
  1160. break;
  1161. case TT_MOVE_FILE:
  1162. break;
  1163. case TT_SET_FILE_PROPS:
  1164. break;
  1165. case TT_SET_FILE_PROP:
  1166. break;
  1167. case TT_ADD_FILE_PROP:
  1168. break;
  1169. case TT_DELETE_FILE_PROP:
  1170. break;
  1171. case TT_GET_FILE_PROP:
  1172. if (result) {
  1173. _tt_free_rpc_property(((_tt_file_prop_results *)
  1174. result)->property);
  1175. }
  1176. break;
  1177. case TT_GET_FILE_PROPS:
  1178. if (result) {
  1179. _tt_free_rpc_properties(((_tt_file_props_results *)
  1180. result)->properties);
  1181. }
  1182. break;
  1183. case TT_GET_FILE_OBJS:
  1184. if (result) {
  1185. _tt_free_rpc_strings(((_tt_file_objs_results *)
  1186. result)->objids);
  1187. }
  1188. break;
  1189. case TT_SET_FILE_ACCESS:
  1190. break;
  1191. case TT_GET_FILE_ACCESS:
  1192. break;
  1193. case TT_SET_OBJ_PROPS:
  1194. break;
  1195. case TT_SET_OBJ_PROP:
  1196. break;
  1197. case TT_ADD_OBJ_PROP:
  1198. break;
  1199. case TT_DELETE_OBJ_PROP:
  1200. break;
  1201. case TT_GET_OBJ_PROP:
  1202. if (result) {
  1203. _tt_free_rpc_property(((_tt_obj_prop_results *)
  1204. result)->property);
  1205. }
  1206. break;
  1207. case TT_GET_OBJ_PROPS:
  1208. if (result) {
  1209. _tt_free_rpc_properties(((_tt_obj_props_results *)
  1210. result)->properties);
  1211. }
  1212. break;
  1213. case TT_SET_OBJ_TYPE:
  1214. break;
  1215. case TT_GET_OBJ_TYPE:
  1216. if (result) {
  1217. free(((_tt_obj_type_results *)result)->otype);
  1218. }
  1219. break;
  1220. case TT_SET_OBJ_FILE:
  1221. break;
  1222. case TT_GET_OBJ_FILE:
  1223. if (result) {
  1224. free(((_tt_obj_file_results *)result)->file);
  1225. }
  1226. break;
  1227. case TT_SET_OBJ_ACCESS:
  1228. break;
  1229. case TT_GET_OBJ_ACCESS:
  1230. break;
  1231. case TT_IS_FILE_IN_DB:
  1232. break;
  1233. case TT_IS_OBJ_IN_DB:
  1234. if (result && ((_tt_is_obj_in_db_results *)
  1235. result)->forward_pointer) {
  1236. free(((_tt_is_obj_in_db_results *)
  1237. result)->forward_pointer);
  1238. }
  1239. break;
  1240. case TT_QUEUE_MESSAGE:
  1241. break;
  1242. case TT_DEQUEUE_MESSAGES:
  1243. if (result) {
  1244. _tt_free_rpc_messages(((_tt_dequeue_msgs_results *)
  1245. result)->messages);
  1246. }
  1247. break;
  1248. default:
  1249. break;
  1250. }
  1251. UNLOCK_RPC();
  1252. #if defined(OPT_AUTO_GARBAGE_COLLECT)
  1253. #if !defined(OPT_GARBAGE_THREADS)
  1254. if (!_tt_debug_mode) {
  1255. #endif
  1256. //
  1257. // The results have been passed back to the client program.
  1258. // Now check for garbage collection at some pre-determined
  1259. // interval (_TT_GARBAGE_COLLECTION_FREQUENCY).
  1260. //
  1261. time_t the_time_now = time(0);
  1262. //
  1263. // Wait at least 5 Min. after startup.
  1264. //
  1265. if (_tt_global->next_garbage_run == -1) {
  1266. _tt_global->next_garbage_run = the_time_now + (60 * 5);
  1267. }
  1268. if (the_time_now > _tt_global->next_garbage_run) {
  1269. _tt_global->next_garbage_run
  1270. = the_time_now + _TT_GARBAGE_COLLECTION_FREQUENCY;
  1271. //
  1272. // Run the cleanup in parallal so the server can
  1273. // keep running.
  1274. _tt_run_garbage_collect(TRUE); // In parallel
  1275. }
  1276. #if !defined(OPT_GARBAGE_THREADS)
  1277. }
  1278. #endif
  1279. #endif /*OPT_AUTO_GARBAGE_COLLECT*/
  1280. return;
  1281. }
  1282. void
  1283. install_signal_handler()
  1284. {
  1285. // It's important to ignore SIGPIPES so we don't die when clients do.
  1286. // SIGUSR1 is used to turn logging on or off.
  1287. //
  1288. // SIGHUP probably *ought* to be used to force any caches to flush
  1289. // For robustness, ought to catch SIGINT/TERM so we finish the current
  1290. // RPC call and write out files..
  1291. //
  1292. _tt_sigset(SIGUSR1, &sig_handler);
  1293. _tt_sigset(SIGUSR2, &sig_handler);
  1294. _tt_sigset(SIGPIPE, &sig_handler);
  1295. #if !defined(OPT_GARBAGE_THREADS)
  1296. _tt_sigset(SIGCHLD, &sig_handler);
  1297. #endif
  1298. return;
  1299. }
  1300. void
  1301. sig_handler(int sig)
  1302. {
  1303. switch (sig) {
  1304. case SIGPIPE:
  1305. // If a client goes away, unlock the message q locks.
  1306. // Rationale: It's better to have potential collisions
  1307. // between old and new clients then lock up the DB
  1308. // indefinitely.
  1309. msg_q_unlock_flag = TRUE;
  1310. break;
  1311. case SIGUSR1:
  1312. // turn trace on (level 1) if it was off. turn trace off
  1313. // if it was on.
  1314. break;
  1315. case SIGUSR2:
  1316. refresh_partition_redirection_map = TRUE;
  1317. break;
  1318. #if !defined(OPT_GARBAGE_THREADS)
  1319. case SIGCHLD:
  1320. waitpid(-1, NULL, WNOHANG); // Reap and run.
  1321. _tt_garbage_id = -1; // Mark as done.
  1322. break;
  1323. #endif
  1324. default:
  1325. break;
  1326. }
  1327. return;
  1328. }