-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-19990327"
+#define DEF_MAIL_VERSION "Snapshot-19990328"
extern char *var_mail_version;
/* LICENSE
/* SYNOPSIS
/* #include <maps.h>
/*
-/* MAPS *maps_create(title, map_names)
+/* MAPS *maps_create(title, map_names, flags)
/* const char *title;
/* const char *map_names;
+/* int flags;
/*
-/* const char *maps_find(maps, key)
+/* const char *maps_find(maps, key, flags)
/* MAPS *maps;
/* const char *key;
+/* int flags;
/*
/* void maps_free(maps)
/* MAPS *maps;
/* named dictionaries.
/* The result is a handle that must be specified along with all
/* other maps_xxx() operations.
+/* see dict_open(3) for a description of flags.
/*
/* maps_find() searches the specified list of dictionaries
/* in the specified order for the named key. The result is in
/* memory that is overwritten upon each call.
+/* The flags argument is either 0 or specifies a filter:
+/* for example, DICT_FLAG_FIXED | DICT_FLAG_PATTERN selects
+/* dictionaries that have fixed keys or pattern keys.
/*
/* maps_free() releases storage claimed by maps_create()
/* and conveniently returns a null pointer.
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
if (dns_status != DNS_OK)
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
"%d <%s>: Host not found",
- var_unk_name_code, name));
+ dns_status == DNS_NOTFOUND ?
+ var_unk_name_code : 450, name));
return (SMTPD_CHECK_DUNNO);
}
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
-TDICT_OPEN_INFO
-TDICT_PCRE
-TDICT_REGEXP
--TDICT_REGEXP_LINE
+-TDICT_REGEXP_RULE
-TDICT_UNIX
-TDNS_FIXED
-TDNS_REPLY
#define DICT_FLAG_DUP_IGNORE (1<<1) /* if file, ignore dups */
#define DICT_FLAG_TRY0NULL (1<<2) /* do not append 0 to key/value */
#define DICT_FLAG_TRY1NULL (1<<3) /* append 0 to key/value */
+#define DICT_FLAG_FIXED (1<<4) /* fixed key map */
+#define DICT_FLAG_PATTERN (1<<5) /* keys are patterns */
extern int dict_unknown_allowed;
extern int dict_errno;
dict_db->dict.close = dict_db_close;
dict_db->dict.fd = db->fd(db);
close_on_exec(dict_db->dict.fd, CLOSE_ON_EXEC);
- dict_db->dict.flags = dict_flags;
+ dict_db->dict.flags = dict_flags | DICT_FLAG_FIXED;
if ((flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
dict_db->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL);
dict_db->db = db;
dict_dbm->dict.close = dict_dbm_close;
dict_dbm->dict.fd = dbm_dirfno(dbm);
close_on_exec(dict_dbm->dict.fd, CLOSE_ON_EXEC);
- dict_dbm->dict.flags = dict_flags;
- if (dict_flagsflags & (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL)) == 0)
+ dict_dbm->dict.flags = dict_flags | DICT_FLAG_FIXED;
+ if ((dict_flags & (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL)) == 0)
dict_dbm->dict.flags |= (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL);
dict_dbm->dbm = dbm;
dict_dbm->path = mystrdup(path);
dict->lookup = dict_env_lookup;
dict->update = dict_env_update;
dict->close = dict_env_close;
- dict->flags = dict_flags;
+ dict->flags = dict_flags | DICT_FLAG_FIXED;
dict->fd = -1;
return (dict);
}
dict_ldap->dict.update = dict_ldap_update;
dict_ldap->dict.close = dict_ldap_close;
dict_ldap->dict.fd = -1;
- dict_ldap->dict.flags = dict_flags;
+ dict_ldap->dict.flags = dict_flags | DICT_FLAG_FIXED;
if (msg_verbose)
msg_info("%s: using LDAP source %s", myname, ldapsource);
d->dict.update = dict_ni_update;
d->dict.close = dict_ni_close;
d->dict.fd = -1;
- d->dict.flags = dict_flags;
+ d->dict.flags = dict_flags | DICT_FLAG_FIXED;
d->path = mystrdup(path);
return &d->dict;
dict_nis->dict.close = dict_nis_close;
dict_nis->dict.fd = -1;
dict_nis->map = mystrdup(map);
- dict_nis->dict.flags = dict_flags;
+ dict_nis->dict.flags = dict_flags | DICT_FLAG_FIXED;
if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
dict_nis->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL);
if (dict_nis_domain == 0)
dict_nisplus->dict.close = dict_nisplus_close;
dict_nisplus->dict.fd = -1;
dict_nisplus->map = mystrdup(map);
- dict_nisplus->dict.flags = dict_flags;
+ dict_nisplus->dict.flags = dict_flags | DICT_FLAG_FIXED;
return (&dict_nisplus->dict);
}
return (0);
/* Search for a matching expression */
+ ctxt.matches = 0;
for (pcre_list = dict_pcre->head; pcre_list; pcre_list = pcre_list->next) {
if (pcre_list->pattern) {
ctxt.matches = pcre_exec(pcre_list->pattern, pcre_list->hints,
/*
* dict_pcre_open - load and compile a file containing regular expressions
*/
-DICT *dict_pcre_open(const char *map, int unused_flags)
+DICT *dict_pcre_open(const char *map, int unused_flags, int dict_flags)
{
DICT_PCRE *dict_pcre;
VSTREAM *map_fp;
dict_pcre->dict.close = dict_pcre_close;
dict_pcre->dict.fd = -1;
dict_pcre->map = mystrdup(map);
- dict_pcre->dict.flags = dict_flags;
+ dict_pcre->dict.flags = dict_flags | DICT_FLAG_PATTERN;
dict_pcre->head = NULL;
if (dict_pcre_init == 0) {
myfree((char *) rule->replace);
myfree((char *) rule);
}
+ if (dict_regexp->pmatch)
+ myfree((char *) dict_regexp->pmatch);
+ myfree(dict_regexp->map);
myfree((char *) dict_regexp);
}
rule->expr[1] = expr2;
rule->replace = mystrdup(p);
rule->lineno = lineno;
+ rule->next = NULL;
return rule;
}
dict_regexp->dict.close = dict_regexp_close;
dict_regexp->dict.fd = -1;
dict_regexp->map = mystrdup(map);
- dict_regexp->dict.flags = dict_flags;
+ dict_regexp->dict.flags = dict_flags | DICT_FLAG_PATTERN;
+ dict_regexp->head = 0;
+ dict_regexp->pmatch = 0;
if ((map_fp = vstream_fopen(map, O_RDONLY, 0)) == 0) {
msg_fatal("open %s: %m", map);
last_rule = rule;
}
}
- last_rule->next = NULL;
- dict_regexp->pmatch = (regmatch_t *) mymalloc(sizeof(regmatch_t) * max_nsub);
+ if (max_nsub > 0)
+ dict_regexp->pmatch =
+ (regmatch_t *) mymalloc(sizeof(regmatch_t) * max_nsub);
dict_regexp->nmatch = max_nsub;
vstring_free(line_buffer);
return (&dict_regexp->dict);
}
-#endif /* NO_POSIX_REGEXP */
+#endif
dict_unix->dict.close = dict_unix_close;
dict_unix->dict.fd = -1;
dict_unix->map = mystrdup(map);
- dict_unix->dict.flags = dict_flags;
+ dict_unix->dict.flags = dict_flags | DICT_FLAG_FIXED;
return (&dict_unix->dict);
}