Added to the repository
Showing
3 changed files
with
611 additions
and
0 deletions
mh/anno.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2003 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with GNU Mailutils; if not, write to the Free Software | ||
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ | ||
17 | |||
18 | /* MH annotate command */ | ||
19 | |||
20 | #include <mh.h> | ||
21 | |||
22 | const char *argp_program_version = "anno (" PACKAGE_STRING ")"; | ||
23 | static char doc[] = N_("GNU MH anno\v" | ||
24 | "Options marked with `*' are not yet implemented.\n" | ||
25 | "Use -help to obtain the list of traditional MH options."); | ||
26 | static char args_doc[] = N_("[msg [msg...]]"); | ||
27 | |||
28 | /* GNU options */ | ||
29 | static struct argp_option options[] = { | ||
30 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
31 | N_("Specify folder to operate upon")}, | ||
32 | {"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
33 | N_("* Annotate the message in place")}, | ||
34 | {"noinplace", ARG_NOINPLACE, NULL, OPTION_HIDDEN, "" }, | ||
35 | {"date", ARG_DATE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
36 | N_("Add FIELD: Date header") }, | ||
37 | {"nodate", ARG_NODATE, NULL, OPTION_HIDDEN, "" }, | ||
38 | {"component", ARG_COMPONENT, N_("FIELD"), 0, | ||
39 | N_("Add this FIELD to the message header") }, | ||
40 | {"text", ARG_TEXT, N_("STRING"), 0, | ||
41 | N_("Field value for the component") }, | ||
42 | { NULL } | ||
43 | }; | ||
44 | |||
45 | struct mh_option mh_option[] = { | ||
46 | {"inplace", 1, MH_OPT_BOOL }, | ||
47 | {"date", 1, MH_OPT_BOOL }, | ||
48 | {"component", 1, MH_OPT_ARG, "field"}, | ||
49 | {"text", 1, MH_OPT_ARG, "body"}, | ||
50 | { NULL } | ||
51 | }; | ||
52 | |||
53 | static char datebuf[80]; | ||
54 | static int inplace; /* Annotate the message in place */ | ||
55 | static char *anno_date; /* Annotation date */ | ||
56 | static char *component; /* header field */ | ||
57 | static char *anno_text; /* header field value */ | ||
58 | |||
59 | static int | ||
60 | opt_handler (int key, char *arg, void *unused) | ||
61 | { | ||
62 | switch (key) | ||
63 | { | ||
64 | case '+': | ||
65 | case ARG_FOLDER: | ||
66 | current_folder = arg; | ||
67 | break; | ||
68 | |||
69 | case ARG_INPLACE: | ||
70 | inplace = is_true (arg); | ||
71 | break; | ||
72 | |||
73 | case ARG_NOINPLACE: | ||
74 | inplace = 0; | ||
75 | break; | ||
76 | |||
77 | case ARG_DATE: | ||
78 | anno_date = datebuf; | ||
79 | break; | ||
80 | |||
81 | case ARG_NODATE: | ||
82 | anno_date = NULL; | ||
83 | break; | ||
84 | |||
85 | case ARG_COMPONENT: | ||
86 | component = arg; | ||
87 | break; | ||
88 | |||
89 | case ARG_TEXT: | ||
90 | anno_text = arg; | ||
91 | break; | ||
92 | |||
93 | default: | ||
94 | return 1; | ||
95 | } | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | void | ||
100 | anno (mailbox_t mbox, message_t msg, size_t num, void *data) | ||
101 | { | ||
102 | header_t hdr; | ||
103 | attribute_t attr; | ||
104 | |||
105 | if (message_get_header (msg, &hdr)) | ||
106 | return; | ||
107 | |||
108 | if (anno_date) | ||
109 | header_set_value (hdr, component, anno_date, 0); | ||
110 | header_set_value (hdr, component, anno_text, 0); | ||
111 | |||
112 | message_get_attribute (msg, &attr); | ||
113 | attribute_set_modified (attr); | ||
114 | } | ||
115 | |||
116 | int | ||
117 | main (int argc, char **argv) | ||
118 | { | ||
119 | int rc; | ||
120 | int index; | ||
121 | mailbox_t mbox; | ||
122 | mh_msgset_t msgset; | ||
123 | time_t t; | ||
124 | struct tm *tm; | ||
125 | |||
126 | mu_init_nls (); | ||
127 | |||
128 | t = time (NULL); | ||
129 | tm = localtime (&t); | ||
130 | strftime (datebuf, sizeof datebuf, "%a, %d %b %Y %H:%M:%S %Z", tm); | ||
131 | |||
132 | mh_argp_parse (argc, argv, options, mh_option, args_doc, doc, | ||
133 | opt_handler, NULL, &index); | ||
134 | |||
135 | mbox = mh_open_folder (current_folder, 0); | ||
136 | |||
137 | if (!component) | ||
138 | { | ||
139 | size_t n; | ||
140 | |||
141 | printf (_("Component name: ")); | ||
142 | if (getline (&component, &n, stdin) <= 0 || *component == 0) | ||
143 | exit (1); | ||
144 | } | ||
145 | |||
146 | if (!anno_text && !anno_date) | ||
147 | exit (0); | ||
148 | |||
149 | argc -= index; | ||
150 | argv += index; | ||
151 | |||
152 | mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); | ||
153 | rc = mh_iterate (mbox, &msgset, anno, NULL); | ||
154 | |||
155 | mailbox_save_attributes (mbox); | ||
156 | mailbox_close (mbox); | ||
157 | mailbox_destroy (&mbox); | ||
158 | return rc; | ||
159 | } | ||
160 | |||
161 | |||
162 | |||
163 | |||
164 | |||
165 | |||
166 |
mh/install-mh.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2003 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with GNU Mailutils; if not, write to the Free Software | ||
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ | ||
17 | |||
18 | #include <mh.h> | ||
19 | |||
20 | const char *argp_program_version = "install-mh (" PACKAGE_STRING ")"; | ||
21 | static char doc[] = N_("GNU MH install-mh\v" | ||
22 | "Use -help to obtain the list of traditional MH options."); | ||
23 | static char args_doc[] = ""; | ||
24 | |||
25 | /* GNU options */ | ||
26 | static struct argp_option options[] = { | ||
27 | {"auto", ARG_AUTO, NULL, 0, N_("Do not ask for anything")}, | ||
28 | {"compat", ARG_COMPAT, NULL, OPTION_HIDDEN, ""}, | ||
29 | {NULL} | ||
30 | }; | ||
31 | |||
32 | struct mh_option mh_option[] = { | ||
33 | {"auto", 1, 0, }, | ||
34 | {"compat", 1, 0, }, | ||
35 | { NULL } | ||
36 | }; | ||
37 | |||
38 | int automode; | ||
39 | |||
40 | static int | ||
41 | opt_handler (int key, char *arg, void *unused) | ||
42 | { | ||
43 | switch (key) | ||
44 | { | ||
45 | case ARG_AUTO: | ||
46 | automode = 1; | ||
47 | break; | ||
48 | |||
49 | case ARG_COMPAT: | ||
50 | break; | ||
51 | |||
52 | default: | ||
53 | return 1; | ||
54 | } | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | int | ||
59 | main (int argc, char **argv) | ||
60 | { | ||
61 | char *home, *name; | ||
62 | extern int mh_auto_install; | ||
63 | /* Native Language Support */ | ||
64 | mu_init_nls (); | ||
65 | |||
66 | mh_auto_install = 0; | ||
67 | mh_argp_parse (argc, argv, options, mh_option, args_doc, doc, | ||
68 | opt_handler, NULL, NULL); | ||
69 | |||
70 | home = mu_get_homedir (); | ||
71 | if (!home) | ||
72 | abort (); /* shouldn't happen */ | ||
73 | asprintf (&name, "%s/%s", home, MH_USER_PROFILE); | ||
74 | |||
75 | mh_install (name, automode); | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | |||
80 | |||
81 |
mh/mark.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2003 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with GNU Mailutils; if not, write to the Free Software | ||
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ | ||
17 | |||
18 | #include <mh.h> | ||
19 | |||
20 | const char *argp_program_version = "mark (" PACKAGE_STRING ")"; | ||
21 | static char doc[] = N_("GNU MH mark\v" | ||
22 | "Use -help to obtain the list of traditional MH options."); | ||
23 | static char args_doc[] = "[msgs...]"; | ||
24 | |||
25 | /* GNU options */ | ||
26 | static struct argp_option options[] = { | ||
27 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
28 | N_("Specify folder to operate upon")}, | ||
29 | {"sequence", ARG_SEQUENCE, N_("NAME"), 0, | ||
30 | N_("Specify sequence name to operate upon")}, | ||
31 | {"add", ARG_ADD, NULL, 0, | ||
32 | N_("Add messages to the sequence")}, | ||
33 | {"delete", ARG_DELETE, NULL, 0, | ||
34 | N_("Delete messages from the sequence")}, | ||
35 | {"list", ARG_LIST, NULL, 0, | ||
36 | N_("List the sequences")}, | ||
37 | {"public", ARG_PUBLIC, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
38 | N_("Create public sequence")}, | ||
39 | {"nopublic", ARG_NOPUBLIC, NULL, OPTION_HIDDEN, "" }, | ||
40 | {"zero", ARG_ZERO, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
41 | N_("Empty the sequence before adding messages")}, | ||
42 | {"nozero", ARG_NOZERO, NULL, OPTION_HIDDEN, "" }, | ||
43 | {NULL} | ||
44 | }; | ||
45 | |||
46 | struct mh_option mh_option[] = { | ||
47 | {"sequence", 1, }, | ||
48 | {"add", 1, }, | ||
49 | {"delete", 1, }, | ||
50 | {"list", 1, }, | ||
51 | {"public", 1, MH_OPT_BOOL }, | ||
52 | {"zero", 1, MH_OPT_BOOL }, | ||
53 | { NULL } | ||
54 | }; | ||
55 | |||
56 | static int action; /* Action to perform */ | ||
57 | static int mode_public = 1; /* Create public sequences */ | ||
58 | static int mode_zero = 1; /* Zero the sequence before addition */ | ||
59 | static list_t seq_list; /* List of sequence names to operate upon */ | ||
60 | |||
61 | static char *mbox_dir; | ||
62 | |||
63 | static void | ||
64 | add_sequence (char *name) | ||
65 | { | ||
66 | if (!seq_list && list_create (&seq_list)) | ||
67 | { | ||
68 | mh_error (_("can't create sequence list")); | ||
69 | exit (1); | ||
70 | } | ||
71 | list_append (seq_list, name); | ||
72 | } | ||
73 | |||
74 | static int | ||
75 | opt_handler (int key, char *arg, void *unused) | ||
76 | { | ||
77 | switch (key) | ||
78 | { | ||
79 | case '+': | ||
80 | case ARG_FOLDER: | ||
81 | current_folder = arg; | ||
82 | break; | ||
83 | |||
84 | case ARG_SEQUENCE: | ||
85 | add_sequence (arg); | ||
86 | break; | ||
87 | |||
88 | case ARG_ADD: | ||
89 | case ARG_DELETE: | ||
90 | case ARG_LIST: | ||
91 | action = key; | ||
92 | break; | ||
93 | |||
94 | case ARG_PUBLIC: | ||
95 | mode_public = is_true (arg); | ||
96 | break; | ||
97 | |||
98 | case ARG_NOPUBLIC: | ||
99 | mode_public = 0; | ||
100 | break; | ||
101 | |||
102 | case ARG_ZERO: | ||
103 | mode_zero = is_true (arg); | ||
104 | break; | ||
105 | |||
106 | case ARG_NOZERO: | ||
107 | mode_zero = 0; | ||
108 | break; | ||
109 | |||
110 | default: | ||
111 | return 1; | ||
112 | } | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static char * | ||
117 | private_sequence_name (char *name) | ||
118 | { | ||
119 | char *p; | ||
120 | |||
121 | asprintf (&p, "atr-%s-%s", name, mbox_dir); | ||
122 | return p; | ||
123 | } | ||
124 | |||
125 | static char * | ||
126 | read_sequence (char *name, int public) | ||
127 | { | ||
128 | char *value; | ||
129 | |||
130 | if (public) | ||
131 | value = mh_global_sequences_get (name, NULL); | ||
132 | else | ||
133 | { | ||
134 | char *p = private_sequence_name (name); | ||
135 | value = mh_global_context_get (p, NULL); | ||
136 | free (p); | ||
137 | } | ||
138 | return value; | ||
139 | } | ||
140 | |||
141 | static void | ||
142 | write_sequence (char *name, char *value, int public) | ||
143 | { | ||
144 | if (public) | ||
145 | mh_global_sequences_set (name, value); | ||
146 | else | ||
147 | { | ||
148 | char *p = private_sequence_name (name); | ||
149 | mh_global_context_set (p, value); | ||
150 | free (p); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | static void | ||
155 | delete_sequence (char *name, int public) | ||
156 | { | ||
157 | write_sequence (name, NULL, public); | ||
158 | } | ||
159 | |||
160 | static int | ||
161 | action_add (void *item, void *data) | ||
162 | { | ||
163 | char *name = item; | ||
164 | mh_msgset_t *mset = data; | ||
165 | char *value = read_sequence (name, mode_public); | ||
166 | char *new_value, *p; | ||
167 | char buf[64]; | ||
168 | size_t i, len; | ||
169 | |||
170 | delete_sequence (name, !mode_public); | ||
171 | |||
172 | if (mode_zero) | ||
173 | value = NULL; | ||
174 | |||
175 | if (value) | ||
176 | len = strlen (value); | ||
177 | else | ||
178 | len = 0; | ||
179 | len++; | ||
180 | for (i = 0; i < mset->count; i++) | ||
181 | { | ||
182 | snprintf (buf, sizeof buf, "%lu", (unsigned long) mset->list[i]); | ||
183 | len += strlen (buf) + 1; | ||
184 | } | ||
185 | |||
186 | new_value = xmalloc (len + 1); | ||
187 | if (value) | ||
188 | strcpy (new_value, value); | ||
189 | else | ||
190 | new_value[0] = 0; | ||
191 | p = new_value + strlen (new_value); | ||
192 | *p++ = ' '; | ||
193 | for (i = 0; i < mset->count; i++) | ||
194 | { | ||
195 | p += sprintf (p, "%lu", (unsigned long) mset->list[i]); | ||
196 | *p++ = ' '; | ||
197 | } | ||
198 | *p = 0; | ||
199 | write_sequence (name, new_value, mode_public); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int | ||
204 | cmp_msgnum (const void *a, const void *b) | ||
205 | { | ||
206 | size_t *as = a; | ||
207 | size_t *bs = b; | ||
208 | |||
209 | if (*as < *bs) | ||
210 | return -1; | ||
211 | if (*as > *bs) | ||
212 | return 1; | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static int | ||
217 | action_delete (void *item, void *data) | ||
218 | { | ||
219 | char *name = item; | ||
220 | mh_msgset_t *mset = data; | ||
221 | char *value = read_sequence (name, mode_public); | ||
222 | char *p; | ||
223 | int argc, i; | ||
224 | char **argv; | ||
225 | |||
226 | if (!value) | ||
227 | return 0; | ||
228 | |||
229 | if (argcv_get (value, "", NULL, &argc, &argv)) | ||
230 | return 0; | ||
231 | |||
232 | for (i = 0; i < argc; i++) | ||
233 | { | ||
234 | char *p; | ||
235 | size_t num = strtoul (argv[i], &p, 10); | ||
236 | |||
237 | if (*p) | ||
238 | continue; | ||
239 | |||
240 | if (bsearch (&num, mset->list, mset->count, sizeof (mset->list[0]), | ||
241 | cmp_msgnum)) | ||
242 | { | ||
243 | free (argv[i]); | ||
244 | argv[i] = NULL; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | p = value; | ||
249 | for (i = 0; i < argc; i++) | ||
250 | { | ||
251 | if (argv[i]) | ||
252 | { | ||
253 | strcpy (p, argv[i]); | ||
254 | p += strlen (p); | ||
255 | *p++ = ' '; | ||
256 | } | ||
257 | } | ||
258 | *p = 0; | ||
259 | write_sequence (name, value, mode_public); | ||
260 | argcv_free (argc, argv); | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int | ||
266 | action_list (void *item, void *data) | ||
267 | { | ||
268 | char *name = item; | ||
269 | char *val; | ||
270 | |||
271 | val = read_sequence (name, 1); | ||
272 | if (val) | ||
273 | printf ("%s: %s\n", name, val); | ||
274 | else if ((val = read_sequence (name, 0))) | ||
275 | printf ("%s (%s): %s\n", name, _("private"), val); | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int | ||
280 | list_private (char *name, char *value, char *data) | ||
281 | { | ||
282 | int nlen; | ||
283 | |||
284 | if (memcmp (name, "atr-", 4)) | ||
285 | return 0; | ||
286 | name += 4; | ||
287 | |||
288 | nlen = strlen (name) - strlen (mbox_dir); | ||
289 | if (nlen > 0 && strcmp (name + nlen, mbox_dir) == 0) | ||
290 | { | ||
291 | name[nlen-1] = 0; | ||
292 | printf ("%s (%s): %s\n", name, _("private"), value); | ||
293 | } | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int | ||
298 | list_public (char *name, char *value, char *data) | ||
299 | { | ||
300 | printf ("%s: %s\n", name, value); | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static void | ||
305 | list_all () | ||
306 | { | ||
307 | mh_global_sequences_iterate (list_public, NULL); | ||
308 | mh_global_context_iterate (list_private, NULL); | ||
309 | } | ||
310 | |||
311 | int | ||
312 | main (int argc, char **argv) | ||
313 | { | ||
314 | int index; | ||
315 | mh_msgset_t msgset; | ||
316 | mailbox_t mbox; | ||
317 | url_t url; | ||
318 | |||
319 | mu_init_nls (); | ||
320 | mh_argp_parse (argc, argv, options, mh_option, args_doc, doc, | ||
321 | opt_handler, NULL, &index); | ||
322 | |||
323 | mbox = mh_open_folder (current_folder, 0); | ||
324 | mailbox_get_url (mbox, &url); | ||
325 | mbox_dir = url_to_string (url); | ||
326 | if (memcmp (mbox_dir, "mh:", 3) == 0) | ||
327 | mbox_dir += 3; | ||
328 | |||
329 | argc -= index; | ||
330 | argv += index; | ||
331 | mh_msgset_parse (mbox, &msgset, argc, argv, "cur"); | ||
332 | |||
333 | switch (action) | ||
334 | { | ||
335 | case ARG_ADD: | ||
336 | if (!seq_list) | ||
337 | { | ||
338 | mh_error (_("--add requires at least one --sequence argument")); | ||
339 | return 1; | ||
340 | } | ||
341 | list_do (seq_list, action_add, (void *) &msgset); | ||
342 | mh_global_save_state (); | ||
343 | break; | ||
344 | |||
345 | case ARG_DELETE: | ||
346 | if (!seq_list) | ||
347 | { | ||
348 | mh_error (_("--delete requires at least one --sequence argument")); | ||
349 | return 1; | ||
350 | } | ||
351 | list_do (seq_list, action_delete, (void *) &msgset); | ||
352 | mh_global_save_state (); | ||
353 | break; | ||
354 | |||
355 | case ARG_LIST: | ||
356 | if (!seq_list) | ||
357 | list_all (); | ||
358 | else | ||
359 | list_do (seq_list, action_list, NULL); | ||
360 | break; | ||
361 | } | ||
362 | |||
363 | return 0; | ||
364 | } |
-
Please register or sign in to post a comment