Merge append/exec fulyl into write/pipe.
Nicholas Marriott
16 years ago
0 | 0 | 10 August 2007 |
1 | 1 | |
2 | * Combine append into write and exec into pipe even more to get rid of | |
3 | deliver-append.c and deliver-exec.c. | |
2 | 4 | * add-from on stdout delivery is gone, an acceptable from line can be prepended |
3 | 5 | using rewrite. |
4 | 6 |
30 | 30 | child-deliver.c child-fetch.c child.c \ |
31 | 31 | pcre.c re.c privsep.c replace.c shm-mmap.c strb.c db-tdb.c \ |
32 | 32 | xmalloc-debug.c xmalloc.c \ |
33 | deliver-add-header.c deliver-append.c deliver-drop.c deliver-exec.c \ | |
34 | deliver-keep.c deliver-maildir.c deliver-mbox.c deliver-pipe.c \ | |
35 | deliver-remove-header.c deliver-rewrite.c deliver-smtp.c \ | |
36 | deliver-stdout.c deliver-tag.c deliver-to-cache.c deliver-write.c \ | |
33 | deliver-add-header.c deliver-drop.c deliver-keep.c deliver-maildir.c \ | |
34 | deliver-mbox.c deliver-pipe.c deliver-remove-header.c deliver-rewrite.c \ | |
35 | deliver-smtp.c deliver-stdout.c deliver-tag.c deliver-to-cache.c \ | |
36 | deliver-write.c \ | |
37 | 37 | fetch-imap.c fetch-imappipe.c fetch-maildir.c fetch-nntp.c fetch-pop3.c \ |
38 | 38 | fetch-stdin.c fetch-mbox.c imap-common.c \ |
39 | 39 | mail-callback.c mail-state.c mail-time.c mail.c file.c \ |
18 | 18 | child-deliver.c child-fetch.c child.c \ |
19 | 19 | pcre.c re.c privsep.c replace.c shm-mmap.c strb.c db-tdb.c \ |
20 | 20 | xmalloc-debug.c xmalloc.c \ |
21 | deliver-add-header.c deliver-append.c deliver-drop.c deliver-exec.c \ | |
22 | deliver-keep.c deliver-maildir.c deliver-mbox.c deliver-pipe.c \ | |
23 | deliver-remove-header.c deliver-rewrite.c deliver-smtp.c \ | |
24 | deliver-stdout.c deliver-tag.c deliver-to-cache.c deliver-write.c \ | |
21 | deliver-add-header.c deliver-drop.c deliver-keep.c deliver-maildir.c \ | |
22 | deliver-mbox.c deliver-pipe.c deliver-remove-header.c deliver-rewrite.c \ | |
23 | deliver-smtp.c deliver-stdout.c deliver-tag.c deliver-to-cache.c \ | |
24 | deliver-write.c \ | |
25 | 25 | fetch-imap.c fetch-imappipe.c fetch-maildir.c fetch-nntp.c fetch-pop3.c \ |
26 | 26 | fetch-stdin.c fetch-mbox.c imap-common.c \ |
27 | 27 | mail-callback.c mail-state.c mail-time.c mail.c file.c \ |
0 | /* $Id$ */ | |
1 | ||
2 | /* | |
3 | * Copyright (c) 2006 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 <errno.h> | |
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include <string.h> | |
24 | #include <unistd.h> | |
25 | ||
26 | #include "fdm.h" | |
27 | #include "deliver.h" | |
28 | ||
29 | int deliver_append_deliver(struct deliver_ctx *, struct actitem *); | |
30 | void deliver_append_desc(struct actitem *, char *, size_t); | |
31 | ||
32 | struct deliver deliver_append = { | |
33 | "append", | |
34 | DELIVER_ASUSER, | |
35 | deliver_append_deliver, | |
36 | deliver_append_desc | |
37 | }; | |
38 | ||
39 | int | |
40 | deliver_append_deliver(struct deliver_ctx *dctx, struct actitem *ti) | |
41 | { | |
42 | return (do_write(dctx, ti, 1)); | |
43 | } | |
44 | ||
45 | void | |
46 | deliver_append_desc(struct actitem *ti, char *buf, size_t len) | |
47 | { | |
48 | struct deliver_write_data *data = ti->data; | |
49 | ||
50 | xsnprintf(buf, len, "append \"%s\"", data->path.str); | |
51 | } |
0 | /* $Id$ */ | |
1 | ||
2 | /* | |
3 | * Copyright (c) 2006 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 <errno.h> | |
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include <string.h> | |
24 | #include <unistd.h> | |
25 | ||
26 | #include "fdm.h" | |
27 | #include "deliver.h" | |
28 | ||
29 | int deliver_exec_deliver(struct deliver_ctx *, struct actitem *); | |
30 | void deliver_exec_desc(struct actitem *, char *, size_t); | |
31 | ||
32 | struct deliver deliver_exec = { | |
33 | "exec", | |
34 | DELIVER_ASUSER, | |
35 | deliver_exec_deliver, | |
36 | deliver_exec_desc | |
37 | }; | |
38 | ||
39 | int | |
40 | deliver_exec_deliver(struct deliver_ctx *dctx, struct actitem *ti) | |
41 | { | |
42 | return (do_pipe(dctx, ti, 0)); | |
43 | } | |
44 | ||
45 | void | |
46 | deliver_exec_desc(struct actitem *ti, char *buf, size_t len) | |
47 | { | |
48 | struct deliver_pipe_data *data = ti->data; | |
49 | ||
50 | xsnprintf(buf, len, "exec \"%s\"", data->cmd.str); | |
51 | } |
39 | 39 | int |
40 | 40 | deliver_pipe_deliver(struct deliver_ctx *dctx, struct actitem *ti) |
41 | 41 | { |
42 | return (do_pipe(dctx, ti, 1)); | |
43 | } | |
44 | ||
45 | void | |
46 | deliver_pipe_desc(struct actitem *ti, char *buf, size_t len) | |
47 | { | |
48 | struct deliver_pipe_data *data = ti->data; | |
49 | ||
50 | xsnprintf(buf, len, "pipe \"%s\"", data->cmd.str); | |
51 | } | |
52 | ||
53 | int | |
54 | do_pipe(struct deliver_ctx *dctx, struct actitem *ti, int pipef) | |
55 | { | |
56 | 42 | struct account *a = dctx->account; |
57 | 43 | struct mail *m = dctx->mail; |
58 | 44 | struct deliver_pipe_data *data = ti->data; |
68 | 54 | goto error; |
69 | 55 | } |
70 | 56 | |
71 | if (pipef) | |
57 | if (data->pipe) { | |
72 | 58 | log_debug2("%s: piping to \"%s\"", a->name, s); |
73 | else | |
59 | cmd = cmd_start(s, CMD_IN|CMD_ONCE, m->data, m->size, &cause); | |
60 | } else { | |
74 | 61 | log_debug2("%s: executing \"%s\"", a->name, s); |
75 | ||
76 | if (pipef) { | |
77 | cmd = cmd_start(s, CMD_IN|CMD_ONCE, m->data, m->size, &cause); | |
78 | } else | |
79 | 62 | cmd = cmd_start(s, 0, NULL, 0, &cause); |
63 | } | |
80 | 64 | if (cmd == NULL) |
81 | 65 | goto error_cause; |
82 | 66 | log_debug3("%s: %s: started", a->name, s); |
92 | 76 | goto error_cause; |
93 | 77 | } |
94 | 78 | if (status == 0 && err != NULL) |
95 | log_warnx("%s: %s: %s", a->name, s, err); | |
79 | log_warnx("%s: %s: %s", a->name, s, err); | |
96 | 80 | } while (status == 0); |
97 | 81 | status--; |
98 | 82 | |
118 | 102 | xfree(s); |
119 | 103 | return (DELIVER_FAILURE); |
120 | 104 | } |
105 | ||
106 | void | |
107 | deliver_pipe_desc(struct actitem *ti, char *buf, size_t len) | |
108 | { | |
109 | struct deliver_pipe_data *data = ti->data; | |
110 | ||
111 | if (data->pipe) | |
112 | xsnprintf(buf, len, "pipe \"%s\"", data->cmd.str); | |
113 | else | |
114 | xsnprintf(buf, len, "exec \"%s\"", data->cmd.str); | |
115 | } |
39 | 39 | int |
40 | 40 | deliver_write_deliver(struct deliver_ctx *dctx, struct actitem *ti) |
41 | 41 | { |
42 | return (do_write(dctx, ti, 0)); | |
43 | } | |
44 | ||
45 | void | |
46 | deliver_write_desc(struct actitem *ti, char *buf, size_t len) | |
47 | { | |
48 | struct deliver_write_data *data = ti->data; | |
49 | ||
50 | xsnprintf(buf, len, "write \"%s\"", data->path.str); | |
51 | } | |
52 | ||
53 | int | |
54 | do_write(struct deliver_ctx *dctx, struct actitem *ti, int appendf) | |
55 | { | |
56 | 42 | struct account *a = dctx->account; |
57 | 43 | struct mail *m = dctx->mail; |
58 | 44 | struct deliver_write_data *data = ti->data; |
67 | 53 | return (DELIVER_FAILURE); |
68 | 54 | } |
69 | 55 | |
70 | if (appendf) | |
56 | if (data->append) { | |
71 | 57 | log_debug2("%s: appending to %s", a->name, path); |
72 | else | |
58 | f = fopen(path, "a"); | |
59 | } else { | |
73 | 60 | log_debug2("%s: writing to %s", a->name, path); |
74 | ||
75 | f = fopen(path, appendf ? "a" : "w"); | |
61 | f = fopen(path, "w"); | |
62 | } | |
76 | 63 | if (f == NULL) { |
77 | 64 | log_warn("%s: %s: fopen", a->name, path); |
78 | 65 | goto error; |
98 | 85 | xfree(path); |
99 | 86 | return (DELIVER_FAILURE); |
100 | 87 | } |
88 | ||
89 | ||
90 | void | |
91 | deliver_write_desc(struct actitem *ti, char *buf, size_t len) | |
92 | { | |
93 | struct deliver_write_data *data = ti->data; | |
94 | ||
95 | if (data->append) | |
96 | xsnprintf(buf, len, "append \"%s\"", data->path.str); | |
97 | else | |
98 | xsnprintf(buf, len, "write \"%s\"", data->path.str); | |
99 | } |
93 | 93 | /* Deliver write data. */ |
94 | 94 | struct deliver_write_data { |
95 | 95 | struct replpath path; |
96 | int append; | |
96 | 97 | }; |
97 | 98 | |
98 | 99 | /* Deliver maildir data. */ |
108 | 109 | /* Deliver pipe data. */ |
109 | 110 | struct deliver_pipe_data { |
110 | 111 | struct replpath cmd; |
112 | int pipe; | |
111 | 113 | }; |
112 | 114 | |
113 | 115 | /* Deliver tag data. */ |
138 | 140 | |
139 | 141 | /* deliver-pipe.c */ |
140 | 142 | extern struct deliver deliver_pipe; |
141 | int do_pipe(struct deliver_ctx *, struct actitem *, int); | |
142 | ||
143 | /* deliver-exec.c */ | |
144 | extern struct deliver deliver_exec; | |
145 | 143 | |
146 | 144 | /* deliver-drop.c */ |
147 | 145 | extern struct deliver deliver_drop; |
163 | 161 | |
164 | 162 | /* deliver-write.c */ |
165 | 163 | extern struct deliver deliver_write; |
166 | int do_write(struct deliver_ctx *, struct actitem *, int); | |
167 | ||
168 | /* deliver-append.c */ | |
169 | extern struct deliver deliver_append; | |
170 | 164 | |
171 | 165 | /* deliver-rewrite.c */ |
172 | 166 | extern struct deliver deliver_rewrite; |
391 | 391 | void |
392 | 392 | free_actitem(struct actitem *ti) |
393 | 393 | { |
394 | if (ti->deliver == &deliver_pipe || ti->deliver == &deliver_exec) { | |
394 | if (ti->deliver == &deliver_pipe) { | |
395 | 395 | struct deliver_pipe_data *data = ti->data; |
396 | 396 | xfree(data->cmd.str); |
397 | 397 | } else if (ti->deliver == &deliver_rewrite) { |
398 | 398 | struct deliver_rewrite_data *data = ti->data; |
399 | 399 | xfree(data->cmd.str); |
400 | } else if (ti->deliver == &deliver_write || | |
401 | ti->deliver == &deliver_append) { | |
400 | } else if (ti->deliver == &deliver_write) { | |
402 | 401 | struct deliver_write_data *data = ti->data; |
403 | 402 | xfree(data->path.str); |
404 | 403 | } else if (ti->deliver == &deliver_maildir) { |
181 | 181 | %type <expritem> expritem |
182 | 182 | %type <exprop> exprop |
183 | 183 | %type <fetch> fetchtype |
184 | %type <flag> cont icase not disabled keep execpipe compress verify | |
184 | %type <flag> cont icase not disabled keep execpipe writeappend compress verify | |
185 | 185 | %type <flag> poptype imaptype nntptype |
186 | 186 | %type <gid> gid |
187 | 187 | %type <locks> lock locklist |
1104 | 1104 | } |
1105 | 1105 | |
1106 | 1106 | /** ACTITEM: <actitem> (struct actitem *) */ |
1107 | actitem: TOKPIPE strv | |
1107 | actitem: execpipe strv | |
1108 | 1108 | /** [$2: strv (char *)] */ |
1109 | 1109 | { |
1110 | 1110 | struct deliver_pipe_data *data; |
1118 | 1118 | data = xcalloc(1, sizeof *data); |
1119 | 1119 | $$->data = data; |
1120 | 1120 | |
1121 | data->cmd.str = $2; | |
1122 | } | |
1123 | | TOKEXEC strv | |
1124 | /** [$2: strv (char *)] */ | |
1125 | { | |
1126 | struct deliver_pipe_data *data; | |
1127 | ||
1128 | if (*$2 == '\0') | |
1129 | yyerror("invalid command"); | |
1130 | ||
1131 | $$ = xcalloc(1, sizeof *$$); | |
1132 | $$->deliver = &deliver_exec; | |
1133 | ||
1134 | data = xcalloc(1, sizeof *data); | |
1135 | $$->data = data; | |
1136 | ||
1121 | data->pipe = $1; | |
1137 | 1122 | data->cmd.str = $2; |
1138 | 1123 | } |
1139 | 1124 | | TOKREWRITE strv |
1152 | 1137 | |
1153 | 1138 | data->cmd.str = $2; |
1154 | 1139 | } |
1155 | | TOKWRITE strv | |
1140 | | writeappend strv | |
1156 | 1141 | /** [$2: strv (char *)] */ |
1157 | 1142 | { |
1158 | 1143 | struct deliver_write_data *data; |
1166 | 1151 | data = xcalloc(1, sizeof *data); |
1167 | 1152 | $$->data = data; |
1168 | 1153 | |
1169 | data->path.str = $2; | |
1170 | } | |
1171 | | TOKAPPEND strv | |
1172 | /** [$2: strv (char *)] */ | |
1173 | { | |
1174 | struct deliver_write_data *data; | |
1175 | ||
1176 | if (*$2 == '\0') | |
1177 | yyerror("invalid path"); | |
1178 | ||
1179 | $$ = xcalloc(1, sizeof *$$); | |
1180 | $$->deliver = &deliver_append; | |
1181 | ||
1182 | data = xcalloc(1, sizeof *data); | |
1183 | $$->data = data; | |
1184 | ||
1154 | data->append = $1; | |
1185 | 1155 | data->path.str = $2; |
1186 | 1156 | } |
1187 | 1157 | | TOKMAILDIR strv |
1597 | 1567 | { |
1598 | 1568 | $$ = 1; |
1599 | 1569 | } |
1570 | ||
1571 | /** WRITEAPPEND: <flag> (int) */ | |
1572 | writeappend: TOKWRITE | |
1573 | { | |
1574 | $$ = 0; | |
1575 | } | |
1576 | | TOKAPPEND | |
1577 | { | |
1578 | $$ = 1; | |
1579 | } | |
1600 | 1580 | |
1601 | 1581 | /** EXPROP: <exprop> (enum exprop) */ |
1602 | 1582 | exprop: TOKAND |