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