00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #ifndef CONF_DIRECTIVES_H
00028 #define CONF_DIRECTIVES_H
00029
00030
00031
00032 #if HAVE_NETINET_IN_H
00033 # include <netinet/in.h>
00034 #endif
00035
00036 #include <map>
00037 #include <string>
00038 #include <vector>
00039
00040 #include <misc/ratio.h>
00041 #include <misc/string.h>
00042 #include <conf/parser.h>
00043
00044
00045
00047
00048 namespace conf
00049 {
00050
00051
00052
00053 class Conf;
00054
00055
00056
00058
00072 class ConfDir
00073 {
00074 public:
00076
00088 explicit ConfDir(std::string const &name, bool reloadable,
00089 unsigned short min = 0, unsigned short max = 0) : m_name(name),
00090 m_reloadable(reloadable), m_ready(false), m_minparams(min),
00091 m_maxparams(max) { }
00093 ConfDir(ConfDir const &cd) : m_name(cd.m_name),
00094 m_reloadable(cd.m_reloadable), m_ready(cd.m_ready),
00095 m_minparams(cd.m_minparams), m_maxparams(cd.m_maxparams) { }
00097 virtual ~ConfDir() { }
00099 virtual ConfDir &operator=(ConfDir const &cd);
00100
00102
00120 virtual bool begin(Conf &conf) { return (m_ready = true); }
00122
00141 virtual bool set(Conf &conf, unsigned short count,
00142 std::string const params[]);
00144
00162 virtual bool end(Conf &conf) { m_ready = false; return true; }
00163
00165 std::string const &name() const { return m_name; }
00167 bool reloadable() const { return m_reloadable; }
00169 bool ready() const { return m_ready; }
00170
00172
00186 virtual char const *label(size_t index) const { return 0; }
00188
00196 virtual size_t label_count() const { return 0; }
00198
00207 virtual Conf const *sub() const { return 0; }
00208 protected:
00210 std::string m_name;
00212 bool m_reloadable;
00213
00215 bool m_ready;
00216
00218 unsigned short m_minparams;
00220 unsigned short m_maxparams;
00221 };
00222
00223
00224
00225
00226
00228
00243 template <class T>
00244 class ConfValue : public ConfDir
00245 {
00246 public:
00248 typedef T value_type;
00249
00251 explicit ConfValue(std::string const &name, bool reloadable,
00252 unsigned short min_params = 1, unsigned short max_params = 1) :
00253 ConfDir(name, reloadable, min_params, max_params), m_value(),
00254 m_value_set(false), m_value_changed(false), m_defvalue(),
00255 m_has_default(false), m_oldvalue(), m_label() { }
00257 ConfValue(std::string const &name, T const &defval, bool reloadable,
00258 unsigned short min_params = 1, unsigned short max_params = 1) :
00259 ConfDir(name, reloadable, min_params, max_params), m_value(),
00260 m_value_set(false), m_value_changed(false), m_defvalue(defval),
00261 m_has_default(true), m_oldvalue(), m_label() { }
00263 ConfValue(ConfValue const &cd) : ConfDir(cd), m_value(cd.m_value),
00264 m_value_set(cd.m_value_set),
00265 m_value_changed(cd.m_value_changed), m_defvalue(cd.m_defvalue),
00266 m_has_default(cd.m_has_default), m_oldvalue(cd.m_oldvalue),
00267 m_label(cd.m_label) { }
00269 virtual ConfValue<T> &operator=(ConfValue<T> const &right);
00270
00272
00274 virtual bool begin(Conf &conf);
00276
00277 virtual bool set(Conf &conf, unsigned short count,
00278 std::string const params[]);
00280
00285 virtual bool end(Conf &conf);
00286
00288
00293 T const &value() const { return m_value; }
00295 bool has_value_changed() const { return m_value_changed; }
00296
00298 bool has_default() const { return m_has_default; }
00299
00301
00305 T const &old_value() const { return m_oldvalue; }
00306
00308 virtual char const *label(size_t index) const
00309 { return m_label.c_str(); }
00311 virtual size_t label_count() const { return 1; }
00312 protected:
00314 T m_value;
00316 bool m_value_set;
00318 bool m_value_changed;
00319
00321 T m_defvalue;
00323 bool m_has_default;
00324
00326 T m_oldvalue;
00327
00329 mutable std::string m_label;
00330
00332
00346 virtual bool assign(Conf &conf, unsigned short count,
00347 std::string const params[]) = 0;
00349
00357 virtual bool check(Conf &conf, T const &value) { return true; }
00358
00360
00367 virtual bool apply(Conf &conf) { return true; }
00368
00370
00377 virtual bool apply_change(Conf &conf) { return true; }
00378 };
00379
00380
00381
00383
00390 class ConfBool : public ConfValue<bool>
00391 {
00392 public:
00394 explicit ConfBool(std::string const &name, bool reloadable) :
00395 ConfValue<bool>(name, reloadable) { }
00397 ConfBool(std::string const &name, bool const &defval,
00398 bool reloadable) :
00399 ConfValue<bool>(name, defval, reloadable) { }
00401 operator bool() const { return m_value; }
00402
00404 virtual char const *label(size_t index) const
00405 { return (m_value ? "yes" : "no"); }
00406 protected:
00407 virtual bool assign(Conf &conf, unsigned short count,
00408 std::string const params[]);
00409 };
00410
00411
00412
00414
00424 class ConfDuration : public ConfValue<time_t>
00425 {
00426 public:
00428
00436 explicit ConfDuration(std::string const &name, bool reloadable,
00437 time_t mindur, time_t maxdur) :
00438 ConfValue<time_t>(name, reloadable), m_mindur(mindur),
00439 m_maxdur(maxdur) { }
00441
00450 ConfDuration(std::string const &name, time_t defval,
00451 bool reloadable, time_t mindur,
00452 time_t maxdur) :
00453 ConfValue<time_t>(name, defval, reloadable), m_mindur(mindur),
00454 m_maxdur(maxdur) { }
00456 ConfDuration(std::string const &name, bool reloadable) :
00457 ConfValue<time_t>(name, reloadable), m_mindur(0),
00458 m_maxdur(2147483647) { }
00460 ConfDuration(ConfDuration const &cd) : ConfValue<time_t>(cd),
00461 m_mindur(cd.m_mindur), m_maxdur(cd.m_maxdur) { }
00463 virtual ConfDuration &operator=(ConfDuration const &right);
00465 operator time_t() const { return m_value; }
00466
00468 virtual char const *label(size_t index) const;
00469 protected:
00471 time_t m_mindur;
00473 time_t m_maxdur;
00474
00475 virtual bool assign(Conf &conf, unsigned short count,
00476 std::string const params[]);
00477
00479 virtual bool check(Conf &conf, time_t value) const;
00480 };
00481
00482
00483
00485
00497 template <class T = u_int32_t>
00498 class ConfEnum : public ConfValue<T>
00499 {
00500 public:
00501 typedef std::map<std::string, T, misc::insensitive_less> ValueList;
00502
00504 explicit ConfEnum(std::string const &name, bool reloadable) :
00505 ConfValue<T>(name, reloadable), m_values() { }
00507 ConfEnum(std::string const &name, T const &defval, bool reloadable) :
00508 ConfValue<T>(name, defval, reloadable), m_values() { }
00510 ConfEnum(ConfEnum const &cd) : ConfValue<T>(cd),
00511 m_values(cd.m_values) { }
00513 virtual ConfEnum<T> &operator=(ConfEnum<T> const &right);
00515 operator T const &() const { return ConfValue<T>::m_value; }
00516
00518 virtual char const *label(size_t index) const;
00519 protected:
00521 ValueList m_values;
00522
00524
00531 virtual bool add(Conf &conf) = 0;
00532
00534 virtual bool assign(Conf &conf, unsigned short count,
00535 std::string const params[]);
00536 };
00537
00538
00539
00541
00542 inline bool operator==(struct in_addr const &in1, struct in_addr const &in2)
00543 {
00544 return (in1.s_addr == in2.s_addr);
00545 }
00546
00548
00559 class ConfHostname : public ConfValue<struct in_addr>
00560 {
00561 public:
00563 explicit ConfHostname(std::string const &name,
00564 bool reloadable) :
00565 ConfValue<struct in_addr>(name, reloadable) { }
00567 ConfHostname(std::string const &name, struct in_addr const &defval,
00568 bool reloadable) :
00569 ConfValue<struct in_addr>(name, defval, reloadable) { }
00571 operator struct in_addr const &() const { return m_value; }
00572
00574 virtual char const *label(size_t index) const;
00575 protected:
00576 virtual bool assign(Conf &conf, unsigned short count,
00577 std::string const params[]);
00578 };
00579
00580
00581
00583
00595 template <class T>
00596 class ConfInt : public ConfValue<T>
00597 {
00598 public:
00600
00608 explicit ConfInt(std::string const &name, bool reloadable,
00609 T minvalue, T maxvalue) :
00610 ConfValue<T>(name, reloadable), m_minvalue(minvalue),
00611 m_maxvalue(maxvalue) { }
00613
00622 ConfInt(std::string const &name, T const &defval, bool reloadable,
00623 T minvalue, T maxvalue) :
00624 ConfValue<T>(name, defval, reloadable), m_minvalue(minvalue),
00625 m_maxvalue(maxvalue) { }
00627 ConfInt(std::string const &name, bool reloadable) :
00628 ConfValue<T>(name, reloadable), m_minvalue(LONG_MIN),
00629 m_maxvalue(LONG_MAX) { }
00631 ConfInt(ConfInt const &cd) : ConfValue<T>(cd),
00632 m_minvalue(cd.m_minvalue), m_maxvalue(cd.m_maxvalue) { }
00634 virtual ConfInt<T> &operator=(ConfInt<T> const &right);
00636 operator T() const { return ConfValue<T>::m_value; }
00637
00639 virtual char const *label(size_t index) const;
00640 protected:
00641 T m_minvalue;
00642 T m_maxvalue;
00643
00644 virtual bool assign(Conf &conf, unsigned short count,
00645 std::string const params[]);
00646
00648 virtual bool check(Conf &conf, T const &value) const;
00649
00651
00659 virtual bool convert(Conf &conf, std::string const &expr,
00660 T &result) const;
00661
00663
00667 virtual T my_strtol(char const *nptr, char **endptr, int base) const
00668 { return strtol(nptr, endptr, base); }
00669 };
00670
00671
00672
00674
00680 template <class T>
00681 class ConfIntNZ : public ConfInt<T>
00682 {
00683 public:
00685 explicit ConfIntNZ(std::string const &name, bool reloadable,
00686 T minvalue, T maxvalue) :
00687 ConfInt<T>(name, reloadable, minvalue, maxvalue) { }
00689 ConfIntNZ(std::string const &name, T const &defval, bool reloadable,
00690 T minvalue, T maxvalue) :
00691 ConfInt<T>(name, defval, reloadable, minvalue, maxvalue) { }
00693 ConfIntNZ(std::string const &name, bool reloadable) :
00694 ConfInt<T>(name, reloadable) { }
00695 protected:
00697 virtual bool check(Conf &conf, T const &value) const;
00698 };
00699
00700
00701
00703
00704 class ConfPort : public ConfInt<uint16_t>
00705 {
00706 public:
00708 explicit ConfPort(std::string const &name, bool reloadable) :
00709 ConfInt<uint16_t>(name, reloadable, 0, 65535) { }
00711 ConfPort(std::string const &name, uint16_t const &defval,
00712 bool reloadable) : ConfInt<uint16_t>(name, defval,
00713 reloadable, 0, 65535) { }
00714 };
00715
00716
00717
00719
00725 class ConfRatio : public ConfValue<misc::Ratio>
00726 {
00727 public:
00729
00739 explicit ConfRatio(std::string const &name, bool reloadable,
00740 int32_t minx, int32_t maxx, int32_t miny, int32_t maxy) :
00741 ConfValue<misc::Ratio>(name, reloadable), m_minx(minx),
00742 m_maxx(maxx), m_miny(miny), m_maxy(maxy) { }
00744
00755 ConfRatio(std::string const &name, misc::Ratio const &defval,
00756 bool reloadable, int32_t minx, int32_t maxx, int32_t miny,
00757 int32_t maxy) : ConfValue<misc::Ratio>(name, defval, reloadable),
00758 m_minx(minx), m_maxx(maxx), m_miny(miny), m_maxy(maxy) { }
00760 ConfRatio(std::string const &name, bool reloadable) :
00761 ConfValue<misc::Ratio>(name, reloadable), m_minx(-2147483647),
00762 m_maxx(2147483647), m_miny(-2147483647), m_maxy(2147483647) { }
00764 ConfRatio(ConfRatio const &cd) : ConfValue<misc::Ratio>(cd),
00765 m_minx(cd.m_minx), m_maxx(cd.m_maxx),
00766 m_miny(cd.m_miny), m_maxy(cd.m_maxy) { }
00768 virtual ConfRatio &operator=(ConfRatio const &right);
00769
00771 virtual char const *label(size_t index) const;
00772 protected:
00774 time_t m_minx;
00776 time_t m_maxx;
00778 time_t m_miny;
00780 time_t m_maxy;
00781
00782 virtual bool assign(Conf &conf, unsigned short count,
00783 std::string const params[]);
00784
00786 virtual bool check(Conf &conf, misc::Ratio value) const;
00787 };
00788
00789
00790
00792
00811 template <class T = u_int32_t>
00812 class ConfSet : public ConfValue<T>
00813 {
00814 public:
00815 typedef std::map<std::string, T, misc::insensitive_less> BitList;
00816
00818 explicit ConfSet(std::string const &name, bool reloadable) :
00819 ConfValue<T>(name, reloadable), m_bits() { }
00821 ConfSet(std::string const &name, T const &defval, bool reloadable) :
00822 ConfValue<T>(name, defval, reloadable), m_bits() { }
00824 ConfSet(ConfSet const &cd) : ConfValue<T>(cd), m_bits(cd.m_bits) { }
00826 virtual ConfSet<T> &operator=(ConfSet<T> const &right);
00828 operator T const &() const { return ConfValue<T>::m_value; }
00829
00831 virtual char const *label(size_t index) const;
00832 protected:
00834 BitList m_bits;
00835
00837
00844 virtual bool add(Conf &conf) = 0;
00845
00846 virtual bool assign(Conf &conf, unsigned short count,
00847 std::string const params[]);
00848 };
00849
00850
00851
00853
00857 class ConfStr : public ConfValue<std::string>
00858 {
00859 public:
00861
00873 explicit ConfStr(std::string const &name, bool reloadable,
00874 std::string::size_type minlen,
00875 std::string::size_type maxlen, std::string const &validchars) :
00876 ConfValue<std::string>(name, reloadable), m_minlen(minlen),
00877 m_maxlen(maxlen), m_validchars(validchars) { }
00879
00892 ConfStr(std::string const &name, std::string const &defval,
00893 bool reloadable, std::string::size_type minlen,
00894 std::string::size_type maxlen, std::string const &validchars) :
00895 ConfValue<std::string>(name, defval, reloadable),
00896 m_minlen(minlen), m_maxlen(maxlen), m_validchars(validchars)
00897 { }
00899 ConfStr(std::string const &name, bool reloadable) :
00900 ConfValue<std::string>(name, reloadable), m_minlen(0),
00901 m_maxlen(2147483647), m_validchars("") { }
00903 ConfStr(ConfStr const &cd) : ConfValue<std::string>(cd),
00904 m_minlen(cd.m_minlen), m_maxlen(cd.m_maxlen),
00905 m_validchars(cd.m_validchars) { }
00907 virtual ConfStr &operator=(ConfStr const &right);
00909 bool operator==(ConfStr const &right) const
00910 { return (m_value == right.m_value); }
00912 bool operator==(std::string const &right) const
00913 { return (m_value == right); }
00915 bool operator!=(ConfStr const &right) const
00916 { return (m_value != right.m_value); }
00918 bool operator!=(std::string const &right) const
00919 { return (m_value != right); }
00921 bool operator<(ConfStr const &right) const
00922 { return (m_value < right.m_value); }
00924 bool operator<(std::string const &right) const
00925 { return (m_value < right); }
00927 bool operator<=(ConfStr const &right) const
00928 { return (m_value <= right.m_value); }
00930 bool operator<=(std::string const &right) const
00931 { return (m_value <= right); }
00933 bool operator>(ConfStr const &right) const
00934 { return (m_value > right.m_value); }
00936 bool operator>(std::string const &right) const
00937 { return (m_value > right); }
00939 bool operator>=(ConfStr const &right) const
00940 { return (m_value >= right.m_value); }
00942 bool operator>=(std::string const &right) const
00943 { return (m_value >= right); }
00944
00946 virtual char const *label(size_t index) const
00947 { return m_value.c_str(); }
00948 protected:
00949 std::string::size_type m_minlen;
00950 std::string::size_type m_maxlen;
00951 std::string m_validchars;
00952
00953 virtual bool assign(Conf &conf, unsigned short count,
00954 std::string const params[]);
00955
00957 virtual bool check(Conf &conf, std::string const &value) const;
00958 };
00959
00960
00961
00963
00964 class ConfStrChar : public ConfStr
00965 {
00966 public:
00968 explicit ConfStrChar(std::string const &name, bool reloadable,
00969 std::string::size_type minlen, std::string::size_type maxlen,
00970 std::string const &validchars) :
00971 ConfStr(name, reloadable, minlen, maxlen, validchars) { }
00973 ConfStrChar(std::string const &name, std::string const &defval,
00974 bool reloadable, std::string::size_type minlen,
00975 std::string::size_type maxlen, std::string const &validchars) :
00976 ConfStr(name, defval, reloadable, minlen, maxlen,
00977 validchars) { }
00979 ConfStrChar(std::string const &name, bool reloadable) :
00980 ConfStr(name, reloadable) { }
00982 operator char const *() const
00983 { return (m_value.size() ? m_value.c_str() : 0); }
00984 };
00985
00986
00987
00989
00990 class ConfString : public ConfStr
00991 {
00992 public:
00994 explicit ConfString(std::string const &name, bool reloadable,
00995 std::string::size_type minlen, std::string::size_type maxlen,
00996 std::string const &validchars) :
00997 ConfStr(name, reloadable, minlen, maxlen, validchars) { }
00999 ConfString(std::string const &name, std::string const &defval,
01000 bool reloadable, std::string::size_type minlen,
01001 std::string::size_type maxlen, std::string const &validchars) :
01002 ConfStr(name, defval, reloadable, minlen, maxlen,
01003 validchars) { }
01005 ConfString(std::string const &name, bool reloadable) :
01006 ConfStr(name, reloadable) { }
01008 char operator[](std::string::size_type idx) const
01009 { return m_value[idx]; }
01011 operator std::string() const { return m_value; }
01012 };
01013
01014
01015
01017
01025 template <class T>
01026 class ConfUint : public ConfInt<T>
01027 {
01028 public:
01030
01038 explicit ConfUint(std::string const &name, bool reloadable,
01039 T minvalue, T maxvalue) :
01040 ConfInt<T>(name, reloadable, minvalue, maxvalue) { }
01042
01051 ConfUint(std::string const &name, T const &defval, bool reloadable,
01052 T minvalue, T maxvalue) :
01053 ConfInt<T>(name, defval, reloadable, minvalue, maxvalue) { }
01055 ConfUint(std::string const &name, bool reloadable) :
01056 ConfInt<T>(name, reloadable) { }
01057
01059 virtual char const *label(size_t index) const;
01060 protected:
01062 virtual bool check(Conf &conf, T const &value) const;
01063
01065 virtual bool convert(Conf &conf, std::string const &expr,
01066 T &result) const;
01068 virtual T my_strtol(char const *nptr, char **endptr, int base) const
01069 { return strtoul(nptr, endptr, base); }
01070 };
01071
01072
01073
01075
01102 template <class ValueT, class ContainerT = std::vector<ValueT> >
01103 class ConfArray : public ConfValue <ContainerT>
01104 {
01105 public:
01106 typedef ValueT value_type;
01107 typedef ContainerT container_type;
01108
01110
01117 explicit ConfArray(std::string const &name, bool reloadable = true,
01118 typename ContainerT::size_type max = INT_MAX) :
01119 ConfValue <ContainerT>(name, reloadable), m_max_values(max) { }
01121
01129 ConfArray(std::string const &name, ContainerT const &defval,
01130 bool reloadable = true,
01131 typename ContainerT::size_type max = INT_MAX) :
01132 ConfValue <ContainerT>(name, defval, reloadable),
01133 m_max_values(max) { }
01135 ConfArray(ConfArray const &cd) : ConfValue<ContainerT>(cd),
01136 m_max_values(cd.m_max_values) { }
01138 virtual ConfArray<ValueT, ContainerT>
01139 &operator=(ConfArray<ValueT, ContainerT> const &right);
01141 operator ContainerT const &() const { return ConfValue <ContainerT>::m_value; }
01143 ContainerT const &operator*() const { return ConfValue <ContainerT>::m_value; }
01145 ContainerT const *operator->() const { return &(this->ConfValue<ContainerT>::m_value); }
01146
01148 virtual char const *label(size_t index) const;
01150 virtual size_t label_count() const
01151 { return ConfValue <ContainerT>::m_value.size(); }
01152 protected:
01153 typename ContainerT::size_type m_max_values;
01154
01155 virtual bool assign(Conf &conf, unsigned short count,
01156 std::string const params[]);
01157
01159
01166 virtual typename ContainerT::iterator insert();
01167 };
01168
01169
01170
01171 typedef ConfArray<ConfBool> ConfBoolA;
01172 typedef ConfArray<ConfDuration> ConfDurationA;
01173 typedef ConfArray<ConfHostname> ConfHostnameA;
01174 typedef ConfArray<ConfPort> ConfPortA;
01175 typedef ConfArray<ConfStr> ConfStrA;
01176 typedef ConfArray<ConfStrChar> ConfStrCharA;
01177 typedef ConfArray<ConfString> ConfStringA;
01178
01179
01180
01181
01182
01184
01196 class ConfBlock : public ConfDir
01197 {
01198 public:
01200 explicit ConfBlock(std::string const &name, bool reloadable = true) :
01201 ConfDir(name, reloadable, 1, 1), m_conf(0) { }
01203 ConfBlock(ConfBlock const &cd);
01205 virtual ~ConfBlock();
01207 virtual ConfBlock &operator=(ConfBlock const &right);
01209
01213 virtual bool operator==(ConfBlock const &) const { return false; }
01214
01216
01220 virtual bool begin(Conf &conf);
01222
01223 virtual bool set(Conf &conf, unsigned short count,
01224 std::string const params[]);
01226
01227 virtual bool end(Conf &conf);
01228
01230 virtual Conf const *sub() const { return m_conf; }
01231 protected:
01233 Conf *m_conf;
01234
01236
01246 virtual bool add(Conf &conf, Conf &new_conf) = 0;
01247
01249
01254 virtual bool apply_changes(Conf &conf) { return true; }
01255 };
01256
01257
01258
01260
01284 class ConfBoolBlock : public ConfBlock
01285 {
01286 public:
01288 explicit ConfBoolBlock(std::string const &name,
01289 bool reloadable = true) : ConfBlock(name, reloadable),
01290 m_set(false) { }
01292 ConfBoolBlock(ConfBoolBlock const &cd) : ConfBlock(cd),
01293 m_set(cd.m_set) { }
01295 virtual ConfBoolBlock &operator=(ConfBoolBlock const &right);
01297 operator bool() const { return m_set; }
01298
01300 virtual bool begin(Conf &) { m_set = false; return true; }
01302 virtual bool set(Conf &conf, unsigned short count,
01303 std::string const params[]);
01304
01306 virtual char const *label(size_t index) const
01307 { return (m_set ? "yes" : "no"); }
01309 virtual size_t label_count() const { return 1; }
01310 protected:
01311 bool m_set;
01312 };
01313
01314
01315
01316 typedef ConfArray<ConfBlock> ConfBlockA;
01317 typedef ConfArray<ConfBoolBlock> ConfBoolBlockA;
01318
01319
01320
01321
01322
01324
01328 class ConfHostPort : public ConfBlock
01329 {
01330 public:
01331
01333 ConfHostname hostname;
01335 ConfPort port;
01336
01337
01339 explicit ConfHostPort(std::string const &name,
01340 bool reloadable = true) : ConfBlock(name, reloadable),
01341 hostname("hostname", reloadable), port("port", reloadable) { }
01343 ConfHostPort(std::string const &name, struct in_addr const &defhost,
01344 uint16_t defport, bool reloadable = true) :
01345 ConfBlock(name, reloadable),
01346 hostname("hostname", defhost, reloadable),
01347 port("port", defport, reloadable) { }
01349 ConfHostPort(std::string const &name, uint16_t defport,
01350 bool reloadable = true) : ConfBlock(name, reloadable),
01351 hostname("hostname", reloadable),
01352 port("port", defport, reloadable) { }
01354 ConfHostPort(ConfHostPort const &cd) : ConfBlock(cd),
01355 hostname(cd.hostname), port(cd.port) { }
01357 virtual ConfHostPort &operator=(ConfHostPort const &right);
01358 protected:
01359 virtual bool add(Conf &conf, Conf &new_conf);
01360 };
01361
01362
01363
01365
01366
01367
01368
01369
01370 class ConfRules : public ConfBlock
01371 {
01372 public:
01373
01374
01376
01378 class Rule
01379 {
01380 public:
01382
01385 Rule(int type, std::string const &value) : m_type(type),
01386 m_value(value) { }
01388 Rule(Rule const &r) : m_type(r.m_type),
01389 m_value(r.m_value) { }
01391 Rule &operator=(Rule const &right);
01392
01394 int type() const { return m_type; }
01396 std::string const &value() const { return m_value; }
01397 protected:
01399 int m_type;
01401 std::string m_value;
01402 };
01403
01404
01405 typedef std::vector<Rule> container_type;
01406
01407
01408
01410
01414 class ConfRule : public ConfDir
01415 {
01416 public:
01418
01427 ConfRule(std::string const &name, bool reloadable,
01428 ConfRules::container_type &container, int type) :
01429 ConfDir(name, reloadable, 1, 1),
01430 m_container(&container), m_type(type) { }
01432 ConfRule(ConfRule const &cd) : ConfDir(cd),
01433 m_container(cd.m_container), m_type(cd.m_type) { }
01435 virtual ConfRule &operator=(ConfRule const &right);
01436
01438 virtual bool set(Conf &conf, unsigned short count,
01439 std::string const params[]);
01440
01442 ConfRules::container_type *container() const
01443 { return m_container; }
01445 ConfRules::container_type *
01446 container(ConfRules::container_type &c)
01447 { return (m_container = &c); }
01448 protected:
01450
01458 virtual bool check(std::string const &value) const
01459 { return true; }
01460 protected:
01462 ConfRules::container_type *m_container;
01464 int m_type;
01465 };
01466
01467
01468
01470 ConfRules(std::string const &name, bool reloadable) :
01471 ConfBlock(name, reloadable), m_rules() { }
01473 ConfRules(ConfRules const &cd) : ConfBlock(cd), m_rules(cd.m_rules) { }
01475 virtual ConfRules &operator=(ConfRules const &right);
01476
01478 virtual bool begin(Conf &conf);
01479
01481 container_type const &rules() const { return m_rules; }
01482 protected:
01484 container_type m_rules;
01485 };
01486
01487
01488
01489
01490
01492
01496 class ConfWarning : public ConfDir
01497 {
01498 public:
01500 explicit ConfWarning(std::string const &name,
01501 std::string const &msg) : ConfDir(name, true, 0, 65535),
01502 m_msg(msg) { }
01504 ConfWarning(ConfWarning const &cd) : ConfDir(cd),
01505 m_msg(cd.m_msg) { }
01507 virtual ConfWarning &operator=(ConfWarning const &right);
01508
01510 virtual bool set(Conf &conf, unsigned short count,
01511 std::string const params[]);
01512
01514 std::string const &msg() const { return m_msg; }
01515 protected:
01516 std::string m_msg;
01517 };
01518
01519
01520
01522
01526 class ConfError : public ConfWarning
01527 {
01528 public:
01530 explicit ConfError(std::string const &name, std::string const &msg) :
01531 ConfWarning(name, msg) { }
01532
01534 virtual bool set(Conf &conf, unsigned short count,
01535 std::string const params[]);
01536 };
01537
01538
01539
01540
01541
01543
01550 class ConfElse : public ConfDir
01551 {
01552 public:
01554 explicit ConfElse(std::string const &name) : ConfDir(name, true, 1, 1),
01555 m_process(false) { }
01557 ConfElse(ConfElse const &cd) : ConfDir(cd), m_process(cd.m_process) { }
01559 virtual ConfElse &operator=(ConfElse const &cd);
01560
01562
01566 bool can_process() const { return m_process; }
01568
01574 bool can_process(bool process) { return (m_process = process); }
01575
01577 virtual bool set(Conf &conf, unsigned short count, std::string const
01578 params[]);
01579 private:
01580 bool m_process;
01581 };
01582
01583
01584
01586
01593 class ConfIf : public ConfDir
01594 {
01595 public:
01597 explicit ConfIf(std::string const &name, unsigned short min = 2,
01598 unsigned short max = 2) : ConfDir(name, true, min, max) { }
01599
01601 virtual bool set(Conf &conf, unsigned short count,
01602 std::string const params[]);
01603
01604 protected:
01606
01612 virtual bool can_process(Conf &conf, std::string const &expr) const = 0;
01613 };
01614
01615
01616
01618
01621 class ConfIfnset : public ConfIf
01622 {
01623 public:
01625 explicit ConfIfnset(std::string const &name) : ConfIf(name) { }
01626
01627 protected:
01629 virtual bool can_process(Conf &conf, std::string const &expr) const;
01630 };
01631
01632
01633
01635
01638 class ConfIfset : public ConfIf
01639 {
01640 public:
01642 explicit ConfIfset(std::string const &name) : ConfIf(name) { }
01643
01644 protected:
01646 virtual bool can_process(Conf &conf, std::string const &expr) const;
01647 };
01648
01649
01650
01652
01655 class ConfInclude : public ConfDir
01656 {
01657 public:
01659 explicit ConfInclude(std::string const &name) :
01660 ConfDir(name, true, 1, 1) { }
01661
01663 virtual bool set(Conf &conf, unsigned short count,
01664 std::string const params[]);
01665 };
01666
01667
01668
01670
01673 class ConfPath : public ConfDir
01674 {
01675 public:
01677 explicit ConfPath(std::string const &name) :
01678 ConfDir(name, true, 1, 1) { }
01679
01681 virtual bool set(Conf &conf, unsigned short count,
01682 std::string const params[]);
01683 };
01684
01685
01686
01688
01691 class ConfVarSet : public ConfDir
01692 {
01693 public:
01695 explicit ConfVarSet(std::string const &name) :
01696 ConfDir(name, true, 1, 2) { }
01697
01699 virtual bool set(Conf &conf, unsigned short count,
01700 std::string const params[]);
01701 };
01702
01703
01704
01706
01709 class ConfUnset : public ConfDir
01710 {
01711 public:
01713 explicit ConfUnset(std::string const &name) :
01714 ConfDir(name, true, 1, 1) { }
01715
01717 virtual bool set(Conf &conf, unsigned short count,
01718 std::string const params[]);
01719 };
01720
01721
01722
01723
01724 template <class T>
01725 ConfValue<T> &ConfValue<T>::operator=(ConfValue<T> const &right)
01726 {
01727 if (&right != this)
01728 {
01729 ConfDir::operator=(right);
01730
01731 m_value = right.m_value;
01732 m_value_set = right.m_value_set;
01733 m_value_changed = right.m_value_changed;
01734
01735 m_has_default = right.m_has_default;
01736 m_defvalue = right.m_defvalue;
01737
01738 m_oldvalue = right.m_oldvalue;
01739
01740 m_label = right.m_label;
01741 }
01742
01743 return *this;
01744 }
01745
01746
01747
01748 template <class T>
01749 bool ConfValue<T>::begin(Conf &conf)
01750 {
01751 if (m_ready)
01752 return true;
01753
01754
01755
01756 if (conf.reloading())
01757 {
01758 m_oldvalue = m_value;
01759 m_label = "";
01760 }
01761
01762 return ConfDir::begin(conf);
01763 }
01764
01765
01766
01767 template <class T>
01768 bool ConfValue<T>::end(Conf &conf)
01769 {
01770 if (!m_ready)
01771 return true;
01772
01773 if (!m_value_set)
01774 {
01775 if (m_has_default) {
01776 #if DEBUG
01777 conf.debugf(Conf::dbgProcess,
01778 "Setting directive %s to its default value",
01779 m_name.c_str());
01780 #endif
01781 m_value = m_defvalue;
01782 } else {
01783 conf.errorf("Directive %s has not been set and there is "
01784 "no default value", m_name.c_str());
01785 return false;
01786 }
01787 }
01788
01789 if (conf.reloading() && !(m_value == m_oldvalue))
01790 {
01791 m_value_changed = true;
01792 if (!apply_change(conf))
01793 return false;
01794 } else {
01795 m_value_changed = false;
01796 }
01797
01798 if (!apply(conf))
01799 return false;
01800
01801 m_value_set = false;
01802 return ConfDir::end(conf);
01803 }
01804
01805
01806
01807 template <class T>
01808 bool ConfValue<T>::set(Conf &conf, unsigned short count,
01809 std::string const params[])
01810 {
01811 if (!ConfDir::set(conf, count, params) || !assign(conf, count, params))
01812 return false;
01813
01814 m_value_set = true;
01815 return true;
01816 }
01817
01818
01819
01820 template <class T>
01821 ConfEnum<T> &ConfEnum<T>::operator=(ConfEnum<T> const &right)
01822 {
01823 if (&right != this)
01824 {
01825 ConfValue<T>::operator=(right);
01826
01827 m_values = right.m_values;
01828 }
01829
01830 return *this;
01831 }
01832
01833
01834
01835 template <class T>
01836 bool ConfEnum<T>::assign(Conf &conf, unsigned short count,
01837 std::string const params[])
01838 {
01839 if (!ConfValue<T>::m_value_set && !add(conf))
01840 return false;
01841
01842 typename ValueList::const_iterator pos;
01843
01844 if ((pos = m_values.find(params[0])) == m_values.end())
01845 {
01846 conf.errorf("Invalid option name %s to %s", params[0].c_str(),
01847 ConfValue<T>::m_name.c_str());
01848 return false;
01849 }
01850
01851 ConfValue<T>::m_value = pos->second;
01852
01853 #if DEBUG
01854 conf.debugf(Conf::dbgProcess,
01855 "Set %s to %s (%ld)",
01856 ConfValue<T>::m_name.c_str(), params[0].c_str(),
01857 (long) pos->second);
01858 #endif
01859 return true;
01860 }
01861
01862
01863
01864 template <class T>
01865 char const* ConfEnum<T>::label(size_t index) const
01866 {
01867 if (ConfValue<T>::m_label.empty())
01868 {
01869 typename ValueList::const_iterator it, end;
01870
01871 for (it = m_values.begin(), end = m_values.end(); it != end; ++it)
01872 {
01873 if (it->second == ConfValue<T>::m_value)
01874 {
01875 ConfValue<T>::m_label = it->first;
01876 break;
01877 }
01878 }
01879 }
01880
01881 return ConfValue<T>::m_label.c_str();
01882 }
01883
01884
01885
01886 template <class T>
01887 ConfInt<T> &ConfInt<T>::operator=(ConfInt<T> const &right)
01888 {
01889 if (&right != this)
01890 {
01891 ConfValue<T>::operator=(right);
01892
01893 m_minvalue = right.m_minvalue;
01894 m_maxvalue = right.m_maxvalue;
01895 }
01896
01897 return *this;
01898 }
01899
01900
01901
01902 template <class T>
01903 bool ConfInt<T>::assign(Conf &conf, unsigned short count,
01904 std::string const params[])
01905 {
01906 if (params[0].empty())
01907 {
01908 conf.errorf("Can't set directive %s: empty string is not a valid value",
01909 ConfValue<T>::m_name.c_str());
01910 return false;
01911 }
01912
01913 T value;
01914
01915 if (!convert(conf, params[0], value) || !check(conf, value))
01916 return false;
01917
01918 ConfValue<T>::m_value = value;
01919
01920 #if DEBUG
01921 conf.debugf(Conf::dbgProcess, "Set %s to %s", ConfValue<T>::m_name.c_str(),
01922 params[0].c_str());
01923 #endif
01924 return true;
01925 }
01926
01927
01928
01929 template <class T>
01930 bool ConfInt<T>::check(Conf &conf, T const &value) const
01931 {
01932 if ((value < m_minvalue) || (value > m_maxvalue))
01933 {
01934 conf.errorf("Can't set directive %s to %ld: value must be "
01935 "between %ld and %ld", ConfValue<T>::m_name.c_str(),
01936 (long) value, (long) m_minvalue, (long) m_maxvalue);
01937 return false;
01938 }
01939
01940 return true;
01941 }
01942
01943
01944
01945 template <class T>
01946 bool ConfInt<T>::convert(Conf &conf, std::string const &expr, T &result) const
01947 {
01948 char *end;
01949 T value = my_strtol(expr.c_str(), &end, 0);
01950
01951 if (*end != 0)
01952 {
01953 conf.errorf("Can't set directive %s: value %s is not a valid number",
01954 ConfValue<T>::m_name.c_str(), expr.c_str());
01955 return false;
01956 }
01957
01958 if (errno == ERANGE)
01959 {
01960 conf.errorf("Can't set directive %s: value %s is out-of-range.",
01961 ConfValue<T>::m_name.c_str(), expr.c_str());
01962 return false;
01963 }
01964
01965 result = value;
01966 return true;
01967 }
01968
01969
01970
01971 template <class T>
01972 char const* ConfInt<T>::label(size_t index) const
01973 {
01974 if (ConfValue<T>::m_label.empty())
01975 {
01976 char buf[64];
01977 snprintf(buf, sizeof(buf), "%ld", (long) ConfValue<T>::m_value);
01978
01979 ConfValue<T>::m_label = buf;
01980 }
01981
01982 return ConfValue<T>::m_label.c_str();
01983 }
01984
01985
01986
01987 template <class T>
01988 bool ConfIntNZ<T>::check(Conf &conf, T const &value) const
01989 {
01990 if (value == 0)
01991 {
01992 conf.errorf("Can't set directive %s: value must be non-zero ",
01993 ConfInt<T>::m_name.c_str());
01994 return false;
01995 }
01996
01997 return ConfInt<T>::check(conf, value);
01998 }
01999
02000
02001
02002 template <class T>
02003 ConfSet<T> &ConfSet<T>::operator=(ConfSet<T> const &right)
02004 {
02005 if (&right != this)
02006 {
02007 ConfValue<T>::operator=(right);
02008
02009 m_bits = right.m_bits;
02010 }
02011
02012 return *this;
02013 }
02014
02015
02016
02017 template <class T>
02018 bool ConfSet<T>::assign(Conf &conf, unsigned short count,
02019 std::string const params[])
02020 {
02021 if (!ConfValue<T>::m_value_set && !add(conf))
02022 return false;
02023
02024 if (params[0].size() > 1)
02025 {
02026 bool add = true;
02027
02028 switch (params[0][0])
02029 {
02030 case '-':
02031 add = false;
02032 break;
02033 case '+':
02034 add = true;
02035 break;
02036 default:
02037 conf.errorf("Invalid option modifier %c for directive %s",
02038 params[0][0], ConfValue<T>::m_name.c_str());
02039 return false;
02040 }
02041
02042 std::string name(params[0], 1);
02043
02044 typename BitList::const_iterator pos;
02045
02046 if ((pos = m_bits.find(name)) == m_bits.end())
02047 {
02048 conf.errorf("Invalid option name %s to %s", name.c_str(),
02049 ConfValue<T>::m_name.c_str());
02050 return false;
02051 } else {
02052 if (add)
02053 ConfValue<T>::m_value |= pos->second;
02054 else
02055 ConfValue<T>::m_value &= ~pos->second;
02056
02057 #if DEBUG
02058 conf.debugf(Conf::dbgProcess,
02059 "%s option %s (0x%08lx) to %s",
02060 (add ? "Added" : "Removed"), name.c_str(),
02061 (long) pos->second, ConfValue<T>::m_name.c_str());
02062 #endif
02063 return true;
02064 }
02065 }
02066
02067 conf.errorf("Invalid option %s for directive %s",
02068 (params[0].empty() ? "\"\"" : params[0].c_str()), ConfValue<T>::m_name.c_str());
02069 return false;
02070 }
02071
02072
02073
02074 template <class T>
02075 char const *ConfSet<T>::label(size_t index) const
02076 {
02077 ConfValue<T>::m_label.clear();
02078
02079 typename BitList::const_iterator it, end;
02080
02081 for (it = m_bits.begin(), end = m_bits.end(); it != end; ++it)
02082 {
02083 if (ConfValue<T>::m_value & it->second)
02084 {
02085 ConfValue<T>::m_label += "\"+";
02086 ConfValue<T>::m_label += it->first;
02087 ConfValue<T>::m_label += "\" ";
02088 }
02089 }
02090
02091 return ConfValue<T>::label(index);
02092 }
02093
02094
02095
02096 template <class T>
02097 bool ConfUint<T>::check(Conf &conf, T const &value) const
02098 {
02099 if ((value < ConfInt<T>::m_minvalue) || (value > ConfInt<T>::m_maxvalue))
02100 {
02101 conf.errorf("Can't set directive %s to %lu: value must be "
02102 "between %lu and %lu", ConfInt<T>::m_name.c_str(),
02103 (unsigned long) value, (unsigned long) ConfInt<T>::m_minvalue,
02104 (unsigned long) ConfInt<T>::m_maxvalue);
02105 return false;
02106 }
02107
02108 return true;
02109 }
02110
02111
02112
02113 template <class T>
02114 bool ConfUint<T>::convert(Conf &conf, std::string const &expr, T &result) const
02115 {
02116 if (expr[0] == '-')
02117 {
02118 conf.errorf("Can't set directive %s to %s: value must be a positive "
02119 "number", ConfInt<T>::m_name.c_str(), expr.c_str());
02120 return false;
02121 }
02122
02123 return ConfInt<T>::convert(conf, expr, result);
02124 }
02125
02126
02127
02128 template <class T>
02129 char const* ConfUint<T>::label(size_t index) const
02130 {
02131 if (ConfValue<T>::m_label.empty())
02132 {
02133 char buf[64];
02134 snprintf(buf, sizeof(buf), "%lu",
02135 (unsigned long) ConfValue<T>::m_value);
02136
02137 ConfValue<T>::m_label = buf;
02138 }
02139
02140 return ConfValue<T>::m_label.c_str();
02141 }
02142
02143
02144
02145 template <class ValueT, class ContainerT>
02146 ConfArray<ValueT, ContainerT> &ConfArray<ValueT, ContainerT>::operator=
02147 (ConfArray<ValueT, ContainerT> const &right)
02148 {
02149 if (&right != this)
02150 {
02151 ConfValue<ContainerT>::operator=(right);
02152
02153 m_max_values = right.m_max_values;
02154 }
02155
02156 return *this;
02157 }
02158
02159
02160
02161 template <class ValueT, class ContainerT>
02162 bool ConfArray<ValueT, ContainerT>::assign(Conf &conf, unsigned short count,
02163 std::string const params[])
02164 {
02165
02166 if (conf.reloading() && !ConfValue<ContainerT>::m_value_set)
02167 ConfValue<ContainerT>::m_value.clear();
02168
02169 if (m_max_values == ConfValue<ContainerT>::m_value.size())
02170 {
02171 conf.errorf("Can't accept more than %ld values for directive %s",
02172 (long) m_max_values, ConfValue<ContainerT>::m_name.c_str());
02173 return false;
02174 }
02175
02176 typename container_type::iterator pos = insert();
02177
02178 if (!pos->begin(conf))
02179 return false;
02180
02181 if (!pos->set(conf, 1, params))
02182 return false;
02183
02184 if (!pos->end(conf))
02185 return false;
02186
02187 return true;
02188 }
02189
02190
02191
02192 template <class ValueT, class ContainerT>
02193 typename ContainerT::iterator ConfArray<ValueT, ContainerT>::insert()
02194 {
02195 using namespace std;
02196
02197 char buf[512];
02198 snprintf(buf, sizeof(buf), "%s[%ld]",
02199 ConfValue<ContainerT>::m_name.c_str(),
02200 (long) ConfValue<ContainerT>::m_value.size());
02201
02202 return ConfValue<ContainerT>::m_value.insert(ConfValue<ContainerT>::m_value.end(), ValueT(buf, ConfValue<ContainerT>::m_reloadable));
02203 }
02204
02205
02206
02207 template <class ValueT, class ContainerT>
02208 char const *ConfArray<ValueT, ContainerT>::label(size_t index) const
02209 {
02210 if (ConfValue<ContainerT>::m_value.size() <= index)
02211 return 0;
02212
02213 ValueT const &dir = ConfValue<ContainerT>::m_value[index];
02214
02215 if (dir.label_count() != 1)
02216 return 0;
02217
02218 return dir.label(0);
02219 }
02220
02221
02222
02223
02224 inline ConfElse &ConfElse::operator=(ConfElse const &right)
02225 {
02226 if (&right != this)
02227 {
02228 ConfDir::operator=(right);
02229
02230 m_process = right.m_process;
02231 }
02232
02233 return *this;
02234 }
02235
02236
02237
02238 }
02239
02240
02241
02242 #endif