7 /* simple master.cf service name.type pattern matcher
9 /* #include <match_service.h>
11 /* ARGV *match_service_init(pattern_list)
12 /* const char *pattern_list;
14 /* int match_service_match(list, name_type)
16 /* const char *name_type;
18 /* void match_service_free(list)
21 /* This module implements pattern matching for Postfix master.cf
22 /* services. This is more precise than using domain_list(3),
23 /* because match_service(3) won't treat a dotted service name
24 /* as a domain hierarchy. Moreover, this module has the advantage
25 /* that it does not drag in all the LDAP, SQL and other map
26 /* lookup client code into programs that don't need it.
28 /* Each pattern is of the form "name.type" or "type", where
29 /* "name" and "type" are the first two fields of a master.cf
30 /* entry. Patterns are separated by whitespace and/or commas.
31 /* Matches are case insensitive. Patterns are matched in the
32 /* specified order, and the matching process stops at the first
33 /* match. In order to reverse the result of a pattern match,
34 /* precede a pattern with an exclamation point (!).
36 /* match_service_init() parses the pattern list. The result
37 /* must be passed to match_service_match() or match_service_free().
39 /* match_service_match() matches one service name.type string
40 /* against the specified pattern list.
42 /* match_service_free() releases storage allocated by
43 /* match_service_init().
45 /* Fatal error: out of memory, malformed pattern.
46 /* Panic: malformed search string.
48 /* domain_list(3) match domain names.
52 /* The Secure Mailer license must be distributed with this software.
55 /* IBM T.J. Watson Research
57 /* Yorktown Heights, NY 10598, USA
65 #ifdef STRCASECMP_IN_STRINGS_H
69 /* Utility library. */
74 #include <stringops.h>
75 #include <match_service.h>
77 /* match_service_init - initialize pattern list */
79 ARGV
*match_service_init(const char *patterns
)
81 const char *delim
= " ,\t\r\n";
82 ARGV
*list
= argv_alloc(1);
83 char *saved_patterns
= mystrdup(patterns
);
84 char *bp
= saved_patterns
;
87 while ((item
= mystrtok(&bp
, delim
)) != 0)
88 argv_add(list
, item
, (char *) 0);
90 myfree(saved_patterns
);
94 /* match_service_match - match service name.type against pattern list */
96 int match_service_match(ARGV
*list
, const char *name_type
)
98 const char *myname
= "match_service_match";
105 * Quick check for empty list.
107 if (list
->argv
[0] == 0)
113 if ((type
= strrchr(name_type
, '.')) == 0 || *++type
== 0)
114 msg_panic("%s: malformed service: \"%s\"; need \"name.type\" format",
118 * Iterate over all patterns in the list, stop at the first match.
120 for (cpp
= list
->argv
; (pattern
= *cpp
) != 0; cpp
++) {
122 msg_info("%s: %s ~? %s", myname
, name_type
, pattern
);
123 for (match
= 1; *pattern
== '!'; pattern
++)
125 if (strcasecmp(strchr(pattern
, '.') ? name_type
: type
, pattern
) == 0) {
127 msg_info("%s: %s: found match", myname
, name_type
);
132 msg_info("%s: %s: no match", myname
, name_type
);
136 /* match_service_free - release storage */
138 void match_service_free(ARGV
*list
)