2
* $Id: pattern.h 216 2006-11-02 21:23:08Z hubert@u.washington.edu $
4
* ========================================================================
5
* Copyright 2006 University of Washington
7
* Licensed under the Apache License, Version 2.0 (the "License");
8
* you may not use this file except in compliance with the License.
9
* You may obtain a copy of the License at
11
* http://www.apache.org/licenses/LICENSE-2.0
13
* ========================================================================
16
#ifndef PITH_PATTERN_INCLUDED
17
#define PITH_PATTERN_INCLUDED
20
#include "../pith/msgno.h"
21
#include "../pith/sorttype.h"
22
#include "../pith/string.h"
26
* This structure is used to contain strings which are matched against
27
* header fields. The match is a simple substring match. The match is
28
* an OR of all the patterns in the PATTERN_S list. That is,
29
* substring1_matches OR substring2_matches OR substring3_matches.
30
* If not is set in the _head_ of the PATTERN_S, it is a NOT of the
31
* whole pattern, that is,
32
* NOT (substring1_matches OR substring2_matches OR substring3_matches).
33
* The not variable is not meaningful except in the head member of the
36
typedef struct pattern_s {
37
int not; /* NOT of whole pattern */
39
struct pattern_s *next;
43
* List of these is a list of arbitrary freetext headers and patterns.
44
* This may be part of a pattern group.
45
* The isemptyval bit is to keep track of the difference between an arb
46
* header with no value set and one with the empty value "" set. For the
47
* other builtin headers this difference is kept track of by whether or
48
* not the header is in the config file at all or not. Here we want to
49
* be able to add a header to the config file without necessarily giving
52
typedef struct arbhdr_s {
56
struct arbhdr_s *next;
60
* A list of intervals of integers.
62
typedef struct intvl_s {
68
* A Pattern group gives characteristics of an envelope to match against. Any of
69
* the characteristics (to, from, ...) which is non-null must match for the
70
* whole thing to be considered a match. That is, it is an AND of all the
73
typedef struct patgrp_s {
75
char *comment; /* for user, not used for anything */
88
STRLIST_S *charsets_list; /* used for efficiency, computed from charset */
89
ARBHDR_S *arbhdr; /* list of arbitrary hdrnames and patterns */
90
int fldr_type; /* see FLDR_* below */
91
PATTERN_S *folder; /* folder if type FLDR_SPECIFIC */
92
int inabook; /* see IAB_* below */
97
INTVL_S *age; /* ages are in days */
100
int age_uses_sentdate; /* on or off */
104
long cat_lim; /* -1 no limit 0 only headers */
105
int bogus; /* patgrp contains unknown stuff */
106
int stat_new, /* msg status is New (Unseen) */
107
stat_rec, /* msg status is Recent */
108
stat_del, /* msg status is Deleted */
109
stat_imp, /* msg is flagged Important */
110
stat_ans, /* msg is flagged Answered */
111
stat_8bitsubj, /* subject contains 8bit chars */
112
stat_bom, /* this is first pine run of the month */
113
stat_boy; /* this is first pine run of the year */
119
#define FLDR_SPECIFIC 3
121
#define FLDR_DEFL FLDR_EMAIL
124
#define IAB_EITHER 0x0 /* don't care if in or not */
126
#define IAB_TYPE_MASK 0xf
127
#define IAB_YES 0x1 /* addresses in any abook */
128
#define IAB_NO 0x2 /* " not " */
129
#define IAB_SPEC_YES 0x3 /* addresses in specific abooks */
130
#define IAB_SPEC_NO 0x4
133
* Warning about reply-to. We're using the c-client envelope reply-to which
134
* means if there isn't a real reply-to it uses the From!
136
#define IAB_ADDR_MASK 0xff0
137
#define IAB_FROM 0x10 /* from address included in list */
138
#define IAB_REPLYTO 0x20 /* reply-to address included in list */
139
#define IAB_SENDER 0x40 /* sender address included in list */
140
#define IAB_TO 0x80 /* to address included in list */
141
#define IAB_CC 0x100 /* cc address included in list */
143
#define IAB_DEFL IAB_EITHER
146
#define FILTER_STATE 0
147
#define FILTER_KILL 1
148
#define FILTER_FOLDER 2
151
* For the Status parts of a PATGRP_S. For example, stat_del is Deleted
152
* status. User sets EITHER means they don't care, it always matches.
153
* YES means it must be deleted to match. NO means it must not be deleted.
155
#define PAT_STAT_EITHER 0 /* we don't care which, yes or no */
156
#define PAT_STAT_YES 1 /* yes, this status is true */
157
#define PAT_STAT_NO 2 /* no, this status is not true */
160
* For the State setting part of a filter action
162
#define ACT_STAT_LEAVE 0 /* leave msg state alone */
163
#define ACT_STAT_SET 1 /* set this part of msg state */
164
#define ACT_STAT_CLEAR 2 /* clear this part of msg state */
166
typedef struct action_s {
167
unsigned is_a_role:1; /* this is a role action */
168
unsigned is_a_incol:1; /* this is an index color action */
169
unsigned is_a_score:1; /* this is a score setting action */
170
unsigned is_a_filter:1; /* this is a filter action */
171
unsigned is_a_other:1; /* this is a miscellaneous action */
172
unsigned bogus:1; /* action contains unknown stuff */
173
unsigned been_here_before:1; /* inheritance loop prevention */
174
/* --- These are for roles --- */
175
ADDRESS *from; /* value to set for From */
176
ADDRESS *replyto; /* value to set for Reply-To */
177
char **cstm; /* custom headers */
178
char **smtp; /* custom SMTP server for this role */
179
char **nntp; /* custom NNTP server for this role */
180
char *fcc; /* value to set for Fcc */
181
char *litsig; /* value to set Literal Signature */
182
char *sig; /* value to set for Sig File */
183
char *template; /* value to set for Template */
184
char *nick; /* value to set for Nickname */
185
int repl_type; /* see ROLE_REPL_* below */
186
int forw_type; /* see ROLE_FORW_* below */
187
int comp_type; /* see ROLE_COMP_* below */
188
char *inherit_nick; /* pattern we inherit actions from */
189
/* --- This is for indexcoloring --- */
190
COLOR_PAIR *incol; /* colors for index line */
191
/* --- This is for scoring --- */
193
/* --- These are for filtering --- */
195
long state_setting_bits;
196
PATTERN_S *keyword_set; /* set these keywords */
197
PATTERN_S *keyword_clr; /* clear these keywords */
198
PATTERN_S *folder; /* folders to recv. filtered mail */
199
int move_only_if_not_deleted; /* on or off */
200
int non_terminating; /* on or off */
201
/* --- These are for other --- */
202
/* sort order of folder */
203
unsigned sort_is_set:1;
204
SortOrder sortorder; /* sorting order */
205
int revsort; /* whether or not to reverse sort */
206
/* Index format of folder */
208
unsigned startup_rule;
211
/* flags for first_pattern..., set_role_from_msg, and confirm_role() */
212
#define PAT_CLOSED 0x00000000 /* closed */
213
#define PAT_OPENED 0x00000001 /* opened successfully */
214
#define PAT_OPEN_FAILED 0x00000002
215
#define PAT_USE_CURRENT 0x00000010 /* use current_val to set up pattern */
216
#define PAT_USE_CHANGED 0x00000020 /* use changed_val to set up pattern */
217
#define PAT_USE_MAIN 0x00000040 /* use main_user_val */
218
#define PAT_USE_POST 0x00000080 /* use post_user_val */
219
#define ROLE_COMPOSE 0x00000100 /* roles with compose value != NO */
220
#define ROLE_REPLY 0x00000200 /* roles with reply value != NO */
221
#define ROLE_FORWARD 0x00000400 /* roles with forward value != NO */
222
#define ROLE_INCOL 0x00000800 /* patterns with non-Normal colors */
223
#define ROLE_SCORE 0x00001000 /* patterns with non-zero scorevals */
224
#define ROLE_DEFAULTOK 0x00002000 /* ok to use default role w confirm */
225
#define ROLE_DO_ROLES 0x00010000 /* role patterns */
226
#define ROLE_DO_INCOLS 0x00020000 /* index line color patterns */
227
#define ROLE_DO_SCORES 0x00040000 /* set score patterns */
228
#define ROLE_DO_FILTER 0x00080000 /* filter patterns */
229
#define ROLE_DO_OTHER 0x00100000 /* miscellaneous patterns */
230
#define ROLE_OLD_PAT 0x00200000 /* old patterns variable */
231
#define ROLE_OLD_FILT 0x00400000 /* old patterns-filters variable */
232
#define ROLE_OLD_SCORE 0x00800000 /* old patterns-scores variable */
233
#define ROLE_CHANGES 0x01000000 /* start editing with changes
234
already registered */
236
#define PAT_OPEN_MASK 0x0000000f
237
#define PAT_USE_MASK 0x000000f0
238
#define ROLE_MASK 0x00ffff00
240
#define ROLE_REPL_NO 0 /* never use for reply */
241
#define ROLE_REPL_YES 1 /* use for reply with confirmation */
242
#define ROLE_REPL_NOCONF 2 /* use for reply without confirmation */
243
#define ROLE_FORW_NO 0 /* ... forward ... */
244
#define ROLE_FORW_YES 1
245
#define ROLE_FORW_NOCONF 2
246
#define ROLE_COMP_NO 0 /* ... compose ... */
247
#define ROLE_COMP_YES 1
248
#define ROLE_COMP_NOCONF 2
250
#define ROLE_REPL_DEFL ROLE_REPL_YES /* default reply value */
251
#define ROLE_FORW_DEFL ROLE_FORW_YES /* default forward value */
252
#define ROLE_COMP_DEFL ROLE_COMP_NO /* default compose value */
253
#define ROLE_NOTAROLE_DEFL ROLE_COMP_NO
255
#define INTVL_INF (2147483646L)
256
#define INTVL_UNDEF (INTVL_INF + 1L)
257
#define SCORE_UNDEF INTVL_UNDEF
258
#define SCORE_MIN (-100)
259
#define SCORE_MAX (100)
260
#define SCOREUSE_GET 0x000
261
#define SCOREUSE_INVALID 0x001 /* will recalculate scores_in_use next time */
262
#define SCOREUSE_ROLES 0x010 /* scores are used for roles */
263
#define SCOREUSE_INCOLS 0x020 /* scores are used for index line colors */
264
#define SCOREUSE_FILTERS 0x040 /* scores are used for filters */
265
#define SCOREUSE_OTHER 0x080 /* scores are used for miscellaneous stuff */
266
#define SCOREUSE_INDEX 0x100 /* scores are used in index-format */
267
#define SCOREUSE_STATEDEP 0x200 /* scores depend on message state */
270
* A message is compared with a pattern group to see if it matches.
271
* If it does match, then there are actions which are taken.
273
typedef struct pat_s {
276
struct pat_line_s *patline; /* pat_line that goes with this pat */
283
typedef enum {TypeNotSet = 0, Literal, File, Inherit} PAT_TYPE;
286
* There's one of these for each line in the pinerc variable.
287
* Normal type=Literal patterns have a patline with both first and last
288
* pointing to the pattern. Type File has one patline for the file and first
289
* and last point to the first and last patterns in the file.
290
* The patterns aren't linked into one giant list, the patlines are.
291
* To traverse all the patterns you have to go through the patline list
292
* and then for each patline go from first to last through the patterns.
293
* That's what next_pattern and friends do.
295
typedef struct pat_line_s {
297
PAT_S *first; /* 1st pattern in list belonging to this line */
299
char *filename; /* If type File, the filename */
302
unsigned dirty:1; /* needs to be written back to storage */
303
struct pat_line_s *next;
304
struct pat_line_s *prev;
307
typedef struct pat_handle {
308
PAT_LINE_S *patlinehead; /* list of in-core, parsed pat lines */
309
unsigned dirtypinerc:1; /* needs to be written */
312
typedef struct pat_state {
315
PAT_LINE_S *patlinecurrent;
316
PAT_S *patcurrent; /* current pat within patline */
319
#define PATTERN_MAGIC "P#Pats"
320
#define PATTERN_FILE_VERS "01"
323
typedef struct role_args {
331
* This is a little dangerous. We're passing flags to match_pattern and
332
* peeling some of them off for our own use while passing the rest on
333
* to mail_search_full. So we need to define ours so they don't overlap
334
* with the c-client flags that can be passed to mail_search_full.
335
* We could formalize it with mrc.
337
#define MP_IN_CCLIENT_CB 0x10000 /* we're in a c-client callback! */
338
#define MP_NOT 0x20000 /* use ! of patgrp for search */
341
/* match_pattern_folder_specific flags */
342
#define FOR_PATTERN 0x01
345
extern PAT_HANDLE **cur_pat_h;
348
/* exported protoypes */
349
void role_process_filters(void);
350
int add_to_pattern(PAT_S *, long);
351
char *add_pat_escapes(char *);
352
char *remove_pat_escapes(char *);
353
char *add_roletake_escapes(char *);
354
char *add_comma_escapes(char *);
355
void set_pathandle(long);
356
void close_every_pattern(void);
357
void close_patterns(long);
358
int nonempty_patterns(long, PAT_STATE *);
359
int any_patterns(long, PAT_STATE *);
360
int edit_pattern(PAT_S *, int, long);
361
int add_pattern(PAT_S *, long);
362
int delete_pattern(int, long);
363
int shuffle_pattern(int, int, long);
364
PAT_LINE_S *parse_pat_file(char *);
365
INTVL_S *parse_intvl(char *);
366
char *stringform_of_intvl(INTVL_S *);
367
int scores_are_used(int);
368
int patgrp_depends_on_state(PATGRP_S *);
369
int patgrp_depends_on_active_state(PATGRP_S *);
370
PATTERN_S *parse_pattern(char *, char *, int);
371
PATTERN_S *string_to_pattern(char *);
372
char *pattern_to_string(PATTERN_S *);
373
char *pattern_to_config(PATTERN_S *);
374
PATTERN_S *config_to_pattern(char *);
375
PATTERN_S *editlist_to_pattern(char **);
376
char **pattern_to_editlist(PATTERN_S *);
377
PATGRP_S *nick_to_patgrp(char *, int);
378
PAT_S *first_pattern(PAT_STATE *);
379
PAT_S *last_pattern(PAT_STATE *);
380
PAT_S *prev_pattern(PAT_STATE *);
381
PAT_S *next_pattern(PAT_STATE *);
382
int write_patterns(long);
383
void convert_statebits_to_vals(long, int *, int *, int *, int *);
384
int match_pattern(PATGRP_S *, MAILSTREAM *, SEARCHSET *,char *,
385
long (*)(MAILSTREAM *, long), long);
386
void find_8bitsubj_in_messages(MAILSTREAM *, SEARCHSET *, int, int);
387
void find_charsets_in_messages(MAILSTREAM *, SEARCHSET *, PATGRP_S *, int);
388
int compare_strlists_for_match(STRLIST_S *, STRLIST_S *);
389
int match_pattern_folder(PATGRP_S *, MAILSTREAM *);
390
int match_pattern_folder_specific(PATTERN_S *, MAILSTREAM *, int);
391
SEARCHPGM *match_pattern_srchpgm(PATGRP_S *, MAILSTREAM *, char **, SEARCHSET *);
392
void calc_extra_hdrs(void);
393
char *get_extra_hdrs(void);
394
void free_extra_hdrs(void);
395
void free_pat(PAT_S **);
396
void free_pattern(PATTERN_S **);
397
void free_action(ACTION_S **);
398
PAT_S *copy_pat(PAT_S *);
399
PATGRP_S *copy_patgrp(PATGRP_S *);
400
ACTION_S *copy_action(ACTION_S *);
401
ACTION_S *combine_inherited_role(ACTION_S *);
402
void mail_expunge_prefilter(MAILSTREAM *, int);
403
void process_filter_patterns(MAILSTREAM *, MSGNO_S *, long);
404
void reprocess_filter_patterns(MAILSTREAM *, MSGNO_S *, int);
405
int trivial_patgrp(PATGRP_S *);
406
int some_filter_depends_on_active_state(void);
407
void delete_filtered_msgs(MAILSTREAM *);
410
#endif /* PITH_PATTERN_INCLUDED */