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