2 * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
3 * Copyright (C) 2009 Intel Corporation
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) version 3.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #ifndef INCL_SYNC_EVOLUTION_CONFIG
21 # define INCL_SYNC_EVOLUTION_CONFIG
23 #include <syncevo/FilterConfigNode.h>
24 #include <syncevo/SafeConfigNode.h>
25 #include <syncevo/FileConfigNode.h>
27 #include <boost/shared_ptr.hpp>
28 #include <boost/algorithm/string/predicate.hpp>
29 #include <boost/algorithm/string/trim.hpp>
30 #include <boost/foreach.hpp>
40 #include <syncevo/declarations.h>
45 * @defgroup ConfigHandling Configuration Handling
49 class SyncSourceConfig;
50 typedef SyncSourceConfig PersistentSyncSourceConfig;
52 class ConfigUserInterface;
53 class SyncSourceNodes;
54 class ConstSyncSourceNodes;
56 /** name of the per-source admin data property */
57 extern const char *const SourceAdminDataName;
60 * A property has a name and a comment. Derived classes might have
61 * additional code to read and write the property from/to a
62 * ConfigNode. They might also one or more of the properties
63 * on the fly, therefore the virtual get methods which return a
64 * string value and not just a reference.
66 * A default value is returned if the ConfigNode doesn't have
67 * a value set (= empty string). Invalid values in the configuration
68 * trigger an exception. Setting invalid values does not because
69 * it is not known where the value comes from - the caller should
72 * Properties are either registered as source properties or
73 * source-independent sync properties. In each of these two sets of
74 * properties, the names must be unique.
76 * Properties can be either user-visible (and editable) or
77 * internal. Internal properties are used to cache some information
78 * and may get lost when copying configurations. Therefore it
79 * must be possible to recreate them somehow, if necessary with
80 * an expensive operation like a slow sync.
82 * Starting with SyncEvolution 1.0, the internal storage of
83 * property values was reorganized so that some properties
84 * can be shared between peers. The concept of two property
85 * sets (source and sync properties) was preserved because of
86 * the simplicity that it brings to the APIs. Now this concept
87 * is implemented by mapping properties into "views" that
88 * contain the properties relevant for a particular peer.
89 * Setting a shared value in one view updates the value in
90 * another. For details, see:
91 * http://syncevolution.org/development/configuration-handling
93 * As in the migration from the Sync4j config layout (internal and
94 * user-visible properties in the same file), the code is written so
95 * that properties are mapped to config nodes according to the most
96 * recent layout. Older layouts are accessed by using the same config
97 * node instance multiple times.
99 class ConfigProperty {
101 ConfigProperty(const string &name, const string &comment,
102 const string &def = string(""), const string &descr = string("")) :
105 m_sharing(NO_SHARING),
108 m_comment(boost::trim_right_copy(comment)),
112 virtual ~ConfigProperty() {}
114 virtual string getName() const { return m_name; }
115 virtual string getComment() const { return m_comment; }
116 virtual string getDefValue() const { return m_defValue; }
117 virtual string getDescr() const { return m_descr; }
120 * Check whether the given value is okay.
121 * If not, then set an error string (one line, no punctuation).
123 * @return true if value is okay
125 virtual bool checkValue(const string &value, string &error) const { return true; }
128 * Only useful when a config property wants to check itself whether to retrieve password
129 * Check the password and cache the result in the filter node on the fly if a property needs.
130 * sourceName and sourceConfigNode might be not set by caller. They only affect
131 * when checking password for syncsourceconfig
132 * @param ui user interface
133 * @param serverName server name
134 * @param globalConfigNode the sync global config node for a server
135 * @param sourceName the source name used for source config properties
136 * @param sourceConfigNode the config node for the source
138 virtual void checkPassword(ConfigUserInterface &ui,
139 const string &serverName,
140 FilterConfigNode &globalConfigNode,
141 const string &sourceName = string(),
142 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode = boost::shared_ptr<FilterConfigNode>()) const {}
145 * Try to save password if a config property wants.
146 * It firstly check password and then invoke ui's savePassword
147 * function to save the password if necessary
149 virtual void savePassword(ConfigUserInterface &ui,
150 const string &serverName,
151 FilterConfigNode &globalConfigNode,
152 const string &sourceName = string(),
153 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode = boost::shared_ptr<FilterConfigNode>()) const {}
156 * This is used to generate description dynamically according to the context information
157 * Defalut implmenentation is to return value set in the constructor.
158 * Derived classes can override this function. Used by 'checkPassword' and 'savePassword'
159 * to generate description for user interface.
161 virtual const string getDescr(const string &serverName,
162 FilterConfigNode &globalConfigNode,
163 const string &sourceName = string(),
164 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode=boost::shared_ptr<FilterConfigNode>()) const { return m_descr; }
167 /** split \n separated comment into lines without \n, appending them to commentLines */
168 static void splitComment(const string &comment, list<string> &commentLines);
170 /** internal property? */
171 bool isHidden() const { return m_hidden; }
172 void setHidden(bool hidden) { m_hidden = hidden; }
174 /** config is invalid without setting this property? */
175 bool isObligatory() const { return m_obligatory; }
176 void setObligatory(bool obligatory) { m_obligatory = obligatory; }
179 * determines how a property is shared between different views
182 GLOBAL_SHARING, /**< shared between all views,
183 for example the "default peer" property */
184 SOURCE_SET_SHARING, /**< shared between all peers accessing
185 the same source set, for example the
187 NO_SHARING /**< each peer has his own values */
189 Sharing getSharing() const { return m_sharing; }
190 void setSharing(Sharing sharing) { m_sharing = sharing; }
193 * special hacks for certain properties
196 SHARED_AND_UNSHARED = 1<<0 /**< value is stored with
197 SOURCE_SET_SHARING and
198 NO_SHARING, the later taking
199 precedency when reading
202 void setFlags(int flags) { m_flags = flags; }
203 int getFlags(void) const { return m_flags; }
205 /** set value unconditionally, even if it is not valid */
206 void setProperty(ConfigNode &node, const string &value) const { node.setProperty(getName(), value, getComment()); }
207 void setProperty(FilterConfigNode &node, const string &value, bool temporarily = false) const {
209 node.addFilter(m_name, value);
211 node.setProperty(m_name, value, getComment());
215 /** set default value of a property, marked as default unless forced setting */
216 void setDefaultProperty(ConfigNode &node, bool force) const {
217 string defValue = getDefValue();
218 node.setProperty(m_name, defValue, getComment(), force ? NULL : &defValue);
222 * String representation of property value. getPropertyValue() in
223 * some derived classes returns the value in some other, class specific
226 * @retval isDefault return true if the node had no value set and
227 * the default was returned instead
229 virtual string getProperty(const ConfigNode &node, bool *isDefault = NULL) const {
230 string name = getName();
231 string value = node.readProperty(name);
232 if (!value.empty()) {
234 if (!checkValue(value, error)) {
235 throwValueError(node, name, value, error);
245 return getDefValue();
249 // true if property is set to non-empty value
250 bool isSet(const ConfigNode &node) const {
251 string name = getName();
252 string value = node.readProperty(name);
253 return !value.empty();
257 void throwValueError(const ConfigNode &node, const string &name, const string &value, const string &error) const;
264 const string m_name, m_comment, m_defValue, m_descr;
267 template<class T> class InitList : public list<T> {
270 InitList(const T &initialValue) {
271 push_back(initialValue);
273 InitList &operator + (const T &rhs) {
277 InitList &operator += (const T &rhs) {
282 typedef InitList<string> Aliases;
283 typedef InitList<Aliases> Values;
287 * A string property which maps multiple different possible value
288 * strings to one generic value, ignoring the case. Values not listed
289 * are passed through unchanged. The first value in the list of
290 * aliases is the generic one.
292 * The addition operator is defined for the aliases so that they
293 * can be constructed more easily.
295 class StringConfigProperty : public ConfigProperty {
297 StringConfigProperty(const string &name, const string &comment,
298 const string &def = string(""),
299 const string &descr = string(""),
300 const Values &values = Values()) :
301 ConfigProperty(name, comment, def, descr),
306 * @return false if aliases are defined and the string is not one of them
308 bool normalizeValue(string &res) const {
309 Values values = getValues();
310 BOOST_FOREACH(const Values::value_type &value, values) {
311 BOOST_FOREACH(const string &alias, value) {
312 if (boost::iequals(res, alias)) {
313 res = *value.begin();
318 return values.empty();
322 * This implementation accepts all values if no aliases
323 * are given, otherwise the value must be part of the aliases.
325 virtual bool checkValue(const string &propValue, string &error) const {
326 Values values = getValues();
327 if (values.empty()) {
332 err << "not one of the valid values (";
333 bool firstval = true;
334 BOOST_FOREACH(const Values::value_type &value, values) {
340 bool firstalias = true;
341 BOOST_FOREACH(const string &alias, value) {
353 if (boost::iequals(propValue, alias)) {
363 virtual string getProperty(const ConfigNode &node, bool *isDefault = NULL) const {
364 string res = ConfigProperty::getProperty(node, isDefault);
370 virtual Values getValues() const { return m_values; }
373 const Values m_values;
378 * Instead of reading and writing strings, this class interprets the content
379 * as a specific type.
381 template<class T> class TypedConfigProperty : public ConfigProperty {
383 TypedConfigProperty(const string &name, const string &comment, const string &defValue = string("0"), const string &descr = string("")) :
384 ConfigProperty(name, comment, defValue, descr)
388 * This implementation accepts all values that can be converted
389 * to the required type.
391 virtual bool checkValue(const string &value, string &error) const {
392 istringstream in(value);
397 error = "cannot parse value";
402 void setProperty(ConfigNode &node, const T &value) const {
406 node.setProperty(getName(), out.str(), getComment());
408 void setProperty(FilterConfigNode &node, const T &value, bool temporarily = false) const {
413 node.addFilter(getName(), out.str());
415 node.setProperty(getName(), out.str(), getComment());
419 T getPropertyValue(const ConfigNode &node, bool *isDefault = NULL) const {
420 string name = getName();
421 string value = node.readProperty(name);
422 istringstream in(value);
425 istringstream defStream(getDefValue());
433 throwValueError(node, name, value, "cannot parse value");
444 * The "in >> res" check in TypedConfigProperty::checkValue
445 * is to loose. For example, the standard library accepts
446 * -1 for an unsigned type.
448 * This class accepts a function pointer to strtoul() or
449 * strtol() and uses that function to do strict value checking.
451 * @param T type to be converted to and from (like int)
452 * @param Tmin minimum value of T for range checking
453 * @param Tmax maximum value of T for range checking
454 * @param C intermediate type for conversion (like long)
455 * @param Cmin minimum value of C for range checking
456 * @param Cmax maximum value of C for range checking
457 * @param strto conversion function
459 template <class T, T Tmin, T Tmax,
460 class C, C Cmin, C Cmax,
461 C (*strto)(const char *, char **, int)>
462 class ScalarConfigProperty : public TypedConfigProperty<T>
465 ScalarConfigProperty(const string &name, const string &comment, const string &defValue = string("0"), const string &descr = string("")) :
466 TypedConfigProperty<T>(name, comment, defValue, descr)
469 virtual bool checkValue(const string &value, string &error) const {
471 const char *nptr = value.c_str();
473 // use base 10 because not specifying a base
474 // would interpret 077 as octal value, which
475 // could be confusing for users
476 C val = strto(nptr, &endptr, 10);
477 if ((errno == ERANGE && (val == Cmin || val == Cmax))) {
478 error = "range error";
481 if (errno != 0 && val == 0) {
482 error = "cannot parse";
485 if (endptr == nptr) {
486 error = "decimal value expected";
489 while (isspace(*endptr)) {
492 if (*endptr != '\0') {
493 error = "unexpected trailing non-whitespace characters: ";
497 if (val > Tmax || val < Tmin) {
498 error = "range error";
502 // check that we didn't accidentally accept a negative value,
503 // strtoul() does that
504 const char *start = nptr;
505 while (*start && isspace(*start)) {
509 error = "range error";
518 typedef ScalarConfigProperty<int, INT_MIN, INT_MAX, long, LONG_MIN, LONG_MAX, strtol> IntConfigProperty;
519 typedef ScalarConfigProperty<unsigned int, 0, UINT_MAX, unsigned long, 0, ULONG_MAX, strtoul> UIntConfigProperty;
520 typedef ScalarConfigProperty<long, LONG_MIN, LONG_MAX, long, LONG_MIN, LONG_MAX, strtol> LongConfigProperty;
521 typedef ScalarConfigProperty<unsigned long, 0, ULONG_MAX, unsigned long, 0, ULONG_MAX, strtoul> ULongConfigProperty;
524 * This struct wraps keys for storing passwords
525 * in configuration system. Some fields might be empty
526 * for some passwords. Each field might have different
527 * meaning for each password. Fields using depends on
528 * what user actually wants.
530 struct ConfigPasswordKey {
532 ConfigPasswordKey() : port(0) {}
534 /** the user for the password */
536 /** the server for the password */
538 /** the domain name */
540 /** the remote object */
542 /** the network protocol */
544 /** the authentication type */
546 /** the network port */
551 * This interface has to be provided by the user of the config
552 * to let the config code interact with the user.
554 class ConfigUserInterface {
556 virtual ~ConfigUserInterface() {}
559 * A helper function which interactively asks the user for
560 * a certain password. May throw errors.
562 * @param passwordName the name of the password in the config file, such as 'proxyPassword'
563 * @param descr A simple string explaining what the password is needed for,
564 * e.g. "SyncML server". This string alone has to be enough
565 * for the user to know what the password is for, i.e. the
566 * string has to be unique.
567 * @param key the key used to retrieve password. Using this instead of ConfigNode is
568 * to make user interface independent on Configuration Tree
569 * @return entered password
571 virtual string askPassword(const string &passwordName, const string &descr, const ConfigPasswordKey &key) = 0;
574 * A helper function which is used for user interface to save
575 * a certain password. Currently possibly syncml server. May
577 * @param passwordName the name of the password in the config file, such as 'proxyPassword'
578 * @param password password to be saved
579 * @param key the key used to store password
580 * @return true if ui saves the password and false if not
582 virtual bool savePassword(const string &passwordName, const string &password, const ConfigPasswordKey &key) = 0;
585 class PasswordConfigProperty : public ConfigProperty {
587 PasswordConfigProperty(const string &name, const string &comment, const string &def = string(""),const string &descr = string("")) :
588 ConfigProperty(name, comment, def, descr)
592 * Check the password and cache the result.
594 virtual void checkPassword(ConfigUserInterface &ui,
595 const string &serverName,
596 FilterConfigNode &globalConfigNode,
597 const string &sourceName = "",
598 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode =
599 boost::shared_ptr<FilterConfigNode>()) const;
602 * It firstly check password and then invoke ui's savePassword
603 * function to save the password if necessary
605 virtual void savePassword(ConfigUserInterface &ui,
606 const string &serverName,
607 FilterConfigNode &globalConfigNode,
608 const string &sourceName = "",
609 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode =
610 boost::shared_ptr<FilterConfigNode>()) const;
613 * Get password key for storing or retrieving passwords
614 * The default implemention is for 'password' in global config.
615 * @param descr decription for password
616 * @param globalConfigNode the global config node
617 * @param sourceConfigNode the source config node. It might be empty
619 virtual ConfigPasswordKey getPasswordKey(const string &descr,
620 const string &serverName,
621 FilterConfigNode &globalConfigNode,
622 const string &sourceName = string(),
623 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode =
624 boost::shared_ptr<FilterConfigNode>()) const;
627 * return the cached value if necessary and possible
629 virtual string getCachedProperty(const ConfigNode &node,
630 const string &cachedPassword);
634 * A derived ConfigProperty class for the property "proxyPassword"
636 class ProxyPasswordConfigProperty : public PasswordConfigProperty {
638 ProxyPasswordConfigProperty(const string &name, const string &comment, const string &def = string(""), const string &descr = string("")) :
639 PasswordConfigProperty(name,comment,def,descr)
642 * re-implement this function for it is necessary to do a check
643 * before retrieving proxy password
645 virtual void checkPassword(ConfigUserInterface &ui,
646 const string &serverName,
647 FilterConfigNode &globalConfigNode,
648 const string &sourceName,
649 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode) const;
650 virtual ConfigPasswordKey getPasswordKey(const string &descr,
651 const string &serverName,
652 FilterConfigNode &globalConfigNode,
653 const string &sourceName = string(),
654 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode=boost::shared_ptr<FilterConfigNode>()) const;
658 * A derived ConfigProperty class for the property "evolutionpassword"
660 class EvolutionPasswordConfigProperty : public PasswordConfigProperty {
662 EvolutionPasswordConfigProperty(const string &name,
663 const string &comment,
664 const string &def = string(""),
665 const string &descr = string("")):
666 PasswordConfigProperty(name,comment,def,descr)
668 virtual ConfigPasswordKey getPasswordKey(const string &descr,
669 const string &serverName,
670 FilterConfigNode &globalConfigNode,
671 const string &sourceName = string(),
672 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode=boost::shared_ptr<FilterConfigNode>()) const;
673 virtual const string getDescr(const string &serverName,
674 FilterConfigNode &globalConfigNode,
675 const string &sourceName,
676 const boost::shared_ptr<FilterConfigNode> &sourceConfigNode) const {
677 string descr = sourceName;
679 descr += ConfigProperty::getDescr();
685 * Instead of reading and writing strings, this class interprets the content
686 * as boolean with T/F or 1/0 (default format).
688 class BoolConfigProperty : public StringConfigProperty {
690 BoolConfigProperty(const string &name, const string &comment, const string &defValue = string("F"),const string &descr = string("")) :
691 StringConfigProperty(name, comment, defValue,descr,
692 Values() + (Aliases("1") + "T" + "TRUE") + (Aliases("0") + "F" + "FALSE"))
695 void setProperty(ConfigNode &node, bool value) {
696 StringConfigProperty::setProperty(node, value ? "1" : "0");
698 void setProperty(FilterConfigNode &node, bool value, bool temporarily = false) {
699 StringConfigProperty::setProperty(node, value ? "1" : "0", temporarily);
701 int getPropertyValue(const ConfigNode &node, bool *isDefault = NULL) const {
702 string res = ConfigProperty::getProperty(node, isDefault);
704 return boost::iequals(res, "T") ||
705 boost::iequals(res, "TRUE") ||
706 atoi(res.c_str()) != 0;
711 * A property for arbitrary strings.
713 class SafeConfigProperty : public ConfigProperty {
715 SafeConfigProperty(const string &name, const string &comment) :
716 ConfigProperty(name, comment)
719 void setProperty(ConfigNode &node, const string &value) {
720 ConfigProperty::setProperty(node, SafeConfigNode::escape(value, true, false));
722 virtual string getProperty(const ConfigNode &node, bool *isDefault = NULL) const {
723 string res = ConfigProperty::getProperty(node, isDefault);
724 res = SafeConfigNode::unescape(res);
730 * A registry for all properties which might be saved in the same ConfigNode.
731 * Currently the same as a simple list. Someone else owns the instances.
733 class ConfigPropertyRegistry : public list<const ConfigProperty *> {
735 /** case-insensitive search for property */
736 const ConfigProperty *find(const string &propName) const {
737 BOOST_FOREACH(const ConfigProperty *prop, *this) {
738 if (boost::iequals(prop->getName(), propName)) {
747 * Store the current string value of a property in a cache
748 * and return the "const char *" pointer that is expected by
749 * the client library.
751 class ConfigStringCache {
753 const char *getProperty(const ConfigNode &node, const ConfigProperty &prop) {
754 string value = prop.getProperty(node);
755 return storeString(prop.getName(), value);
758 const char *storeString(const string &key, const string &value) {
759 const string &entry = m_cache[key] = value;
760 return entry.c_str();
764 map<string, string> m_cache;
768 * This class implements the client library configuration interface
769 * by mapping values to properties to entries in a ConfigTree. The
770 * mapping is either the traditional one used by SyncEvolution <= 0.7
771 * and client library <= 6.5 or the new layout introduced with
772 * SyncEvolution >= 0.8. If for a given server name the old config
773 * exists, then it is used. Otherwise the new layout is used.
775 * This class can be instantiated on its own and then provides access
776 * to properties actually stored in files. SyncContext
777 * inherits from this class so that a derived client has the chance to
778 * override every single property (although it doesn't have to).
779 * Likewise SyncSource is derived from
782 * Properties can be set permanently (this changes the underlying
783 * ConfigNode) and temporarily (this modifies the FilterConfigNode
784 * which wraps the ConfigNode).
787 * - $HOME/.sync4j/evolution/<server>/spds/syncml/config.txt
788 * -- spds/sources/<source>/config.txt
789 * --- changes_<changeid>/config.txt
792 * - ${XDG_CONFIG:-${HOME}/.config}/syncevolution/foo - base directory for server foo
793 * -- config.ini - constant per-server settings
794 * -- .internal.ini - read/write server properties - hidden from users because of the leading dot
795 * -- sources/bar - base directory for source bar
796 * --- config.ini - constant per-source settings
797 * --- .internal.ini - read/write source properties
798 * --- .changes_<changeid>.ini - change tracking node (content under control of sync source)
800 * Because this class needs to handle different file layouts it always
801 * uses a FileConfigTree instance. Other implementations would be
807 * Opens the configuration for a specific server,
808 * searching for the config files in the usual
809 * places. Will succeed even if config does not
810 * yet exist: flushing such a config creates it.
812 * @param peer string that identifies the peer,
813 * matching regex (.*)(@([^@]*))?
814 * where the $1 (the first part) is
815 * the peer name and the optional $2
816 * (the part after the last @) is the
817 * context, "default" if not given.
818 * For example "scheduleworld" =
820 * "scheduleworld@default", but not the same as
821 * "scheduleworld@other_context"
823 * @param tree if non-NULL, then this is used
824 * as configuration tree instead of
825 * searching for it; always uses the
826 * current layout in that tree
828 SyncConfig(const string &peer,
829 boost::shared_ptr<ConfigTree> tree = boost::shared_ptr<ConfigTree>());
832 * Creates a temporary configuration.
833 * Can be copied around, but not flushed.
837 /** absolute directory name of the configuration root */
838 string getRootPath() const;
840 typedef list< std::pair<std::string, std::string> > ConfigList;
842 /** A simple description of the template or the configuration based on a
843 * template. The rank field is used to indicate how good it matches the
844 * user input <MacAddress, DeviceName> */
845 struct TemplateDescription {
846 // The name of the template
848 // The description of the template (eg. the web server URL for a
849 // SyncML server. This is not used for UI, only CMD line used this.
850 std::string m_description;
851 // The matched percentage of the template, larger the better.
854 //a unique identity of the device that the template is for, used by caller
857 // A string identify which fingerprint the template is matched with.
858 std::string m_fingerprint;
860 // A unique string identify the template path, so that a later operation
861 // fetching this config will be much easier
864 // A string indicates the original fingerprint in the matched template, this
865 // will not necessarily the same with m_fingerprint
866 std::string m_matchedModel;
868 TemplateDescription (const std::string &name, const std::string &description,
869 const int rank, const std::string id, const std::string &fingerprint, const std::string &path, const std::string &model)
871 m_description (description),
874 m_fingerprint (fingerprint),
876 m_matchedModel(model)
880 TemplateDescription (const std::string &name, const std::string &description);
882 static bool compare_op (boost::shared_ptr<TemplateDescription> &left, boost::shared_ptr<TemplateDescription> &right);
886 /*Match templates when we work as SyncML server, i.e. the peer is the client*/
887 MATCH_FOR_SERVER_MODE,
888 /*Match templates when work as SyncML client, i.e. the peer is the server*/
889 MATCH_FOR_CLIENT_MODE,
890 /*Match templates for both SyncML server and SyncML client*/
895 typedef list<boost::shared_ptr <TemplateDescription> > TemplateList;
897 struct DeviceDescription {
898 /** the id of the device */
899 std::string m_deviceId;
900 /** the finger print of the device used for matching templates */
901 std::string m_fingerprint;
902 /** match mode used for matching templates */
903 MatchMode m_matchMode;
904 DeviceDescription(const std::string &deviceId,
905 const std::string &fingerprint,
907 :m_deviceId(deviceId), m_fingerprint(fingerprint), m_matchMode(mode)
909 DeviceDescription() : m_matchMode(INVALID)
913 typedef list<DeviceDescription> DeviceList;
916 * returns list of servers in either the old (.sync4j) or
917 * new config directory (.config), given as server name
918 * and absolute root of config
920 static ConfigList getConfigs();
923 * returns list of available config templates:
924 * for each peer listed in @peers, matching against the fingerprint information
925 * from the peer (deviceName likely), sorted by the matching score,
926 * templates failed to match(as long as it's for SyncML server) will also
927 * be returned as a fallback mechanism so that user can select a configuration
929 * Any templates for SyncMl Client is also returned, with a default rank.
930 * The assumption currently is only work for SyncML client peers.
931 * DeviceList is a list of matching tuples <fingerprint, SyncConfig::MatchMode>.
933 static TemplateList getPeerTemplates(const DeviceList &peers);
936 * match the built-in templates against @param fingerprint, return a list of
937 * servers sorted by the matching rank.
939 static TemplateList matchPeerTemplates(const DeviceList &peers, bool fuzzyMatch = true);
942 * get the built-in default templates
944 static TemplateList getBuiltInTemplates ();
947 * Creates a new instance of a configuration template.
948 * The result can be modified to set filters, but it
951 * @param peer a configuration name, *without* a context (scheduleworld, not scheduleworld@default),
952 * or a configuration path in the system directory which can avoid another fuzzy match process.
953 * @return NULL if no such template
955 static boost::shared_ptr<SyncConfig> createPeerTemplate(const string &peer);
957 /** true if the main configuration file already exists */
961 * The normalized, unique config name used by this instance.
962 * Empty if not backed up by a real config.
964 string getConfigName() const { return m_peer; }
967 * Do something before doing flush to files. This is particularly
968 * useful when user interface wants to do preparation jobs, such
969 * as savePassword and others.
971 virtual void preFlush(ConfigUserInterface &ui);
976 * Remove the configuration. Config directories are removed if
979 * When the configuration is peer-specific, only the peer's
980 * properties and config nodes are removed. Otherwise the complete
981 * configuration is removed, including all peers.
983 * Does *not* remove logs associated with the configuration.
984 * For that use the logdir handling in SyncContext
985 * before removing the configuration.
990 * A list of all properties. Can be extended by derived clients.
992 static ConfigPropertyRegistry &getRegistry();
995 * Normalize a config string:
997 * - non-printable and unsafe characters (colon, slash, backslash)
998 * replaced by underscore
999 * - when no context specified: search for peer config first in @default,
1000 * then also in other contexts in alphabetical order
1001 * - @default stripped
1002 * - empty string replaced with "@default"
1004 static string normalizeConfigString(const string &config);
1007 * Split a config string (normalized or not) into the peer part
1008 * (before final @) and the context (after that @, not including
1009 * it), return "default" as context if not specified otherwise.
1011 static void splitConfigString(const string &config, string &peer, string &context);
1014 * Replaces the property filter of either the sync properties or
1015 * all sources. This can be used to e.g. temporarily override
1016 * the active sync mode.
1018 * @param sync true if the filter applies to sync properties,
1019 * false if it applies to sources
1020 * @param source empty string if filter applies to all sources,
1021 * otherwise the source name to which it applies
1022 * @param filter key (case insensitive)/value pairs of properties
1023 * which are to be overridden
1025 void setConfigFilter(bool sync,
1026 const std::string &source,
1027 const FilterConfigNode::ConfigFilter &filter);
1030 * Read-write access to all configurable properties of the server.
1031 * The visible properties are passed through the config filter,
1032 * which can be modified.
1034 boost::shared_ptr<FilterConfigNode> getProperties(bool hidden = false) { return m_props[hidden]; }
1035 boost::shared_ptr<const FilterConfigNode> getProperties(bool hidden = false) const { return const_cast<SyncConfig *>(this)->getProperties(hidden); }
1038 * Returns the right config node for a certain property,
1039 * depending on visibility and sharing.
1041 boost::shared_ptr<FilterConfigNode> getNode(const ConfigProperty &prop);
1042 boost::shared_ptr<const FilterConfigNode> getNode(const ConfigProperty &prop) const
1044 return const_cast<SyncConfig *>(this)->getNode(prop);
1048 * Returns a wrapper around all properties of the given source
1049 * which are saved in the config tree. Note that this is different
1050 * from the set of sync source configs used by the SyncManager:
1051 * the SyncManger uses the AbstractSyncSourceConfig. In
1052 * SyncEvolution those are implemented by the
1053 * SyncSource's actually instantiated by
1054 * SyncContext. Those are complete whereas
1055 * PersistentSyncSourceConfig only provides access to a
1056 * subset of the properties.
1058 * Can be called for sources which do not exist yet.
1060 virtual boost::shared_ptr<PersistentSyncSourceConfig> getSyncSourceConfig(const string &name);
1061 virtual boost::shared_ptr<const PersistentSyncSourceConfig> getSyncSourceConfig(const string &name) const {
1062 return const_cast<SyncConfig *>(this)->getSyncSourceConfig(name);
1066 * Returns list of all configured (not active!) sync sources.
1068 virtual list<string> getSyncSources() const;
1071 * Creates config nodes for a certain node. The nodes are not
1072 * yet created in the backend if they do not yet exist.
1074 * @param name the name of the sync source
1075 * @param trackName additional part of the tracking node name (used for unit testing)
1077 SyncSourceNodes getSyncSourceNodes(const string &name,
1078 const string &trackName = "");
1079 ConstSyncSourceNodes getSyncSourceNodes(const string &name,
1080 const string &trackName = "") const;
1083 * initialize all properties with their default value
1085 void setDefaults(bool force = true);
1088 * create a new sync source configuration with default values
1090 void setSourceDefaults(const string &name, bool force = true);
1093 * Remove sync source configuration. And remove the directory
1094 * if it has no other files.
1096 * When the configuration is peer-specific, only the peer's
1097 * properties are removed. Otherwise the complete source
1098 * configuration is removed, including properties stored
1099 * for in any of the peers.
1101 void removeSyncSource(const string &name);
1104 * clear existing visible source properties selected by the
1105 * configuration: with or without peer-specific properties,
1106 * depending on the current view
1108 void clearSyncSourceProperties(const string &name);
1111 * clear all global sync properties, with or without
1112 * peer-specific properties, depending on the current view
1114 void clearSyncProperties();
1117 * Copy all registered properties (hidden and visible) and the
1118 * tracking node into the current config. This is done by reading
1119 * all properties from the source config, which implies the unset
1120 * properties will be set to their default values. The current
1121 * config is not cleared so additional, unregistered properties
1122 * (should they exist) will continue to exist unchanged.
1124 * The current config still needs to be flushed to make the
1125 * changes permanent.
1127 * @param sources if NULL, then copy all sources; if not NULL,
1128 * then copy exactly the sources listed here
1129 * (regardless whether they exist or not)
1131 void copy(const SyncConfig &other,
1132 const set<string> *sources);
1135 * @name Settings specific to SyncEvolution
1137 * See the property definitions in SyncConfig.cpp
1138 * for the user-visible explanations of
1143 virtual string getDefaultPeer() const;
1144 virtual void setDefaultPeer(const string &value);
1146 virtual const char *getLogDir() const;
1147 virtual void setLogDir(const string &value, bool temporarily = false);
1149 virtual int getMaxLogDirs() const;
1150 virtual void setMaxLogDirs(int value, bool temporarily = false);
1152 virtual int getLogLevel() const;
1153 virtual void setLogLevel(int value, bool temporarily = false);
1155 virtual bool getPrintChanges() const;
1156 virtual void setPrintChanges(bool value, bool temporarily = false);
1158 virtual std::string getWebURL() const;
1159 virtual void setWebURL(const std::string &url, bool temporarily = false);
1161 virtual std::string getIconURI() const;
1162 virtual void setIconURI(const std::string &uri, bool temporarily = false);
1165 * A property of server template configs. True if the server is
1166 * ready for use by "normal" users (everyone can get an account
1167 * and some kind of support, we have tested the server well
1170 virtual bool getConsumerReady() const;
1171 virtual void setConsumerReady(bool ready);
1173 virtual unsigned long getHashCode() const;
1174 virtual void setHashCode(unsigned long hashCode);
1176 virtual std::string getConfigDate() const;
1177 virtual void setConfigDate(); /* set current time always */
1182 * @name Settings inherited from Funambol
1184 * These settings are required by the Funambol C++ client library.
1185 * Some of them are hard-coded in this class. A derived class could
1186 * make them configurable again, should that be desired.
1190 virtual const char* getUsername() const;
1191 virtual void setUsername(const string &value, bool temporarily = false);
1192 virtual const char* getPassword() const;
1193 virtual void setPassword(const string &value, bool temporarily = false);
1196 * Look at the password setting and if it requires user interaction,
1197 * get it from the user. Then store it for later usage in getPassword().
1198 * Without this call, getPassword() returns the original, unmodified
1201 virtual void checkPassword(ConfigUserInterface &ui);
1204 * Look at the password setting and if it needs special mechanism to
1205 * save password, this function is used to store specified password
1206 * in the config tree.
1207 * @param ui the ui pointer
1209 virtual void savePassword(ConfigUserInterface &ui);
1211 virtual bool getPreventSlowSync() const;
1212 virtual void setPreventSlowSync(bool value, bool temporarily = false);
1213 virtual bool getUseProxy() const;
1214 virtual void setUseProxy(bool value, bool temporarily = false);
1215 virtual const char* getProxyHost() const;
1216 virtual void setProxyHost(const string &value, bool temporarily = false);
1217 virtual int getProxyPort() const { return 0; }
1218 virtual const char* getProxyUsername() const;
1219 virtual void setProxyUsername(const string &value, bool temporarily = false);
1220 virtual const char* getProxyPassword() const;
1221 virtual void checkProxyPassword(ConfigUserInterface &ui);
1222 virtual void saveProxyPassword(ConfigUserInterface &ui);
1223 virtual void setProxyPassword(const string &value, bool temporarily = false);
1224 virtual vector<string> getSyncURL() const;
1225 virtual void setSyncURL(const string &value, bool temporarily = false);
1226 virtual void setSyncURL(const vector<string> &value, bool temporarily = false);
1227 virtual const char* getClientAuthType() const;
1228 virtual void setClientAuthType(const string &value, bool temporarily = false);
1229 virtual unsigned long getMaxMsgSize() const;
1230 virtual void setMaxMsgSize(unsigned long value, bool temporarily = false);
1231 virtual unsigned int getMaxObjSize() const;
1232 virtual void setMaxObjSize(unsigned int value, bool temporarily = false);
1233 virtual unsigned long getReadBufferSize() const { return 0; }
1234 virtual const char* getSSLServerCertificates() const;
1237 * iterate over files mentioned in getSSLServerCertificates()
1238 * and return name of first one which is found, empty string
1241 std::string findSSLServerCertificate();
1243 virtual void setSSLServerCertificates(const string &value, bool temporarily = false);
1244 virtual bool getSSLVerifyServer() const;
1245 virtual void setSSLVerifyServer(bool value, bool temporarily = false);
1246 virtual bool getSSLVerifyHost() const;
1247 virtual void setSSLVerifyHost(bool value, bool temporarily = false);
1248 virtual int getRetryInterval() const;
1249 virtual void setRetryInterval(int value, bool temporarily = false);
1250 virtual int getRetryDuration() const;
1251 virtual void setRetryDuration(int value, bool temporarily = false);
1252 virtual bool getCompression() const;
1253 virtual void setCompression(bool value, bool temporarily = false);
1254 virtual unsigned int getResponseTimeout() const { return 0; }
1255 virtual const char* getDevID() const;
1256 virtual void setDevID(const string &value, bool temporarily = false);
1258 /*Used for Server Alerted Sync*/
1259 virtual const char* getRemoteIdentifier() const;
1260 virtual void setRemoteIdentifier (const string &value, bool temporaritly = false);
1261 virtual bool getPeerIsClient () const;
1262 virtual void setPeerIsClient (bool value, bool temporarily = false);
1265 * An arbitrary name assigned to the peer configuration,
1266 * not necessarily unique. Can be used by a GUI instead
1267 * of the config name.
1269 virtual string getPeerName() const;
1270 virtual void setPeerName(const string &name);
1273 * The Device ID of our peer. Typically only relevant when the
1274 * peer is a client. Servers don't have a Device ID, just some
1275 * unique way of contacting them.
1277 virtual string getRemoteDevID() const;
1278 virtual void setRemoteDevID(const string &value);
1281 * The opaque nonce value stored for a peer, required for MD5
1282 * authentication. Only used when acting as server.
1284 virtual string getNonce() const;
1285 virtual void setNonce(const string &value);
1288 * The opaque per-peer admin data managed by the Synthesis
1289 * engine. Only used when acting as server.
1291 virtual string getDeviceData() const;
1292 virtual void setDeviceData(const string &value);
1295 * Specifies whether WBXML is to be used (default).
1296 * Otherwise XML is used.
1298 virtual bool getWBXML() const;
1299 virtual void setWBXML(bool isWBXML, bool temporarily = false);
1301 virtual const char* getUserAgent() const { return "SyncEvolution"; }
1302 virtual const char* getMan() const { return "Patrick Ohly"; }
1303 virtual const char* getMod() const { return "SyncEvolution"; }
1304 virtual const char* getOem() const { return "Open Source"; }
1305 virtual const char* getHwv() const { return "unknown"; }
1306 virtual const char* getSwv() const;
1307 virtual const char* getDevType() const;
1312 SYNC4J_LAYOUT, /**< .syncj4/evolution/<server>, SyncEvolution <= 0.7.x */
1313 HTTP_SERVER_LAYOUT, /**< .config/syncevolution/<server> with sources
1314 underneath, SyncEvolution <= 0.9.x */
1315 SHARED_LAYOUT /**< .config/syncevolution/<context> containing sources
1316 and peers, with source settings shared by peers,
1317 SyncEvolution >= 1.0 */
1321 * scans for peer configurations
1322 * @param root absolute directory path
1323 * @param configname expected name of config files (config.ini or config.txt)
1324 * @retval res filled with new peer configurations found
1326 static void addPeers(const string &root,
1327 const std::string &configname,
1328 SyncConfig::ConfigList &res);
1331 * set tree and nodes to VolatileConfigTree/Node
1333 void makeVolatile();
1336 * String that identifies the peer, see constructor.
1337 * This is a normalized string (normalizePeerString()).
1338 * The name is a bit of a misnomer, because the config
1339 * might also reference just a context without any
1340 * peer-specific properties ("@some-context", or "@default").
1345 * Lower case path to peer configuration,
1346 * relative to configuration tree root.
1347 * For example "scheduleworld" for "ScheduleWorld" when
1348 * using the old config layouts, "default/peers/scheduleworld"
1349 * in the new layout.
1351 * Empty if configuration view has no peer-specific properties.
1356 * lower case path to source set properties,
1357 * unused for old layouts, else something like
1358 * "default" or "other_context"
1360 string m_contextPath;
1363 string m_cachedPassword;
1364 string m_cachedProxyPassword;
1366 /** holds all config nodes relative to the root that we found */
1367 boost::shared_ptr<ConfigTree> m_tree;
1369 /** access to global sync properties, independent of
1370 the context (for example, "defaultPeer") */
1371 boost::shared_ptr<FilterConfigNode> m_globalNode;
1373 /** access to properties shared between peers */
1374 boost::shared_ptr<FilterConfigNode> m_contextNode;
1375 boost::shared_ptr<ConfigNode> m_contextHiddenNode;
1377 /** access to properties specific to a peer */
1378 boost::shared_ptr<FilterConfigNode> m_peerNode;
1379 boost::shared_ptr<ConfigNode> m_hiddenPeerNode;
1381 /** multiplexer for the other config nodes */
1382 boost::shared_ptr<FilterConfigNode> m_props[2];
1385 * temporary override for all sync source settings
1387 FilterConfigNode::ConfigFilter m_sourceFilter;
1389 /** temporary override for settings of specific sources */
1390 typedef std::map<std::string, FilterConfigNode::ConfigFilter> SourceFilters_t;
1391 SourceFilters_t m_sourceFilters;
1393 mutable ConfigStringCache m_stringCache;
1395 static string getOldRoot() {
1396 return getHome() + "/.sync4j/evolution";
1399 static string getNewRoot() {
1400 const char *xdg_root_str = getenv("XDG_CONFIG_HOME");
1401 return xdg_root_str ? string(xdg_root_str) + "/syncevolution" :
1402 getHome() + "/.config/syncevolution";
1408 * This set of config nodes is to be used by SyncSourceConfig
1409 * to accesss properties. Note that "const SyncSourceNodes"
1410 * only implies that the nodes cannot be changed; the properties
1411 * are still read- and writable. ConstSyncSourceNodes grants
1412 * only read access to properties.
1414 class SyncSourceNodes {
1416 SyncSourceNodes() {}
1419 * @param sharedNode node for user-visible properties, shared between peers
1420 * @param peerNode node for user-visible, per-peer properties (the same
1421 * as sharedNode in SYNC4J_LAYOUT and HTTP_SERVER_LAYOUT)
1422 * @param hiddenPeerNode node for internal, per-peer properties (the same as
1423 * sharedNode in SYNC4J_LAYOUT)
1424 * @param trackingNode node for tracking changes (always different than the
1426 * @param serverNode node for tracking items in a server (always different
1427 * than the other nodes)
1429 SyncSourceNodes(const boost::shared_ptr<FilterConfigNode> &sharedNode,
1430 const boost::shared_ptr<FilterConfigNode> &peerNode,
1431 const boost::shared_ptr<ConfigNode> &hiddenPeerNode,
1432 const boost::shared_ptr<ConfigNode> &trackingNode,
1433 const boost::shared_ptr<ConfigNode> &serverNode);
1435 /** true if the peer-specific config node exists */
1436 bool exists() const { return m_peerNode->exists(); }
1439 * Returns the right config node for a certain property,
1440 * depending on visibility and sharing.
1442 boost::shared_ptr<FilterConfigNode> getNode(const ConfigProperty &prop) const;
1445 * Read-write access to all configurable properties of the source.
1446 * The visible properties are passed through the config filter,
1447 * which can be modified.
1449 boost::shared_ptr<FilterConfigNode> getProperties(bool hidden = false) const { return m_props[hidden]; }
1451 /** read-write access to SyncML server specific config node */
1452 boost::shared_ptr<ConfigNode> getServerNode() const { return m_serverNode; }
1454 /** read-write access to backend specific tracking node */
1455 boost::shared_ptr<ConfigNode> getTrackingNode() const { return m_trackingNode; }
1458 const boost::shared_ptr<FilterConfigNode> m_sharedNode;
1459 const boost::shared_ptr<FilterConfigNode> m_peerNode;
1460 const boost::shared_ptr<ConfigNode> m_hiddenPeerNode;
1461 const boost::shared_ptr<ConfigNode> m_trackingNode;
1462 const boost::shared_ptr<ConfigNode> m_serverNode;
1464 /** multiplexer for the other nodes */
1465 boost::shared_ptr<FilterConfigNode> m_props[2];
1469 * same as SyncSourceNodes, but with only read access to properties
1471 class ConstSyncSourceNodes : private SyncSourceNodes
1474 ConstSyncSourceNodes(const SyncSourceNodes &other) :
1475 SyncSourceNodes(other)
1478 boost::shared_ptr<const FilterConfigNode> getProperties(bool hidden = false) const {
1479 return const_cast<SyncSourceNodes *>(static_cast<const SyncSourceNodes *>(this))->getProperties(hidden);
1481 boost::shared_ptr<const ConfigNode> getServerNode() const { return m_serverNode; }
1482 boost::shared_ptr<const ConfigNode> getTrackingNode() const { return m_trackingNode; }
1486 SourceType():m_forceFormat(false)
1488 string m_backend; /**< identifies the SyncEvolution backend (either via a generic term like "addressbook" or a specific one like "Evolution Contacts") */
1489 string m_format; /**< the format to be used (typically a MIME type) */
1490 bool m_forceFormat; /**< force to use the client's preferred format instead giving the engine and server a choice */
1494 * This class maps per-source properties to ConfigNode properties.
1495 * Some properties are not configurable and have to be provided
1496 * by derived classes.
1498 class SyncSourceConfig {
1500 SyncSourceConfig(const string &name, const SyncSourceNodes &nodes);
1502 static ConfigPropertyRegistry &getRegistry();
1505 * Read-write access to all configurable properties of the source.
1506 * The visible properties are passed through the config filter,
1507 * which can be modified.
1509 boost::shared_ptr<FilterConfigNode> getProperties(bool hidden = false) {
1510 return m_nodes.getProperties(hidden);
1512 boost::shared_ptr<const FilterConfigNode> getProperties(bool hidden = false) const { return const_cast<SyncSourceConfig *>(this)->getProperties(hidden); }
1514 virtual const char* getName() const { return m_name.c_str(); }
1517 * Returns the right config node for a certain property,
1518 * depending on visibility and sharing.
1520 boost::shared_ptr<FilterConfigNode> getNode(const ConfigProperty &prop) {
1521 return m_nodes.getNode(prop);
1523 boost::shared_ptr<const FilterConfigNode> getNode(const ConfigProperty &prop) const {
1524 return m_nodes.getNode(prop);
1527 /** access to SyncML server specific config node */
1528 boost::shared_ptr<ConfigNode> getServerNode() { return m_nodes.getServerNode(); }
1529 boost::shared_ptr<const ConfigNode> getServerNode() const { return m_nodes.getServerNode(); }
1531 /** access to backend specific tracking node */
1532 boost::shared_ptr<ConfigNode> getTrackingNode() { return m_nodes.getTrackingNode(); }
1533 boost::shared_ptr<const ConfigNode> getTrackingNode() const { return m_nodes.getTrackingNode(); }
1535 /** sync mode for sync sources */
1536 static StringConfigProperty m_sourcePropSync;
1538 /** true if the source config exists with view-specific properties (not just default or shared ones) */
1539 bool exists() const { return m_nodes.exists(); }
1541 /** checks if a certain property is set to a non-empty value */
1542 bool isSet(ConfigProperty &prop) {
1543 return prop.isSet(*getProperties(prop.isHidden()));
1546 virtual const char *getUser() const;
1547 virtual void setUser(const string &value, bool temporarily = false);
1549 const char *getPassword() const;
1550 virtual void setPassword(const string &value, bool temporarily = false);
1552 /** same as SyncConfig::checkPassword() but with
1553 * an extra argument globalConfigNode for source config property
1554 * may need global config node to check password */
1555 virtual void checkPassword(ConfigUserInterface &ui, const string &serverName, FilterConfigNode& globalConfigNode);
1557 /** same as SyncConfig::savePassword() */
1558 virtual void savePassword(ConfigUserInterface &ui, const string &serverName, FilterConfigNode& globalConfigNode);
1560 /** selects the backend database to use */
1561 virtual const char *getDatabaseID() const;
1562 virtual void setDatabaseID(const string &value, bool temporarily = false);
1565 * internal property: unique integer ID for the source, needed by Synthesis XML <dbtypeid>,
1568 virtual const int getSynthesisID() const;
1569 virtual void setSynthesisID(int value, bool temporarily = false);
1572 * Returns the data source type configured as part of the given
1573 * configuration; different SyncSources then check whether
1574 * they support that type. This call has to work before instantiating
1575 * a source and thus gets passed a node to read from.
1577 * @return the pair of <backend> and the (possibly empty)
1578 * <format> specified in the "type" property; see
1579 * sourcePropSourceType in SyncConfig.cpp
1582 static SourceType getSourceType(const SyncSourceNodes &nodes);
1583 static string getSourceTypeString(const SyncSourceNodes &nodes);
1584 virtual SourceType getSourceType() const;
1586 /** set the source type in <backend>[:format] style */
1587 virtual void setSourceType(const string &value, bool temporarily = false);
1590 * Returns the SyncSource URI: used in SyncML to address the data
1593 * Each URI has to be unique during a sync session, i.e.
1594 * two different sync sources cannot access the same data at
1597 virtual const char* getURI() const;
1598 virtual void setURI(const string &value, bool temporarily = false);
1601 * Gets the default syncMode.
1603 * Sync modes can be one of:
1607 * - one-way-from-server
1608 * - one-way-from-client
1609 * - refresh-from-server
1610 * - refresh-from-client
1612 virtual const char* getSync() const;
1613 virtual void setSync(const string &value, bool temporarily = false);
1617 SyncSourceNodes m_nodes;
1618 mutable ConfigStringCache m_stringCache;
1619 string m_cachedPassword;
1623 * Representing a configuration template node used for fuzzy matching.
1625 class TemplateConfig
1627 boost::shared_ptr<FileConfigNode> m_metaNode;
1628 ConfigProps m_metaProps;
1631 TemplateConfig (const string &path);
1640 static bool isTemplateConfig (const string &path);
1641 virtual int metaMatch (const string &fingerprint, SyncConfig::MatchMode mode);
1642 virtual int serverModeMatch (SyncConfig::MatchMode mode);
1643 virtual int fingerprintMatch (const string &fingerprint);
1644 virtual string getName();
1645 virtual string getDescription();
1646 virtual string getFingerprint();