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 }