WvStreams
uniconfd.cc
00001 #include "wvautoconf.h"
00002 #ifdef HAVE_UNISTD_H
00003 # include <unistd.h>
00004 #endif
00005 #ifdef HAVE_GETOPT_H
00006 # include <getopt.h>
00007 #endif
00008 
00009 #ifndef _WIN32
00010 #include <signal.h>
00011 #include <sys/types.h>
00012 #include <sys/stat.h>
00013 #endif
00014 
00015 #ifdef WITH_SLP
00016 #include "wvslp.h"
00017 #endif
00018 
00019 #include "wvlogrcv.h"
00020 #include "uniconfdaemon.h"
00021 #include "uniclientconn.h"
00022 #include "unisecuregen.h"
00023 #include "unipermgen.h"
00024 #include "uniconfroot.h"
00025 #include "wvstrutils.h"
00026 #include "wvfileutils.h"
00027 #include "wvstreamsdaemon.h"
00028 
00029 #ifdef WITH_SLP
00030 #include "slp.h"
00031 #endif
00032 
00033 #include <map>
00034 
00035 using std::map;
00036 using wv::shared_ptr;
00037 
00038 
00039 #ifdef _WIN32
00040 #pragma comment(linker, "/include:?UniRegistryGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A")
00041 #pragma comment(linker, "/include:?UniPStoreGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A")
00042 #pragma comment(linker, "/include:?UniIniGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A")
00043 #endif
00044 
00045 #define DEFAULT_CONFIG_FILE "ini:uniconf.ini"
00046 
00047 
00048 static map<WvString, shared_ptr<IUniConfGen> > namedgens;
00049 
00050 
00051 static IUniConfGen *creator(WvStringParm s, IObject*)
00052 {
00053     map<WvString, shared_ptr<IUniConfGen> >::iterator it = namedgens.find(s);
00054     shared_ptr<IUniConfGen> gen;
00055 
00056     if (it != namedgens.end())
00057         gen = it->second;
00058 
00059     if (gen)
00060         gen->addRef();
00061 
00062     return gen.get();
00063 }
00064 
00065 WvMoniker<IUniConfGen> UniNamedMoniker("named", creator);
00066 
00067 
00068 class UniConfd : public WvStreamsDaemon
00069 {
00070     bool needauth;
00071     WvString permmon;
00072     WvStringList lmonikers;
00073     time_t commit_interval;
00074 
00075     UniConfRoot cfg;
00076     bool first_time;
00077     IUniConfGen *permgen;
00078     
00079     bool namedgen_cb(WvStringParm option, void *)
00080     {
00081         WvString name(option);
00082         WvString moniker;
00083         char* ptr;
00084 
00085         ptr = strchr(name.edit(), '=');
00086 
00087         if (!ptr)
00088             return false;
00089 
00090         *ptr = 0;
00091         moniker = ptr + 1;
00092 
00093         namedgens[name] = shared_ptr<IUniConfGen>(
00094             wvcreate<IUniConfGen>(moniker),
00095             wv::bind(&IUniConfGen::release, _1));
00096 
00097         return true;
00098     }
00099 
00100     void commit_stream_cb(WvStream *s)
00101     {
00102         cfg.commit();
00103         cfg.refresh();
00104         if (permgen)
00105             permgen->refresh();
00106             
00107         s->alarm(commit_interval * 1000);
00108     }
00109     
00110     void startup()
00111     {
00112         if (first_time)
00113         {
00114             WvStringList::Iter i(_extra_args);
00115             for (i.rewind(); i.next(); )
00116             {
00117                 WvString path = *i, moniker;
00118                 char *cptr = strchr(path.edit(), '=');
00119                 if (!cptr)
00120                 {
00121                     moniker = path;
00122                     path = "/";
00123                 }
00124                 else
00125                 {
00126                     *cptr = 0;
00127                     moniker = cptr+1;
00128                 }
00129                 
00130                 log("Mounting '%s' on '%s': ", moniker, path);
00131                 IUniConfGen *gen = cfg[path].mount(moniker, false);
00132                 if (gen && gen->isok())
00133                     log("ok.\n");
00134                 else
00135                     log("FAILED!\n");
00136             }
00137             
00138             cfg.refresh();
00139         }
00140 
00141         permgen = !!permmon ? wvcreate<IUniConfGen>(permmon) : NULL;
00142         
00143         UniConfDaemon *daemon = new UniConfDaemon(cfg, needauth, permgen);
00144         add_die_stream(daemon, true, "uniconfd");
00145         
00146         if (lmonikers.isempty())
00147         {
00148             log(WvLog::Critical, "Can't start: no listeners given!\n");
00149             die(7);
00150             return;
00151         }
00152 
00153         WvStringList::Iter i(lmonikers);
00154         for (i.rewind(); i.next(); )
00155             daemon->listen(*i);
00156 
00157         WvStream *commit_stream = new WvStream;
00158         commit_stream->setcallback(wv::bind(&UniConfd::commit_stream_cb, this,
00159                                             commit_stream));
00160         commit_stream->alarm(commit_interval * 1000);
00161         add_die_stream(commit_stream, true, "commit");
00162         
00163         if (first_time)
00164             first_time = false;
00165     }
00166     
00167 public:
00168 
00169     UniConfd():
00170         WvStreamsDaemon("uniconfd", VERBOSE_WVPACKAGE_VERSION,
00171                         wv::bind(&UniConfd::startup, this)),
00172         needauth(false),
00173         commit_interval(5*60),
00174         first_time(true),
00175         permgen(NULL)
00176     {
00177         args.add_option(0, "pid-file",
00178                 "Specify the .pid file to use (only applies with --daemonize)", "filename",
00179                 pid_file);
00180         args.add_set_bool_option('a', "need-auth",
00181                 "Require authentication on incoming connections", needauth);
00182         args.add_option('A', "check-access",
00183                 "Check all accesses against perms moniker", "moniker",
00184                 permmon);
00185         args.add_option('l', "listen",
00186                 "Listen on the given socket (eg. tcp:4111, ssl:tcp:4112)",
00187                 "lmoniker", lmonikers);
00188         args.add_option('n', "named-gen",
00189                         "creates a \"named\" moniker 'name' from 'moniker'",
00190                         "name=moniker",
00191                         wv::bind(&UniConfd::namedgen_cb, this, _1, _2), NULL);
00192         args.add_optional_arg("MONIKERS", true);
00193         args.set_email("<" WVPACKAGE_BUGREPORT ">");
00194     }
00195     
00196     
00197 };
00198 
00199 int main(int argc, char **argv)
00200 {
00201     UniConfd uniconfd;
00202    
00203     return uniconfd.run(argc, argv);
00204 }