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 <conf/parser.h>
00041 #include <misc/ratio.h>
00042 #include <misc/string.h>
00043 #include <misc/uri.h>
00044
00045
00046
00048
00049 namespace conf
00050 {
00051
00052
00053
00054 class Conf;
00055
00056
00057
00059
00073 class ConfDir
00074 {
00075 public:
00077
00089 explicit ConfDir(std::string const &name, bool reloadable,
00090 unsigned short min = 0, unsigned short max = 0) : m_name(name),
00091 m_reloadable(reloadable), m_ready(false), m_minparams(min),
00092 m_maxparams(max) { }
00094 ConfDir(ConfDir const &cd) : m_name(cd.m_name),
00095 m_reloadable(cd.m_reloadable), m_ready(cd.m_ready),
00096 m_minparams(cd.m_minparams), m_maxparams(cd.m_maxparams) { }
00098 virtual ~ConfDir() { }
00100 virtual ConfDir &operator=(ConfDir const &cd);
00101
00103
00121 virtual bool begin(Conf &conf) { return (m_ready = true); }
00123
00142 virtual bool set(Conf &conf, unsigned short count,
00143 std::string const params[]);
00145
00163 virtual bool end(Conf &conf) { m_ready = false; return true; }
00164
00166 std::string const &name() const { return m_name; }
00168 bool reloadable() const { return m_reloadable; }
00170 bool ready() const { return m_ready; }
00171
00173
00187 virtual char const *label(size_t index) const { return 0; }
00189
00197 virtual size_t label_count() const { return 0; }
00199
00208 virtual Conf const *sub() const { return 0; }
00209 protected:
00211 std::string m_name;
00213 bool m_reloadable;
00214
00216 bool m_ready;
00217
00219 unsigned short m_minparams;
00221 unsigned short m_maxparams;
00222 };
00223
00224
00225
00226
00227
00229
00244 template <class T>
00245 class ConfValue : public ConfDir
00246 {
00247 public:
00249 typedef T value_type;
00250
00252 explicit ConfValue(std::string const &name, bool reloadable,
00253 unsigned short min_params = 1, unsigned short max_params = 1) :
00254 ConfDir(name, reloadable, min_params, max_params), m_value(),
00255 m_value_set(false), m_value_changed(false), m_defvalue(),
00256 m_has_default(false), m_oldvalue(), m_label() { }
00258 ConfValue(std::string const &name, T const &defval, bool reloadable,
00259 unsigned short min_params = 1, unsigned short max_params = 1) :
00260 ConfDir(name, reloadable, min_params, max_params), m_value(),
00261 m_value_set(false), m_value_changed(false), m_defvalue(defval),
00262 m_has_default(true), m_oldvalue(), m_label() { }
00264 ConfValue(ConfValue const &cd) : ConfDir(cd), m_value(cd.m_value),
00265 m_value_set(cd.m_value_set),
00266 m_value_changed(cd.m_value_changed), m_defvalue(cd.m_defvalue),
00267 m_has_default(cd.m_has_default), m_oldvalue(cd.m_oldvalue),
00268 m_label(cd.m_label) { }
00270 virtual ConfValue<T> &operator=(ConfValue<T> const &right);
00271
00273
00275 virtual bool begin(Conf &conf);
00277
00278 virtual bool set(Conf &conf, unsigned short count,
00279 std::string const params[]);
00281
00286 virtual bool end(Conf &conf);
00287
00289
00294 T const &value() const { return m_value; }
00296 bool has_value_changed() const { return m_value_changed; }
00297
00299 bool has_default() const { return m_has_default; }
00300
00302
00306 T const &old_value() const { return m_oldvalue; }
00307
00309 virtual char const *label(size_t index) const
00310 { return m_label.c_str(); }
00312 virtual size_t label_count() const { return 1; }
00313 protected:
00315 T m_value;
00317 bool m_value_set;
00319 bool m_value_changed;
00320
00322 T m_defvalue;
00324 bool m_has_default;
00325
00327 T m_oldvalue;
00328
00330 mutable std::string m_label;
00331
00333
00347 virtual bool assign(Conf &conf, unsigned short count,
00348 std::string const params[]) = 0;
00350
00358 virtual bool check(Conf &conf, T const &value) { return true; }
00359
00361
00368 virtual bool apply(Conf &conf) { return true; }
00369
00371
00378 virtual bool apply_change(Conf &conf) { return true; }
00379 };
00380
00381
00382
00384
00391 class ConfBool : public ConfValue<bool>
00392 {
00393 public:
00395 explicit ConfBool(std::string const &name, bool reloadable) :
00396 ConfValue<bool>(name, reloadable) { }
00398 ConfBool(std::string const &name, bool const &defval,
00399 bool reloadable) :
00400 ConfValue<bool>(name, defval, reloadable) { }
00402 operator bool() const { return m_value; }
00403
00405 virtual char const *label(size_t index) const
00406 { return (m_value ? "yes" : "no"); }
00407 protected:
00408 virtual bool assign(Conf &conf, unsigned short count,
00409 std::string const params[]);
00410 };
00411
00412
00413
00415
00425 class ConfDuration : public ConfValue<time_t>
00426 {
00427 public:
00429
00437 explicit ConfDuration(std::string const &name, bool reloadable,
00438 time_t mindur, time_t maxdur) :
00439 ConfValue<time_t>(name, reloadable), m_mindur(mindur),
00440 m_maxdur(maxdur) { }
00442
00451 ConfDuration(std::string const &name, time_t defval,
00452 bool reloadable, time_t mindur,
00453 time_t maxdur) :
00454 ConfValue<time_t>(name, defval, reloadable), m_mindur(mindur),
00455 m_maxdur(maxdur) { }
00457 ConfDuration(std::string const &name, bool reloadable) :
00458 ConfValue<time_t>(name, reloadable), m_mindur(0),
00459 m_maxdur(2147483647) { }
00461 ConfDuration(ConfDuration const &cd) : ConfValue<time_t>(cd),
00462 m_mindur(cd.m_mindur), m_maxdur(cd.m_maxdur) { }
00464 virtual ConfDuration &operator=(ConfDuration const &right);
00466 operator time_t() const { return m_value; }
00467
00469 virtual char const *label(size_t index) const;
00470 protected:
00472 time_t m_mindur;
00474 time_t m_maxdur;
00475
00476 virtual bool assign(Conf &conf, unsigned short count,
00477 std::string const params[]);
00478
00480 virtual bool check(Conf &conf, time_t value) const;
00481 };
00482
00483
00484
00486
00498 template <class T = u_int32_t>
00499 class ConfEnum : public ConfValue<T>
00500 {
00501 public:
00502 typedef std::map<std::string, T, misc::insensitive_less> ValueList;
00503
00505 explicit ConfEnum(std::string const &name, bool reloadable) :
00506 ConfValue<T>(name, reloadable), m_values() { }
00508 ConfEnum(std::string const &name, T const &defval, bool reloadable) :
00509 ConfValue<T>(name, defval, reloadable), m_values() { }
00511 ConfEnum(ConfEnum const &cd) : ConfValue<T>(cd),
00512 m_values(cd.m_values) { }
00514 virtual ConfEnum<T> &operator=(ConfEnum<T> const &right);
00516 operator T const &() const { return ConfValue<T>::m_value; }
00517
00519 virtual char const *label(size_t index) const;
00520 protected:
00522 ValueList m_values;
00523
00525
00532 virtual bool add(Conf &conf) = 0;
00533
00535 virtual bool assign(Conf &conf, unsigned short count,
00536 std::string const params[]);
00537 };
00538
00539
00540
00542
00543 inline bool operator==(struct in_addr const &in1, struct in_addr const &in2)
00544 {
00545 return (in1.s_addr == in2.s_addr);
00546 }
00547
00549
00560 class ConfHostname : public ConfValue<struct in_addr>
00561 {
00562 public:
00564 explicit ConfHostname(std::string const &name,
00565 bool reloadable) :
00566 ConfValue<struct in_addr>(name, reloadable) { }
00568 ConfHostname(std::string const &name, struct in_addr const &defval,
00569 bool reloadable) :
00570 ConfValue<struct in_addr>(name, defval, reloadable) { }
00572 operator struct in_addr const &() const { return m_value; }
00573
00575 virtual char const *label(size_t index) const;
00576 protected:
00577 virtual bool assign(Conf &conf, unsigned short count,
00578 std::string const params[]);
00579 };
00580
00581
00582
00584
00596 template <class T>
00597 class ConfInt : public ConfValue<T>
00598 {
00599 public:
00601
00609 explicit ConfInt(std::string const &name, bool reloadable,
00610 T minvalue, T maxvalue) :
00611 ConfValue<T>(name, reloadable), m_minvalue(minvalue),
00612 m_maxvalue(maxvalue) { }
00614
00623 ConfInt(std::string const &name, T const &defval, bool reloadable,
00624 T minvalue, T maxvalue) :
00625 ConfValue<T>(name, defval, reloadable), m_minvalue(minvalue),
00626 m_maxvalue(maxvalue) { }
00628 ConfInt(std::string const &name, bool reloadable) :
00629 ConfValue<T>(name, reloadable), m_minvalue(LONG_MIN),
00630 m_maxvalue(LONG_MAX) { }
00632 ConfInt(ConfInt const &cd) : ConfValue<T>(cd),
00633 m_minvalue(cd.m_minvalue), m_maxvalue(cd.m_maxvalue) { }
00635 virtual ConfInt<T> &operator=(ConfInt<T> const &right);
00637 operator T() const { return ConfValue<T>::m_value; }
00638
00640 virtual char const *label(size_t index) const;
00641 protected:
00642 T m_minvalue;
00643 T m_maxvalue;
00644
00645 virtual bool assign(Conf &conf, unsigned short count,
00646 std::string const params[]);
00647
00649 virtual bool check(Conf &conf, T const &value) const;
00650
00652
00660 virtual bool convert(Conf &conf, std::string const &expr,
00661 T &result) const;
00662
00664
00668 virtual T my_strtol(char const *nptr, char **endptr, int base) const
00669 { return strtol(nptr, endptr, base); }
00670 };
00671
00672
00673
00675
00681 template <class T>
00682 class ConfIntNZ : public ConfInt<T>
00683 {
00684 public:
00686 explicit ConfIntNZ(std::string const &name, bool reloadable,
00687 T minvalue, T maxvalue) :
00688 ConfInt<T>(name, reloadable, minvalue, maxvalue) { }
00690 ConfIntNZ(std::string const &name, T const &defval, bool reloadable,
00691 T minvalue, T maxvalue) :
00692 ConfInt<T>(name, defval, reloadable, minvalue, maxvalue) { }
00694 ConfIntNZ(std::string const &name, bool reloadable) :
00695 ConfInt<T>(name, reloadable) { }
00696 protected:
00698 virtual bool check(Conf &conf, T const &value) const;
00699 };
00700
00701
00702
00704
00705 class ConfPort : public ConfInt<uint16_t>
00706 {
00707 public:
00709 explicit ConfPort(std::string const &name, bool reloadable) :
00710 ConfInt<uint16_t>(name, reloadable, 0, 65535) { }
00712 ConfPort(std::string const &name, uint16_t const &defval,
00713 bool reloadable) : ConfInt<uint16_t>(name, defval,
00714 reloadable, 0, 65535) { }
00715 };
00716
00717
00718
00720
00726 class ConfRatio : public ConfValue<misc::Ratio>
00727 {
00728 public:
00730
00740 explicit ConfRatio(std::string const &name, bool reloadable,
00741 int32_t minx, int32_t maxx, int32_t miny, int32_t maxy) :
00742 ConfValue<misc::Ratio>(name, reloadable), m_minx(minx),
00743 m_maxx(maxx), m_miny(miny), m_maxy(maxy) { }
00745
00756 ConfRatio(std::string const &name, misc::Ratio const &defval,
00757 bool reloadable, int32_t minx, int32_t maxx, int32_t miny,
00758 int32_t maxy) : ConfValue<misc::Ratio>(name, defval, reloadable),
00759 m_minx(minx), m_maxx(maxx), m_miny(miny), m_maxy(maxy) { }
00761 ConfRatio(std::string const &name, bool reloadable) :
00762 ConfValue<misc::Ratio>(name, reloadable), m_minx(-2147483647),
00763 m_maxx(2147483647), m_miny(-2147483647), m_maxy(2147483647) { }
00765 ConfRatio(ConfRatio const &cd) : ConfValue<misc::Ratio>(cd),
00766 m_minx(cd.m_minx), m_maxx(cd.m_maxx),
00767 m_miny(cd.m_miny), m_maxy(cd.m_maxy) { }
00769 virtual ConfRatio &operator=(ConfRatio const &right);
00770
00772 virtual char const *label(size_t index) const;
00773 protected:
00775 time_t m_minx;
00777 time_t m_maxx;
00779 time_t m_miny;
00781 time_t m_maxy;
00782
00783 virtual bool assign(Conf &conf, unsigned short count,
00784 std::string const params[]);
00785
00787 virtual bool check(Conf &conf, misc::Ratio value) const;
00788 };
00789
00790
00791
00793
00812 template <class T = u_int32_t>
00813 class ConfSet : public ConfValue<T>
00814 {
00815 public:
00816 typedef std::map<std::string, T, misc::insensitive_less> BitList;
00817
00819 explicit ConfSet(std::string const &name, bool reloadable) :
00820 ConfValue<T>(name, reloadable), m_bits() { }
00822 ConfSet(std::string const &name, T const &defval, bool reloadable) :
00823 ConfValue<T>(name, defval, reloadable), m_bits() { }
00825 ConfSet(ConfSet const &cd) : ConfValue<T>(cd), m_bits(cd.m_bits) { }
00827 virtual ConfSet<T> &operator=(ConfSet<T> const &right);
00829 operator T const &() const { return ConfValue<T>::m_value; }
00830
00832 virtual char const *label(size_t index) const;
00833 protected:
00835 BitList m_bits;
00836
00838
00845 virtual bool add(Conf &conf) = 0;
00846
00847 virtual bool assign(Conf &conf, unsigned short count,
00848 std::string const params[]);
00849 };
00850
00851
00852
00854
00858 class ConfStr : public ConfValue<std::string>
00859 {
00860 public:
00862
00874 explicit ConfStr(std::string const &name, bool reloadable,
00875 std::string::size_type minlen,
00876 std::string::size_type maxlen, std::string const &validchars) :
00877 ConfValue<std::string>(name, reloadable), m_minlen(minlen),
00878 m_maxlen(maxlen), m_validchars(validchars) { }
00880
00893 ConfStr(std::string const &name, std::string const &defval,
00894 bool reloadable, std::string::size_type minlen,
00895 std::string::size_type maxlen, std::string const &validchars) :
00896 ConfValue<std::string>(name, defval, reloadable),
00897 m_minlen(minlen), m_maxlen(maxlen), m_validchars(validchars)
00898 { }
00900 ConfStr(std::string const &name, bool reloadable) :
00901 ConfValue<std::string>(name, reloadable), m_minlen(0),
00902 m_maxlen(2147483647), m_validchars("") { }
00904 ConfStr(ConfStr const &cd) : ConfValue<std::string>(cd),
00905 m_minlen(cd.m_minlen), m_maxlen(cd.m_maxlen),
00906 m_validchars(cd.m_validchars) { }
00908 virtual ConfStr &operator=(ConfStr const &right);
00910 bool operator==(ConfStr const &right) const
00911 { return (m_value == right.m_value); }
00913 bool operator==(std::string const &right) const
00914 { return (m_value == right); }
00916 bool operator!=(ConfStr const &right) const
00917 { return (m_value != right.m_value); }
00919 bool operator!=(std::string const &right) const
00920 { return (m_value != right); }
00922 bool operator<(ConfStr const &right) const
00923 { return (m_value < right.m_value); }
00925 bool operator<(std::string const &right) const
00926 { return (m_value < right); }
00928 bool operator<=(ConfStr const &right) const
00929 { return (m_value <= right.m_value); }
00931 bool operator<=(std::string const &right) const
00932 { return (m_value <= right); }
00934 bool operator>(ConfStr const &right) const
00935 { return (m_value > right.m_value); }
00937 bool operator>(std::string const &right) const
00938 { return (m_value > right); }
00940 bool operator>=(ConfStr const &right) const
00941 { return (m_value >= right.m_value); }
00943 bool operator>=(std::string const &right) const
00944 { return (m_value >= right); }
00945
00947 virtual char const *label(size_t index) const
00948 { return m_value.c_str(); }
00949 protected:
00950 std::string::size_type m_minlen;
00951 std::string::size_type m_maxlen;
00952 std::string m_validchars;
00953
00954 virtual bool assign(Conf &conf, unsigned short count,
00955 std::string const params[]);
00956
00958 virtual bool check(Conf &conf, std::string const &value) const;
00959 };
00960
00961
00962
00964
00965 class ConfStrChar : public ConfStr
00966 {
00967 public:
00969 explicit ConfStrChar(std::string const &name, bool reloadable,
00970 std::string::size_type minlen, std::string::size_type maxlen,
00971 std::string const &validchars) :
00972 ConfStr(name, reloadable, minlen, maxlen, validchars) { }
00974 ConfStrChar(std::string const &name, std::string const &defval,
00975 bool reloadable, std::string::size_type minlen,
00976 std::string::size_type maxlen, std::string const &validchars) :
00977 ConfStr(name, defval, reloadable, minlen, maxlen,
00978 validchars) { }
00980 ConfStrChar(std::string const &name, bool reloadable) :
00981 ConfStr(name, reloadable) { }
00983 operator char const *() const
00984 { return (m_value.size() ? m_value.c_str() : 0); }
00985 };
00986
00987
00988
00990
00991 class ConfString : public ConfStr
00992 {
00993 public:
00995 explicit ConfString(std::string const &name, bool reloadable,
00996 std::string::size_type minlen, std::string::size_type maxlen,
00997 std::string const &validchars) :
00998 ConfStr(name, reloadable, minlen, maxlen, validchars) { }
01000 ConfString(std::string const &name, std::string const &defval,
01001 bool reloadable, std::string::size_type minlen,
01002 std::string::size_type maxlen, std::string const &validchars) :
01003 ConfStr(name, defval, reloadable, minlen, maxlen,
01004 validchars) { }
01006 ConfString(std::string const &name, bool reloadable) :
01007 ConfStr(name, reloadable) { }
01009 char operator[](std::string::size_type idx) const
01010 { return m_value[idx]; }
01012 operator std::string() const { return m_value; }
01013 };
01014
01015
01016
01018
01026 template <class T>
01027 class ConfUint : public ConfInt<T>
01028 {
01029 public:
01031
01039 explicit ConfUint(std::string const &name, bool reloadable,
01040 T minvalue, T maxvalue) :
01041 ConfInt<T>(name, reloadable, minvalue, maxvalue) { }
01043
01052 ConfUint(std::string const &name, T const &defval, bool reloadable,
01053 T minvalue, T maxvalue) :
01054 ConfInt<T>(name, defval, reloadable, minvalue, maxvalue) { }
01056 ConfUint(std::string const &name, bool reloadable) :
01057 ConfInt<T>(name, reloadable) { }
01058
01060 virtual char const *label(size_t index) const;
01061 protected:
01063 virtual bool check(Conf &conf, T const &value) const;
01064
01066 virtual bool convert(Conf &conf, std::string const &expr,
01067 T &result) const;
01069 virtual T my_strtol(char const *nptr, char **endptr, int base) const
01070 { return strtoul(nptr, endptr, base); }
01071 };
01072
01073
01074
01076
01081 class ConfURI : public ConfValue<misc::URI>
01082 {
01083 public:
01085 explicit ConfURI(std::string const &name, bool reloadable) :
01086 ConfValue<misc::URI>(name, reloadable) { }
01088 ConfURI(std::string const &name, misc::URI const &defval,
01089 bool reloadable) :
01090 ConfValue<misc::URI>(name, defval, reloadable) { }
01091
01093 virtual char const *label(size_t index) const;
01094 protected:
01095 virtual bool assign(Conf &conf, unsigned short count,
01096 std::string const params[]);
01097 };
01098
01099
01100
01102
01129 template <class ValueT, class ContainerT = std::vector<ValueT> >
01130 class ConfArray : public ConfValue <ContainerT>
01131 {
01132 public:
01133 typedef ValueT value_type;
01134 typedef ContainerT container_type;
01135
01137
01144 explicit ConfArray(std::string const &name, bool reloadable = true,
01145 typename ContainerT::size_type max = INT_MAX) :
01146 ConfValue <ContainerT>(name, reloadable), m_max_values(max) { }
01148
01156 ConfArray(std::string const &name, ContainerT const &defval,
01157 bool reloadable = true,
01158 typename ContainerT::size_type max = INT_MAX) :
01159 ConfValue <ContainerT>(name, defval, reloadable),
01160 m_max_values(max) { }
01162 ConfArray(ConfArray const &cd) : ConfValue<ContainerT>(cd),
01163 m_max_values(cd.m_max_values) { }
01165 virtual ConfArray<ValueT, ContainerT>
01166 &operator=(ConfArray<ValueT, ContainerT> const &right);
01168 operator ContainerT const &() const { return ConfValue <ContainerT>::m_value; }
01170 ContainerT const &operator*() const { return ConfValue <ContainerT>::m_value; }
01172 ContainerT const *operator->() const { return &(this->ConfValue<ContainerT>::m_value); }
01173
01175 virtual char const *label(size_t index) const;
01177 virtual size_t label_count() const
01178 { return ConfValue <ContainerT>::m_value.size(); }
01179 protected:
01180 typename ContainerT::size_type m_max_values;
01181
01182 virtual bool assign(Conf &conf, unsigned short count,
01183 std::string const params[]);
01184
01186
01193 virtual typename ContainerT::iterator insert();
01194 };
01195
01196
01197
01198 typedef ConfArray<ConfBool> ConfBoolA;
01199 typedef ConfArray<ConfDuration> ConfDurationA;
01200 typedef ConfArray<ConfHostname> ConfHostnameA;
01201 typedef ConfArray<ConfPort> ConfPortA;
01202 typedef ConfArray<ConfStr> ConfStrA;
01203 typedef ConfArray<ConfStrChar> ConfStrCharA;
01204 typedef ConfArray<ConfString> ConfStringA;
01205
01206
01207
01208
01209
01211
01223 class ConfBlock : public ConfDir
01224 {
01225 public:
01227 explicit ConfBlock(std::string const &name, bool reloadable = true) :
01228 ConfDir(name, reloadable, 1, 1), m_conf(0) { }
01230 ConfBlock(ConfBlock const &cd);
01232 virtual ~ConfBlock();
01234 virtual ConfBlock &operator=(ConfBlock const &right);
01236
01240 virtual bool operator==(ConfBlock const &) const { return false; }
01241
01243
01247 virtual bool begin(Conf &conf);
01249
01250 virtual bool set(Conf &conf, unsigned short count,
01251 std::string const params[]);
01253
01254 virtual bool end(Conf &conf);
01255
01257 virtual Conf const *sub() const { return m_conf; }
01258 protected:
01260 Conf *m_conf;
01261
01263
01273 virtual bool add(Conf &conf, Conf &new_conf) = 0;
01274
01276
01281 virtual bool apply_changes(Conf &conf) { return true; }
01282 };
01283
01284
01285
01287
01311 class ConfBoolBlock : public ConfBlock
01312 {
01313 public:
01315 explicit ConfBoolBlock(std::string const &name,
01316 bool reloadable = true) : ConfBlock(name, reloadable),
01317 m_set(false) { }
01319 ConfBoolBlock(ConfBoolBlock const &cd) : ConfBlock(cd),
01320 m_set(cd.m_set) { }
01322 virtual ConfBoolBlock &operator=(ConfBoolBlock const &right);
01324 operator bool() const { return m_set; }
01325
01327 virtual bool begin(Conf &) { m_set = false; return true; }
01329 virtual bool set(Conf &conf, unsigned short count,
01330 std::string const params[]);
01331
01333 virtual char const *label(size_t index) const
01334 { return (m_set ? "yes" : "no"); }
01336 virtual size_t label_count() const { return 1; }
01337 protected:
01338 bool m_set;
01339 };
01340
01341
01342
01343 typedef ConfArray<ConfBlock> ConfBlockA;
01344 typedef ConfArray<ConfBoolBlock> ConfBoolBlockA;
01345
01346
01347
01348
01349
01351
01355 class ConfHostPort : public ConfBlock
01356 {
01357 public:
01358
01360 ConfHostname hostname;
01362 ConfPort port;
01363
01364
01366 explicit ConfHostPort(std::string const &name,
01367 bool reloadable = true) : ConfBlock(name, reloadable),
01368 hostname("hostname", reloadable), port("port", reloadable) { }
01370 ConfHostPort(std::string const &name, struct in_addr const &defhost,
01371 uint16_t defport, bool reloadable = true) :
01372 ConfBlock(name, reloadable),
01373 hostname("hostname", defhost, reloadable),
01374 port("port", defport, reloadable) { }
01376 ConfHostPort(std::string const &name, uint16_t defport,
01377 bool reloadable = true) : ConfBlock(name, reloadable),
01378 hostname("hostname", reloadable),
01379 port("port", defport, reloadable) { }
01381 ConfHostPort(ConfHostPort const &cd) : ConfBlock(cd),
01382 hostname(cd.hostname), port(cd.port) { }
01384 virtual ConfHostPort &operator=(ConfHostPort const &right);
01385 protected:
01386 virtual bool add(Conf &conf, Conf &new_conf);
01387 };
01388
01389
01390
01392
01393
01394
01395
01396
01397 class ConfRules : public ConfBlock
01398 {
01399 public:
01400
01401
01403
01405 class Rule
01406 {
01407 public:
01409
01412 Rule(int type, std::string const &value) : m_type(type),
01413 m_value(value) { }
01415 Rule(Rule const &r) : m_type(r.m_type),
01416 m_value(r.m_value) { }
01418 Rule &operator=(Rule const &right);
01419
01421 int type() const { return m_type; }
01423 std::string const &value() const { return m_value; }
01424 protected:
01426 int m_type;
01428 std::string m_value;
01429 };
01430
01431
01432 typedef std::vector<Rule> container_type;
01433
01434
01435
01437
01441 class ConfRule : public ConfDir
01442 {
01443 public:
01445
01454 ConfRule(std::string const &name, bool reloadable,
01455 ConfRules::container_type &container, int type) :
01456 ConfDir(name, reloadable, 1, 1),
01457 m_container(&container), m_type(type) { }
01459 ConfRule(ConfRule const &cd) : ConfDir(cd),
01460 m_container(cd.m_container), m_type(cd.m_type) { }
01462 virtual ConfRule &operator=(ConfRule const &right);
01463
01465 virtual bool set(Conf &conf, unsigned short count,
01466 std::string const params[]);
01467
01469 ConfRules::container_type *container() const
01470 { return m_container; }
01472 ConfRules::container_type *
01473 container(ConfRules::container_type &c)
01474 { return (m_container = &c); }
01475 protected:
01477
01485 virtual bool check(std::string const &value) const
01486 { return true; }
01487 protected:
01489 ConfRules::container_type *m_container;
01491 int m_type;
01492 };
01493
01494
01495
01497 ConfRules(std::string const &name, bool reloadable) :
01498 ConfBlock(name, reloadable), m_rules() { }
01500 ConfRules(ConfRules const &cd) : ConfBlock(cd), m_rules(cd.m_rules) { }
01502 virtual ConfRules &operator=(ConfRules const &right);
01503
01505 virtual bool begin(Conf &conf);
01506
01508 container_type const &rules() const { return m_rules; }
01509 protected:
01511 container_type m_rules;
01512 };
01513
01514
01515
01516
01517
01519
01523 class ConfWarning : public ConfDir
01524 {
01525 public:
01527 explicit ConfWarning(std::string const &name,
01528 std::string const &msg) : ConfDir(name, true, 0, 65535),
01529 m_msg(msg) { }
01531 ConfWarning(ConfWarning const &cd) : ConfDir(cd),
01532 m_msg(cd.m_msg) { }
01534 virtual ConfWarning &operator=(ConfWarning const &right);
01535
01537 virtual bool set(Conf &conf, unsigned short count,
01538 std::string const params[]);
01539
01541 std::string const &msg() const { return m_msg; }
01542 protected:
01543 std::string m_msg;
01544 };
01545
01546
01547
01549
01553 class ConfError : public ConfWarning
01554 {
01555 public:
01557 explicit ConfError(std::string const &name, std::string const &msg) :
01558 ConfWarning(name, msg) { }
01559
01561 virtual bool set(Conf &conf, unsigned short count,
01562 std::string const params[]);
01563 };
01564
01565
01566
01567
01568
01570
01577 class ConfElse : public ConfDir
01578 {
01579 public:
01581 explicit ConfElse(std::string const &name) : ConfDir(name, true, 1, 1),
01582 m_process(false) { }
01584 ConfElse(ConfElse const &cd) : ConfDir(cd), m_process(cd.m_process) { }
01586 virtual ConfElse &operator=(ConfElse const &cd);
01587
01589
01593 bool can_process() const { return m_process; }
01595
01601 bool can_process(bool process) { return (m_process = process); }
01602
01604 virtual bool set(Conf &conf, unsigned short count, std::string const
01605 params[]);
01606 private:
01607 bool m_process;
01608 };
01609
01610
01611
01613
01620 class ConfIf : public ConfDir
01621 {
01622 public:
01624 explicit ConfIf(std::string const &name, unsigned short min = 2,
01625 unsigned short max = 2) : ConfDir(name, true, min, max) { }
01626
01628 virtual bool set(Conf &conf, unsigned short count,
01629 std::string const params[]);
01630
01631 protected:
01633
01639 virtual bool can_process(Conf &conf, std::string const &expr) const = 0;
01640 };
01641
01642
01643
01645
01648 class ConfIfnset : public ConfIf
01649 {
01650 public:
01652 explicit ConfIfnset(std::string const &name) : ConfIf(name) { }
01653
01654 protected:
01656 virtual bool can_process(Conf &conf, std::string const &expr) const;
01657 };
01658
01659
01660
01662
01665 class ConfIfset : public ConfIf
01666 {
01667 public:
01669 explicit ConfIfset(std::string const &name) : ConfIf(name) { }
01670
01671 protected:
01673 virtual bool can_process(Conf &conf, std::string const &expr) const;
01674 };
01675
01676
01677
01679
01682 class ConfInclude : public ConfDir
01683 {
01684 public:
01686 explicit ConfInclude(std::string const &name) :
01687 ConfDir(name, true, 1, 1) { }
01688
01690 virtual bool set(Conf &conf, unsigned short count,
01691 std::string const params[]);
01692 };
01693
01694
01695
01697
01700 class ConfPath : public ConfDir
01701 {
01702 public:
01704 explicit ConfPath(std::string const &name) :
01705 ConfDir(name, true, 1, 1) { }
01706
01708 virtual bool set(Conf &conf, unsigned short count,
01709 std::string const params[]);
01710 };
01711
01712
01713
01715
01718 class ConfVarSet : public ConfDir
01719 {
01720 public:
01722 explicit ConfVarSet(std::string const &name) :
01723 ConfDir(name, true, 1, 2) { }
01724
01726 virtual bool set(Conf &conf, unsigned short count,
01727 std::string const params[]);
01728 };
01729
01730
01731
01733
01736 class ConfUnset : public ConfDir
01737 {
01738 public:
01740 explicit ConfUnset(std::string const &name) :
01741 ConfDir(name, true, 1, 1) { }
01742
01744 virtual bool set(Conf &conf, unsigned short count,
01745 std::string const params[]);
01746 };
01747
01748
01749
01750
01751 template <class T>
01752 ConfValue<T> &ConfValue<T>::operator=(ConfValue<T> const &right)
01753 {
01754 if (&right != this)
01755 {
01756 ConfDir::operator=(right);
01757
01758 m_value = right.m_value;
01759 m_value_set = right.m_value_set;
01760 m_value_changed = right.m_value_changed;
01761
01762 m_has_default = right.m_has_default;
01763 m_defvalue = right.m_defvalue;
01764
01765 m_oldvalue = right.m_oldvalue;
01766
01767 m_label = right.m_label;
01768 }
01769
01770 return *this;
01771 }
01772
01773
01774
01775 template <class T>
01776 bool ConfValue<T>::begin(Conf &conf)
01777 {
01778 if (m_ready)
01779 return true;
01780
01781
01782
01783 if (conf.reloading())
01784 {
01785 m_oldvalue = m_value;
01786 m_label = "";
01787 }
01788
01789 return ConfDir::begin(conf);
01790 }
01791
01792
01793
01794 template <class T>
01795 bool ConfValue<T>::end(Conf &conf)
01796 {
01797 if (!m_ready)
01798 return true;
01799
01800 if (!m_value_set)
01801 {
01802 if (m_has_default) {
01803 #if DEBUG
01804 conf.debugf(Conf::dbgProcess,
01805 "Setting directive %s to its default value",
01806 m_name.c_str());
01807 #endif
01808 m_value = m_defvalue;
01809 } else {
01810 conf.errorf("Directive %s has not been set and there is "
01811 "no default value", m_name.c_str());
01812 return false;
01813 }
01814 }
01815
01816 if (conf.reloading() && !(m_value == m_oldvalue))
01817 {
01818 m_value_changed = true;
01819 if (!apply_change(conf))
01820 return false;
01821 } else {
01822 m_value_changed = false;
01823 }
01824
01825 if (!apply(conf))
01826 return false;
01827
01828 m_value_set = false;
01829 return ConfDir::end(conf);
01830 }
01831
01832
01833
01834 template <class T>
01835 bool ConfValue<T>::set(Conf &conf, unsigned short count,
01836 std::string const params[])
01837 {
01838 if (!ConfDir::set(conf, count, params) || !assign(conf, count, params))
01839 return false;
01840
01841 m_value_set = true;
01842 return true;
01843 }
01844
01845
01846
01847 template <class T>
01848 ConfEnum<T> &ConfEnum<T>::operator=(ConfEnum<T> const &right)
01849 {
01850 if (&right != this)
01851 {
01852 ConfValue<T>::operator=(right);
01853
01854 m_values = right.m_values;
01855 }
01856
01857 return *this;
01858 }
01859
01860
01861
01862 template <class T>
01863 bool ConfEnum<T>::assign(Conf &conf, unsigned short count,
01864 std::string const params[])
01865 {
01866 if (!ConfValue<T>::m_value_set && !add(conf))
01867 return false;
01868
01869 typename ValueList::const_iterator pos;
01870
01871 if ((pos = m_values.find(params[0])) == m_values.end())
01872 {
01873 conf.errorf("Invalid option name %s to %s", params[0].c_str(),
01874 ConfValue<T>::m_name.c_str());
01875 return false;
01876 }
01877
01878 ConfValue<T>::m_value = pos->second;
01879
01880 #if DEBUG
01881 conf.debugf(Conf::dbgProcess,
01882 "Set %s to %s (%ld)",
01883 ConfValue<T>::m_name.c_str(), params[0].c_str(),
01884 (long) pos->second);
01885 #endif
01886 return true;
01887 }
01888
01889
01890
01891 template <class T>
01892 char const* ConfEnum<T>::label(size_t index) const
01893 {
01894 if (ConfValue<T>::m_label.empty())
01895 {
01896 typename ValueList::const_iterator it, end;
01897
01898 for (it = m_values.begin(), end = m_values.end(); it != end; ++it)
01899 {
01900 if (it->second == ConfValue<T>::m_value)
01901 {
01902 ConfValue<T>::m_label = it->first;
01903 break;
01904 }
01905 }
01906 }
01907
01908 return ConfValue<T>::m_label.c_str();
01909 }
01910
01911
01912
01913 template <class T>
01914 ConfInt<T> &ConfInt<T>::operator=(ConfInt<T> const &right)
01915 {
01916 if (&right != this)
01917 {
01918 ConfValue<T>::operator=(right);
01919
01920 m_minvalue = right.m_minvalue;
01921 m_maxvalue = right.m_maxvalue;
01922 }
01923
01924 return *this;
01925 }
01926
01927
01928
01929 template <class T>
01930 bool ConfInt<T>::assign(Conf &conf, unsigned short count,
01931 std::string const params[])
01932 {
01933 if (params[0].empty())
01934 {
01935 conf.errorf("Can't set directive %s: empty string is not a valid value",
01936 ConfValue<T>::m_name.c_str());
01937 return false;
01938 }
01939
01940 T value;
01941
01942 if (!convert(conf, params[0], value) || !check(conf, value))
01943 return false;
01944
01945 ConfValue<T>::m_value = value;
01946
01947 #if DEBUG
01948 conf.debugf(Conf::dbgProcess, "Set %s to %s", ConfValue<T>::m_name.c_str(),
01949 params[0].c_str());
01950 #endif
01951 return true;
01952 }
01953
01954
01955
01956 template <class T>
01957 bool ConfInt<T>::check(Conf &conf, T const &value) const
01958 {
01959 if ((value < m_minvalue) || (value > m_maxvalue))
01960 {
01961 conf.errorf("Can't set directive %s to %ld: value must be "
01962 "between %ld and %ld", ConfValue<T>::m_name.c_str(),
01963 (long) value, (long) m_minvalue, (long) m_maxvalue);
01964 return false;
01965 }
01966
01967 return true;
01968 }
01969
01970
01971
01972 template <class T>
01973 bool ConfInt<T>::convert(Conf &conf, std::string const &expr, T &result) const
01974 {
01975 char *end;
01976 T value = my_strtol(expr.c_str(), &end, 0);
01977
01978 if (*end != 0)
01979 {
01980 conf.errorf("Can't set directive %s: value %s is not a valid number",
01981 ConfValue<T>::m_name.c_str(), expr.c_str());
01982 return false;
01983 }
01984
01985 if (errno == ERANGE)
01986 {
01987 conf.errorf("Can't set directive %s: value %s is out-of-range.",
01988 ConfValue<T>::m_name.c_str(), expr.c_str());
01989 return false;
01990 }
01991
01992 result = value;
01993 return true;
01994 }
01995
01996
01997
01998 template <class T>
01999 char const* ConfInt<T>::label(size_t index) const
02000 {
02001 if (ConfValue<T>::m_label.empty())
02002 {
02003 char buf[64];
02004 snprintf(buf, sizeof(buf), "%ld", (long) ConfValue<T>::m_value);
02005
02006 ConfValue<T>::m_label = buf;
02007 }
02008
02009 return ConfValue<T>::m_label.c_str();
02010 }
02011
02012
02013
02014 template <class T>
02015 bool ConfIntNZ<T>::check(Conf &conf, T const &value) const
02016 {
02017 if (value == 0)
02018 {
02019 conf.errorf("Can't set directive %s: value must be non-zero ",
02020 ConfInt<T>::m_name.c_str());
02021 return false;
02022 }
02023
02024 return ConfInt<T>::check(conf, value);
02025 }
02026
02027
02028
02029 template <class T>
02030 ConfSet<T> &ConfSet<T>::operator=(ConfSet<T> const &right)
02031 {
02032 if (&right != this)
02033 {
02034 ConfValue<T>::operator=(right);
02035
02036 m_bits = right.m_bits;
02037 }
02038
02039 return *this;
02040 }
02041
02042
02043
02044 template <class T>
02045 bool ConfSet<T>::assign(Conf &conf, unsigned short count,
02046 std::string const params[])
02047 {
02048 if (!ConfValue<T>::m_value_set && !add(conf))
02049 return false;
02050
02051 if (params[0].size() > 1)
02052 {
02053 bool add = true;
02054
02055 switch (params[0][0])
02056 {
02057 case '-':
02058 add = false;
02059 break;
02060 case '+':
02061 add = true;
02062 break;
02063 default:
02064 conf.errorf("Invalid option modifier %c for directive %s",
02065 params[0][0], ConfValue<T>::m_name.c_str());
02066 return false;
02067 }
02068
02069 std::string name(params[0], 1);
02070
02071 typename BitList::const_iterator pos;
02072
02073 if ((pos = m_bits.find(name)) == m_bits.end())
02074 {
02075 conf.errorf("Invalid option name %s to %s", name.c_str(),
02076 ConfValue<T>::m_name.c_str());
02077 return false;
02078 } else {
02079 if (add)
02080 ConfValue<T>::m_value |= pos->second;
02081 else
02082 ConfValue<T>::m_value &= ~pos->second;
02083
02084 #if DEBUG
02085 conf.debugf(Conf::dbgProcess,
02086 "%s option %s (0x%08lx) to %s",
02087 (add ? "Added" : "Removed"), name.c_str(),
02088 (long) pos->second, ConfValue<T>::m_name.c_str());
02089 #endif
02090 return true;
02091 }
02092 }
02093
02094 conf.errorf("Invalid option %s for directive %s",
02095 (params[0].empty() ? "\"\"" : params[0].c_str()), ConfValue<T>::m_name.c_str());
02096 return false;
02097 }
02098
02099
02100
02101 template <class T>
02102 char const *ConfSet<T>::label(size_t index) const
02103 {
02104 ConfValue<T>::m_label.clear();
02105
02106 typename BitList::const_iterator it, end;
02107
02108 for (it = m_bits.begin(), end = m_bits.end(); it != end; ++it)
02109 {
02110 if (ConfValue<T>::m_value & it->second)
02111 {
02112 ConfValue<T>::m_label += "\"+";
02113 ConfValue<T>::m_label += it->first;
02114 ConfValue<T>::m_label += "\" ";
02115 }
02116 }
02117
02118 return ConfValue<T>::label(index);
02119 }
02120
02121
02122
02123 template <class T>
02124 bool ConfUint<T>::check(Conf &conf, T const &value) const
02125 {
02126 if ((value < ConfInt<T>::m_minvalue) || (value > ConfInt<T>::m_maxvalue))
02127 {
02128 conf.errorf("Can't set directive %s to %lu: value must be "
02129 "between %lu and %lu", ConfInt<T>::m_name.c_str(),
02130 (unsigned long) value, (unsigned long) ConfInt<T>::m_minvalue,
02131 (unsigned long) ConfInt<T>::m_maxvalue);
02132 return false;
02133 }
02134
02135 return true;
02136 }
02137
02138
02139
02140 template <class T>
02141 bool ConfUint<T>::convert(Conf &conf, std::string const &expr, T &result) const
02142 {
02143 if (expr[0] == '-')
02144 {
02145 conf.errorf("Can't set directive %s to %s: value must be a positive "
02146 "number", ConfInt<T>::m_name.c_str(), expr.c_str());
02147 return false;
02148 }
02149
02150 return ConfInt<T>::convert(conf, expr, result);
02151 }
02152
02153
02154
02155 template <class T>
02156 char const* ConfUint<T>::label(size_t index) const
02157 {
02158 if (ConfValue<T>::m_label.empty())
02159 {
02160 char buf[64];
02161 snprintf(buf, sizeof(buf), "%lu",
02162 (unsigned long) ConfValue<T>::m_value);
02163
02164 ConfValue<T>::m_label = buf;
02165 }
02166
02167 return ConfValue<T>::m_label.c_str();
02168 }
02169
02170
02171
02172 template <class ValueT, class ContainerT>
02173 ConfArray<ValueT, ContainerT> &ConfArray<ValueT, ContainerT>::operator=
02174 (ConfArray<ValueT, ContainerT> const &right)
02175 {
02176 if (&right != this)
02177 {
02178 ConfValue<ContainerT>::operator=(right);
02179
02180 m_max_values = right.m_max_values;
02181 }
02182
02183 return *this;
02184 }
02185
02186
02187
02188 template <class ValueT, class ContainerT>
02189 bool ConfArray<ValueT, ContainerT>::assign(Conf &conf, unsigned short count,
02190 std::string const params[])
02191 {
02192
02193 if (conf.reloading() && !ConfValue<ContainerT>::m_value_set)
02194 ConfValue<ContainerT>::m_value.clear();
02195
02196 if (m_max_values == ConfValue<ContainerT>::m_value.size())
02197 {
02198 conf.errorf("Can't accept more than %ld values for directive %s",
02199 (long) m_max_values, ConfValue<ContainerT>::m_name.c_str());
02200 return false;
02201 }
02202
02203 typename container_type::iterator pos = insert();
02204
02205 if (!pos->begin(conf))
02206 return false;
02207
02208 if (!pos->set(conf, 1, params))
02209 return false;
02210
02211 if (!pos->end(conf))
02212 return false;
02213
02214 return true;
02215 }
02216
02217
02218
02219 template <class ValueT, class ContainerT>
02220 typename ContainerT::iterator ConfArray<ValueT, ContainerT>::insert()
02221 {
02222 using namespace std;
02223
02224 char buf[512];
02225 snprintf(buf, sizeof(buf), "%s[%ld]",
02226 ConfValue<ContainerT>::m_name.c_str(),
02227 (long) ConfValue<ContainerT>::m_value.size());
02228
02229 return ConfValue<ContainerT>::m_value.insert(ConfValue<ContainerT>::m_value.end(), ValueT(buf, ConfValue<ContainerT>::m_reloadable));
02230 }
02231
02232
02233
02234 template <class ValueT, class ContainerT>
02235 char const *ConfArray<ValueT, ContainerT>::label(size_t index) const
02236 {
02237 if (ConfValue<ContainerT>::m_value.size() <= index)
02238 return 0;
02239
02240 ValueT const &dir = ConfValue<ContainerT>::m_value[index];
02241
02242 if (dir.label_count() != 1)
02243 return 0;
02244
02245 return dir.label(0);
02246 }
02247
02248
02249
02250
02251 inline ConfElse &ConfElse::operator=(ConfElse const &right)
02252 {
02253 if (&right != this)
02254 {
02255 ConfDir::operator=(right);
02256
02257 m_process = right.m_process;
02258 }
02259
02260 return *this;
02261 }
02262
02263
02264
02265 }
02266
02267
02268
02269 #endif