+ /* rbldns parameter is:
+ * [no]lock::weight:filename
+ * valid options are:
+ * - lock: memlock the database in memory.
+ * - nolock: don't memlock the database in memory.
+ * - \d+: a number describing the weight to give to the match
+ * the given list [mandatory]
+ * directly import a file issued from a rhbl in rbldns format.
+ */
+ case ATK_RBLDNS: {
+ bool lock = false;
+ int weight = 0;
+ trie_t *trie_hosts = NULL;
+ trie_t *trie_domains = NULL;
+ const char *current = param->value;
+ const char *p = m_strchrnul(param->value, ':');
+ char *next = NULL;
+ for (int i = 0 ; i < 3 ; ++i) {
+ PARSE_CHECK(i == 2 || *p,
+ "file parameter must contains a locking state "
+ "and a weight option");
+ switch (i) {
+ case 0:
+ if ((p - current) == 4 && strncmp(current, "lock", 4) == 0) {
+ lock = true;
+ } else if ((p - current) == 6 && strncmp(current, "nolock", 6) == 0) {
+ lock = false;
+ } else {
+ PARSE_CHECK(false, "illegal locking state %.*s",
+ p - current, current);
+ }
+ break;
+
+ case 1:
+ weight = strtol(current, &next, 10);
+ PARSE_CHECK(next == p && weight >= 0 && weight <= 1024,
+ "illegal weight value %.*s",
+ (p - current), current);
+ break;
+
+ case 2:
+ PARSE_CHECK(strlist_create_from_rhbl(current, lock,
+ &trie_hosts, &trie_domains),
+ "cannot load string list from rhbl %s", current);
+ if (trie_hosts != NULL) {
+ array_add(config->tries, trie_hosts);
+ array_add(config->weights, weight);
+ array_add(config->reverses, true);
+ array_add(config->partiales, false);
+ }
+ if (trie_domains != NULL) {
+ array_add(config->tries, trie_domains);
+ array_add(config->weights, weight);
+ array_add(config->reverses, true);
+ array_add(config->partiales, true);
+ }
+ config->is_hostname = true;
+ break;
+ }
+ if (i != 2) {
+ current = p + 1;
+ p = m_strchrnul(current, ':');
+ }
+ }
+ } break;
+
+ /* dns parameter.
+ * weight:hostname.
+ * define a RBL to use through DNS resolution.
+ */
+ case ATK_DNS: {
+ int weight = 0;
+ const char *current = param->value;
+ const char *p = m_strchrnul(param->value, ':');
+ char *next = NULL;
+ for (int i = 0 ; i < 2 ; ++i) {
+ PARSE_CHECK(i == 1 || *p,
+ "host parameter must contains a weight option");
+ switch (i) {
+ case 0:
+ weight = strtol(current, &next, 10);
+ PARSE_CHECK(next == p && weight >= 0 && weight <= 1024,
+ "illegal weight value %.*s",
+ (p - current), current);
+ break;
+
+ case 1:
+ array_add(config->host_offsets, array_len(config->hosts));
+ array_append(config->hosts, current, strlen(current) + 1);
+ array_add(config->host_weights, weight);
+ break;
+ }
+ if (i != 1) {
+ current = p + 1;
+ p = m_strchrnul(current, ':');
+ }
+ }
+ } break;
+