/src/lldpd/src/daemon/pattern.c
Line | Count | Source |
1 | | /* -*- mode: c; c-file-style: "openbsd" -*- */ |
2 | | /* |
3 | | * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx> |
4 | | * |
5 | | * Permission to use, copy, modify, and/or distribute this software for any |
6 | | * purpose with or without fee is hereby granted, provided that the above |
7 | | * copyright notice and this permission notice appear in all copies. |
8 | | * |
9 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
10 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
11 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
12 | | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
13 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
14 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
15 | | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | | */ |
17 | | |
18 | | #include "lldpd.h" |
19 | | |
20 | | #include <string.h> |
21 | | #include <fnmatch.h> |
22 | | |
23 | | /** |
24 | | * Match a list of patterns. |
25 | | * |
26 | | * @param string String to match against the list of patterns |
27 | | * @param patterns List of comma separated patterns. A pattern may |
28 | | * begin by `!` to negate it. In this case, it is |
29 | | * denied. A pattern may begin with `!!`. In this |
30 | | * case, it is allowed back. Each pattern will then be |
31 | | * matched against `fnmatch()` function. |
32 | | * @param found Value to return if the pattern isn't found. Should be either |
33 | | * PATTERN_MATCH_ALLOWED or PATTERN_MACTH_DENIED. |
34 | | * |
35 | | * If a pattern is found matching and denied at the same time, it |
36 | | * will be denied. If it is both allowed and denied, it |
37 | | * will be allowed. |
38 | | * |
39 | | * @return PATTERN_MATCH_DENIED if the string matches a denied pattern which is not |
40 | | * allowed or if the pattern wasn't found and `found` was set to |
41 | | * PATTERN_MATCH_DENIED. Otherwise, return PATTERN_MATCH_ALLOWED unless the |
42 | | * interface match is exact, in this case return PATTERN_MATCH_ALLOWED_EXACT. |
43 | | */ |
44 | | enum pattern_match_result |
45 | | pattern_match(char *string, char *patterns, int found) |
46 | 0 | { |
47 | 0 | char *pattern; |
48 | 0 | int denied = 0; |
49 | 0 | found = found ? PATTERN_MATCH_ALLOWED : PATTERN_MATCH_DENIED; |
50 | |
|
51 | 0 | if ((patterns = strdup(patterns)) == NULL) { |
52 | 0 | log_warnx("interfaces", "unable to allocate memory"); |
53 | 0 | return PATTERN_MATCH_DENIED; |
54 | 0 | } |
55 | | |
56 | 0 | for (pattern = strtok(patterns, ","); pattern != NULL; |
57 | 0 | pattern = strtok(NULL, ",")) { |
58 | 0 | if ((pattern[0] == '!') && (pattern[1] == '!') && |
59 | 0 | (fnmatch(pattern + 2, string, 0) == 0)) { |
60 | | /* Allowed. No need to search further. */ |
61 | 0 | found = (strcmp(pattern + 2, string)) ? |
62 | 0 | PATTERN_MATCH_ALLOWED : |
63 | 0 | PATTERN_MATCH_ALLOWED_EXACT; |
64 | 0 | break; |
65 | 0 | } |
66 | 0 | if ((pattern[0] == '!') && (fnmatch(pattern + 1, string, 0) == 0)) { |
67 | 0 | denied = 1; |
68 | 0 | found = PATTERN_MATCH_DENIED; |
69 | 0 | } else if (!denied && fnmatch(pattern, string, 0) == 0) { |
70 | 0 | if (!strcmp(pattern, string)) { |
71 | 0 | found = PATTERN_MATCH_ALLOWED_EXACT; |
72 | 0 | } else if (found < 2) { |
73 | 0 | found = PATTERN_MATCH_ALLOWED; |
74 | 0 | } |
75 | 0 | } |
76 | 0 | } |
77 | |
|
78 | 0 | free(patterns); |
79 | 0 | return found; |
80 | 0 | } |