7 /* detect repeated occurrence of string
9 /* #include <been_here.h>
11 /* BH_TABLE *been_here_init(size, flags)
15 /* int been_here_fixed(dup_filter, string)
16 /* BH_TABLE *dup_filter;
19 /* int been_here(dup_filter, format, ...)
20 /* BH_TABLE *dup_filter;
23 /* int been_here_check_fixed(dup_filter, string)
24 /* BH_TABLE *dup_filter;
27 /* int been_here_check(dup_filter, format, ...)
28 /* BH_TABLE *dup_filter;
31 /* void been_here_free(dup_filter)
32 /* BH_TABLE *dup_filter;
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.
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.
58 /* Requests for special processing. Specify the bitwise OR of zero
62 /* Enable case-insensitive lookup.
64 /* A manifest constant that requests no special processing.
67 /* The table with remembered names
69 /* Fixed search string.
71 /* Format for building the search string.
75 /* The Secure Mailer license must be distributed with this software.
78 /* IBM T.J. Watson Research
80 /* Yorktown Heights, NY 10598, USA
86 #include <stdlib.h> /* 44BSD stdarg.h uses abort() */
89 /* Utility library. */
95 #include <stringops.h>
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);
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);
131 * Construct the string to be checked.
134 vstring_vsprintf(buf
, fmt
, ap
);
138 * Do the duplicate check.
140 status
= been_here_fixed(dup_filter
, vstring_str(buf
));
149 /* been_here_fixed - duplicate detector */
151 int been_here_fixed(BH_TABLE
*dup_filter
, const char *string
)
154 const char *lookup_key
;
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
);
169 * Do the duplicate check.
171 if (htable_locate(dup_filter
->table
, lookup_key
) != 0) {
174 if (dup_filter
->limit
<= 0
175 || dup_filter
->limit
> dup_filter
->table
->used
)
176 htable_enter(dup_filter
->table
, lookup_key
, (char *) 0);
180 msg_info("been_here: %s: %d", string
, status
);
186 myfree(folded_string
);
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);
200 * Construct the string to be checked.
203 vstring_vsprintf(buf
, fmt
, ap
);
207 * Do the duplicate check.
209 status
= been_here_check_fixed(dup_filter
, vstring_str(buf
));
218 /* been_here_check_fixed - query duplicate detector */
220 int been_here_check_fixed(BH_TABLE
*dup_filter
, const char *string
)
223 const char *lookup_key
;
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
);
238 * Do the duplicate check.
240 status
= (htable_locate(dup_filter
->table
, lookup_key
) != 0);
242 msg_info("been_here_check: %s: %d", string
, status
);
248 myfree(folded_string
);