File: filter.h

package info (click to toggle)
balsa 2.6.5-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 23,576 kB
  • sloc: ansic: 99,871; xml: 4,934; makefile: 769; sh: 185; awk: 60; python: 34
file content (285 lines) | stat: -rw-r--r-- 10,054 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
/* Balsa E-Mail Client
 *
 * Copyright (C) 1997-2016 Stuart Parmenter and others,
 *                         See the file AUTHORS for a list.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option) 
 * any later version.
 *  
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
 * GNU General Public License for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
 */
/*
 * filter.h
 * 
 * Header for libfilter, the mail filtering porting of balsa
 *
 * Authors:  Joel Becker - Emmanuel Allaud
 */

#ifndef __FILTER_H__
#define __FILTER_H__

#include <glib.h>

#include <time.h>
#include "libbalsa.h"

typedef struct _LibBalsaConditionRegex LibBalsaConditionRegex;

/* Conditions definition :
 * a condition is the basic component of a filter
 * It can be of type (mimic the old filter types) :
 * - CONDITION_STRING : matches when a string is contained in 
 *   one of the specified fields
 * - CONDITION_REGEX : matches when one of the reg exs matches on one
 *   of the specified fields
 * - CONDITION_EXEC : matches when the execution of the given command
 *   with parameters (FIXME : what are they???, see proposition for filter command) returns 1
 *
 * A condition has attributes :
 * - fields : a gint specifying on which fields to apply the condition
 * - negate : a gboolean to negate (logical not) the condition
 */

/* condition match types */

typedef enum {
    CONDITION_NONE,
    CONDITION_STRING, /*  */
    CONDITION_REGEX,
    CONDITION_DATE,
    CONDITION_FLAG,
    CONDITION_AND, /* Condition has a list of subconditions and
                    * matches if all the subconditions match. */
    CONDITION_OR   /* Condition has a list of subconditions and
                    * matches if any subcondition matches. */
} ConditionMatchType;

struct _LibBalsaCondition {
    gint ref_count;
    gboolean negate; /* negate the result of the condition. */
    ConditionMatchType type;

    /* The match type fields */
    union _match {
        /* CONDITION_STRING */
        struct {
            unsigned fields;     /* Contains the header list for
                                  * that this search should look in. */
            gchar * string;	 
            gchar * user_header; /* This is !=NULL and gives the name
                                  * of the user header against which
                                  * we make the match if fields
                                  * includes
                                  * CONDITION_MATCH_US_HEAD. */
        } string;
        /* CONDITION_REGEX */
        struct {
            unsigned fields;     /* Contains the header list for
                                  * that this search should look in. */
            /* GSList * regexs; */
        } regex;
        /* CONDITION_DATE */
	struct {
	    time_t date_low,date_high; /* for CONDITION_DATE            */
                                       /* (date_high==0=>no high limit) */
	} date;
        /* CONDITION_FLAG */
	LibBalsaMessageFlag flags;

        /* CONDITION_AND and CONDITION_OR */
        struct {
            LibBalsaCondition *left, *right;
        } andor;
    } match;
};

LibBalsaCondition* libbalsa_condition_new_from_string(gchar **string);
gchar*             libbalsa_condition_to_string(LibBalsaCondition *cond);
gchar*             libbalsa_condition_to_string_user(LibBalsaCondition *cond);

LibBalsaCondition* libbalsa_condition_new_flag_enum(gboolean negated,
                                                    LibBalsaMessageFlag flgs);

LibBalsaCondition* libbalsa_condition_new_string(gboolean negated,
                                                 unsigned headers,
                                                 gchar *str,
                                                 gchar *user_header);
LibBalsaCondition* libbalsa_condition_new_date(gboolean negated,
                                               time_t *from, time_t *to);
LibBalsaCondition* libbalsa_condition_new_bool_ptr(gboolean negated,
                                                   ConditionMatchType cmt,
                                                   LibBalsaCondition *left,
                                                   LibBalsaCondition *right);
LibBalsaCondition* libbalsa_condition_ref(LibBalsaCondition* cnd);
void               libbalsa_condition_unref(LibBalsaCondition*); 


typedef enum {
    FILTER_NOOP,
    FILTER_OP_OR,
    FILTER_OP_AND             /* Must be the last one */
} FilterOpType;

/* Filter definition :
 * a filter is defined by 
 * - a list of conditions and a gint conditions_op
 *   specifying the logical op to apply on the result of the condition match
 * - an action to perform on match : move, copy, print or trash the
 *   matching message, emit a sound, popup a text, execute a command
 */

typedef enum {
    FILTER_NOTHING,
    FILTER_COPY,
    FILTER_MOVE,
    FILTER_PRINT,
    FILTER_RUN,
    FILTER_TRASH,
    FILTER_COLOR,
    FILTER_N_TYPES
} FilterActionType;

