WvStreams
uniconfd.cc
1 #include "wvautoconf.h"
2 #ifdef HAVE_UNISTD_H
3 # include <unistd.h>
4 #endif
5 #ifdef HAVE_GETOPT_H
6 # include <getopt.h>
7 #endif
8 
9 #ifndef _WIN32
10 #include <signal.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #endif
14 
15 #ifdef WITH_SLP
16 #include "wvslp.h"
17 #endif
18 
19 #include "wvlogrcv.h"
20 #include "uniconfdaemon.h"
21 #include "uniclientconn.h"
22 #include "unisecuregen.h"
23 #include "unipermgen.h"
24 #include "uniconfroot.h"
25 #include "wvstrutils.h"
26 #include "wvfileutils.h"
27 #include "wvstreamsdaemon.h"
28 
29 #ifdef WITH_SLP
30 #include "slp.h"
31 #endif
32 
33 #include <map>
34 
35 using std::map;
36 using wv::shared_ptr;
37 
38 
39 #ifdef _WIN32
40 #pragma comment(linker, "/include:?UniRegistryGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A")
41 #pragma comment(linker, "/include:?UniPStoreGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A")
42 #pragma comment(linker, "/include:?UniIniGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A")
43 #endif
44 
45 #define DEFAULT_CONFIG_FILE "ini:uniconf.ini"
46 
47 
48 static map<WvString, shared_ptr<IUniConfGen> > namedgens;
49 
50 
51 static IUniConfGen *creator(WvStringParm s, IObject*)
52 {
53  map<WvString, shared_ptr<IUniConfGen> >::iterator it = namedgens.find(s);
54  shared_ptr<IUniConfGen> gen;
55 
56  if (it != namedgens.end())
57  gen = it->second;
58 
59  if (gen)
60  gen->addRef();
61 
62  return gen.get();
63 }
64 
65 WvMoniker<IUniConfGen> UniNamedMoniker("named", creator);
66 
67 
68 class UniConfd : public WvStreamsDaemon
69 {
70  bool needauth;
71  WvString permmon;
72  WvStringList lmonikers;
73  time_t commit_interval;
74 
75  UniConfRoot cfg;
76  bool first_time;
77  IUniConfGen *permgen;
78 
79  bool namedgen_cb(WvStringParm option, void *)
80  {
81  WvString name(option);
82  WvString moniker;
83  char* ptr;
84 
85  ptr = strchr(name.edit(), '=');
86 
87  if (!ptr)
88  return false;
89 
90  *ptr = 0;
91  moniker = ptr + 1;
92 
93  namedgens[name] = shared_ptr<IUniConfGen>(
94  wvcreate<IUniConfGen>(moniker),
95  wv::bind(&IUniConfGen::release, _1));
96 
97  return true;
98  }
99 
100  void commit_stream_cb(WvStream *s)
101  {
102  cfg.commit();
103  cfg.refresh();
104  if (permgen)
105  permgen->refresh();
106 
107  s->alarm(commit_interval * 1000);
108  }
109 
110  void startup()
111  {
112  if (first_time)
113  {
114  WvStringList::Iter i(_extra_args);
115  for (i.rewind(); i.next(); )
116  {
117  WvString path = *i, moniker;
118  char *cptr = strchr(path.edit(), '=');
119  if (!cptr)
120  {
121  moniker = path;
122  path = "/";
123  }
124  else
125  {
126  *cptr = 0;
127  moniker = cptr+1;
128  }
129 
130  log("Mounting '%s' on '%s': ", moniker, path);
131  IUniConfGen *gen = cfg[path].mount(moniker, false);
132  if (gen && gen->isok())
133  log("ok.\n");
134  else
135  log("FAILED!\n");
136  }
137 
138  cfg.refresh();
139  }
140 
141  permgen = !!permmon ? wvcreate<IUniConfGen>(permmon) : NULL;
142 
143  UniConfDaemon *daemon = new UniConfDaemon(cfg, needauth, permgen);
144  add_die_stream(daemon, true, "uniconfd");
145 
146  if (lmonikers.isempty())
147  {
148  log(WvLog::Critical, "Can't start: no listeners given!\n");
149  die(7);
150  return;
151  }
152 
153  WvStringList::Iter i(lmonikers);
154  for (i.rewind(); i.next(); )
155  daemon->listen(*i);
156 
157  WvStream *commit_stream = new WvStream;
158  commit_stream->setcallback(wv::bind(&UniConfd::commit_stream_cb, this,
159  commit_stream));
160  commit_stream->alarm(commit_interval * 1000);
161  add_die_stream(commit_stream, true, "commit");
162 
163  if (first_time)
164  first_time = false;
165  }
166 
167 public:
168 
169  UniConfd():
170  WvStreamsDaemon("uniconfd", VERBOSE_WVPACKAGE_VERSION,
171  wv::bind(&UniConfd::startup, this)),
172  needauth(false),
173  commit_interval(5*60),
174  first_time(true),
175  permgen(NULL)
176  {
177  args.add_option(0, "pid-file",
178  "Specify the .pid file to use (only applies with --daemonize)", "filename",
179  pid_file);
180  args.add_set_bool_option('a', "need-auth",
181  "Require authentication on incoming connections", needauth);
182  args.add_option('A', "check-access",
183  "Check all accesses against perms moniker", "moniker",
184  permmon);
185  args.add_option('l', "listen",
186  "Listen on the given socket (eg. tcp:4111, ssl:tcp:4112)",
187  "lmoniker", lmonikers);
188  args.add_option('n', "named-gen",
189  "creates a \"named\" moniker 'name' from 'moniker'",
190  "name=moniker",
191  wv::bind(&UniConfd::namedgen_cb, this, _1, _2), NULL);
192  args.add_optional_arg("MONIKERS", true);
193  args.set_email("<" WVPACKAGE_BUGREPORT ">");
194  }
195 
196 
197 };
198 
199 int main(int argc, char **argv)
200 {
201  UniConfd uniconfd;
202 
203  return uniconfd.run(argc, argv);
204 }