Fix expansion of #, &, %, etc. in mail copy and file commands.
This was accidentally broken by commit eea2c4aa. * include/mailutils/mailbox.h (mu_mailbox_expand_name): New proto. * libmailutils/mailbox/mbx_default.c (mu_mailbox_expand_name): New function. (mu_mailbox_create_default): Use it. (mu_set_folder_directory): Accept NULL as argument. (mu_folder_directory): Reset default value after assiging it. This way the folder directory still defaults to the same value as earlier, but can be reset to NULL, if so desired. (plus_expand): Return a copy of the input string if folder is NULL. * mail/copy.c (append_to_mailbox): Use mu_mailbox_create, as the mailbox name has already been expanded. * mail/file.c (mail_expand_name): Use mu_mailbox_expand_name. (mail_file): Use mu_mailbox_create, as the mailbox name has already been expanded. * mail/mailvar.c (mailvar_cmd): New enum. (mailvar_symbol) <handler>: Change signature and return type. (mailvar_set): Rewrite. Take care not to modify the variable if the handler (if any) returns non-null or if the memory can't be allocated. (set_folder): Handler for the "folder" variable. * mail/tests/copy01.at: New testcase. * mail/tests/copy02.at: New testcase. * mail/tests/copy03.at: New testcase. * mail/tests/copy04.at: New testcase. * mail/tests/Makefile.am: Add new tests. * mail/tests/testsuite.at (MUT_MAIL_CMD): Set MAILRC to /dev/null. Add new tests.
Showing
18 changed files
with
462 additions
and
164 deletions
... | @@ -36,6 +36,8 @@ const char *mu_mailbox_url (void); | ... | @@ -36,6 +36,8 @@ const char *mu_mailbox_url (void); |
36 | const char *mu_folder_directory (void); | 36 | const char *mu_folder_directory (void); |
37 | int mu_construct_user_mailbox_url (char **pout, const char *name); | 37 | int mu_construct_user_mailbox_url (char **pout, const char *name); |
38 | 38 | ||
39 | int mu_mailbox_expand_name (const char *name, char **expansion); | ||
40 | |||
39 | /* Constructor/destructor and possible types. */ | 41 | /* Constructor/destructor and possible types. */ |
40 | extern int mu_mailbox_create (mu_mailbox_t *, const char *); | 42 | extern int mu_mailbox_create (mu_mailbox_t *, const char *); |
41 | extern int mu_mailbox_create_from_url (mu_mailbox_t *, mu_url_t); | 43 | extern int mu_mailbox_create_from_url (mu_mailbox_t *, mu_url_t); | ... | ... |
... | @@ -117,9 +117,17 @@ mu_set_mailbox_pattern (const char *pat) | ... | @@ -117,9 +117,17 @@ mu_set_mailbox_pattern (const char *pat) |
117 | int | 117 | int |
118 | mu_set_folder_directory (const char *p) | 118 | mu_set_folder_directory (const char *p) |
119 | { | 119 | { |
120 | char *fdir = strdup (p); | 120 | char *fdir; |
121 | if (!fdir) | 121 | |
122 | return ENOMEM; | 122 | if (p) |
123 | { | ||
124 | fdir = strdup (p); | ||
125 | if (!fdir) | ||
126 | return ENOMEM; | ||
127 | } | ||
128 | else | ||
129 | fdir = NULL; | ||
130 | |||
123 | if (_mu_folder_dir != _default_folder_dir) | 131 | if (_mu_folder_dir != _default_folder_dir) |
124 | free (_mu_folder_dir); | 132 | free (_mu_folder_dir); |
125 | _mu_folder_dir = fdir; | 133 | _mu_folder_dir = fdir; |
... | @@ -127,7 +135,7 @@ mu_set_folder_directory (const char *p) | ... | @@ -127,7 +135,7 @@ mu_set_folder_directory (const char *p) |
127 | } | 135 | } |
128 | 136 | ||
129 | const char * | 137 | const char * |
130 | mu_mailbox_url () | 138 | mu_mailbox_url (void) |
131 | { | 139 | { |
132 | if (_mu_mailbox_pattern) | 140 | if (_mu_mailbox_pattern) |
133 | return _mu_mailbox_pattern; | 141 | return _mu_mailbox_pattern; |
... | @@ -135,10 +143,13 @@ mu_mailbox_url () | ... | @@ -135,10 +143,13 @@ mu_mailbox_url () |
135 | } | 143 | } |
136 | 144 | ||
137 | const char * | 145 | const char * |
138 | mu_folder_directory () | 146 | mu_folder_directory (void) |
139 | { | 147 | { |
140 | if (!_mu_folder_dir) | 148 | if (!_mu_folder_dir && _default_folder_dir) |
141 | _mu_folder_dir = _default_folder_dir; | 149 | { |
150 | mu_set_folder_directory (_default_folder_dir); | ||
151 | _default_folder_dir = NULL; | ||
152 | } | ||
142 | return _mu_folder_dir; | 153 | return _mu_folder_dir; |
143 | } | 154 | } |
144 | 155 | ||
... | @@ -286,30 +297,40 @@ user_mailbox_name (const char *user, char **mailbox_name) | ... | @@ -286,30 +297,40 @@ user_mailbox_name (const char *user, char **mailbox_name) |
286 | static int | 297 | static int |
287 | plus_expand (const char *file, char **buf) | 298 | plus_expand (const char *file, char **buf) |
288 | { | 299 | { |
289 | char *home; | 300 | int rc = 0; |
290 | const char *folder_dir = mu_folder_directory (); | 301 | const char *folder_dir = mu_folder_directory (); |
291 | 302 | ||
292 | home = get_homedir (NULL); | 303 | if (!folder_dir) |
293 | if (!home) | ||
294 | return ENOENT; | ||
295 | |||
296 | file++; | ||
297 | |||
298 | if (folder_dir[0] == '/' || mu_is_proto (folder_dir)) | ||
299 | { | 304 | { |
300 | *buf = mu_make_file_name (folder_dir, file); | 305 | char *p = strdup (file); |
301 | if (!*buf) | 306 | if (!p) |
302 | return errno; | 307 | return ENOMEM; |
308 | *buf = p; | ||
303 | } | 309 | } |
304 | else | 310 | else |
305 | { | 311 | { |
306 | int rc = mu_asprintf (buf, "%s/%s/%s", home, folder_dir, file); | 312 | file++; |
307 | if (rc) | 313 | |
308 | return rc; | 314 | if (folder_dir[0] == '/' || mu_is_proto (folder_dir)) |
315 | { | ||
316 | char *p = mu_make_file_name (folder_dir, file); | ||
317 | if (!p) | ||
318 | return errno; | ||
319 | *buf = p; | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | char *home = get_homedir (NULL); | ||
324 | |||
325 | if (!home) | ||
326 | return ENOENT; | ||
327 | |||
328 | rc = mu_asprintf (buf, "%s/%s/%s", home, folder_dir, file); | ||
329 | free (home); | ||
330 | } | ||
309 | } | 331 | } |
310 | 332 | ||
311 | free (home); | 333 | return rc; |
312 | return 0; | ||
313 | } | 334 | } |
314 | 335 | ||
315 | static int | 336 | static int |
... | @@ -374,21 +395,75 @@ attach_auth_ticket (mu_mailbox_t mbox) | ... | @@ -374,21 +395,75 @@ attach_auth_ticket (mu_mailbox_t mbox) |
374 | } | 395 | } |
375 | } | 396 | } |
376 | 397 | ||
377 | /* We are trying to be smart about the location of the mail. | 398 | /* Expand mailbox name according to the following rules: |
378 | mu_mailbox_create() is not doing this. | 399 | |
379 | % --> system mailbox for the real uid | 400 | NAME Expands to |
380 | %user --> system mailbox for the given user | 401 | -------------+------------------------------------ |
381 | ~/file --> /home/user/file | 402 | % -> system mailbox for the real uid |
382 | ~user/file --> /home/user/file | 403 | %user -> system mailbox for the given user |
383 | +file --> /home/user/Mail/file | 404 | ~/file -> /home/user/file |
384 | =file --> /home/user/Mail/file | 405 | ~user/file -> /home/user/file |
385 | */ | 406 | +file -> /home/user/Mail/file |
407 | =file -> /home/user/Mail/file | ||
408 | */ | ||
386 | int | 409 | int |
387 | mu_mailbox_create_default (mu_mailbox_t *pmbox, const char *mail) | 410 | mu_mailbox_expand_name (const char *name, char **expansion) |
388 | { | 411 | { |
389 | char *mbox = NULL; | 412 | int status = 0; |
390 | char *tmp_mbox = NULL; | ||
391 | char *p; | 413 | char *p; |
414 | char *mbox = NULL; | ||
415 | |||
416 | if (!name) | ||
417 | return EINVAL; | ||
418 | if (!expansion) | ||
419 | return MU_ERR_OUT_PTR_NULL; | ||
420 | |||
421 | p = mu_tilde_expansion (name, MU_HIERARCHY_DELIMITER, NULL); | ||
422 | if (!p) | ||
423 | return errno; | ||
424 | switch (p[0]) | ||
425 | { | ||
426 | case '%': | ||
427 | status = percent_expand (p, &mbox); | ||
428 | break; | ||
429 | |||
430 | case '+': | ||
431 | case '=': | ||
432 | status = plus_expand (p, &mbox); | ||
433 | break; | ||
434 | |||
435 | case '/': | ||
436 | mbox = p; | ||
437 | p = NULL; | ||
438 | break; | ||
439 | |||
440 | default: | ||
441 | if (!mu_is_proto (p)) | ||
442 | { | ||
443 | char *dir = mu_getcwd(); | ||
444 | mbox = mu_make_file_name (dir, p); | ||
445 | if (!mbox) | ||
446 | status = errno; | ||
447 | free (dir); | ||
448 | } | ||
449 | else | ||
450 | { | ||
451 | mbox = p; | ||
452 | p = NULL; | ||
453 | } | ||
454 | } | ||
455 | free (p); | ||
456 | if (status == 0) | ||
457 | *expansion = mbox; | ||
458 | return status; | ||
459 | } | ||
460 | |||
461 | /* Expand mailbox name MAIL and create a mailbox structure for it. */ | ||
462 | int | ||
463 | mu_mailbox_create_default (mu_mailbox_t *pmbox, const char *mail) | ||
464 | { | ||
465 | char *mboxname = NULL; | ||
466 | char *name_ptr = NULL; | ||
392 | int status = 0; | 467 | int status = 0; |
393 | 468 | ||
394 | /* Sanity. */ | 469 | /* Sanity. */ |
... | @@ -412,63 +487,19 @@ mu_mailbox_create_default (mu_mailbox_t *pmbox, const char *mail) | ... | @@ -412,63 +487,19 @@ mu_mailbox_create_default (mu_mailbox_t *pmbox, const char *mail) |
412 | 487 | ||
413 | if (!mail) | 488 | if (!mail) |
414 | { | 489 | { |
415 | if ((status = user_mailbox_name (NULL, &tmp_mbox))) | 490 | if ((status = user_mailbox_name (NULL, &name_ptr))) |
416 | return status; | 491 | return status; |
417 | mail = tmp_mbox; | 492 | mail = name_ptr; |
418 | } | ||
419 | } | ||
420 | |||
421 | p = mu_tilde_expansion (mail, MU_HIERARCHY_DELIMITER, NULL); | ||
422 | if (tmp_mbox) | ||
423 | free (tmp_mbox); | ||
424 | tmp_mbox = p; | ||
425 | mail = tmp_mbox; | ||
426 | if (!mail) | ||
427 | return ENOMEM; | ||
428 | |||
429 | switch (mail[0]) | ||
430 | { | ||
431 | case '%': | ||
432 | status = percent_expand (mail, &mbox); | ||
433 | break; | ||
434 | |||
435 | case '+': | ||
436 | case '=': | ||
437 | status = plus_expand (mail, &mbox); | ||
438 | break; | ||
439 | |||
440 | case '/': | ||
441 | mbox = strdup (mail); | ||
442 | if (!mbox) | ||
443 | status = errno; | ||
444 | break; | ||
445 | |||
446 | default: | ||
447 | if (!mu_is_proto (mail)) | ||
448 | { | ||
449 | p = mu_getcwd(); | ||
450 | mbox = mu_make_file_name (p, mail); | ||
451 | if (!mbox) | ||
452 | status = errno; | ||
453 | free (p); | ||
454 | } | ||
455 | else | ||
456 | { | ||
457 | mbox = strdup (mail); | ||
458 | if (!mbox) | ||
459 | status = errno; | ||
460 | } | 493 | } |
461 | break; | ||
462 | } | 494 | } |
463 | 495 | ||
464 | if (tmp_mbox) | 496 | status = mu_mailbox_expand_name (mail, &mboxname); |
465 | free (tmp_mbox); | 497 | free (name_ptr); |
466 | |||
467 | if (status) | 498 | if (status) |
468 | return status; | 499 | return status; |
469 | 500 | ||
470 | status = mu_mailbox_create (pmbox, mbox); | 501 | status = mu_mailbox_create (pmbox, mboxname); |
471 | free (mbox); | 502 | free (mboxname); |
472 | if (status == 0) | 503 | if (status == 0) |
473 | attach_auth_ticket (*pmbox); | 504 | attach_auth_ticket (*pmbox); |
474 | 505 | ... | ... |
... | @@ -40,7 +40,7 @@ append_to_mailbox (char const *filename, msgset_t *msglist, int mark, | ... | @@ -40,7 +40,7 @@ append_to_mailbox (char const *filename, msgset_t *msglist, int mark, |
40 | size_t size; | 40 | size_t size; |
41 | mu_message_t msg; | 41 | mu_message_t msg; |
42 | 42 | ||
43 | if ((status = mu_mailbox_create_default (&mbx, filename)) != 0) | 43 | if ((status = mu_mailbox_create (&mbx, filename)) != 0) |
44 | { | 44 | { |
45 | mu_error (_("Cannot create mailbox %s: %s"), filename, | 45 | mu_error (_("Cannot create mailbox %s: %s"), filename, |
46 | mu_strerror (status)); | 46 | mu_strerror (status)); |
... | @@ -96,7 +96,7 @@ append_to_file (char const *filename, msgset_t *msglist, int mark, | ... | @@ -96,7 +96,7 @@ append_to_file (char const *filename, msgset_t *msglist, int mark, |
96 | size_t lines; | 96 | size_t lines; |
97 | mu_message_t msg; | 97 | mu_message_t msg; |
98 | mu_locker_t locker; | 98 | mu_locker_t locker; |
99 | 99 | ||
100 | status = mu_file_stream_create (&ostr, filename, | 100 | status = mu_file_stream_create (&ostr, filename, |
101 | MU_STREAM_CREAT|MU_STREAM_APPEND); | 101 | MU_STREAM_CREAT|MU_STREAM_APPEND); |
102 | if (status) | 102 | if (status) | ... | ... |
... | @@ -23,44 +23,43 @@ static char *prev_name; | ... | @@ -23,44 +23,43 @@ static char *prev_name; |
23 | * # the previous file | 23 | * # the previous file |
24 | * & the current mbox | 24 | * & the current mbox |
25 | * +file the file named in the folder directory (set folder=foo) | 25 | * +file the file named in the folder directory (set folder=foo) |
26 | * Note 1) The followig notations are left intact, since they are | ||
27 | * handled by mu_mailbox_create_default: | ||
28 | * % system mailbox | 26 | * % system mailbox |
29 | * %user system mailbox of the user | 27 | * %user system mailbox of the user |
30 | * Note 2) Allocates memory | ||
31 | */ | 28 | */ |
32 | char * | 29 | char * |
33 | mail_expand_name (const char *name) | 30 | mail_expand_name (const char *name) |
34 | { | 31 | { |
35 | switch (name[0]) | 32 | int status = 0; |
33 | char *exp = NULL; | ||
34 | |||
35 | if (strcmp (name, "#") == 0) | ||
36 | { | 36 | { |
37 | case '#': | ||
38 | if (!prev_name) | 37 | if (!prev_name) |
39 | { | 38 | { |
40 | mu_error (_("No previous file")); | 39 | mu_error (_("No previous file")); |
41 | return NULL; | 40 | return NULL; |
42 | } | 41 | } |
43 | else | 42 | else |
44 | name = mu_strdup (prev_name); | 43 | return mu_strdup (prev_name); |
45 | break; | 44 | } |
46 | 45 | ||
47 | case '&': | 46 | if (strcmp (name, "&") == 0) |
47 | { | ||
48 | name = getenv ("MBOX"); | 48 | name = getenv ("MBOX"); |
49 | if (!name) | 49 | if (!name) |
50 | mu_error (_("MBOX environment variable not set")); | 50 | { |
51 | else | 51 | mu_error (_("MBOX environment variable not set")); |
52 | name = mu_strdup (name); | 52 | return NULL; |
53 | break; | 53 | } |
54 | 54 | /* else fall through */ | |
55 | case '+': | ||
56 | name = util_folder_path (name); | ||
57 | break; | ||
58 | |||
59 | default: | ||
60 | name = mu_strdup (name); | ||
61 | break; | ||
62 | } | 55 | } |
63 | return (char*) name; | 56 | |
57 | status = mu_mailbox_expand_name (name, &exp); | ||
58 | |||
59 | if (status) | ||
60 | mu_error (_("Failed to expand %s: %s"), name, mu_strerror (status)); | ||
61 | |||
62 | return (char*) exp; | ||
64 | } | 63 | } |
65 | 64 | ||
66 | /* | 65 | /* |
... | @@ -87,7 +86,7 @@ mail_file (int argc, char **argv) | ... | @@ -87,7 +86,7 @@ mail_file (int argc, char **argv) |
87 | if (!name) | 86 | if (!name) |
88 | return 1; | 87 | return 1; |
89 | 88 | ||
90 | if ((status = mu_mailbox_create_default (&newbox, name)) != 0 | 89 | if ((status = mu_mailbox_create (&newbox, name)) != 0 |
91 | || (status = mu_mailbox_open (newbox, MU_STREAM_RDWR)) != 0) | 90 | || (status = mu_mailbox_open (newbox, MU_STREAM_RDWR)) != 0) |
92 | { | 91 | { |
93 | mu_mailbox_destroy (&newbox); | 92 | mu_mailbox_destroy (&newbox); | ... | ... |
... | @@ -538,10 +538,10 @@ compile_headline (const char *str) | ... | @@ -538,10 +538,10 @@ compile_headline (const char *str) |
538 | static struct header_segm *mail_header_line; | 538 | static struct header_segm *mail_header_line; |
539 | 539 | ||
540 | void | 540 | void |
541 | mail_compile_headline (struct mailvar_variable *var) | 541 | mail_compile_headline (char const *str) |
542 | { | 542 | { |
543 | free_headline (mail_header_line); | 543 | free_headline (mail_header_line); |
544 | mail_header_line = compile_headline (var->value.string); | 544 | mail_header_line = compile_headline (str); |
545 | } | 545 | } |
546 | 546 | ||
547 | 547 | ... | ... |
... | @@ -330,6 +330,7 @@ static char *default_setup[] = { | ... | @@ -330,6 +330,7 @@ static char *default_setup[] = { |
330 | "set noinplacealiases", | 330 | "set noinplacealiases", |
331 | "set fromfield", | 331 | "set fromfield", |
332 | "set headline=\"%>%a%4m %18f %16d %3L/%-5o %s\"", | 332 | "set headline=\"%>%a%4m %18f %16d %3L/%-5o %s\"", |
333 | "unset folder", | ||
333 | 334 | ||
334 | /* Start in mail reading mode */ | 335 | /* Start in mail reading mode */ |
335 | "setq mode=read", | 336 | "setq mode=read", | ... | ... |
... | @@ -193,7 +193,7 @@ extern int mail_folders (int argc, char **argv); | ... | @@ -193,7 +193,7 @@ extern int mail_folders (int argc, char **argv); |
193 | extern int mail_followup (int argc, char **argv); | 193 | extern int mail_followup (int argc, char **argv); |
194 | extern int mail_from (int argc, char **argv); | 194 | extern int mail_from (int argc, char **argv); |
195 | extern int mail_from0 (msgset_t *mspec, mu_message_t msg, void *data); | 195 | extern int mail_from0 (msgset_t *mspec, mu_message_t msg, void *data); |
196 | extern void mail_compile_headline (struct mailvar_variable *var); | 196 | extern void mail_compile_headline (char const *str); |
197 | 197 | ||
198 | extern int mail_headers (int argc, char **argv); | 198 | extern int mail_headers (int argc, char **argv); |
199 | extern int mail_hold (int argc, char **argv); | 199 | extern int mail_hold (int argc, char **argv); | ... | ... |
... | @@ -22,20 +22,34 @@ | ... | @@ -22,20 +22,34 @@ |
22 | 22 | ||
23 | #define MAILVAR_TYPEMASK(type) (1<<(8+(type))) | 23 | #define MAILVAR_TYPEMASK(type) (1<<(8+(type))) |
24 | 24 | ||
25 | enum mailvar_cmd | ||
26 | { | ||
27 | mailvar_cmd_set, | ||
28 | mailvar_cmd_unset | ||
29 | }; | ||
30 | |||
25 | struct mailvar_symbol | 31 | struct mailvar_symbol |
26 | { | 32 | { |
27 | struct mailvar_variable var; | 33 | struct mailvar_variable var; |
28 | int flags; | 34 | int flags; |
29 | char *descr; | 35 | char *descr; |
30 | void (*handler) (struct mailvar_variable *); | 36 | int (*handler) (enum mailvar_cmd, struct mailvar_variable *); |
31 | }; | 37 | }; |
32 | 38 | ||
33 | mu_list_t mailvar_list = NULL; | 39 | mu_list_t mailvar_list = NULL; |
34 | 40 | ||
35 | static void set_decode_fallback (struct mailvar_variable *); | 41 | static int set_decode_fallback (enum mailvar_cmd cmd, |
36 | static void set_replyregex (struct mailvar_variable *); | 42 | struct mailvar_variable *); |
37 | static void set_screen (struct mailvar_variable *); | 43 | static int set_replyregex (enum mailvar_cmd cmd, |
38 | static void set_debug (struct mailvar_variable *); | 44 | struct mailvar_variable *); |
45 | static int set_screen (enum mailvar_cmd cmd, | ||
46 | struct mailvar_variable *); | ||
47 | static int set_debug (enum mailvar_cmd cmd, | ||
48 | struct mailvar_variable *); | ||
49 | static int set_folder (enum mailvar_cmd cmd, | ||
50 | struct mailvar_variable *); | ||
51 | static int set_headline (enum mailvar_cmd, | ||
52 | struct mailvar_variable *); | ||
39 | 53 | ||
40 | struct mailvar_symbol mailvar_tab[] = | 54 | struct mailvar_symbol mailvar_tab[] = |
41 | { | 55 | { |
... | @@ -119,7 +133,8 @@ struct mailvar_symbol mailvar_tab[] = | ... | @@ -119,7 +133,8 @@ struct mailvar_symbol mailvar_tab[] = |
119 | N_("swap the meaning of reply and Reply commands") }, | 133 | N_("swap the meaning of reply and Reply commands") }, |
120 | { { "folder", }, | 134 | { { "folder", }, |
121 | MAILVAR_TYPEMASK (mailvar_type_string), | 135 | MAILVAR_TYPEMASK (mailvar_type_string), |
122 | N_("folder directory name") }, | 136 | N_("folder directory name"), |
137 | set_folder }, | ||
123 | { { "fromfield", }, | 138 | { { "fromfield", }, |
124 | MAILVAR_TYPEMASK (mailvar_type_boolean), | 139 | MAILVAR_TYPEMASK (mailvar_type_boolean), |
125 | N_("get sender address from the `From:' header, instead of " | 140 | N_("get sender address from the `From:' header, instead of " |
... | @@ -133,7 +148,7 @@ struct mailvar_symbol mailvar_tab[] = | ... | @@ -133,7 +148,7 @@ struct mailvar_symbol mailvar_tab[] = |
133 | { { "headline", }, | 148 | { { "headline", }, |
134 | MAILVAR_TYPEMASK (mailvar_type_string), | 149 | MAILVAR_TYPEMASK (mailvar_type_string), |
135 | N_("format string to use for the header summary"), | 150 | N_("format string to use for the header summary"), |
136 | mail_compile_headline }, | 151 | set_headline }, |
137 | { { "hold", }, | 152 | { { "hold", }, |
138 | MAILVAR_TYPEMASK (mailvar_type_boolean), | 153 | MAILVAR_TYPEMASK (mailvar_type_boolean), |
139 | N_("hold the read or saved messages in the system mailbox") }, | 154 | N_("hold the read or saved messages in the system mailbox") }, |
... | @@ -471,9 +486,10 @@ int | ... | @@ -471,9 +486,10 @@ int |
471 | mailvar_set (const char *variable, void *value, enum mailvar_type type, | 486 | mailvar_set (const char *variable, void *value, enum mailvar_type type, |
472 | int flags) | 487 | int flags) |
473 | { | 488 | { |
474 | struct mailvar_variable *var; | 489 | struct mailvar_variable *var, newvar; |
475 | const struct mailvar_symbol *sym = find_mailvar_symbol (variable); | 490 | const struct mailvar_symbol *sym = find_mailvar_symbol (variable); |
476 | int unset = flags & MOPTF_UNSET; | 491 | enum mailvar_cmd cmd = |
492 | (flags & MOPTF_UNSET) ? mailvar_cmd_unset : mailvar_cmd_set; | ||
477 | 493 | ||
478 | if (!(flags & MOPTF_QUIET) | 494 | if (!(flags & MOPTF_QUIET) |
479 | && mailvar_get (NULL, "variable-strict", mailvar_type_boolean, 0) == 0) | 495 | && mailvar_get (NULL, "variable-strict", mailvar_type_boolean, 0) == 0) |
... | @@ -488,95 +504,174 @@ mailvar_set (const char *variable, void *value, enum mailvar_type type, | ... | @@ -488,95 +504,174 @@ mailvar_set (const char *variable, void *value, enum mailvar_type type, |
488 | return 1; | 504 | return 1; |
489 | } | 505 | } |
490 | else if (!(sym->flags & MAILVAR_TYPEMASK (type)) | 506 | else if (!(sym->flags & MAILVAR_TYPEMASK (type)) |
491 | && !unset) | 507 | && cmd == mailvar_cmd_set) |
492 | { | 508 | { |
493 | mu_error (_("Wrong type for %s"), variable); | 509 | mu_error (_("Wrong type for %s"), variable); |
494 | return 1; | 510 | return 1; |
495 | } | 511 | } |
496 | } | 512 | } |
497 | 513 | ||
498 | var = mailvar_find_variable (variable, !unset); | 514 | var = mailvar_find_variable (variable, cmd == mailvar_cmd_set); |
499 | 515 | ||
500 | if (!var || (var->set && !(flags & MOPTF_OVERWRITE))) | 516 | if (!var || (var->set && !(flags & MOPTF_OVERWRITE))) |
501 | return 0; | 517 | return 0; |
502 | 518 | ||
503 | mailvar_variable_reset (var); | 519 | newvar.name = var->name; |
504 | if (!unset) | 520 | newvar.type = var->type; |
521 | newvar.set = 0; | ||
522 | memset (&newvar.value, 0, sizeof (newvar.value)); | ||
523 | |||
524 | switch (cmd) | ||
505 | { | 525 | { |
506 | var->type = type; | 526 | case mailvar_cmd_set: |
507 | if (value) | 527 | if (value) |
508 | { | 528 | { |
509 | var->set = 1; | ||
510 | switch (type) | 529 | switch (type) |
511 | { | 530 | { |
512 | case mailvar_type_number: | 531 | case mailvar_type_number: |
513 | var->value.number = *(int*)value; | 532 | newvar.value.number = *(int*)value; |
514 | break; | 533 | break; |
515 | 534 | ||
516 | case mailvar_type_string: | 535 | case mailvar_type_string: |
517 | var->value.string = strdup (value); | 536 | { |
537 | char *p = strdup (value); | ||
538 | if (!p) | ||
539 | { | ||
540 | mu_error ("%s", _("Not enough memory")); | ||
541 | return 1; | ||
542 | } | ||
543 | newvar.value.string = p; | ||
544 | } | ||
518 | break; | 545 | break; |
519 | 546 | ||
520 | case mailvar_type_boolean: | 547 | case mailvar_type_boolean: |
521 | var->value.bool = *(int*)value; | 548 | newvar.value.bool = *(int*)value; |
522 | break; | 549 | break; |
523 | 550 | ||
524 | default: | 551 | default: |
525 | abort(); | 552 | abort(); |
526 | } | 553 | } |
554 | newvar.set = 1; | ||
555 | } | ||
556 | newvar.type = type; | ||
557 | if (sym | ||
558 | && sym->handler | ||
559 | && sym->flags & MAILVAR_TYPEMASK (type) | ||
560 | && sym->handler (cmd, &newvar)) | ||
561 | { | ||
562 | mailvar_variable_reset (&newvar); | ||
563 | return 1; | ||
527 | } | 564 | } |
565 | mailvar_variable_reset (var); | ||
566 | *var = newvar; | ||
567 | break; | ||
568 | |||
569 | case mailvar_cmd_unset: | ||
570 | if (sym | ||
571 | && sym->handler | ||
572 | && sym->handler (cmd, var)) | ||
573 | return 1; | ||
574 | mailvar_variable_reset (var); | ||
528 | } | 575 | } |
529 | 576 | ||
530 | /* Special handling for some variables */ | 577 | return 0; |
531 | if (sym && sym->flags & MAILVAR_TYPEMASK (type) && sym->handler) | 578 | } |
532 | sym->handler (var); | 579 | |
580 | static int | ||
581 | set_folder (enum mailvar_cmd cmd, struct mailvar_variable *var) | ||
582 | { | ||
583 | int rc = mu_set_folder_directory (var->value.string); | ||
584 | if (rc) | ||
585 | mu_diag_funcall (MU_DIAG_ERROR, "mu_set_folder_directory", | ||
586 | var->value.string, rc); | ||
587 | return rc; | ||
588 | } | ||
589 | |||
590 | |||
591 | static int | ||
592 | set_headline (enum mailvar_cmd cmd, struct mailvar_variable *var) | ||
593 | { | ||
594 | if (cmd == mailvar_cmd_unset) | ||
595 | return 1; | ||
533 | 596 | ||
597 | mail_compile_headline (var->value.string); | ||
534 | return 0; | 598 | return 0; |
535 | } | 599 | } |
536 | 600 | ||
537 | 601 | static int | |
538 | static void | 602 | set_decode_fallback (enum mailvar_cmd cmd, struct mailvar_variable *var) |
539 | set_decode_fallback (struct mailvar_variable *var) | ||
540 | { | 603 | { |
541 | if (mu_set_default_fallback (var->value.string)) | 604 | char *value; |
605 | int rc; | ||
606 | |||
607 | switch (cmd) | ||
608 | { | ||
609 | case mailvar_cmd_set: | ||
610 | value = var->value.string; | ||
611 | break; | ||
612 | |||
613 | case mailvar_cmd_unset: | ||
614 | value = "none"; | ||
615 | } | ||
616 | |||
617 | rc = mu_set_default_fallback (value); | ||
618 | if (rc) | ||
542 | mu_error (_("Incorrect value for decode-fallback")); | 619 | mu_error (_("Incorrect value for decode-fallback")); |
620 | return rc; | ||
543 | } | 621 | } |
544 | 622 | ||
545 | static void | 623 | static int |
546 | set_replyregex (struct mailvar_variable *var) | 624 | set_replyregex (enum mailvar_cmd cmd, struct mailvar_variable *var) |
547 | { | 625 | { |
548 | int rc; | 626 | int rc; |
549 | char *err; | 627 | char *err; |
550 | 628 | ||
551 | if ((rc = mu_unre_set_regex (var->value.string, 0, &err))) | 629 | switch (cmd) |
552 | { | 630 | { |
553 | if (err) | 631 | case mailvar_cmd_set: |
554 | mu_error ("%s: %s", mu_strerror (rc), err); | 632 | if ((rc = mu_unre_set_regex (var->value.string, 0, &err))) |
555 | else | 633 | { |
556 | mu_error ("%s", mu_strerror (rc)); | 634 | if (err) |
635 | mu_error ("%s: %s", mu_strerror (rc), err); | ||
636 | else | ||
637 | mu_error ("%s", mu_strerror (rc)); | ||
638 | return 1; | ||
639 | } | ||
640 | break; | ||
641 | |||
642 | case mailvar_cmd_unset: | ||
643 | return 1; | ||
557 | } | 644 | } |
645 | |||
646 | return 0; | ||
558 | } | 647 | } |
559 | 648 | ||
560 | static void | 649 | static int |
561 | set_screen (struct mailvar_variable *var) | 650 | set_screen (enum mailvar_cmd cmd, struct mailvar_variable *var) |
562 | { | 651 | { |
563 | page_invalidate (1); | 652 | if (cmd == mailvar_cmd_set) |
653 | page_invalidate (1); | ||
654 | return 0; | ||
564 | } | 655 | } |
565 | 656 | ||
566 | #define DEFAULT_DEBUG_LEVEL MU_DEBUG_LEVEL_UPTO (MU_DEBUG_TRACE7) | 657 | #define DEFAULT_DEBUG_LEVEL MU_DEBUG_LEVEL_UPTO (MU_DEBUG_TRACE7) |
567 | 658 | ||
568 | static void | 659 | static int |
569 | set_debug (struct mailvar_variable *var) | 660 | set_debug (enum mailvar_cmd cmd, struct mailvar_variable *var) |
570 | { | 661 | { |
571 | mu_debug_clear_all (); | 662 | mu_debug_clear_all (); |
572 | 663 | ||
573 | if (var->type == mailvar_type_boolean) | 664 | if (cmd == mailvar_cmd_set) |
574 | { | 665 | { |
575 | if (var->set) | 666 | if (var->type == mailvar_type_boolean) |
576 | mu_debug_set_category_level (MU_DEBCAT_ALL, DEFAULT_DEBUG_LEVEL); | 667 | { |
577 | return; | 668 | if (var->set) |
669 | mu_debug_set_category_level (MU_DEBCAT_ALL, DEFAULT_DEBUG_LEVEL); | ||
670 | return 0; | ||
671 | } | ||
672 | mu_debug_parse_spec (var->value.string); | ||
578 | } | 673 | } |
579 | mu_debug_parse_spec (var->value.string); | 674 | return 0; |
580 | } | 675 | } |
581 | 676 | ||
582 | 677 | ... | ... |
... | @@ -42,6 +42,10 @@ TESTSUITE_AT =\ | ... | @@ -42,6 +42,10 @@ TESTSUITE_AT =\ |
42 | cols00.at\ | 42 | cols00.at\ |
43 | cols01.at\ | 43 | cols01.at\ |
44 | copy00.at\ | 44 | copy00.at\ |
45 | copy01.at\ | ||
46 | copy02.at\ | ||
47 | copy03.at\ | ||
48 | copy04.at\ | ||
45 | nohome.at\ | 49 | nohome.at\ |
46 | testsuite.at\ | 50 | testsuite.at\ |
47 | version.at | 51 | version.at | ... | ... |
... | @@ -24,7 +24,6 @@ AT_KEYWORDS([columns cols00]) | ... | @@ -24,7 +24,6 @@ AT_KEYWORDS([columns cols00]) |
24 | 24 | ||
25 | AT_CHECK([ | 25 | AT_CHECK([ |
26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) | 26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) |
27 | unset MAILRC | ||
28 | COLUMNS=26 MUT_MAIL_CMD -nH -E 'set columns=26' -f ./mbox | 27 | COLUMNS=26 MUT_MAIL_CMD -nH -E 'set columns=26' -f ./mbox |
29 | COLUMNS=31 MUT_MAIL_CMD -nH -f ./mbox | 28 | COLUMNS=31 MUT_MAIL_CMD -nH -f ./mbox |
30 | ], | 29 | ], | ... | ... |
... | @@ -24,7 +24,6 @@ AT_KEYWORDS([columns cols01]) | ... | @@ -24,7 +24,6 @@ AT_KEYWORDS([columns cols01]) |
24 | 24 | ||
25 | AT_CHECK([ | 25 | AT_CHECK([ |
26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) | 26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) |
27 | unset MAILRC | ||
28 | MUT_MAIL_CMD -nH -E 'set columns=26' -f ./mbox | 27 | MUT_MAIL_CMD -nH -E 'set columns=26' -f ./mbox |
29 | MUT_MAIL_CMD -nH -E 'set columns=31' -f ./mbox | 28 | MUT_MAIL_CMD -nH -E 'set columns=31' -f ./mbox |
30 | ], | 29 | ], | ... | ... |
... | @@ -25,7 +25,6 @@ AT_KEYWORDS([copy copy00]) | ... | @@ -25,7 +25,6 @@ AT_KEYWORDS([copy copy00]) |
25 | AT_CHECK([ | 25 | AT_CHECK([ |
26 | test -f /dev/stdout || AT_SKIP_TEST | 26 | test -f /dev/stdout || AT_SKIP_TEST |
27 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) | 27 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) |
28 | unset MAILRC | ||
29 | echo 'copy 1 /dev/stdout' | MUT_MAIL_CMD -N -E 'set readonly' -f ./mbox | sed 's/ *$//;/^Held 1 message/d'; | 28 | echo 'copy 1 /dev/stdout' | MUT_MAIL_CMD -N -E 'set readonly' -f ./mbox | sed 's/ *$//;/^Held 1 message/d'; |
30 | ], | 29 | ], |
31 | [0], | 30 | [0], | ... | ... |
mail/tests/copy01.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2015-2016 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # 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, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AT_SETUP([copy: % expansion]) | ||
18 | AT_KEYWORDS([copy copy01]) | ||
19 | |||
20 | # Description: Check whether special mailbox notations are correctly expanded | ||
21 | # in copy command. This was broken by commit eea2c4aa. | ||
22 | # | ||
23 | # This testcase checks for expansion of "%". | ||
24 | |||
25 | AT_CHECK([ | ||
26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) | ||
27 | mbox=`pwd`/user | ||
28 | echo 'copy 1 %' | dnl | ||
29 | MUT_MAIL_CMD -N -f ./mbox --set '|mailbox|mailbox-pattern'=$mbox | dnl | ||
30 | sed 's/ *$//;/^Held 1 message/d;s|'$mbox'|MBOX|' | ||
31 | cmp user $abs_top_srcdir/testsuite/spool/mbox | ||
32 | ], | ||
33 | [0], | ||
34 | ["MBOX" 14/438 | ||
35 | |||
36 | ]) | ||
37 | |||
38 | AT_CLEANUP |
mail/tests/copy02.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2015-2016 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # 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, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AT_SETUP([copy: + expansion]) | ||
18 | AT_KEYWORDS([copy copy02]) | ||
19 | |||
20 | # Description: Check whether special mailbox notations are correctly expanded | ||
21 | # in copy command. This was broken by commit eea2c4aa. | ||
22 | # | ||
23 | # This testcase checks for expansion of "+". | ||
24 | |||
25 | AT_CHECK([ | ||
26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) | ||
27 | mkdir folder | ||
28 | folder=`pwd`/folder | ||
29 | echo 'copy 1 +saved' | dnl | ||
30 | MUT_MAIL_CMD -N -E "set folder=\"$folder\"" -f ./mbox | dnl | ||
31 | sed 's/ *$//;/^Held 1 message/d;s|'$folder/saved'|MBOX|' | ||
32 | test -f $folder/saved || exit 1 | ||
33 | cmp $folder/saved $abs_top_srcdir/testsuite/spool/mbox | ||
34 | ], | ||
35 | [0], | ||
36 | ["MBOX" 14/438 | ||
37 | |||
38 | ]) | ||
39 | |||
40 | AT_CLEANUP |
mail/tests/copy03.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2015-2016 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # 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, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AT_SETUP([copy: & expansion]) | ||
18 | AT_KEYWORDS([copy copy03]) | ||
19 | |||
20 | # Description: Check whether special mailbox notations are correctly expanded | ||
21 | # in copy command. This was broken by commit eea2c4aa. | ||
22 | # | ||
23 | # This testcase checks for expansion of "&". | ||
24 | |||
25 | AT_CHECK([ | ||
26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) | ||
27 | mkdir folder | ||
28 | MBOX=`pwd`/MBOX | ||
29 | export MBOX | ||
30 | echo 'copy 1 &' | dnl | ||
31 | MUT_MAIL_CMD -N -E "set folder=\"$folder\"" -f ./mbox | dnl | ||
32 | sed 's/ *$//;/^Held 1 message/d;s|'$MBOX'|MBOX|' | ||
33 | test -f $MBOX || exit 1 | ||
34 | cmp $MBOX $abs_top_srcdir/testsuite/spool/mbox | ||
35 | ], | ||
36 | [0], | ||
37 | ["MBOX" 14/438 | ||
38 | |||
39 | ]) | ||
40 | |||
41 | AT_CLEANUP |
mail/tests/copy04.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2015-2016 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # 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, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AT_SETUP([copy: # expansion]) | ||
18 | AT_KEYWORDS([copy copy04]) | ||
19 | |||
20 | # Description: Check whether special mailbox notations are correctly expanded | ||
21 | # in copy command. This was broken by commit eea2c4aa. | ||
22 | # | ||
23 | # This testcase checks for expansion of "#". | ||
24 | |||
25 | AT_CHECK([ | ||
26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) | ||
27 | folder=`pwd` | ||
28 | MBOX=$folder/mbox | ||
29 | NEW=$folder/new | ||
30 | >$NEW | ||
31 | AT_DATA([script],[file +new | ||
32 | file +mbox | ||
33 | copy 1 # | ||
34 | ]) | ||
35 | MUT_MAIL_CMD -N -E "set folder=\"$folder\"" -f $MBOX < script | dnl | ||
36 | sed 's/ *$//;s|'$NEW'|NEW|;s|'$MBOX'|MBOX|' | ||
37 | sed '/^X-IMAPbase:/d;/^Status:/d;/^X-UID/d' $NEW | diff - $abs_top_srcdir/testsuite/spool/mbox | ||
38 | ], | ||
39 | [0], | ||
40 | [Held 1 message in MBOX | ||
41 | Held 0 messages in NEW | ||
42 | "NEW" 17/482 | ||
43 | |||
44 | Held 1 message in MBOX | ||
45 | ]) | ||
46 | |||
47 | AT_CLEANUP |
... | @@ -24,7 +24,6 @@ AT_KEYWORDS([nohome]) | ... | @@ -24,7 +24,6 @@ AT_KEYWORDS([nohome]) |
24 | 24 | ||
25 | AT_CHECK([ | 25 | AT_CHECK([ |
26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) | 26 | MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) |
27 | unset MAILRC | ||
28 | unset HOME | 27 | unset HOME |
29 | MAIL=./mbox MUT_MAIL_CMD -nH | 28 | MAIL=./mbox MUT_MAIL_CMD -nH |
30 | ], | 29 | ], | ... | ... |
... | @@ -16,7 +16,7 @@ | ... | @@ -16,7 +16,7 @@ |
16 | 16 | ||
17 | m4_include([testsuite.inc]) | 17 | m4_include([testsuite.inc]) |
18 | 18 | ||
19 | m4_define([MUT_MAIL_CMD],[mail MUT_DEFAULT_OPTIONS]) | 19 | m4_define([MUT_MAIL_CMD],[MAILRC=/dev/null mail MUT_DEFAULT_OPTIONS]) |
20 | 20 | ||
21 | AT_INIT | 21 | AT_INIT |
22 | AT_TESTED([mail]) | 22 | AT_TESTED([mail]) |
... | @@ -25,4 +25,8 @@ m4_include([version.at]) | ... | @@ -25,4 +25,8 @@ m4_include([version.at]) |
25 | m4_include([nohome.at]) | 25 | m4_include([nohome.at]) |
26 | m4_include([cols00.at]) | 26 | m4_include([cols00.at]) |
27 | m4_include([cols01.at]) | 27 | m4_include([cols01.at]) |
28 | m4_include([copy00.at]) | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
28 | m4_include([copy00.at]) | ||
29 | m4_include([copy01.at]) | ||
30 | m4_include([copy02.at]) | ||
31 | m4_include([copy03.at]) | ||
32 | m4_include([copy04.at]) | ... | ... |
-
Please register or sign in to post a comment