eyedbd.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021   Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 #include <stdio.h>
00026 #include <unistd.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <eyedb/eyedb.h>
00030 #include "base_p.h"
00031 #include "eyedb/internals/ObjectHeader.h"
00032 #include <eyedblib/rpc_lib.h>
00033 #include <eyedbsm/smd.h>
00034 #include "SessionLog.h"
00035 #include <eyedblib/connman.h>
00036 #include "eyedblib/log.h"
00037 #include "eyedblib/butils.h"
00038 #include "eyedb/Log.h"
00039 #include "GetOpt.h"
00040 
00041 #include "serv_lib.h"
00042 #include "kernel.h"
00043 
00044 //#define RPC_TIMEOUT
00045 
00046 using namespace std;
00047 
00048 namespace eyedb {
00049   extern void (*garbage_handler)(void);
00050   extern void printVersion();
00051 }
00052 
00053 #ifdef RPC_TIMEOUT
00054 extern void (*settimeout)(int);
00055 #endif
00056 namespace eyedbsm {
00057   extern Boolean backend;
00058 }
00059 
00060 using namespace eyedb;
00061 
00062 static Bool nod;
00063 
00064 //#define NO_DATDIR
00065 
00066 static int
00067 get_opts(int argc, char *argv[],
00068          const char **accessfile,
00069          const char **datdir,
00070          const char **sesslogdev,
00071          int *sessloglevel,
00072          int *nofork)
00073 {
00074   int i;
00075   const char *s;
00076 
00077   *accessfile = eyedb::ServerConfig::getSValue("access_file");
00078   *nofork = 0;
00079   *sesslogdev = 0;
00080   *sessloglevel = 0;
00081 
00082 #ifndef NO_DATDIR
00083   *datdir = 0;
00084 #else
00085   *datdir = "";
00086 #endif
00087 
00088   static const std::string access_file_opt = "access-file";
00089   static const std::string datdir_opt = "databasedir";
00090   static const std::string nod_opt = "nod";
00091   static const std::string sesslogdev_opt = "sesslogdev";
00092   static const std::string sessloglevel_opt = "sessloglevel";
00093   static const std::string help_opt = "help";
00094 
00095   Option opts[] = {
00096     Option(access_file_opt, OptionStringType(),
00097            Option::MandatoryValue, OptionDesc("Access file", "ACCESS_FILE")),
00098 #ifndef NO_DATDIR
00099     Option(datdir_opt, OptionStringType(),
00100            Option::MandatoryValue, OptionDesc("Default datafile directory", "DATDIR")),
00101 #endif
00102     Option(nod_opt, OptionBoolType(),
00103            0, OptionDesc("No daemon: does not close fd 0, 1 & 2")),
00104     Option('h', help_opt, OptionBoolType(),
00105            0, OptionDesc("Display this message"))
00106   };
00107 
00108   GetOpt getopt(argv[0], opts, sizeof(opts)/sizeof(opts[0]));
00109 
00110   if (!getopt.parse(argc, argv)) {
00111     print_standard_usage(getopt, "", std::cerr, true);
00112     //getopt.usage("\n");
00113     return 1;
00114   }
00115 
00116   GetOpt::Map &map = getopt.getMap();
00117 
00118   if (map.find(help_opt) != map.end()) {
00119     print_standard_help(getopt, vector<string>(), std::cerr, true);
00120     //getopt.help(cerr, "  ");
00121     return 1;
00122   }
00123 
00124   if (map.find(access_file_opt) != map.end())
00125     *accessfile = strdup(map[access_file_opt].value.c_str());
00126 
00127 #ifndef NO_DATDIR
00128   if (map.find(datdir_opt) != map.end())
00129     *datdir = strdup(map[datdir_opt].value.c_str());
00130 #endif
00131 
00132   if (map.find(nod_opt) != map.end())
00133     nod = True;
00134 
00135   if (map.find(sesslogdev_opt) != map.end())
00136     *sesslogdev = strdup(map[sesslogdev_opt].value.c_str());
00137 
00138   if (map.find(sessloglevel_opt) != map.end())
00139     *sessloglevel = ((OptionIntType *)map[sessloglevel_opt].type)->
00140       getIntValue(map[sessloglevel_opt].value);
00141 
00142 #ifndef NO_DATDIR
00143   if (!*datdir) {
00144     if (s = eyedb::ServerConfig::getSValue("databasedir"))
00145       *datdir = strdup(s);
00146     else {
00147       fprintf(stderr, "configuration variable databasedir is not set\n");
00148       exit(1);
00149     }
00150   }
00151 #endif
00152 
00153   return 0;
00154 }
00155 
00156 static SessionLog *sesslog;
00157 
00158 void rpc_unlink_socket();
00159 
00160 static void
00161 _quit_handler(void *xpid, int)
00162 {
00163   if (*(int *)xpid == rpc_getpid()) {
00164     sesslog->remove();
00165     rpc_unlink_socket();
00166   }
00167 }
00168 
00169 static int
00170 notice(int status)
00171 {
00172   const char *s;
00173   if (s = getenv("EYEDBPFD")) {
00174     int pfd = atoi(s);
00175     if (pfd > 0) {
00176       write(pfd, &status, sizeof(status));
00177       close(pfd);
00178     }
00179   }
00180 
00181   return status;
00182 }
00183 
00184 static unsigned int get_ports(const char *ports[], const char *hosts[],
00185                               const char *_listen)
00186 {
00187   if (!_listen)
00188     return 0;
00189 
00190   char *listen = strdup(_listen);
00191   unsigned int nlisten = 0;
00192   for (;;) {
00193     ports[nlisten++] = listen;
00194     listen = strchr(listen, ',');
00195     if (!listen)
00196       break;
00197     *listen++ = 0;
00198   }
00199 
00200   for (int n = 0; n < nlisten; n++) {
00201     const char *p = strchr(ports[n], ':');
00202     if (p) {
00203       *(char *)p = 0;
00204       hosts[n] = ports[n];
00205       ports[n] = p + 1;
00206     }
00207     else {
00208       hosts[n] = "localhost";
00209     }
00210   }
00211         
00212 
00213   return nlisten;
00214 }
00215 
00216 int
00217 main(int argc, char *argv[])
00218 {
00219   rpc_Server *server;
00220   rpc_PortHandle *port[32];
00221   const char *ports[32];
00222   const char *hosts[32];
00223   eyedbsm::Status status;
00224   const char *hostname;
00225   const char *accessfile, *datdir;
00226   const char *listen;
00227   const char *sesslogdev;
00228   int sessloglevel;
00229   unsigned int nlisten;
00230 
00231   int nofork;
00232 
00233   string sv_listen;
00234 
00235   try {
00236     eyedb::init(argc, argv, &sv_listen, true);
00237 
00238     listen = sv_listen.c_str();
00239 
00240     server = rpcBeInit();
00241 
00242     garbage_handler = GARBAGE;
00243 #ifdef RPC_TIMEOUT
00244     settimeout = rpc_setTimeOut;
00245 #endif
00246 
00247     eyedbsm::backend = eyedbsm::True;
00248 
00249     if (get_opts(argc, argv, &accessfile, &datdir, &sesslogdev,
00250                  &sessloglevel, &nofork))
00251       return notice(1);
00252 
00253     rpc_setProgName(argv[0]);
00254 
00255     if (!*listen)
00256       listen = eyedb::ServerConfig::getSValue("listen");
00257 
00258     nlisten = get_ports(ports, hosts, listen);
00259 
00260     for (int n = 0; n < nlisten; n++) {
00261       if (!eyedblib::is_number(ports[n]) && strcmp(hosts[n], "localhost")) {
00262         fprintf(stderr, "eyedbd: cannot specify host '%s' for named pipe '%s'\n",
00263                 hosts[n], ports[n]);
00264         return 1;
00265       }
00266     }
00267 
00268     if (rpc_connman_init(accessfile))
00269       return notice(1);
00270 
00271     if (!nlisten) {
00272       fprintf(stderr, "eyedbd: at least one port must be set.\n");
00273       return notice(1);
00274     }
00275 
00276     for (int i = 0; i < nlisten; i++)
00277       if (rpc_portOpen(server, hosts[i], ports[i], &port[i]))
00278         return notice(1);
00279 
00280     int *pid = new int;
00281     *pid = getpid();
00282     rpc_setQuitHandler(_quit_handler, pid);
00283 
00284     const char *sv_tmpdir = eyedb::ServerConfig::getSValue("tmpdir");
00285 
00286     if (!sv_tmpdir)
00287       sv_tmpdir = "/tmp";
00288 
00289     std::string logdir = sv_tmpdir;
00290 
00291     eyedb::Exception::setMode(eyedb::Exception::StatusMode);
00292 
00293     sesslog = new SessionLog(logdir.c_str(), eyedb::getVersion(),
00294                              nlisten, hosts, ports,
00295                              datdir, sesslogdev, sessloglevel);
00296 
00297 #ifndef NO_DATDIR
00298     IDB_init(datdir, 0 /* passwdfile */, sesslog, 0 /*timeout*/);
00299 #else
00300     IDB_init(0, 0 /* passwdfile */, sesslog, 0 /*timeout*/);
00301 #endif
00302 
00303     if (sesslog->getStatus()) {
00304       sesslog->getStatus()->print();
00305       return notice(1);
00306     }
00307 
00308     (void)notice(0);
00309 
00310     if (!nod) {
00311       close(0);
00312       if (!Log::getLog() || strcmp(Log::getLog(), "stdout"))
00313         close(1);
00314       if (!Log::getLog() || strcmp(Log::getLog(), "stderr"))
00315         close(2);
00316     }
00317 
00318     rpc_serverMainLoop(server, port, nlisten);
00319   }
00320   catch(Exception &e) {
00321     cerr << e << flush;
00322     return 1;
00323   }
00324   catch(int status) {
00325     return status;
00326   }
00327   return 0;
00328 }

Generated on Mon Dec 22 18:15:54 2008 for eyedb by  doxygen 1.5.3