Commit b7e41daa b7e41daa82b7ed40c06c6a01cd502fa409f836c3 by Sergey Poznyakoff

* NEWS: Update.

* frm/testsuite/frm/test.exp: Call mu_init with -noflags option.
Use --mail-folder option when necessary.
* messages/testsuite/messages/test.exp: Likewise.
* readmsg/testsuite/readmsg/test.exp: Likewise.
* sieve/testsuite/lib/sieve.exp: Likewise.
* sieve/testsuite/sieve/action.exp: Likewise.
* sieve/testsuite/scripts/fileinto.sv: Use +file, instead of
%file.

* imap4d/imap4d.c: Register mailbox formats before parsing
configuration.
* imap4d/util.c (util_wcard_match): Replaced with a more efficient
implementation, based on wildmat from GNU Radius.
* imap4d/testsuite/imap4d/list.exp: Expect two non-mailbox files
to appear in the list output (see libproto/mbox/folder.c, 2007-12-28).

* libargp/common.c: New option --mail-folder.
* libcfg/common.c: New statement mailbox/folder

* libproto/maildir/folder.c (_maildir_is_scheme): Never return
MU_FOLDER_ATTRIBUTE_DIRECTORY bit: maildir folders cannot contain
subfolders.
* libproto/maildir/mbox.c (maildir_msg_init): Bugfix: use full
file name.
Print additional diagnostics if stat fails.
* libproto/mbox/folder.c (list_helper): Take additional argument,
record, specifying a mu_record_t object to match entries
against. If it is NULL, mu_registrar_lookup is used.
Fix descending into subdirectories.

* maidag/deliver.c (deliver): Split off deliver_to_user function;
call it with user privileges. This fixes privileges of any created
maildir folders.
* maidag/maidag.c (set_debug_flags): Bugfix.

* mail/mail.c (main): Open the mailbox with MU_STREAM_CREAT flag.

* mailbox/amd.c (amd_open): Do not initialize amd->mtime to
trigger initial scanning.
(_amd_message_save): Check rename return value.
(amd_is_updated): Do not check for msg_count==0, rely on the
timestamp.

