pfix-srsd: add a -I option
[apps/pfixtools.git] / postlicyd / counters.c
1 /******************************************************************************/
2 /*          pfixtools: a collection of postfix related tools                  */
3 /*          ~~~~~~~~~                                                         */
4 /*  ________________________________________________________________________  */
5 /*                                                                            */
6 /*  Redistribution and use in source and binary forms, with or without        */
7 /*  modification, are permitted provided that the following conditions        */
8 /*  are met:                                                                  */
9 /*                                                                            */
10 /*  1. Redistributions of source code must retain the above copyright         */
11 /*     notice, this list of conditions and the following disclaimer.          */
12 /*  2. Redistributions in binary form must reproduce the above copyright      */
13 /*     notice, this list of conditions and the following disclaimer in the    */
14 /*     documentation and/or other materials provided with the distribution.   */
15 /*  3. The names of its contributors may not be used to endorse or promote    */
16 /*     products derived from this software without specific prior written     */
17 /*     permission.                                                            */
18 /*                                                                            */
19 /*  THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS   */
20 /*  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED         */
21 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE    */
22 /*  DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY         */
23 /*  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL        */
24 /*  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS   */
25 /*  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)     */
26 /*  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,       */
27 /*  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  */
28 /*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           */
29 /*  POSSIBILITY OF SUCH DAMAGE.                                               */
30 /*                                                                            */
31 /*   Copyright (c) 2006-2008 the Authors                                      */
32 /*   see AUTHORS and source files for details                                 */
33 /******************************************************************************/
34
35 /*
36  * Copyright © 2008 Florent Bruneau
37  */
38
39 #include "filter.h"
40 #include "config.h"
41 #include "query.h"
42
43 typedef struct counter_config_t {
44     int counter;
45     uint32_t hard_threshold;
46     uint32_t soft_threshold;
47 } counter_config_t;
48
49
50 static counter_config_t *counter_config_new(void)
51 {
52     return p_new(counter_config_t, 1);
53 }
54
55 static void counter_config_delete(counter_config_t **config)
56 {
57     if (*config) {
58         p_delete(config);
59     }
60 }
61
62 static bool counter_filter_constructor(filter_t *filter)
63 {
64     counter_config_t *config = counter_config_new();
65     config->counter = -1;
66
67 #define PARSE_CHECK(Expr, Str, ...)                                            \
68     if (!(Expr)) {                                                             \
69         err(Str, ##__VA_ARGS__);                                               \
70         counter_config_delete(&config);                                          \
71         return false;                                                          \
72     }
73
74     config->hard_threshold = 1;
75     config->soft_threshold = 1;
76     foreach (filter_param_t *param, filter->params) {
77         switch (param->type) {
78           FILTER_PARAM_PARSE_INT(COUNTER, config->counter);
79           FILTER_PARAM_PARSE_INT(HARD_THRESHOLD, config->hard_threshold);
80           FILTER_PARAM_PARSE_INT(SOFT_THRESHOLD, config->soft_threshold);
81           default: break;
82         }
83     }}
84
85     PARSE_CHECK(config->counter >= 0 && config->counter < MAX_COUNTERS,
86                 "invalid counter number: %d", config->counter);
87     filter->data = config;
88     return true;
89 }
90
91 static void counter_filter_destructor(filter_t *filter)
92 {
93     counter_config_t *config = filter->data;
94     counter_config_delete(&config);
95     filter->data = config;
96 }
97
98 static filter_result_t counter_filter(const filter_t *filter, const query_t *query,
99                                       filter_context_t *context)
100 {
101     const counter_config_t *counter = filter->data;
102     const uint32_t val = context->counters[counter->counter];
103
104     if (val >= counter->hard_threshold) {
105         return HTK_HARD_MATCH;
106     } else if (val >= counter->soft_threshold) {
107         return HTK_SOFT_MATCH;
108     } else {
109         return HTK_FAIL;
110     }
111 }
112
113 static int counter_init(void)
114 {
115     filter_type_t type =  filter_register("counter", counter_filter_constructor,
116                                           counter_filter_destructor, counter_filter,
117                                           NULL, NULL);
118     /* Hooks.
119      */
120     (void)filter_hook_register(type, "fail");
121     (void)filter_hook_register(type, "hard_match");
122     (void)filter_hook_register(type, "soft_match");
123
124     /* Parameters.
125      */
126     (void)filter_param_register(type, "counter");
127     (void)filter_param_register(type, "hard_threshold");
128     (void)filter_param_register(type, "soft_threshold");
129     return 0;
130 }
131 module_init(counter_init);