diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-12-30 00:01:55 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-12-30 00:01:55 +0000 |
commit | b7e41daa82b7ed40c06c6a01cd502fa409f836c3 (patch) | |
tree | 10c7ba0060f02fa285f052725901dfa84324faf7 | |
parent | 36868ac9ddc6b4e521913858b04ace62d8edfa5a (diff) | |
download | mailutils-b7e41daa82b7ed40c06c6a01cd502fa409f836c3.tar.gz mailutils-b7e41daa82b7ed40c06c6a01cd502fa409f836c3.tar.bz2 |
* 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.
-rw-r--r-- | ChangeLog | 60 | ||||
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | frm/testsuite/frm/test.exp | 10 | ||||
-rw-r--r-- | imap4d/imap4d.c | 6 | ||||
-rw-r--r-- | imap4d/testsuite/imap4d/list.exp | 2 | ||||
-rw-r--r-- | imap4d/util.c | 75 | ||||
-rw-r--r-- | libargp/common.c | 8 | ||||
-rw-r--r-- | libcfg/common.c | 11 | ||||
-rw-r--r-- | libproto/maildir/folder.c | 7 | ||||
-rw-r--r-- | libproto/maildir/mbox.c | 15 | ||||
-rw-r--r-- | libproto/mbox/folder.c | 62 | ||||
-rw-r--r-- | maidag/deliver.c | 110 | ||||
-rw-r--r-- | maidag/maidag.c | 2 | ||||
-rw-r--r-- | mail/mail.c | 3 | ||||
-rw-r--r-- | mailbox/amd.c | 8 | ||||
-rw-r--r-- | mailbox/mailbox.c | 22 | ||||
-rw-r--r-- | mailbox/mbx_default.c | 38 | ||||
-rw-r--r-- | messages/testsuite/messages/test.exp | 5 | ||||
-rw-r--r-- | readmsg/testsuite/readmsg/test.exp | 2 | ||||
-rw-r--r-- | sieve/testsuite/lib/sieve.exp | 2 | ||||
-rw-r--r-- | sieve/testsuite/scripts/fileinto.sv | 4 | ||||
-rw-r--r-- | sieve/testsuite/sieve/action.exp | 8 |
22 files changed, 310 insertions, 158 deletions
@@ -1,3 +1,60 @@ +2007-12-30 Sergey Poznyakoff <gray@gnu.org.ua> + + * 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. + 2007-12-28 Sergey Poznyakoff <gray@gnu.org.ua> Additional mailbox URL parameters `type', `user' and `param' can @@ -33,7 +90,8 @@ (_path_is_scheme): Change signature. * libproto/mh/folder.c (_mh_is_scheme): Change signature. (_mh_url_init): Remove. - (_mh_record): Use mu_url_expand_path as url_init. + (_mh_record): Use + mu_url_expand_path as url_init. * libproto/mbox/Makefile.am (libmu_mbox_la_SOURCES): Remove url.c * libproto/mbox/url.c: Remove. @@ -1,4 +1,4 @@ -GNU mailutils NEWS -- history of user-visible changes. 2007-12-28 +GNU mailutils NEWS -- history of user-visible changes. 2007-12-30 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. See the end of file for copying conditions. @@ -31,6 +31,12 @@ affect the given program. Additional mailbox URL parameters `type', `user' and `param' can appear in any local URLs. +** MAIL and FOLDER environment variables. + +These variables are consulted only if mail-spool directory is not +explicitely set either in the configuration files or in the command +line. This is different from the previous versions. + ** New utility `maidag' Maidag is a MAIl Delivery AGent. It is a general-purpose MDA able to diff --git a/frm/testsuite/frm/test.exp b/frm/testsuite/frm/test.exp index 60bd3f186..87a3737ad 100644 --- a/frm/testsuite/frm/test.exp +++ b/frm/testsuite/frm/test.exp @@ -19,7 +19,7 @@ source $top_srcdir/testsuite/lib/mailutils.exp -mu_init +mu_init -noflags set env(MAIL) $MU_SPOOL_DIR/mbox1 set env(FOLDER) $env(MAIL) @@ -48,17 +48,17 @@ mu_exec -retcode 1 -message "frm -l" -arg -l \ mu_exec -retcode 1 -message "frm -qS" -arg -qS \ "Folder contains 5 new messages." -mu_exec -retcode 1 -arg %mbox -message "frm %mbox" \ -"Sergey Poznyakoff\tMBOX" - mu_exec -retcode 1 -arg -q -message "frm -q" \ "There are messages in that folder." +mu_exec -retcode 1 -arg "--mail-folder=$MU_SPOOL_DIR" -arg +mbox -message "frm +mbox" \ +"Sergey Poznyakoff\tMBOX" + mu_exec -arg -q -arg %nonexistent -retcode 2 -message "frm -q %nonexistent" \ "No messages in that folder!" set env(MAIL) $MU_SPOOL_DIR/bigto.mbox -set env(FOLDER) $env(MAIL) +unset env(FOLDER) mu_exec -retcode 1 -message "frm -l on long headers" -arg -l \ "(Ayoung-Chee, Nigel Paul -- Nigel Paul Ayoung-Chee)\tPatrick Chan\tNew email address, etc." diff --git a/imap4d/imap4d.c b/imap4d/imap4d.c index 6a68d6535..442b6dfbf 100644 --- a/imap4d/imap4d.c +++ b/imap4d/imap4d.c @@ -326,6 +326,9 @@ main (int argc, char **argv) state = STATE_NONAUTH; /* Starting state in non-auth. */ MU_AUTH_REGISTER_ALL_MODULES (); + /* Register the desired formats. */ + mu_register_local_mbox_formats (); + imap4d_capability_init (); mu_gocs_daemon = default_gocs_daemon; #ifdef WITH_TLS @@ -374,9 +377,6 @@ main (int argc, char **argv) } } - /* Register the desired formats. */ - mu_register_local_mbox_formats (); - /* Set the signal handlers. */ signal (SIGINT, imap4d_signal); signal (SIGQUIT, imap4d_signal); diff --git a/imap4d/testsuite/imap4d/list.exp b/imap4d/testsuite/imap4d/list.exp index 9c4922098..e27f54967 100644 --- a/imap4d/testsuite/imap4d/list.exp +++ b/imap4d/testsuite/imap4d/list.exp @@ -53,6 +53,8 @@ imap4d_test "LIST \"/\" \"*\""\ imap4d_test -sort "LIST \"$MU_DATA_DIR\" \"*\""\ "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/etc"\ +"LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/etc/mail.rc"\ +"LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/etc/passwd"\ "LIST (\\NoSelect) \"/\" $MU_DATA_DIR/spool"\ "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/bigto.mbox"\ "LIST (\\NoInferiors) \"/\" $MU_DATA_DIR/spool/relational.mbox" \ diff --git a/imap4d/util.c b/imap4d/util.c index cb5ddc2ef..9737dafa8 100644 --- a/imap4d/util.c +++ b/imap4d/util.c @@ -1030,50 +1030,59 @@ util_localname () /* Match STRING against the IMAP4 wildcard pattern PATTERN. */ +#define WILD_FALSE 0 +#define WILD_TRUE 1 +#define WILD_ABORT 2 + int -util_wcard_match (const char *string, const char *pattern, const char *delim) +_wild_match (const char *expr, const char *name, const char *delim) { - const char *p = pattern, *n = string; - char c; - - for (; (c = *p++) != '\0' && *n; n++) + while (expr && *expr) { - switch (c) + if (*name == 0 && *expr != '*') + return WILD_ABORT; + switch (*expr) { - case '%': - /* Matches everything except '/' */ - if (*p == '\0') + case '*': + while (*++expr == '*') + ; + if (*expr == 0) + return WILD_TRUE; + while (*name) { - for (; *n; ++n) - if (*n == *delim) - return 1; - return 0; + int res = _wild_match (expr, name++, delim); + if (res != WILD_FALSE) + return res; } - else - for (; *n != '\0'; ++n) - if (util_wcard_match (n, p, delim) == 0) - return 0; - break; - - case '*': - if (*p == '\0') - return 0; - else - for (; *n != '\0'; ++n) - if (util_wcard_match (n, p, delim) == 0) - return 0; - break; + return WILD_ABORT; + case '%': + while (*++expr == '%') + ; + if (*expr == 0) + return strchr (name, delim) ? WILD_FALSE : WILD_TRUE; + while (*name && *name != delim) + { + int res = _wild_match (expr, name++, delim); + if (res != WILD_FALSE) + return res; + } + return _wild_match (expr, name, delim); + default: - if (c != *n) - return 1; + if (*expr != *name) + return WILD_FALSE; + expr++; + name++; } } + return *name == 0; +} - if (!c && !*n) - return 0; - - return 1; +int +util_wcard_match (const char *name, const char *expr, const char *delim) +{ + return _wild_match (expr, name, delim[0]) != WILD_TRUE; } /* Return the uindvalidity of a mailbox. diff --git a/libargp/common.c b/libargp/common.c index 1aefd7c41..5084af75c 100644 --- a/libargp/common.c +++ b/libargp/common.c @@ -23,6 +23,7 @@ #include <string.h> #include <mailutils/syslog.h> #include <mailutils/daemon.h> +#include <mailutils/mailbox.h> /* ************************************************************************* */ @@ -45,6 +46,7 @@ enum { OPT_LICENSE, OPT_MAILBOX_PATTERN, OPT_MAILBOX_TYPE, + OPT_MAIL_FOLDER, OPT_DEBUG_LEVEL, OPT_LINE_INFO, OPT_HELP_CONFIG @@ -235,6 +237,8 @@ static struct argp_option mu_mailbox_argp_option[] = { "", 0 }, { "mailbox-type", OPT_MAILBOX_TYPE, N_("PROTO"), OPTION_HIDDEN, N_("Default mailbox type to use"), 0 }, + { "mail-folder", OPT_MAIL_FOLDER, N_("DIR"), OPTION_HIDDEN, + N_("Default user mail folder"), 0 }, { NULL } }; @@ -257,6 +261,10 @@ mu_mailbox_argp_parser (int key, char *arg, struct argp_state *state) case OPT_MAILBOX_TYPE: mu_argp_node_list_new (&lst, "mailbox-type", arg); break; + + case OPT_MAIL_FOLDER: + mu_argp_node_list_new (&lst, "folder", arg); + break; case ARGP_KEY_INIT: mu_argp_node_list_init (&lst); diff --git a/libcfg/common.c b/libcfg/common.c index 6288e89a6..1e6122d0d 100644 --- a/libcfg/common.c +++ b/libcfg/common.c @@ -24,6 +24,7 @@ #include <mailutils/daemon.h> #include <mailutils/debug.h> #include <mailutils/syslog.h> +#include <mailutils/mailbox.h> #include <mu_umaxtostr.h> static struct mu_gocs_daemon daemon_settings; @@ -39,6 +40,13 @@ static struct mu_gocs_debug debug_settings; /* Mailbox */ /* ************************************************************************* */ +static int +_cb_folder (mu_debug_t debug, void *data, char *arg) +{ + mu_set_folder_directory (arg); + return 0; +} + static struct mu_cfg_param mu_mailbox_param[] = { { "mail-spool", mu_cfg_string, &mailbox_settings.mail_spool, 0, NULL, N_("Use specified URL as a mailspool directory."), @@ -49,6 +57,9 @@ static struct mu_cfg_param mu_mailbox_param[] = { N_("pattern") }, { "mailbox-type", mu_cfg_string, &mailbox_settings.mailbox_type, 0, NULL, N_("Default mailbox type."), N_("protocol") }, + { "folder", mu_cfg_callback, NULL, 0, _cb_folder, + N_("Default user mail folder"), + N_("dir") }, { NULL } }; diff --git a/libproto/maildir/folder.c b/libproto/maildir/folder.c index cc91b32d8..33215e809 100644 --- a/libproto/maildir/folder.c +++ b/libproto/maildir/folder.c @@ -60,14 +60,13 @@ static int _maildir_is_scheme (mu_record_t record, mu_url_t url, int flags) { if (mu_url_is_scheme (url, record->scheme)) - return MU_FOLDER_ATTRIBUTE_ALL & flags; + return MU_FOLDER_ATTRIBUTE_FILE & flags; if (mu_scheme_autodetect_p (url)) { /* Attemp auto-detection */ const char *path; struct stat st; - int rc = 0; if (mu_url_sget_path (url, &path)) return 0; @@ -78,13 +77,11 @@ _maildir_is_scheme (mu_record_t record, mu_url_t url, int flags) if (!S_ISDIR (st.st_mode)) return 0; - rc |= (MU_FOLDER_ATTRIBUTE_DIRECTORY & flags); - if ((flags & MU_FOLDER_ATTRIBUTE_FILE) && dir_exists (path, TMPSUF) && dir_exists (path, CURSUF) && dir_exists (path, NEWSUF)) - return rc | MU_FOLDER_ATTRIBUTE_FILE; + return MU_FOLDER_ATTRIBUTE_FILE; } return 0; } diff --git a/libproto/maildir/mbox.c b/libproto/maildir/mbox.c index 2eece03c9..d9e062755 100644 --- a/libproto/maildir/mbox.c +++ b/libproto/maildir/mbox.c @@ -299,7 +299,7 @@ maildir_uniq (struct _amd_data *amd, int fd) struct timeval tv; unsigned long n; struct stat st; - + gettimeofday (&tv, NULL); FMT ("%lu", tv.tv_sec); COPY ("."); @@ -409,24 +409,27 @@ static int maildir_msg_init (struct _amd_data *amd, struct _amd_message *amm) { struct _maildir_message *msg = (struct _maildir_message *) amm; - char *name; + char *name, *fname; struct stat st; int i; - /* chdir (amd->name); FIXME */ name = maildir_uniq (amd, -1); - + fname = maildir_mkfilename (amd->name, NEWSUF, name); + for (i = 0; i < NTRIES; i++) { - if (stat (name, &st) < 0 && errno == ENOENT) + if (stat (fname, &st) < 0 && errno == ENOENT) { msg->uid = amd->next_uid (amd); msg->file_name = name; + free (fname); return 0; } + mu_diag_output (MU_DIAG_WARNING, "cannot stat %s: %s", fname, + mu_strerror (errno)); sleep (2); } - + free (fname); free (name); return MU_ERR_BAD_RESUMPTION; } diff --git a/libproto/mbox/folder.c b/libproto/mbox/folder.c index cf23178f3..e2406441f 100644 --- a/libproto/mbox/folder.c +++ b/libproto/mbox/folder.c @@ -317,7 +317,8 @@ inode_list_lookup (struct inode_list *list, struct stat *st) } static int -list_helper (struct search_data *data, const char *dirname, size_t level, +list_helper (struct search_data *data, mu_record_t record, + const char *dirname, size_t level, struct inode_list *ilist) { DIR *dirp; @@ -341,21 +342,20 @@ list_helper (struct search_data *data, const char *dirname, size_t level, { char const *ename = dp->d_name; char *fname; + struct stat st; if (ename[ename[0] != '.' ? 0 : ename[1] != '.' ? 1 : 2] == 0) continue; fname = get_pathname (dirname, ename); - if (data->folder->_match == NULL - || data->folder->_match (fname + data->dirlen + - ((data->dirlen > 1 - && data->dirname[data->dirlen-1] != '/') ? - 1 : 0), - data->pattern, - data->flags) == 0) + if (stat (fname, &st) == 0) { - struct stat st; - - if (stat (fname, &st) == 0) + if (data->folder->_match == NULL + || data->folder->_match (fname + data->dirlen + + ((data->dirlen > 1 + && data->dirname[data->dirlen-1] != '/') ? + 1 : 0), + data->pattern, + data->flags) == 0) { char *refname = fname; int type = 0; @@ -371,8 +371,22 @@ list_helper (struct search_data *data, const char *dirname, size_t level, continue; } - mu_registrar_lookup (refname, MU_FOLDER_ATTRIBUTE_ALL, NULL, - &type); + if (record) + { + mu_url_t url; + int rc = mu_url_create (&url, refname); + if (rc == 0) + { + rc = mu_url_parse (url); + if (rc == 0) + type = mu_record_is_scheme (record, url, + MU_FOLDER_ATTRIBUTE_ALL); + } + mu_url_destroy (&url); + } + else + mu_registrar_lookup (refname, MU_FOLDER_ATTRIBUTE_ALL, + &record, &type); resp->name = fname; resp->level = level; @@ -413,16 +427,26 @@ list_helper (struct search_data *data, const char *dirname, size_t level, idata.inode = st.st_ino; idata.dev = st.st_dev; idata.next = ilist; - stop = list_helper (data, refname, level + 1, &idata); + stop = list_helper (data, record, refname, level + 1, + &idata); } } - else + else if (S_ISDIR (st.st_mode)) { - MU_DEBUG2 (data->folder->debug, MU_DEBUG_ERROR, - "list_helper cannot stat %s: %s", - fname, mu_strerror (errno)); + struct inode_list idata; + + idata.inode = st.st_ino; + idata.dev = st.st_dev; + idata.next = ilist; + stop = list_helper (data, NULL, fname, level + 1, &idata); } } + else + { + MU_DEBUG2 (data->folder->debug, MU_DEBUG_ERROR, + "list_helper cannot stat %s: %s", + fname, mu_strerror (errno)); + } free (fname); } closedir (dirp); @@ -452,7 +476,7 @@ folder_mbox_list (mu_folder_t folder, const char *ref, sdata.max_level = max_level; sdata.folder = folder; sdata.errcnt = 0; - list_helper (&sdata, sdata.dirname, 0, &iroot); + list_helper (&sdata, NULL, sdata.dirname, 0, &iroot); free (sdata.dirname); /* FIXME: error code */ return 0; diff --git a/maidag/deliver.c b/maidag/deliver.c index 51737adec..0d39cd7b6 100644 --- a/maidag/deliver.c +++ b/maidag/deliver.c @@ -143,66 +143,20 @@ attach_notify (mu_mailbox_t mbox) } int -deliver (mu_mailbox_t imbx, char *name, char **errp) +deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg, + struct mu_auth_data *auth, const char *name, + char **errp) { - mu_mailbox_t mbox; - mu_message_t msg; + int status; char *path; mu_url_t url = NULL; mu_locker_t lock; - struct mu_auth_data *auth; - int status; int failed = 0; - auth = mu_get_auth_by_name (name); - if (!auth) - { - mailer_err (_("%s: no such user"), name); - if (errp) - asprintf (errp, "%s: no such user", name); - exit_code = EX_UNAVAILABLE; - return EX_UNAVAILABLE; - } - if (current_uid) - auth->change_uid = 0; - - if (!sieve_test (auth, imbx)) - { - exit_code = EX_OK; - mu_auth_data_free (auth); - return 0; - } - - if ((status = mu_mailbox_get_message (imbx, 1, &msg)) != 0) - { - mailer_err (_("Cannot get message from the temporary mailbox: %s"), - mu_strerror (status)); - mu_auth_data_free (auth); - return EX_TEMPFAIL; - } - - if ((status = mu_mailbox_create (&mbox, auth->mailbox)) != 0) - { - mailer_err (_("Cannot open mailbox %s: %s"), - auth->mailbox, mu_strerror (status)); - mu_auth_data_free (auth); - return EX_TEMPFAIL; - } - mu_mailbox_get_url (mbox, &url); path = (char*) mu_url_to_string (url); - biff_user_name = name; - - /* Actually open the mailbox. Switch to the user's euid to make - sure the maildrop file will have right privileges, in case it - will be created */ - if (switch_user_id (auth, 1)) - return EX_TEMPFAIL; status = mu_mailbox_open (mbox, MU_STREAM_APPEND|MU_STREAM_CREAT); - if (switch_user_id (auth, 0)) - return EX_TEMPFAIL; - if (status != 0) { mailer_err (_("Cannot open mailbox %s: %s"), path, mu_strerror (status)); @@ -317,3 +271,59 @@ deliver (mu_mailbox_t imbx, char *name, char **errp) mu_mailbox_destroy (&mbox); return failed ? exit_code : 0; } + +int +deliver (mu_mailbox_t imbx, char *name, char **errp) +{ + struct mu_auth_data *auth; + mu_mailbox_t mbox; + mu_message_t msg; + int status; + + auth = mu_get_auth_by_name (name); + if (!auth) + { + mailer_err (_("%s: no such user"), name); + if (errp) + asprintf (errp, "%s: no such user", name); + exit_code = EX_UNAVAILABLE; + return EX_UNAVAILABLE; + } + if (current_uid) + auth->change_uid = 0; + + if (!sieve_test (auth, imbx)) + { + exit_code = EX_OK; + mu_auth_data_free (auth); + return 0; + } + + if ((status = mu_mailbox_get_message (imbx, 1, &msg)) != 0) + { + mailer_err (_("Cannot get message from the temporary mailbox: %s"), + mu_strerror (status)); + mu_auth_data_free (auth); + return EX_TEMPFAIL; + } + + if ((status = mu_mailbox_create (&mbox, auth->mailbox)) != 0) + { + mailer_err (_("Cannot open mailbox %s: %s"), + auth->mailbox, mu_strerror (status)); + mu_auth_data_free (auth); + return EX_TEMPFAIL; + } + + biff_user_name = name; + + /* Actually open the mailbox. Switch to the user's euid to make + sure the maildrop file will have right privileges, in case it + will be created */ + if (switch_user_id (auth, 1)) + return EX_TEMPFAIL; + status = deliver_to_user (imbx, mbox, msg, auth, name, errp); + if (switch_user_id (auth, 0)) + return EX_TEMPFAIL; + return status; +} diff --git a/maidag/maidag.c b/maidag/maidag.c index 26d1fd215..3b44c6a4a 100644 --- a/maidag/maidag.c +++ b/maidag/maidag.c @@ -161,7 +161,7 @@ set_debug_flags (mu_debug_t debug, const char *arg) } if (*arg == ',') arg++; - else + else if (*arg) mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("expected comma, but found %c"), *arg); } diff --git a/mail/mail.c b/mail/mail.c index 077dbf8fd..0abe376b0 100644 --- a/mail/mail.c +++ b/mail/mail.c @@ -436,14 +436,13 @@ main (int argc, char **argv) mu_debug_set_level (debug, MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT)); } - if ((rc = mu_mailbox_open (mbox, MU_STREAM_RDWR)) != 0 && rc != ENOENT) + if ((rc = mu_mailbox_open (mbox, MU_STREAM_RDWR|MU_STREAM_CREAT)) != 0) { mu_url_t url = NULL; mu_mailbox_get_url (mbox, &url); util_error (_("Cannot open mailbox %s: %s"), mu_url_to_string (url), mu_strerror (rc)); mu_mailbox_destroy (&mbox); - exit (EXIT_FAILURE); } if (rc) diff --git a/mailbox/amd.c b/mailbox/amd.c index cd46a43dd..fdbacb519 100644 --- a/mailbox/amd.c +++ b/mailbox/amd.c @@ -347,8 +347,6 @@ amd_open (mu_mailbox_t mailbox, int flags) if (!S_ISDIR (st.st_mode)) return EINVAL; - amd->mtime = st.st_mtime; - return 0; } @@ -711,7 +709,8 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, int expunge) fclose (fp); msg_name = amd->msg_file_name (mhm, mhm->deleted); - rename (name, msg_name); + if (rename (name, msg_name)) + status = errno; free (name); free (msg_name); @@ -1147,9 +1146,6 @@ amd_is_updated (mu_mailbox_t mailbox) struct stat st; struct _amd_data *amd = mailbox->data; - if (amd->msg_count == 0) - return 0; - if (stat (amd->name, &st) < 0) return 1; diff --git a/mailbox/mailbox.c b/mailbox/mailbox.c index af690d554..08834a27a 100644 --- a/mailbox/mailbox.c +++ b/mailbox/mailbox.c @@ -74,12 +74,26 @@ int mu_mailbox_set_default_proto (const char *proto) { char *p; + size_t len = strlen (proto); - if (mu_registrar_lookup (proto, MU_FOLDER_ATTRIBUTE_FILE, NULL, NULL)) + if (proto [len - 1] == ':') + { + p = strdup (proto); + if (!p) + return ENOMEM; + } + else + { + p = malloc (len + 2); + if (!p) + return ENOMEM; + strcpy (p, proto); + p[len] = ':'; + p[len+1] = 0; + } + + if (mu_registrar_lookup (p, MU_FOLDER_ATTRIBUTE_FILE, NULL, NULL)) return MU_ERR_NO_HANDLER; - p = strdup (proto); - if (!p) - return ENOMEM; if (default_proto) free (default_proto); default_proto = p; diff --git a/mailbox/mbx_default.c b/mailbox/mbx_default.c index 40e1d2b09..c0db199c8 100644 --- a/mailbox/mbx_default.c +++ b/mailbox/mbx_default.c @@ -82,6 +82,11 @@ mu_set_mail_directory (const char *p) { if (_mu_mailbox_pattern) free (_mu_mailbox_pattern); + if (!p) + { + _mu_mailbox_pattern = NULL; + return 0; + } return mu_normalize_mailbox_url (&_mu_mailbox_pattern, p); } @@ -90,6 +95,11 @@ mu_set_mailbox_pattern (const char *pat) { if (_mu_mailbox_pattern) free (_mu_mailbox_pattern); + if (!pat) + { + _mu_mailbox_pattern = NULL; + return 0; + } _mu_mailbox_pattern = strdup (pat); return _mu_mailbox_pattern ? 0 : ENOMEM; } @@ -339,22 +349,26 @@ mu_mailbox_create_default (mu_mailbox_t *pmbox, const char *mail) if (pmbox == NULL) return MU_ERR_OUT_PTR_NULL; - /* Other utilities may not understand GNU mailutils url namespace, so - use FOLDER instead, to not confuse others by using MAIL. */ if (mail == NULL || *mail == '\0') { - mail = getenv ("FOLDER"); - - /* Fallback to wellknown environment. */ - if (!mail) - mail = getenv ("MAIL"); + if (!_mu_mailbox_pattern) + { + /* Other utilities may not understand GNU mailutils url namespace, so + use FOLDER instead, to not confuse others by using MAIL. */ + mail = getenv ("FOLDER"); + if (!mail) + { + /* Fallback to well-known environment. */ + mail = getenv ("MAIL"); + } + } if (!mail) - { - if ((status = user_mailbox_name (NULL, &tmp_mbox))) - return status; - mail = tmp_mbox; - } + { + if ((status = user_mailbox_name (NULL, &tmp_mbox))) + return status; + mail = tmp_mbox; + } } p = mu_tilde_expansion (mail, "/", NULL); diff --git a/messages/testsuite/messages/test.exp b/messages/testsuite/messages/test.exp index 87b822e3d..955cf9db3 100644 --- a/messages/testsuite/messages/test.exp +++ b/messages/testsuite/messages/test.exp @@ -19,7 +19,7 @@ source $top_srcdir/testsuite/lib/mailutils.exp -mu_init +mu_init -noflags set env(MAIL) $MU_SPOOL_DIR/mbox1 set env(FOLDER) $env(MAIL) @@ -30,7 +30,8 @@ mu_exec -message "messages" \ mu_exec -message "messages -q" -arg -q "5" -mu_exec -message "messages %teaparty.mbox" -arg %teaparty.mbox \ +mu_exec -message "messages +teaparty.mbox" \ + -arg "--mail-folder=$MU_SPOOL_DIR" -arg +teaparty.mbox \ "Number of messages in $MU_SPOOL_DIR/teaparty.mbox: 95" #end of test.exp diff --git a/readmsg/testsuite/readmsg/test.exp b/readmsg/testsuite/readmsg/test.exp index a04b1c50a..cc834d96d 100644 --- a/readmsg/testsuite/readmsg/test.exp +++ b/ |