Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / been_here.c
blob642d487dc032388790618c3aef48d2cd0cda5c30
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* been_here 3
6 /* SUMMARY
7 /* detect repeated occurrence of string
8 /* SYNOPSIS
9 /* #include <been_here.h>
11 /* BH_TABLE *been_here_init(size, flags)
12 /* int size;
13 /* int flags;
15 /* int been_here_fixed(dup_filter, string)
16 /* BH_TABLE *dup_filter;
17 /* char *string;
19 /* int been_here(dup_filter, format, ...)
20 /* BH_TABLE *dup_filter;
21 /* char *format;
23 /* int been_here_check_fixed(dup_filter, string)
24 /* BH_TABLE *dup_filter;
25 /* char *string;
27 /* int been_here_check(dup_filter, format, ...)
28 /* BH_TABLE *dup_filter;
29 /* char *format;
31 /* void been_here_free(dup_filter)
32 /* BH_TABLE *dup_filter;
33 /* DESCRIPTION
34 /* This module implements a simple filter to detect repeated
35 /* occurrences of character strings.
37 /* been_here_init() creates an empty duplicate filter.
39 /* been_here_fixed() looks up a fixed string in the given table, and
40 /* makes an entry in the table if the string was not found. The result
41 /* is non-zero (true) if the string was found, zero (false) otherwise.
43 /* been_here() formats its arguments, looks up the result in the
44 /* given table, and makes an entry in the table if the string was
45 /* not found. The result is non-zero (true) if the formatted result was
46 /* found, zero (false) otherwise.
48 /* been_here_check_fixed() and been_here_check() are similar
49 /* but do not update the duplicate filter.
51 /* been_here_free() releases storage for a duplicate filter.
53 /* Arguments:
54 /* .IP size
55 /* Upper bound on the table size; at most \fIsize\fR strings will
56 /* be remembered. Specify a value <= 0 to disable the upper bound.
57 /* .IP flags
58 /* Requests for special processing. Specify the bitwise OR of zero
59 /* or more flags:
60 /* .RS
61 /* .IP BH_FLAG_FOLD
62 /* Enable case-insensitive lookup.
63 /* .IP BH_FLAG_NONE
64 /* A manifest constant that requests no special processing.
65 /* .RE
66 /* .IP dup_filter
67 /* The table with remembered names
68 /* .IP string
69 /* Fixed search string.
70 /* .IP format
71 /* Format for building the search string.
72 /* LICENSE
73 /* .ad
74 /* .fi
75 /* The Secure Mailer license must be distributed with this software.
76 /* AUTHOR(S)
77 /* Wietse Venema
78 /* IBM T.J. Watson Research
79 /* P.O. Box 704
80 /* Yorktown Heights, NY 10598, USA
81 /*--*/
83 /* System library. */
85 #include "sys_defs.h"
86 #include <stdlib.h> /* 44BSD stdarg.h uses abort() */
87 #include <stdarg.h>
89 /* Utility library. */
91 #include <msg.h>
92 #include <mymalloc.h>
93 #include <htable.h>
94 #include <vstring.h>
95 #include <stringops.h>
97 /* Global library. */
99 #include "been_here.h"
101 /* been_here_init - initialize duplicate filter */
103 BH_TABLE *been_here_init(int limit, int flags)
105 BH_TABLE *dup_filter;
107 dup_filter = (BH_TABLE *) mymalloc(sizeof(*dup_filter));
108 dup_filter->limit = limit;
109 dup_filter->flags = flags;
110 dup_filter->table = htable_create(0);
111 return (dup_filter);
114 /* been_here_free - destroy duplicate filter */
116 void been_here_free(BH_TABLE *dup_filter)
118 htable_free(dup_filter->table, (void (*) (char *)) 0);
119 myfree((char *) dup_filter);
122 /* been_here - duplicate detector with finer control */
124 int been_here(BH_TABLE *dup_filter, const char *fmt,...)
126 VSTRING *buf = vstring_alloc(100);
127 int status;
128 va_list ap;
131 * Construct the string to be checked.
133 va_start(ap, fmt);
134 vstring_vsprintf(buf, fmt, ap);
135 va_end(ap);
138 * Do the duplicate check.
140 status = been_here_fixed(dup_filter, vstring_str(buf));
143 * Cleanup.
145 vstring_free(buf);
146 return (status);
149 /* been_here_fixed - duplicate detector */
151 int been_here_fixed(BH_TABLE *dup_filter, const char *string)
153 char *folded_string;
154 const char *lookup_key;
155 int status;
158 * Special processing: case insensitive lookup.
160 if (dup_filter->flags & BH_FLAG_FOLD) {
161 folded_string = mystrdup(string);
162 lookup_key = lowercase(folded_string);
163 } else {
164 folded_string = 0;
165 lookup_key = string;
169 * Do the duplicate check.
171 if (htable_locate(dup_filter->table, lookup_key) != 0) {
172 status = 1;
173 } else {
174 if (dup_filter->limit <= 0
175 || dup_filter->limit > dup_filter->table->used)
176 htable_enter(dup_filter->table, lookup_key, (char *) 0);
177 status = 0;
179 if (msg_verbose)
180 msg_info("been_here: %s: %d", string, status);
183 * Cleanup.
185 if (folded_string)
186 myfree(folded_string);
188 return (status);
191 /* been_here_check - query duplicate detector with finer control */
193 int been_here_check(BH_TABLE *dup_filter, const char *fmt,...)
195 VSTRING *buf = vstring_alloc(100);
196 int status;
197 va_list ap;
200 * Construct the string to be checked.
202 va_start(ap, fmt);
203 vstring_vsprintf(buf, fmt, ap);
204 va_end(ap);
207 * Do the duplicate check.
209 status = been_here_check_fixed(dup_filter, vstring_str(buf));
212 * Cleanup.
214 vstring_free(buf);
215 return (status);
218 /* been_here_check_fixed - query duplicate detector */
220 int been_here_check_fixed(BH_TABLE *dup_filter, const char *string)
222 char *folded_string;
223 const char *lookup_key;
224 int status;
227 * Special processing: case insensitive lookup.
229 if (dup_filter->flags & BH_FLAG_FOLD) {
230 folded_string = mystrdup(string);
231 lookup_key = lowercase(folded_string);
232 } else {
233 folded_string = 0;
234 lookup_key = string;
238 * Do the duplicate check.
240 status = (htable_locate(dup_filter->table, lookup_key) != 0);
241 if (msg_verbose)
242 msg_info("been_here_check: %s: %d", string, status);
245 * Cleanup.
247 if (folded_string)
248 myfree(folded_string);
250 return (status);