Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

daemonmain.cc

Go to the documentation of this file.
00001 #include <signal.h>
00002 
00003 #include "wvcrash.h"
00004 #include "wvlog.h"
00005 #include "wvlogrcv.h"
00006 #include "uniconf.h"
00007 #include "uniconfdaemon.h"
00008 #include "uniclientconn.h"
00009 #include "unisecuregen.h"
00010 #include "unipermgen.h"
00011 #include "wvx509.h"
00012 #include "uniconfroot.h"
00013 #include "strutils.h"
00014 
00015 #define DEFAULT_CONFIG_FILE "ini:uniconf.ini"
00016 
00017 static UniConfDaemon *globdaemon = NULL;
00018 
00019 // we now want execution to stop
00020 static void sighandler_die(int sig)
00021 {
00022     globdaemon->close();
00023     signal(sig, SIG_DFL);
00024 }
00025 
00026 
00027 static void usage()
00028 {
00029     wverr->print(
00030         "uniconfdaemon usage:  uniconfdaemon "
00031             "[-mount mountpoint moniker perms] [-p port] [-ssl sslport] [-d level]\n"
00032         "    mountpoint - the point to mount the config keys under\n"
00033         "    moniker    - the moniker, eg. ini:myfile\n"
00034         "    perms      - moniker to get permissions from (optional)\n"
00035         "    level      - the debug level\n"
00036         "                 Critical, Error, Warning, Notice, Info, or Debug[1-5]\n"
00037         "    port       - the port to listen on for TCP connections (use 0 to disallow)\n"
00038         "    sslport    - the port to listen on for SSL-encrypted TCP connections (use 0 to disallow)\n");
00039     exit(2);
00040 }
00041 
00042 
00043 static WvLog::LogLevel findloglevel(char *arg)
00044 {
00045     if (!strcasecmp(arg, "Critical"))
00046         return WvLog::Critical;
00047     else if (!strcasecmp(arg, "Error"))
00048         return WvLog::Error;
00049     else if (!strcasecmp(arg, "Warning"))
00050         return WvLog::Warning;
00051     else if (!strcasecmp(arg, "Notice"))
00052         return WvLog::Notice;
00053     else if (!strcasecmp(arg, "Info"))
00054         return WvLog::Info;
00055     else if (!strcasecmp(arg, "Debug1"))
00056         return WvLog::Debug1;
00057     else if (!strcasecmp(arg, "Debug2"))
00058         return WvLog::Debug2;
00059     else if (!strcasecmp(arg, "Debug3"))
00060         return WvLog::Debug3;
00061     else if (!strcasecmp(arg, "Debug4"))
00062         return WvLog::Debug4;
00063     else if (!strcasecmp(arg, "Debug5"))
00064         return WvLog::Debug5;
00065     else
00066         return WvLog::Info;
00067 }
00068 
00069 
00070 static void trymount(const UniConf &cfg, const UniConfKey &key,
00071     WvStringParm location, WvStringParm perms = WvString::null)
00072 {
00073     UniConfGen *gen;
00074     WvString errormsg;
00075     if (perms.isnull())
00076     {
00077         errormsg = WvString("Unable to mount \"%s\" at \"%s\"\n",
00078                 location, key);
00079         gen = cfg[key].mount(location);
00080     }
00081     else
00082     {
00083         errormsg = WvString("Unable to mount \"%s\" at \"%s\","
00084                 "with permissions source \"%s\"\n", 
00085                 location, key, perms);
00086         gen = cfg[key].mountgen(new UniSecureGen(location,
00087                     new UniPermGen(perms)));
00088     }
00089 
00090     if (! gen || ! gen->isok())
00091     {
00092         wverr->print(errormsg);
00093         exit(1);
00094     }
00095 }
00096 
00097 int main(int argc, char **argv)
00098 {
00099     signal(SIGINT,  sighandler_die);
00100     signal(SIGTERM, sighandler_die);
00101     signal(SIGPIPE, SIG_IGN);
00102     wvcrash_setup(argv[0]);
00103 
00104     WvLogConsole logcons(2, WvLog::Info);
00105     
00106     UniConfRoot root;
00107     UniConf cfg(root);
00108 
00109     bool mountattempt = false;
00110     bool needauth = false;
00111     unsigned int port = DEFAULT_UNICONF_DAEMON_TCP_PORT;
00112     unsigned int sslport = DEFAULT_UNICONF_DAEMON_SSL_PORT;
00113 
00114     for (int i = 1; i < argc; i++)
00115     {
00116         if (!strcmp(argv[i],"-mount"))
00117         {
00118             if (argc < i + 3) usage();
00119             WvString mountpoint = argv[i + 1];
00120             WvString mountloc = argv[i + 2];
00121             WvString perms;
00122             if (argc < i + 4 || argv[i + 3][0] == '-')
00123                 i += 2;
00124             else
00125             {
00126                 perms = argv[i + 3];
00127                 i += 3;
00128                 needauth = true;
00129             }
00130             trymount(cfg, mountpoint, mountloc, perms);
00131             mountattempt = true;
00132         }
00133         else if (!strcmp(argv[i], "-p"))
00134         {
00135             if (argc < i + 2) usage();
00136             port = WvString(argv[i + 1]).num();
00137             i += 1;
00138         }
00139         else if (!strcmp(argv[i], "-ssl"))
00140         {
00141             if (argc < i + 2) usage();
00142             sslport = WvString(argv[i + 1]).num();
00143             i += 1;
00144         }
00145         else if (!strcmp(argv[i], "-d"))
00146         {
00147             if (argc < i + 2) usage();
00148             logcons.level(findloglevel(argv[i + 1]));
00149             i += 1;
00150         }
00151         else
00152             usage();
00153     }
00154 
00155     if (!mountattempt)
00156         trymount(cfg, UniConfKey::EMPTY, DEFAULT_CONFIG_FILE);
00157 
00158     globdaemon = new UniConfDaemon(cfg, needauth);
00159     
00160     // FIXME: THIS IS NOT SAFE!
00161     system("mkdir -p /tmp/uniconf");
00162     system("rm -f /tmp/uniconf/uniconfsocket");
00163     if (! globdaemon->setupunixsocket("/tmp/uniconf/uniconfsocket"))
00164         exit(1);
00165     if (port && ! globdaemon->setuptcpsocket(WvIPPortAddr("0.0.0.0", port)))
00166         exit(1);
00167 
00168     if (sslport)
00169     {
00170         WvString dName = encode_hostname_as_DN(fqdomainname());
00171         WvX509Mgr *x509cert = new WvX509Mgr(dName, 1024);
00172         if (!x509cert->isok())
00173         {
00174             WvLog log("uniconfdaemon", WvLog::Error);
00175             log("Couldn't generate X509 certificate: SSL not available\n");
00176         }
00177         else if (sslport && !globdaemon->setupsslsocket(WvIPPortAddr("0.0.0.0", sslport), x509cert))
00178             exit(1);
00179     }
00180     
00181     // since we're a daemon, we should now background ourselves.
00182     pid_t pid = fork();
00183     if (pid <= 0) // child or failed
00184     {
00185         while (globdaemon->isok())
00186         {
00187             if (globdaemon->select(5000))
00188                 globdaemon->callback();
00189             else
00190             {
00191                 // FIXME: do this *exactly* every so x seconds
00192                 cfg.commit();
00193                 cfg.refresh();
00194             }
00195         }
00196         globdaemon->close();
00197         delete globdaemon;
00198     }
00199     else // parent
00200     {
00201         _exit(0);
00202     }
00203     
00204     return 0;
00205 }

Generated on Wed Dec 15 15:08:10 2004 for WvStreams by  doxygen 1.3.9.1