* mailbox/mailbox.c (mu_mailbox_set_default_proto): Accept an
argument without trailing semicolon.
* mailbox/mbx_default.c (mu_set_mail_directory): Accept NULL
argument.
(mu_set_mailbox_pattern): Likewise.
(mu_mailbox_create_default): Use FOLDER or MAIL environment
variables only if _mu_mailbox_pattern is not set. In other words,
setting mail-spool in the configuration file overrides these
variables.
1 parent 36868ac9
1 2007-12-30 Sergey Poznyakoff <gray@gnu.org.ua>
2
3 * NEWS: Update.
4
5 * frm/testsuite/frm/test.exp: Call mu_init with -noflags option.
6 Use --mail-folder option when necessary.
7 * messages/testsuite/messages/test.exp: Likewise.
8 * readmsg/testsuite/readmsg/test.exp: Likewise.
9 * sieve/testsuite/lib/sieve.exp: Likewise.
10 * sieve/testsuite/sieve/action.exp: Likewise.
11 * sieve/testsuite/scripts/fileinto.sv: Use +file, instead of
12 %file.
13
14 * imap4d/imap4d.c: Register mailbox formats before parsing
15 configuration.
16 * imap4d/util.c (util_wcard_match): Replaced with a more efficient
17 implementation, based on wildmat from GNU Radius.
18 * imap4d/testsuite/imap4d/list.exp: Expect two non-mailbox files
19 to appear in the list output (see libproto/mbox/folder.c, 2007-12-28).
20
21 * libargp/common.c: New option --mail-folder.
22 * libcfg/common.c: New statement mailbox/folder
23
24 * libproto/maildir/folder.c (_maildir_is_scheme): Never return
25 MU_FOLDER_ATTRIBUTE_DIRECTORY bit: maildir folders cannot contain
26 subfolders.
27 * libproto/maildir/mbox.c (maildir_msg_init): Bugfix: use full
28 file name.
29 Print additional diagnostics if stat fails.
30 * libproto/mbox/folder.c (list_helper): Take additional argument,
31 record, specifying a mu_record_t object to match entries
32 against. If it is NULL, mu_registrar_lookup is used.
33 Fix descending into subdirectories.
34
35 * maidag/deliver.c (deliver): Split off deliver_to_user function;
36 call it with user privileges. This fixes privileges of any created
37 maildir folders.
38 * maidag/maidag.c (set_debug_flags): Bugfix.
39
40 * mail/mail.c (main): Open the mailbox with MU_STREAM_CREAT flag.
41
42 * mailbox/amd.c (amd_open): Do not initialize amd->mtime to
43 trigger initial scanning.
44 (_amd_message_save): Check rename return value.
45 (amd_is_updated): Do not check for msg_count==0, rely on the
46 timestamp.
47
48 * mailbox/mailbox.c (mu_mailbox_set_default_proto): Accept an
49 argument without trailing semicolon.
50 * mailbox/mbx_default.c (mu_set_mail_directory): Accept NULL
51 argument.
52 (mu_set_mailbox_pattern): Likewise.
53 (mu_mailbox_create_default): Use FOLDER or MAIL environment
54 variables only if _mu_mailbox_pattern is not set. In other words,
55 setting mail-spool in the configuration file overrides these
56 variables.
57
1 2007-12-28 Sergey Poznyakoff <gray@gnu.org.ua> 58 2007-12-28 Sergey Poznyakoff <gray@gnu.org.ua>
2 59
3 Additional mailbox URL parameters `type', `user' and `param' can 60 Additional mailbox URL parameters `type', `user' and `param' can
...@@ -33,7 +90,8 @@ ...@@ -33,7 +90,8 @@
33 (_path_is_scheme): Change signature. 90 (_path_is_scheme): Change signature.
34 * libproto/mh/folder.c (_mh_is_scheme): Change signature. 91 * libproto/mh/folder.c (_mh_is_scheme): Change signature.
35 (_mh_url_init): Remove. 92 (_mh_url_init): Remove.
36 (_mh_record): Use mu_url_expand_path as url_init. 93 (_mh_record): Use
94 mu_url_expand_path as url_init.
37 * libproto/mbox/Makefile.am (libmu_mbox_la_SOURCES): Remove url.c 95 * libproto/mbox/Makefile.am (libmu_mbox_la_SOURCES): Remove url.c
38 * libproto/mbox/url.c: Remove. 96 * libproto/mbox/url.c: Remove.
39 97
......
1 GNU mailutils NEWS -- history of user-visible changes. 2007-12-28 1 GNU mailutils NEWS -- history of user-visible changes. 2007-12-30
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
3 See the end of file for copying conditions. 3 See the end of file for copying conditions.
4 4
...@@ -31,6 +31,12 @@ affect the given program. ...@@ -31,6 +31,12 @@ affect the given program.
31 Additional mailbox URL parameters `type', `user' and `param' can 31 Additional mailbox URL parameters `type', `user' and `param' can
32 appear in any local URLs. 32 appear in any local URLs.
33 33
34 ** MAIL and FOLDER environment variables.
35
36 These variables are consulted only if mail-spool directory is not
37 explicitely set either in the configuration files or in the command
38 line. This is different from the previous versions.
39
34 ** New utility `maidag' 40 ** New utility `maidag'
35 41
36 Maidag is a MAIl Delivery AGent. It is a general-purpose MDA able to 42 Maidag is a MAIl Delivery AGent. It is a general-purpose MDA able to
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 19
20 source $top_srcdir/testsuite/lib/mailutils.exp 20 source $top_srcdir/testsuite/lib/mailutils.exp
21 21
22 mu_init 22 mu_init -noflags
23 set env(MAIL) $MU_SPOOL_DIR/mbox1 23 set env(MAIL) $MU_SPOOL_DIR/mbox1
24 set env(FOLDER) $env(MAIL) 24 set env(FOLDER) $env(MAIL)
25 25
...@@ -48,17 +48,17 @@ mu_exec -retcode 1 -message "frm -l" -arg -l \ ...@@ -48,17 +48,17 @@ mu_exec -retcode 1 -message "frm -l" -arg -l \
48 mu_exec -retcode 1 -message "frm -qS" -arg -qS \ 48 mu_exec -retcode 1 -message "frm -qS" -arg -qS \
49 "Folder contains 5 new messages." 49 "Folder contains 5 new messages."
50 50
51 mu_exec -retcode 1 -arg %mbox -message "frm %mbox" \
52 "Sergey Poznyakoff\tMBOX"
53
54 mu_exec -retcode 1 -arg -q -message "frm -q" \ 51 mu_exec -retcode 1 -arg -q -message "frm -q" \
55 "There are messages in that folder." 52 "There are messages in that folder."
56 53
54 mu_exec -retcode 1 -arg "--mail-folder=$MU_SPOOL_DIR" -arg +mbox -message "frm +mbox" \
55 "Sergey Poznyakoff\tMBOX"
56
57 mu_exec -arg -q -arg %nonexistent -retcode 2 -message "frm -q %nonexistent" \ 57 mu_exec -arg -q -arg %nonexistent -retcode 2 -message "frm -q %nonexistent" \
58 "No messages in that folder!" 58 "No messages in that folder!"
59 59
60 set env(MAIL) $MU_SPOOL_DIR/bigto.mbox 60 set env(MAIL) $MU_SPOOL_DIR/bigto.mbox
61 set env(FOLDER) $env(MAIL) 61 unset env(FOLDER)
62 mu_exec -retcode 1 -message "frm -l on long headers" -arg -l \ 62 mu_exec -retcode 1 -message "frm -l on long headers" -arg -l \
63 "(Ayoung-Chee, Nigel Paul -- Nigel Paul Ayoung-Chee)\tPatrick Chan\tNew email address, etc." 63 "(Ayoung-Chee, Nigel Paul -- Nigel Paul Ayoung-Chee)\tPatrick Chan\tNew email address, etc."
64 64
......
...@@ -326,6 +326,9 @@ main (int argc, char **argv) ...@@ -326,6 +326,9 @@ main (int argc, char **argv)
326 state = STATE_NONAUTH; /* Starting state in non-auth. */ 326 state = STATE_NONAUTH; /* Starting state in non-auth. */
327 327
328 MU_AUTH_REGISTER_ALL_MODULES (); 328 MU_AUTH_REGISTER_ALL_MODULES ();
329 /* Register the desired formats. */
330 mu_register_local_mbox_formats ();
331
329 imap4d_capability_init (); 332 imap4d_capability_init ();
330 mu_gocs_daemon = default_gocs_daemon; 333 mu_gocs_daemon = default_gocs_daemon;
331 #ifdef WITH_TLS 334 #ifdef WITH_TLS
...@@ -374,9 +377,6 @@ main (int argc, char **argv) ...@@ -374,9 +377,6 @@ main (int argc, char **argv)
374 } 377 }
375 } 378 }
376 379
377 /* Register the desired formats. */
378 mu_register_local_mbox_formats ();
379
380 /* Set the signal handlers. */ 380 /* Set the signal handlers. */
381 signal (SIGINT, imap4d_signal); 381 signal (SIGINT, imap4d_signal);
382 signal (SIGQUIT, imap4d_signal); 382 signal (SIGQUIT, imap4d_signal);
......
...@@ -53,6 +53,8 @@ imap4d_test "LIST \"/\" \"*\""\ ...@@ -53,6 +53,8 @@ imap4d_test "LIST \"/\" \"*\""\
53 53
54 imap4d_test -sort "LIST \"$MU_DATA_DIR\" \"*\""\ 54 imap4d_test -sort "LIST \"$MU_DATA_DIR\" \"*\""\
55 "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/etc"\ 55 "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/etc"\
56 "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/etc/mail.rc"\
57 "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/etc/passwd"\
56 "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/spool"\ 58 "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/spool"\
57 "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/bigto.mbox"\ 59 "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/bigto.mbox"\
58 "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/relational.mbox" \ 60 "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/relational.mbox" \
......
...@@ -1030,50 +1030,59 @@ util_localname () ...@@ -1030,50 +1030,59 @@ util_localname ()
1030 1030
1031 /* Match STRING against the IMAP4 wildcard pattern PATTERN. */ 1031 /* Match STRING against the IMAP4 wildcard pattern PATTERN. */
1032 1032
1033 #define WILD_FALSE 0
1034 #define WILD_TRUE 1
1035 #define WILD_ABORT 2
1036
1033 int 1037 int
1034 util_wcard_match (const char *string, const char *pattern, const char *delim) 1038 _wild_match (const char *expr, const char *name, const char *delim)
1035 { 1039 {
1036 const char *p = pattern, *n = string; 1040 while (expr && *expr)
1037 char c;
1038
1039 for (; (c = *p++) != '\0' && *n; n++)
1040 { 1041 {
1041 switch (c) 1042 if (*name == 0 && *expr != '*')
1043 return WILD_ABORT;
1044 switch (*expr)
1042 { 1045 {
1043 case '%': 1046 case '*':
1044 /* Matches everything except '/' */ 1047 while (*++expr == '*')
1045 if (*p == '\0') 1048 ;
1049 if (*expr == 0)
1050 return WILD_TRUE;
1051 while (*name)
1046 { 1052 {
1047 for (; *n; ++n) 1053 int res = _wild_match (expr, name++, delim);
1048 if (*n == *delim) 1054 if (res != WILD_FALSE)
1049 return 1; 1055 return res;
1050 return 0;
1051 } 1056 }
1052 else 1057 return WILD_ABORT;
1053 for (; *n != '\0'; ++n)
1054 if (util_wcard_match (n, p, delim) == 0)
1055 return 0;
1056 break;
1057
1058 case '*':
1059 if (*p == '\0')
1060 return 0;
1061 else
1062 for (; *n != '\0'; ++n)
1063 if (util_wcard_match (n, p, delim) == 0)
1064 return 0;
1065 break;
1066 1058
1059 case '%':
1060 while (*++expr == '%')
1061 ;
1062 if (*expr == 0)
1063 return strchr (name, delim) ? WILD_FALSE : WILD_TRUE;
1064 while (*name && *name != delim)
1065 {
1066 int res = _wild_match (expr, name++, delim);
1067 if (res != WILD_FALSE)
1068 return res;
1069 }
1070 return _wild_match (expr, name, delim);
1071
1067 default: 1072 default:
1068 if (c != *n) 1073 if (*expr != *name)
1069 return 1; 1074 return WILD_FALSE;
1075 expr++;
1076 name++;
1070 } 1077 }
1071 } 1078 }
1079 return *name == 0;
1080 }
1072 1081
1073 if (!c && !*n) 1082 int
1074 return 0; 1083 util_wcard_match (const char *name, const char *expr, const char *delim)
1075 1084 {
1076 return 1; 1085 return _wild_match (expr, name, delim[0]) != WILD_TRUE;
1077 } 1086 }
1078 1087
1079 /* Return the uindvalidity of a mailbox. 1088 /* Return the uindvalidity of a mailbox.
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
23 #include <string.h> 23 #include <string.h>
24 #include <mailutils/syslog.h> 24 #include <mailutils/syslog.h>
25 #include <mailutils/daemon.h> 25 #include <mailutils/daemon.h>
26 #include <mailutils/mailbox.h>
26 27
27 28
28 /* ************************************************************************* */ 29 /* ************************************************************************* */
...@@ -45,6 +46,7 @@ enum { ...@@ -45,6 +46,7 @@ enum {
45 OPT_LICENSE, 46 OPT_LICENSE,
46 OPT_MAILBOX_PATTERN, 47 OPT_MAILBOX_PATTERN,
47 OPT_MAILBOX_TYPE, 48 OPT_MAILBOX_TYPE,
49 OPT_MAIL_FOLDER,
48 OPT_DEBUG_LEVEL, 50 OPT_DEBUG_LEVEL,
49 OPT_LINE_INFO, 51 OPT_LINE_INFO,
50 OPT_HELP_CONFIG 52 OPT_HELP_CONFIG
...@@ -235,6 +237,8 @@ static struct argp_option mu_mailbox_argp_option[] = { ...@@ -235,6 +237,8 @@ static struct argp_option mu_mailbox_argp_option[] = {
235 "", 0 }, 237 "", 0 },
236 { "mailbox-type", OPT_MAILBOX_TYPE, N_("PROTO"), OPTION_HIDDEN, 238 { "mailbox-type", OPT_MAILBOX_TYPE, N_("PROTO"), OPTION_HIDDEN,
237 N_("Default mailbox type to use"), 0 }, 239 N_("Default mailbox type to use"), 0 },
240 { "mail-folder", OPT_MAIL_FOLDER, N_("DIR"), OPTION_HIDDEN,
241 N_("Default user mail folder"), 0 },
238 { NULL } 242 { NULL }
239 }; 243 };
240 244
...@@ -257,6 +261,10 @@ mu_mailbox_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -257,6 +261,10 @@ mu_mailbox_argp_parser (int key, char *arg, struct argp_state *state)
257 case OPT_MAILBOX_TYPE: 261 case OPT_MAILBOX_TYPE:
258 mu_argp_node_list_new (&lst, "mailbox-type", arg); 262 mu_argp_node_list_new (&lst, "mailbox-type", arg);
259 break; 263 break;
264
265 case OPT_MAIL_FOLDER:
266 mu_argp_node_list_new (&lst, "folder", arg);
267 break;
260 268
261 case ARGP_KEY_INIT: 269 case ARGP_KEY_INIT:
262 mu_argp_node_list_init (&lst); 270 mu_argp_node_list_init (&lst);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
24 #include <mailutils/daemon.h> 24 #include <mailutils/daemon.h>
25 #include <mailutils/debug.h> 25 #include <mailutils/debug.h>
26 #include <mailutils/syslog.h> 26 #include <mailutils/syslog.h>
27 #include <mailutils/mailbox.h>
27 #include <mu_umaxtostr.h> 28 #include <mu_umaxtostr.h>
28 29
29 static struct mu_gocs_daemon daemon_settings; 30 static struct mu_gocs_daemon daemon_settings;
...@@ -39,6 +40,13 @@ static struct mu_gocs_debug debug_settings; ...@@ -39,6 +40,13 @@ static struct mu_gocs_debug debug_settings;
39 /* Mailbox */ 40 /* Mailbox */
40 /* ************************************************************************* */ 41 /* ************************************************************************* */
41 42
43 static int
44 _cb_folder (mu_debug_t debug, void *data, char *arg)
45 {
46 mu_set_folder_directory (arg);
47 return 0;
48 }
49
42 static struct mu_cfg_param mu_mailbox_param[] = { 50 static struct mu_cfg_param mu_mailbox_param[] = {
43 { "mail-spool", mu_cfg_string, &mailbox_settings.mail_spool, 0, NULL, 51 { "mail-spool", mu_cfg_string, &mailbox_settings.mail_spool, 0, NULL,
44 N_("Use specified URL as a mailspool directory."), 52 N_("Use specified URL as a mailspool directory."),
...@@ -49,6 +57,9 @@ static struct mu_cfg_param mu_mailbox_param[] = { ...@@ -49,6 +57,9 @@ static struct mu_cfg_param mu_mailbox_param[] = {
49 N_("pattern") }, 57 N_("pattern") },
50 { "mailbox-type", mu_cfg_string, &mailbox_settings.mailbox_type, 0, NULL, 58 { "mailbox-type", mu_cfg_string, &mailbox_settings.mailbox_type, 0, NULL,
51 N_("Default mailbox type."), N_("protocol") }, 59 N_("Default mailbox type."), N_("protocol") },
60 { "folder", mu_cfg_callback, NULL, 0, _cb_folder,
61 N_("Default user mail folder"),
62 N_("dir") },
52 { NULL } 63 { NULL }
53 }; 64 };
54 65
......
...@@ -60,14 +60,13 @@ static int ...@@ -60,14 +60,13 @@ static int
60 _maildir_is_scheme (mu_record_t record, mu_url_t url, int flags) 60 _maildir_is_scheme (mu_record_t record, mu_url_t url, int flags)
61 { 61 {
62 if (mu_url_is_scheme (url, record->scheme)) 62 if (mu_url_is_scheme (url, record->scheme))
63 return MU_FOLDER_ATTRIBUTE_ALL & flags; 63 return MU_FOLDER_ATTRIBUTE_FILE & flags;
64 64
65 if (mu_scheme_autodetect_p (url)) 65 if (mu_scheme_autodetect_p (url))
66 { 66 {
67 /* Attemp auto-detection */ 67 /* Attemp auto-detection */
68 const char *path; 68 const char *path;
69 struct stat st; 69 struct stat st;
70 int rc = 0;
71 70
72 if (mu_url_sget_path (url, &path)) 71 if (mu_url_sget_path (url, &path))
73 return 0; 72 return 0;
...@@ -78,13 +77,11 @@ _maildir_is_scheme (mu_record_t record, mu_url_t url, int flags) ...@@ -78,13 +77,11 @@ _maildir_is_scheme (mu_record_t record, mu_url_t url, int flags)
78 if (!S_ISDIR (st.st_mode)) 77 if (!S_ISDIR (st.st_mode))
79 return 0; 78 return 0;
80 79
81 rc |= (MU_FOLDER_ATTRIBUTE_DIRECTORY & flags);
82
83 if ((flags & MU_FOLDER_ATTRIBUTE_FILE) 80 if ((flags & MU_FOLDER_ATTRIBUTE_FILE)
84 && dir_exists (path, TMPSUF) 81 && dir_exists (path, TMPSUF)
85 && dir_exists (path, CURSUF) 82 && dir_exists (path, CURSUF)
86 && dir_exists (path, NEWSUF)) 83 && dir_exists (path, NEWSUF))
87 return rc | MU_FOLDER_ATTRIBUTE_FILE; 84 return MU_FOLDER_ATTRIBUTE_FILE;
88 } 85 }
89 return 0; 86 return 0;
90 } 87 }
......
...@@ -299,7 +299,7 @@ maildir_uniq (struct _amd_data *amd, int fd) ...@@ -299,7 +299,7 @@ maildir_uniq (struct _amd_data *amd, int fd)
299 struct timeval tv; 299 struct timeval tv;
300 unsigned long n; 300 unsigned long n;
301 struct stat st; 301 struct stat st;
302 302
303 gettimeofday (&tv, NULL); 303 gettimeofday (&tv, NULL);
304 FMT ("%lu", tv.tv_sec); 304 FMT ("%lu", tv.tv_sec);
305 COPY ("."); 305 COPY (".");
...@@ -409,24 +409,27 @@ static int ...@@ -409,24 +409,27 @@ static int
409 maildir_msg_init (struct _amd_data *amd, struct _amd_message *amm) 409 maildir_msg_init (struct _amd_data *amd, struct _amd_message *amm)
410 { 410 {
411 struct _maildir_message *msg = (struct _maildir_message *) amm; 411 struct _maildir_message *msg = (struct _maildir_message *) amm;
412 char *name; 412 char *name, *fname;
413 struct stat st; 413 struct stat st;
414 int i; 414 int i;
415 415
416 /* chdir (amd->name); FIXME */
417 name = maildir_uniq (amd, -1); 416 name = maildir_uniq (amd, -1);
418 417 fname = maildir_mkfilename (amd->name, NEWSUF, name);
418
419 for (i = 0; i < NTRIES; i++) 419 for (i = 0; i < NTRIES; i++)
420 { 420 {
421 if (stat (name, &st) < 0 && errno == ENOENT) 421 if (stat (fname, &st) < 0 && errno == ENOENT)
422 { 422 {
423 msg->uid = amd->next_uid (amd); 423 msg->uid = amd->next_uid (amd);
424 msg->file_name = name; 424 msg->file_name = name;
425 free (fname);
425 return 0; 426 return 0;
426 } 427 }
428 mu_diag_output (MU_DIAG_WARNING, "cannot stat %s: %s", fname,
429 mu_strerror (errno));
427 sleep (2); 430 sleep (2);
428 } 431 }
429 432 free (fname);
430 free (name); 433 free (name);
431 return MU_ERR_BAD_RESUMPTION; 434 return MU_ERR_BAD_RESUMPTION;
432 } 435 }
......
...@@ -317,7 +317,8 @@ inode_list_lookup (struct inode_list *list, struct stat *st) ...@@ -317,7 +317,8 @@ inode_list_lookup (struct inode_list *list, struct stat *st)
317 } 317 }
318 318
319 static int 319 static int
320 list_helper (struct search_data *data, const char *dirname, size_t level, 320 list_helper (struct search_data *data, mu_record_t record,
321 const char *dirname, size_t level,
321 struct inode_list *ilist) 322 struct inode_list *ilist)
322 { 323 {
323 DIR *dirp; 324 DIR *dirp;
...@@ -341,21 +342,20 @@ list_helper (struct search_data *data, const char *dirname, size_t level, ...@@ -341,21 +342,20 @@ list_helper (struct search_data *data, const char *dirname, size_t level,
341 { 342 {
342 char const *ename = dp->d_name; 343 char const *ename = dp->d_name;
343 char *fname; 344 char *fname;
345 struct stat st;
344 346
345 if (ename[ename[0] != '.' ? 0 : ename[1] != '.' ? 1 : 2] == 0) 347 if (ename[ename[0] != '.' ? 0 : ename[1] != '.' ? 1 : 2] == 0)
346 continue; 348 continue;
347 fname = get_pathname (dirname, ename); 349 fname = get_pathname (dirname, ename);
348 if (data->folder->_match == NULL 350 if (stat (fname, &st) == 0)
349 || data->folder->_match (fname + data->dirlen +
350 ((data->dirlen > 1
351 && data->dirname[data->dirlen-1] != '/') ?
352 1 : 0),
353 data->pattern,
354 data->flags) == 0)
355 { 351 {
356 struct stat st; 352 if (data->folder->_match == NULL
357 353 || data->folder->_match (fname + data->dirlen +
358 if (stat (fname, &st) == 0) 354 ((data->dirlen > 1
355 && data->dirname[data->dirlen-1] != '/') ?
356 1 : 0),
357 data->pattern,
358 data->flags) == 0)
359 { 359 {
360 char *refname = fname; 360 char *refname = fname;
361 int type = 0; 361 int type = 0;
...@@ -371,8 +371,22 @@ list_helper (struct search_data *data, const char *dirname, size_t level, ...@@ -371,8 +371,22 @@ list_helper (struct search_data *data, const char *dirname, size_t level,
371 continue; 371 continue;
372 } 372 }
373 373
374 mu_registrar_lookup (refname, MU_FOLDER_ATTRIBUTE_ALL, NULL, 374 if (record)
375 &type); 375 {
376 mu_url_t url;
377 int rc = mu_url_create (&url, refname);
378 if (rc == 0)
379 {
380 rc = mu_url_parse (url);
381 if (rc == 0)
382 type = mu_record_is_scheme (record, url,
383 MU_FOLDER_ATTRIBUTE_ALL);
384 }
385 mu_url_destroy (&url);
386 }
387 else
388 mu_registrar_lookup (refname, MU_FOLDER_ATTRIBUTE_ALL,
389 &record, &type);
376 390
377 resp->name = fname; 391 resp->name = fname;
378 resp->level = level; 392 resp->level = level;
...@@ -413,16 +427,26 @@ list_helper (struct search_data *data, const char *dirname, size_t level, ...@@ -413,16 +427,26 @@ list_helper (struct search_data *data, const char *dirname, size_t level,
413 idata.inode = st.st_ino; 427 idata.inode = st.st_ino;
414 idata.dev = st.st_dev; 428 idata.dev = st.st_dev;
415 idata.next = ilist; 429 idata.next = ilist;
416 stop = list_helper (data, refname, level + 1, &idata); 430 stop = list_helper (data, record, refname, level + 1,
431 &idata);
417 } 432 }
418 } 433 }
419 else 434 else if (S_ISDIR (st.st_mode))
420 { 435 {
421 MU_DEBUG2 (data->folder->debug, MU_DEBUG_ERROR, 436 struct inode_list idata;
422 "list_helper cannot stat %s: %s", 437
423 fname, mu_strerror (errno)); 438 idata.inode = st.st_ino;
439 idata.dev = st.st_dev;
440 idata.next = ilist;
441 stop = list_helper (data, NULL, fname, level + 1, &idata);
424 } 442 }
425 } 443 }
444 else
445 {
446 MU_DEBUG2 (data->folder->debug, MU_DEBUG_ERROR,
447 "list_helper cannot stat %s: %s",
448 fname, mu_strerror (errno));
449 }
426 free (fname); 450 free (fname);
427 } 451 }
428 closedir (dirp); 452 closedir (dirp);
...@@ -452,7 +476,7 @@ folder_mbox_list (mu_folder_t folder, const char *ref, ...@@ -452,7 +476,7 @@ folder_mbox_list (mu_folder_t folder, const char *ref,
452 sdata.max_level = max_level; 476 sdata.max_level = max_level;
453 sdata.folder = folder; 477 sdata.folder = folder;
454 sdata.errcnt = 0; 478 sdata.errcnt = 0;
455 list_helper (&sdata, sdata.dirname, 0, &iroot); 479 list_helper (&sdata, NULL, sdata.dirname, 0, &iroot);
456 free (sdata.dirname); 480 free (sdata.dirname);
457 /* FIXME: error code */ 481 /* FIXME: error code */
458 return 0; 482 return 0;
......
...@@ -143,66 +143,20 @@ attach_notify (mu_mailbox_t mbox) ...@@ -143,66 +143,20 @@ attach_notify (mu_mailbox_t mbox)
143 } 143 }
144 144
145 int 145 int
146 deliver (mu_mailbox_t imbx, char *name, char **errp) 146 deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg,
147 struct mu_auth_data *auth, const char *name,
148 char **errp)
147 { 149 {
148 mu_mailbox_t mbox; 150 int status;
149 mu_message_t msg;
150 char *path; 151 char *path;
151 mu_url_t url = NULL; 152 mu_url_t url = NULL;
152 mu_locker_t lock; 153 mu_locker_t lock;
153 struct mu_auth_data *auth;
154 int status;
155 int failed = 0; 154 int failed = 0;
156 155
157 auth = mu_get_auth_by_name (name);
158 if (!auth)
159 {
160 mailer_err (_("%s: no such user"), name);
161 if (errp)
162 asprintf (errp, "%s: no such user", name);
163 exit_code = EX_UNAVAILABLE;
164 return EX_UNAVAILABLE;
165 }
166 if (current_uid)
167 auth->change_uid = 0;
168
169 if (!sieve_test (auth, imbx))
170 {
171 exit_code = EX_OK;
172 mu_auth_data_free (auth);
173 return 0;
174 }
175
176 if ((status = mu_mailbox_get_message (imbx, 1, &msg)) != 0)
177 {
178 mailer_err (_("Cannot get message from the temporary mailbox: %s"),
179 mu_strerror (status));
180 mu_auth_data_free (auth);
181 return EX_TEMPFAIL;
182 }
183
184 if ((status = mu_mailbox_create (&mbox, auth->mailbox)) != 0)
185 {
186 mailer_err (_("Cannot open mailbox %s: %s"),
187 auth->mailbox, mu_strerror (status));
188 mu_auth_data_free (auth);
189 return EX_TEMPFAIL;
190 }
191
192 mu_mailbox_get_url (mbox, &url); 156 mu_mailbox_get_url (mbox, &url);
193 path = (char*) mu_url_to_string (url); 157 path = (char*) mu_url_to_string (url);
194 158
195 biff_user_name = name;
196
197 /* Actually open the mailbox. Switch to the user's euid to make
198 sure the maildrop file will have right privileges, in case it
199 will be created */
200 if (switch_user_id (auth, 1))
201 return EX_TEMPFAIL;
202 status = mu_mailbox_open (mbox, MU_STREAM_APPEND|MU_STREAM_CREAT); 159 status = mu_mailbox_open (mbox, MU_STREAM_APPEND|MU_STREAM_CREAT);
203 if (switch_user_id (auth, 0))
204 return EX_TEMPFAIL;
205
206 if (status != 0) 160 if (status != 0)
207 { 161 {
208 mailer_err (_("Cannot open mailbox %s: %s"), path, mu_strerror (status)); 162 mailer_err (_("Cannot open mailbox %s: %s"), path, mu_strerror (status));
...@@ -317,3 +271,59 @@ deliver (mu_mailbox_t imbx, char *name, char **errp) ...@@ -317,3 +271,59 @@ deliver (mu_mailbox_t imbx, char *name, char **errp)
317 mu_mailbox_destroy (&mbox); 271 mu_mailbox_destroy (&mbox);
318 return failed ? exit_code : 0; 272 return failed ? exit_code : 0;
319 } 273 }
274
275 int
276 deliver (mu_mailbox_t imbx, char *name, char **errp)
277 {
278 struct mu_auth_data *auth;
279 mu_mailbox_t mbox;
280 mu_message_t msg;
281 int status;
282
283 auth = mu_get_auth_by_name (name);
284 if (!auth)
285 {
286 mailer_err (_("%s: no such user"), name);
287 if (errp)
288 asprintf (errp, "%s: no such user", name);
289 exit_code = EX_UNAVAILABLE;
290 return EX_UNAVAILABLE;
291 }
292 if (current_uid)
293 auth->change_uid = 0;
294
295 if (!sieve_test (auth, imbx))
296 {
297 exit_code = EX_OK;
298 mu_auth_data_free (auth);
299 return 0;
300 }
301
302 if ((status = mu_mailbox_get_message (imbx, 1, &msg)) != 0)
303 {
304 mailer_err (_("Cannot get message from the temporary mailbox: %s"),
305 mu_strerror (status));
306 mu_auth_data_free (auth);
307 return EX_TEMPFAIL;
308 }
309
310 if ((status = mu_mailbox_create (&mbox, auth->mailbox)) != 0)
311 {
312 mailer_err (_("Cannot open mailbox %s: %s"),
313 auth->mailbox, mu_strerror (status));
314 mu_auth_data_free (auth);
315 return EX_TEMPFAIL;
316 }
317
318 biff_user_name = name;
319
320 /* Actually open the mailbox. Switch to the user's euid to make
321 sure the maildrop file will have right privileges, in case it
322 will be created */
323 if (switch_user_id (auth, 1))
324 return EX_TEMPFAIL;
325 status = deliver_to_user (imbx, mbox, msg, auth, name, errp);
326 if (switch_user_id (auth, 0))
327 return EX_TEMPFAIL;
328 return status;
329 }
......
...@@ -161,7 +161,7 @@ set_debug_flags (mu_debug_t debug, const char *arg) ...@@ -161,7 +161,7 @@ set_debug_flags (mu_debug_t debug, const char *arg)
161 } 161 }
162 if (*arg == ',') 162 if (*arg == ',')
163 arg++; 163 arg++;
164 else 164 else if (*arg)
165 mu_cfg_format_error (debug, MU_DEBUG_ERROR, 165 mu_cfg_format_error (debug, MU_DEBUG_ERROR,
166 _("expected comma, but found %c"), *arg); 166 _("expected comma, but found %c"), *arg);
167 } 167 }
......
...@@ -436,14 +436,13 @@ main (int argc, char **argv) ...@@ -436,14 +436,13 @@ main (int argc, char **argv)
436 mu_debug_set_level (debug, MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT)); 436 mu_debug_set_level (debug, MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT));
437 } 437 }
438 438
439 if ((rc = mu_mailbox_open (mbox, MU_STREAM_RDWR)) != 0 && rc != ENOENT) 439 if ((rc = mu_mailbox_open (mbox, MU_STREAM_RDWR|MU_STREAM_CREAT)) != 0)
440 { 440 {
441 mu_url_t url = NULL; 441 mu_url_t url = NULL;
442 mu_mailbox_get_url (mbox, &url); 442 mu_mailbox_get_url (mbox, &url);
443 util_error (_("Cannot open mailbox %s: %s"), 443 util_error (_("Cannot open mailbox %s: %s"),
444 mu_url_to_string (url), mu_strerror (rc)); 444 mu_url_to_string (url), mu_strerror (rc));
445 mu_mailbox_destroy (&mbox); 445 mu_mailbox_destroy (&mbox);
446 exit (EXIT_FAILURE);
447 } 446 }
448 447
449 if (rc) 448 if (rc)
......
...@@ -347,8 +347,6 @@ amd_open (mu_mailbox_t mailbox, int flags) ...@@ -347,8 +347,6 @@ amd_open (mu_mailbox_t mailbox, int flags)
347 if (!S_ISDIR (st.st_mode)) 347 if (!S_ISDIR (st.st_mode))
348 return EINVAL; 348 return EINVAL;
349 349
350 amd->mtime = st.st_mtime;
351
352 return 0; 350 return 0;
353 } 351 }
354 352
...@@ -711,7 +709,8 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, int expunge) ...@@ -711,7 +709,8 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, int expunge)
711 fclose (fp); 709 fclose (fp);
712 710
713 msg_name = amd->msg_file_name (mhm, mhm->deleted); 711 msg_name = amd->msg_file_name (mhm, mhm->deleted);
714 rename (name, msg_name); 712 if (rename (name, msg_name))
713 status = errno;
715 free (name); 714 free (name);
716 free (msg_name); 715 free (msg_name);
717 716
...@@ -1147,9 +1146,6 @@ amd_is_updated (mu_mailbox_t mailbox) ...@@ -1147,9 +1146,6 @@ amd_is_updated (mu_mailbox_t mailbox)
1147 struct stat st; 1146 struct stat st;
1148 struct _amd_data *amd = mailbox->data; 1147 struct _amd_data *amd = mailbox->data;
1149 1148
1150 if (amd->msg_count == 0)
1151 return 0;
1152
1153 if (stat (amd->name, &st) < 0) 1149 if (stat (amd->name, &st) < 0)
1154 return 1; 1150 return 1;
1155 1151
......
...@@ -74,12 +74,26 @@ int ...@@ -74,12 +74,26 @@ int
74 mu_mailbox_set_default_proto (const char *proto) 74 mu_mailbox_set_default_proto (const char *proto)
75 { 75 {
76 char *p; 76 char *p;
77 size_t len = strlen (proto);
77 78
78 if (mu_registrar_lookup (proto, MU_FOLDER_ATTRIBUTE_FILE, NULL, NULL)) 79 if (proto [len - 1] == ':')
80 {
81 p = strdup (proto);
82 if (!p)
83 return ENOMEM;
84 }
85 else
86 {
87 p = malloc (len + 2);
88 if (!p)
89 return ENOMEM;
90 strcpy (p, proto);
91 p[len] = ':';
92 p[len+1] = 0;
93 }
94
95 if (mu_registrar_lookup (p, MU_FOLDER_ATTRIBUTE_FILE, NULL, NULL))
79 return MU_ERR_NO_HANDLER; 96 return MU_ERR_NO_HANDLER;
80 p = strdup (proto);
81 if (!p)
82 return ENOMEM;
83 if (default_proto) 97 if (default_proto)
84 free (default_proto); 98 free (default_proto);
85 default_proto = p; 99 default_proto = p;
......
...@@ -82,6 +82,11 @@ mu_set_mail_directory (const char *p) ...@@ -82,6 +82,11 @@ mu_set_mail_directory (const char *p)
82 { 82 {
83 if (_mu_mailbox_pattern) 83 if (_mu_mailbox_pattern)
84 free (_mu_mailbox_pattern); 84 free (_mu_mailbox_pattern);
85 if (!p)
86 {
87 _mu_mailbox_pattern = NULL;
88 return 0;
89 }
85 return mu_normalize_mailbox_url (&_mu_mailbox_pattern, p); 90 return mu_normalize_mailbox_url (&_mu_mailbox_pattern, p);
86 } 91 }
87 92
...@@ -90,6 +95,11 @@ mu_set_mailbox_pattern (const char *pat) ...@@ -90,6 +95,11 @@ mu_set_mailbox_pattern (const char *pat)
90 { 95 {
91 if (_mu_mailbox_pattern) 96 if (_mu_mailbox_pattern)
92 free (_mu_mailbox_pattern); 97 free (_mu_mailbox_pattern);
98 if (!pat)
99 {
100 _mu_mailbox_pattern = NULL;
101 return 0;
102 }
93 _mu_mailbox_pattern = strdup (pat); 103 _mu_mailbox_pattern = strdup (pat);
94 return _mu_mailbox_pattern ? 0 : ENOMEM; 104 return _mu_mailbox_pattern ? 0 : ENOMEM;
95 } 105 }
...@@ -339,22 +349,26 @@ mu_mailbox_create_default (mu_mailbox_t *pmbox, const char *mail) ...@@ -339,22 +349,26 @@ mu_mailbox_create_default (mu_mailbox_t *pmbox, const char *mail)
339 if (pmbox == NULL) 349 if (pmbox == NULL)
340 return MU_ERR_OUT_PTR_NULL; 350 return MU_ERR_OUT_PTR_NULL;
341 351
342 /* Other utilities may not understand GNU mailutils url namespace, so
343 use FOLDER instead, to not confuse others by using MAIL. */
344 if (mail == NULL || *mail == '\0') 352 if (mail == NULL || *mail == '\0')
345 { 353 {
346 mail = getenv ("FOLDER"); 354 if (!_mu_mailbox_pattern)
347 355 {
348 /* Fallback to wellknown environment. */ 356 /* Other utilities may not understand GNU mailutils url namespace, so
349 if (!mail) 357 use FOLDER instead, to not confuse others by using MAIL. */
350 mail = getenv ("MAIL"); 358 mail = getenv ("FOLDER");
359 if (!mail)
360 {
361 /* Fallback to well-known environment. */
362 mail = getenv ("MAIL");
363 }
364 }
351 365
352 if (!mail) 366 if (!mail)
353 { 367 {
354 if ((status = user_mailbox_name (NULL, &tmp_mbox))) 368 if ((status = user_mailbox_name (NULL, &tmp_mbox)))
355 return status; 369 return status;
356 mail = tmp_mbox; 370 mail = tmp_mbox;
357 } 371 }
358 } 372 }
359 373
360 p = mu_tilde_expansion (mail, "/", NULL); 374 p = mu_tilde_expansion (mail, "/", NULL);
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 19
20 source $top_srcdir/testsuite/lib/mailutils.exp 20 source $top_srcdir/testsuite/lib/mailutils.exp
21 21
22 mu_init 22 mu_init -noflags
23 set env(MAIL) $MU_SPOOL_DIR/mbox1 23 set env(MAIL) $MU_SPOOL_DIR/mbox1
24 set env(FOLDER) $env(MAIL) 24 set env(FOLDER) $env(MAIL)
25 25
...@@ -30,7 +30,8 @@ mu_exec -message "messages" \ ...@@ -30,7 +30,8 @@ mu_exec -message "messages" \
30 30
31 mu_exec -message "messages -q" -arg -q "5" 31 mu_exec -message "messages -q" -arg -q "5"
32 32
33 mu_exec -message "messages %teaparty.mbox" -arg %teaparty.mbox \ 33 mu_exec -message "messages +teaparty.mbox" \
34 -arg "--mail-folder=$MU_SPOOL_DIR" -arg +teaparty.mbox \
34 "Number of messages in $MU_SPOOL_DIR/teaparty.mbox: 95" 35 "Number of messages in $MU_SPOOL_DIR/teaparty.mbox: 95"
35 36
36 #end of test.exp 37 #end of test.exp
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 19
20 source $top_srcdir/testsuite/lib/mailutils.exp 20 source $top_srcdir/testsuite/lib/mailutils.exp
21 21
22 mu_init 22 mu_init -noflags
23 set env(MAIL) $MU_SPOOL_DIR/mbox1 23 set env(MAIL) $MU_SPOOL_DIR/mbox1
24 set env(FOLDER) $env(MAIL) 24 set env(FOLDER) $env(MAIL)
25 25
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 source $top_srcdir/testsuite/lib/mailutils.exp 20 source $top_srcdir/testsuite/lib/mailutils.exp
21 set sieve_source_dir "${srcdir}/scripts" 21 set sieve_source_dir "${srcdir}/scripts"
22 22
23 mu_init 23 mu_init -noflags
24 set env(MAIL) $MU_SPOOL_DIR/sieve.mbox 24 set env(MAIL) $MU_SPOOL_DIR/sieve.mbox
25 set env(FOLDER) $env(MAIL) 25 set env(FOLDER) $env(MAIL)
26 26
......
1 # -*- sieve -*- 1 # -*- sieve -*-
2 # This file is part of Mailutils testsuite. 2 # This file is part of Mailutils testsuite.
3 # Copyright (C) 2002, Free Software Foundation. 3 # Copyright (C) 2002, 2007 Free Software Foundation.
4 # See file COPYING for distribution conditions. 4 # See file COPYING for distribution conditions.
5 5
6 require "fileinto"; 6 require "fileinto";
7 7
8 fileinto "%file"; 8 fileinto "+file";
......
...@@ -37,10 +37,10 @@ sieve_test discard.sv -pattern\ ...@@ -37,10 +37,10 @@ sieve_test discard.sv -pattern\
37 "DISCARD on msg uid 2: marking as deleted"\ 37 "DISCARD on msg uid 2: marking as deleted"\
38 "DISCARD on msg uid 3: marking as deleted" 38 "DISCARD on msg uid 3: marking as deleted"
39 39
40 sieve_test fileinto.sv -pattern\ 40 sieve_test --mail-folder='$MU_SPOOL_DIR' fileinto.sv -pattern\
41 "FILEINTO on msg uid 1: delivering into %file"\ 41 "FILEINTO on msg uid 1: delivering into +file"\
42 "FILEINTO on msg uid 2: delivering into %file"\ 42 "FILEINTO on msg uid 2: delivering into +file"\
43 "FILEINTO on msg uid 3: delivering into %file" 43 "FILEINTO on msg uid 3: delivering into +file"
44 44
45 mu_test_file "$MU_SPOOL_DIR/file" \ 45 mu_test_file "$MU_SPOOL_DIR/file" \
46 "From coyote@desert.example.org Sun May 6 22:16:47 2001"\ 46 "From coyote@desert.example.org Sun May 6 22:16:47 2001"\
......