Deliver remove-from-cache.
Nicholas Marriott
16 years ago
0 | 0 | 02 October 2007 |
1 | 1 | |
2 | * "remove-from-cache" action. | |
2 | 3 | * Rename to-cache to add-to-cache (to-cache remains as a compatibility alias). |
3 | This is to match the planned delete-from-cache and perhaps other similar. | |
4 | This is to match the planned remove-from-cache and perhaps other similar. | |
4 | 5 | * The account/all warnings are now gone. |
5 | 6 | |
6 | 7 | 01 October 2007 |
33 | 33 | deliver-add-header.c deliver-drop.c deliver-keep.c deliver-maildir.c \ |
34 | 34 | deliver-mbox.c deliver-pipe.c deliver-remove-header.c deliver-rewrite.c \ |
35 | 35 | deliver-smtp.c deliver-stdout.c deliver-tag.c deliver-add-to-cache.c \ |
36 | deliver-write.c \ | |
36 | deliver-remove-from-cache.c deliver-write.c \ | |
37 | 37 | fetch-imap.c fetch-imappipe.c fetch-maildir.c fetch-nntp.c fetch-pop3.c \ |
38 | 38 | fetch-pop3pipe.c fetch-stdin.c fetch-mbox.c pop3-common.c imap-common.c \ |
39 | 39 | mail-state.c mail-time.c mail.c file.c \ |
1248 | 1248 | |
1249 | 1249 | match all action add-to-cache "~/my-cache" key "%[message_id]" |
1250 | 1250 | |
1251 | Or the existence of a key in the cache may be tested for using the 'in-cache' | |
1251 | Or removed with the 'remove-from-cache' action: | |
1252 | ||
1253 | match all action remove-from-cache "~/my-cache" key "%[message_id]" | |
1254 | ||
1255 | And the existence of a key in the cache may be tested for using the 'in-cache' | |
1252 | 1256 | condition: |
1253 | 1257 | |
1254 | 1258 | match in-cache "~/my-cache" key "%[message_id]" action "foundincache" |
21 | 21 | deliver-add-header.c deliver-drop.c deliver-keep.c deliver-maildir.c \ |
22 | 22 | deliver-mbox.c deliver-pipe.c deliver-remove-header.c deliver-rewrite.c \ |
23 | 23 | deliver-smtp.c deliver-stdout.c deliver-tag.c deliver-add-to-cache.c \ |
24 | deliver-write.c \ | |
24 | deliver-remove-from-cache.c deliver-write.c \ | |
25 | 25 | fetch-imap.c fetch-imappipe.c fetch-maildir.c fetch-nntp.c fetch-pop3.c \ |
26 | 26 | fetch-pop3pipe.c fetch-stdin.c fetch-mbox.c pop3-common.c imap-common.c \ |
27 | 27 | mail-state.c mail-time.c mail.c file.c \ |
34 | 34 | copying them... bad idea |
35 | 35 | - no-create to stop creation of nonexistent mboxes/maildirs |
36 | 36 | - create missing dirs when delivering |
37 | - delete-from-cache action | |
38 | 37 | - cache commands: |
39 | 38 | fdm cache-add $cachename $key |
40 | 39 | fdm cache-delete $cachename $key |
66 | 66 | } |
67 | 67 | |
68 | 68 | int |
69 | db_remove(TDB_CONTEXT *db, char *k) | |
70 | { | |
71 | TDB_DATA key; | |
72 | ||
73 | key.dptr = k; | |
74 | key.dsize = strlen(k); | |
75 | ||
76 | return (tdb_delete(db, key)); | |
77 | } | |
78 | ||
79 | int | |
69 | 80 | db_contains(TDB_CONTEXT *db, char *k) |
70 | 81 | { |
71 | 82 | TDB_DATA key; |
0 | /* $Id$ */ | |
1 | ||
2 | /* | |
3 | * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | |
4 | * | |
5 | * Permission to use, copy, modify, and distribute this software for any | |
6 | * purpose with or without fee is hereby granted, provided that the above | |
7 | * copyright notice and this permission notice appear in all copies. | |
8 | * | |
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
13 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER | |
14 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | |
15 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
16 | */ | |
17 | ||
18 | #include <sys/types.h> | |
19 | ||
20 | #include <string.h> | |
21 | ||
22 | #include "fdm.h" | |
23 | #include "deliver.h" | |
24 | ||
25 | int deliver_remove_from_cache_deliver( | |
26 | struct deliver_ctx *, struct actitem *); | |
27 | void deliver_remove_from_cache_desc(struct actitem *, char *, size_t); | |
28 | ||
29 | struct deliver deliver_remove_from_cache = { | |
30 | "remove-from-cache", | |
31 | DELIVER_INCHILD, | |
32 | deliver_remove_from_cache_deliver, | |
33 | deliver_remove_from_cache_desc | |
34 | }; | |
35 | ||
36 | int | |
37 | deliver_remove_from_cache_deliver(struct deliver_ctx *dctx, struct actitem *ti) | |
38 | { | |
39 | struct account *a = dctx->account; | |
40 | struct mail *m = dctx->mail; | |
41 | struct deliver_remove_from_cache_data *data = ti->data; | |
42 | char *key; | |
43 | struct cache *cache; | |
44 | ||
45 | key = replacestr(&data->key, m->tags, m, &m->rml); | |
46 | if (key == NULL || *key == '\0') { | |
47 | log_warnx("%s: empty key", a->name); | |
48 | goto error; | |
49 | } | |
50 | log_debug2("%s: removing from cache %s: %s", a->name, data->path, key); | |
51 | ||
52 | TAILQ_FOREACH(cache, &conf.caches, entry) { | |
53 | if (strcmp(data->path, cache->path) == 0) { | |
54 | if (open_cache(a, cache) != 0) | |
55 | goto error; | |
56 | if (db_contains(cache->db, key) && | |
57 | db_remove(cache->db, key) != 0) { | |
58 | log_warnx( | |
59 | "%s: error removing from cache %s: %s", | |
60 | a->name, cache->path, key); | |
61 | goto error; | |
62 | } | |
63 | xfree(key); | |
64 | return (DELIVER_SUCCESS); | |
65 | } | |
66 | } | |
67 | log_warnx("%s: cache %s not declared", a->name, data->path); | |
68 | ||
69 | error: | |
70 | if (key != NULL) | |
71 | xfree(key); | |
72 | return (DELIVER_FAILURE); | |
73 | } | |
74 | ||
75 | void | |
76 | deliver_remove_from_cache_desc(struct actitem *ti, char *buf, size_t len) | |
77 | { | |
78 | struct deliver_remove_from_cache_data *data = ti->data; | |
79 | ||
80 | xsnprintf(buf, len, | |
81 | "remove-from-cache \"%s\" key \"%s\"", data->path, data->key.str); | |
82 | } |
123 | 123 | struct replstrs *actions; |
124 | 124 | }; |
125 | 125 | |
126 | /* Deliver rewrite data. */ | |
126 | /* Deliver add-to-cache data. */ | |
127 | 127 | struct deliver_add_to_cache_data { |
128 | char *path; | |
129 | struct replstr key; | |
130 | }; | |
131 | ||
132 | /* Deliver remove-from-cache data. */ | |
133 | struct deliver_remove_from_cache_data { | |
128 | 134 | char *path; |
129 | 135 | struct replstr key; |
130 | 136 | }; |
168 | 174 | /* deliver-add-to-cache.c */ |
169 | 175 | extern struct deliver deliver_add_to_cache; |
170 | 176 | |
177 | /* deliver-remove-from-cache.c */ | |
178 | extern struct deliver deliver_remove_from_cache; | |
179 | ||
171 | 180 | #endif |
654 | 654 | Caches must be declared before they are used. Items are added to caches using |
655 | 655 | the |
656 | 656 | .Ic add-to-cache |
657 | action | |
658 | and they are searched using the | |
657 | action, removed using the | |
658 | .Ic remove-from-cache | |
659 | action, and searched for using the | |
659 | 660 | .Ic in-cache |
660 | 661 | condition; see below for information on these. |
661 | 662 | .Sh ACTIONS |
796 | 797 | This action adds the string |
797 | 798 | .Ar key |
798 | 799 | to the cache specified by |
799 | .Ar path . | |
800 | .Ar path . | |
801 | If | |
802 | .Ar key | |
803 | already exists in the cache, it is replaced. | |
804 | .It Ic remove-from-cache Ar path Ic key Ar key | |
805 | Remove the string | |
806 | .Ar key | |
807 | from the cache | |
808 | .Ar path , | |
809 | if a matching key is present. | |
800 | 810 | .It Ic action Ar name |
801 | 811 | This invokes another named action. |
802 | 812 | A maximum of five actions may be called in a sequence. |
871 | 871 | TDB_CONTEXT *db_open(char *); |
872 | 872 | void db_close(TDB_CONTEXT *); |
873 | 873 | int db_add(TDB_CONTEXT *, char *); |
874 | int db_remove(TDB_CONTEXT *, char *); | |
874 | 875 | int db_contains(TDB_CONTEXT *, char *); |
875 | 876 | int db_size(TDB_CONTEXT *); |
876 | 877 | int db_expire(TDB_CONTEXT *, uint64_t); |
85 | 85 | { "day", TOKDAYS }, |
86 | 86 | { "days", TOKDAYS }, |
87 | 87 | { "default-user", TOKDEFUSER }, |
88 | { "delete-from-cache", TOKADDFROMCACHE }, | |
89 | 88 | { "delete-oversized", TOKDELTOOBIG }, |
90 | 89 | { "disabled", TOKDISABLED }, |
91 | 90 | { "domain", TOKDOMAIN }, |
158 | 157 | { "purge-after", TOKPURGEAFTER }, |
159 | 158 | { "queue-high", TOKQUEUEHIGH }, |
160 | 159 | { "queue-low", TOKQUEUELOW }, |
160 | { "remove-from-cache", TOKREMOVEFROMCACHE }, | |
161 | 161 | { "remove-header", TOKREMOVEHEADER }, |
162 | 162 | { "remove-headers", TOKREMOVEHEADERS }, |
163 | 163 | { "returns", TOKRETURNS }, |
176 | 176 | { "tagged", TOKTAGGED }, |
177 | 177 | { "timeout", TOKTIMEOUT }, |
178 | 178 | { "to", TOKTO }, |
179 | { "to-cache", TOKTOCACHE }, | |
179 | { "to-cache", TOKADDTOCACHE }, | |
180 | 180 | { "total-size", TOKTOTALSIZE }, |
181 | 181 | { "unmatched", TOKUNMATCHED }, |
182 | 182 | { "unmatched-mail", TOKIMPLACT }, |
351 | 351 | xfree(data->key.str); |
352 | 352 | if (data->value.str != NULL) |
353 | 353 | xfree(data->value.str); |
354 | } else if (ti->deliver == &deliver_to_cache) { | |
355 | struct deliver_to_cache_data *data = ti->data; | |
354 | } else if (ti->deliver == &deliver_add_to_cache) { | |
355 | struct deliver_add_to_cache_data *data = ti->data; | |
356 | xfree(data->key.str); | |
357 | xfree(data->path); | |
358 | } else if (ti->deliver == &deliver_remove_from_cache) { | |
359 | struct deliver_remove_from_cache_data *data = ti->data; | |
356 | 360 | xfree(data->key.str); |
357 | 361 | xfree(data->path); |
358 | 362 | } else if (ti->deliver == &deliver_smtp) { |
134 | 134 | %token TOKGROUP TOKGROUPS TOKPURGEAFTER TOKCOMPRESS TOKNORECEIVED TOKFILEUMASK |
135 | 135 | %token TOKFILEGROUP TOKVALUE TOKTIMEOUT TOKREMOVEHEADER TOKREMOVEHEADERS |
136 | 136 | %token TOKSTDOUT TOKNOVERIFY TOKADDHEADER TOKQUEUEHIGH TOKQUEUELOW TOKNOAPOP |
137 | %token TOKVERIFYCERTS TOKEXPIRE TOKADDTOCACHE TOKINCACHE TOKKEY TOKNEWONLY | |
138 | %token TOKOLDONLY TOKCACHE TOKFLOCK TOKFCNTL TOKDOTLOCK TOKSTRIPCHARACTERS | |
137 | %token TOKVERIFYCERTS TOKEXPIRE TOKADDTOCACHE TOKREMOVEFROMCACHE TOKINCACHE | |
138 | %token TOKKEY TOKNEWONLY TOKOLDONLY TOKCACHE TOKFLOCK TOKFCNTL TOKDOTLOCK | |
139 | %token TOKSTRIPCHARACTERS | |
139 | 140 | |
140 | 141 | %union |
141 | 142 | { |
1302 | 1303 | | TOKADDTOCACHE replpathv TOKKEY strv |
1303 | 1304 | /** [$2: replpathv (char *)] [$4: strv (char *)] */ |
1304 | 1305 | { |
1305 | struct deliver_to_cache_data *data; | |
1306 | struct deliver_add_to_cache_data *data; | |
1306 | 1307 | |
1307 | 1308 | if (*$2 == '\0') |
1308 | 1309 | yyerror("invalid path"); |
1310 | 1311 | yyerror("invalid key"); |
1311 | 1312 | |
1312 | 1313 | $$ = xcalloc(1, sizeof *$$); |
1313 | $$->deliver = &deliver_to_cache; | |
1314 | $$->deliver = &deliver_add_to_cache; | |
1315 | ||
1316 | data = xcalloc(1, sizeof *data); | |
1317 | $$->data = data; | |
1318 | ||
1319 | data->key.str = $4; | |
1320 | data->path = $2; | |
1321 | } | |
1322 | | TOKREMOVEFROMCACHE replpathv TOKKEY strv | |
1323 | /** [$2: replpathv (char *)] [$4: strv (char *)] */ | |
1324 | { | |
1325 | struct deliver_remove_from_cache_data *data; | |
1326 | ||
1327 | if (*$2 == '\0') | |
1328 | yyerror("invalid path"); | |
1329 | if (*$4 == '\0') | |
1330 | yyerror("invalid key"); | |
1331 | ||
1332 | $$ = xcalloc(1, sizeof *$$); | |
1333 | $$->deliver = &deliver_remove_from_cache; | |
1314 | 1334 | |
1315 | 1335 | data = xcalloc(1, sizeof *data); |
1316 | 1336 | $$->data = data; |