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
35using std::map;
36using 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
48static map<WvString, shared_ptr<IUniConfGen> > namedgens;
49
50
51static 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
65WvMoniker<IUniConfGen> UniNamedMoniker("named", creator);
66
67
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
167public:
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
199int main(int argc, char **argv)
200{
201 UniConfd uniconfd;
202
203 return uniconfd.run(argc, argv);
204}
The basic interface which is included by all other XPLC interfaces and objects.
virtual unsigned int release()=0
Indicate that you are finished using this object.
An abstract data container that backs a UniConf tree.
virtual bool isok()=0
Determines if the generator is usable and working properly.
virtual bool refresh()=0
Refreshes information about a key recursively.
void listen(WvStringParm lmoniker)
Start listening on a socket described by the given WvListener moniker.
Represents the root of a hierarhical registry consisting of pairs of UniConfKeys and associated strin...
void commit() const
Commits information about this key recursively.
Definition uniconf.cc:125
bool refresh() const
Refreshes information about this key recursively.
Definition uniconf.cc:119
IUniConfGen * mount(WvStringParm moniker, bool refresh=true) const
Mounts a generator at this key using a moniker.
Definition uniconf.cc:131
void add_optional_arg(WvStringParm desc, bool multiple=false)
Add an optional argument to the list of parameters.
Definition wvargs.cc:982
void add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, int &val)
Add a switch that takes an integer argument.
Definition wvargs.cc:888
void set_email(WvStringParm email)
Set the e-mail address for bug reports.
Definition wvargs.cc:825
void add_set_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val)
Add a boolean option, which, when specified, sets the specified boolean variable to true.
Definition wvargs.cc:856
WvString pid_file
The path to the pid file to use for the daemon; defaults to /var/run/name.pid, where name is above.
WvString name
The name and version of the daemon; used for -V and logging.
int run(const char *argv0)
Run the daemon with no argument processing. Returns exit status.
Definition wvdaemon.cc:119
void die(int status=0)
Force the daemon to exit as soon as the run callback exits.
WvArgs args
The arguments the daemon accepts; the defaults are described above.
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Unified support for streams, that is, sequences of bytes that may or may not be ready for read/write ...
void alarm(time_t msec_timeout)
set an alarm, ie.
Definition wvstream.cc:1049
void setcallback(IWvStreamCallback _callfunc)
define the callback function for this stream, called whenever the callback() member is run,...
Definition wvstream.cc:1129
WvStreamsDaemon - High-level abstraction for a daemon process that does nothing but add streams to th...
void add_die_stream(IWvStream *istream, bool auto_free, const char *id)
Add a stream to the daemon; if the stream goes !isok() the daemon will exit.
This is a WvList of WvStrings, and is a really handy way to parse strings.
WvString is an implementation of a simple and efficient printable-string class.
char * edit()
make the string editable, and return a non-const (char*)