/*
 * filter error codes
 * (not an enum cause they *have* to match filter_errlist)
 */

#define FILTER_NOERR         0
#define FILTER_EFILESYN      1
#define FILTER_ENOMEM        2
#define FILTER_EREGSYN       3
#define FILTER_EINVALID      4

/*
 * Filter errors set the variable filter_errno (like errno)
 * See policy to use it in filter-error.c
 */
extern gint filter_errno;

typedef struct _LibBalsaFilter {

    gchar *name;
    gint flags;

    LibBalsaCondition *condition; /* A codition, possibly a composite
                                   * one. */

    /* The notification fields : NULL signifies no notification */
    gchar * sound;
    gchar * popup_text;

    /* The action */
    FilterActionType action;
    /* action_string depends on action : 
     * - if action is FILTER_MOVE, or FILTER_COPY, action_string is
     *   the URL (this is mandatory because it determines UNIQUELY
     *   the mailbox, unlike the name) of the mailbox to move/copy 
     *   the matching message
     * - if action is FILTER_RUN, action_string is the command to run
     *   for now this is the way to specify parameters (replaced by
     *   pieces of the matching message) for the running command,
     *   proposition : %f,%t,%c,%s are replaced by the corresponding
     *   header (from,to,cc,subject) field of the matching message on
     *   the command line with enclosing quotes if necessary, e.g. :
     *   command_to_run %t %s -----> command_to_run manu@wanadoo.fr
     *   "about filters" If you want the body, we must find a way to
     *   pipe it to the std input of the command (FIXME what do we do
     *   for different parts, attachments and so on?)
     * - if action is FILTER_TRASH it's NULL
     * - FIXME if action is FILTER_PRINT it could be the print command ?
     */
    gchar * action_string;
} LibBalsaFilter;

/*
 * Exported filter functions A lot are, to have a fine-grained API so
 * we can use filter engine for a lot of different purpose : search
 * functions, virtual folders..., not only filtering
 */

void libbalsa_condition_regex_set(LibBalsaConditionRegex * reg, gchar *str);
/* returns pointer to internal data, treat with caution! */
const gchar* libbalsa_condition_regex_get(LibBalsaConditionRegex * reg);

void libbalsa_condition_prepend_regex(LibBalsaCondition* cond,
                                      LibBalsaConditionRegex *new_reg);

/** libbalsa_condition_matches() checks whether given message matches the 
 * condition. */
gboolean libbalsa_condition_matches(LibBalsaCondition* cond,
                                    LibBalsaMessage* message);

/* Filtering functions */
/* FIXME : perhaps I should try to use multithreading -> but we must
   therefore use lock very well */
/* prepare_filters_to_run will test all filters for correctness,
   compile regexs if needed
 * Return 
 * - TRUE on success (all filters are valid, ready to be applied)
 * - FALSE if there are invalid filters
 */

gint filters_prepare_to_run(GSList * filters);

/* Apply the filter action to the list of messages.
 * It returns TRUE if the trash bin has been filled with something
 * this is used to call enable_empty_trash after
 */

gboolean libbalsa_filter_mailbox_messages(LibBalsaFilter * filt,
					  LibBalsaMailbox * mailbox,
					  GArray * msgnos);

/*
 * libbalsa_filter_get_by_name()
 * search in the filter list the filter of name fname or NULL if unfound
 */

LibBalsaFilter* libbalsa_filter_get_by_name(const gchar* fname);

/*
 * Dialog calls
 */
/* filters_edit_dialog launches (guess what :) the filters edit dialog box
 * to modify the list of all filters
 */
void filters_edit_dialog(GtkWindow * parent);

/* filter_run_dialog edits and runs the list of filters of the mailbox
 */
void filters_run_dialog(LibBalsaMailbox * mbox, GtkWindow * parent);

/* filter_export_dialog to export filters as sieve scripts
 */

void filters_export_dialog(GtkWindow * parent);

void libbalsa_filters_set_trash(LibBalsaMailbox* new_trash);
typedef LibBalsaMailbox* (*UrlToMailboxMapper)(const gchar* url);
void libbalsa_filters_set_url_mapper(UrlToMailboxMapper u2mm);
void libbalsa_filters_set_filter_list(GSList** list);

/*
 * Error calls
 */
gchar *filter_strerror(gint filter_errnum);
void filter_perror(const gchar * s);

/* Test */
gboolean libbalsa_condition_can_match(LibBalsaCondition * cond,
				      LibBalsaMessage * message);
gboolean libbalsa_condition_is_flag_only(LibBalsaCondition * cond,
                                         LibBalsaMailbox * mailbox,
                                         guint msgno, gboolean * match);

#endif				/* __FILTER_H__ */