commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. mu-1-2-90-separate-argp-cfg


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. mu-1-2-90-separate-argp-cfg-294-g0517ca0
Date: Sun, 12 Jul 2009 16:43:39 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=0517ca033b3222afc09f5b70626c38280c749c14

The branch, master has been updated
       via  0517ca033b3222afc09f5b70626c38280c749c14 (commit)
       via  1184b4a5c89edabc5f951647460b284062d5abda (commit)
       via  4f12cc0c9924afccb721ef418efe6e83c95c0cd1 (commit)
       via  0a7e59334332346755a05df5f85aafdba629d78d (commit)
      from  61295ae0e724c62ac016dfc374d6064c63270288 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 0517ca033b3222afc09f5b70626c38280c749c14
Author: Paul Vojta <address@hidden>
Date:   Sun Jul 12 19:43:20 2009 +0300

    Fix the way mail accounts for the status of messages.
    
    * mail/mail.h (MAIL_ATTRIBUTE_PRESERVED)
    (MAIL_ATTRIBUTE_TOUCHED): New define.
    * mail/from.c (mail_from0): Mark with 'R' only those messages that
    have been read in this mail session.
    * mail/hold.c (hold0): Set MAIL_ATTRIBUTE_PRESERVED
    * mail/mbox.c (mbox0): Don't mark message as read.
    * mail/quit.c (mail_mbox_commit): Force keepsave on
    not system mailboxes.
    * mail/touch.c: Use MAIL_ATTRIBUTE_TOUCHED
    * mail/undelete.c: Clear MAIL_ATTRIBUTE_PRESERVED and
    MAIL_ATTRIBUTE_MBOXED bits.
    * mail/testsuite/mail/write.exp: Account for the above changes.

commit 1184b4a5c89edabc5f951647460b284062d5abda
Author: Sergey Poznyakoff <address@hidden>
Date:   Sun Jul 12 18:36:29 2009 +0300

    Implement `mail -F'.
    
    * NEWS, doc/texinfo/programs.texi: Update.
    * mail/mail.c (parse_opt): Remove the fixme.
    * mail/mailvar.c (mailvar_tab): Add `byname'.
    * mail/reply.c (reply0): Use `byname' when deciding where to
    save the message.
    * mail/util.c: Fix comment.

commit 4f12cc0c9924afccb721ef418efe6e83c95c0cd1
Author: Sergey Poznyakoff <address@hidden>
Date:   Sun Jul 12 18:18:43 2009 +0300

    Further improvements in `mail'.
    
    * NEWS: Update.
    * mail/mail.h (MOPTF_UNSET): New constant.
    * mail/mailvar.c (MAILVAR_TYPEMASK): New define.
    (struct mailvar_symbol): Remove `type'. Add `handler'.
    The latter supplies special handling for certain variables.
    (mailvar_tab): Update accordingly.
    Implement "debug" variable.
    (mailvar_set): Enforce correct variable type in variable-strict mode.
    Handle MOPTF_UNSET flag.
    Remove kludgy special handling for some attributes, use sym->handler
    instead.
    (set_decode_fallback, set_replyregex)
    (set_screen, set_mailbox_debug_level, set_debug): New functions.
    (describe_symbol): Handle alternative symbol types.
    * mail/set.c: Use MOPTF_UNSET when unsetting the variable.
    * mail/source.c: Set correct locus. This allows to display
    locations along with error messages.

commit 0a7e59334332346755a05df5f85aafdba629d78d
Author: Sergey Poznyakoff <address@hidden>
Date:   Sun Jul 12 18:09:57 2009 +0300

    Improve mail compliance to POSIX standard
    
    * mail/mail.c: Redo -f option handling to fully comply to POSIX
    Set default diagnostics printer for interactive mode.
    * NEWS, doc/texinfo/programs.texi: Document the use of -f option.

-----------------------------------------------------------------------

Summary of changes:
 NEWS                          |   33 ++++-
 doc/texinfo/programs.texi     |   83 +++++++--
 mail/from.c                   |    8 +-
 mail/hold.c                   |    1 +
 mail/mail.c                   |  163 +++++++++--------
 mail/mail.h                   |    9 +-
 mail/mailvar.c                |  406 +++++++++++++++++++++++++++++-----------
 mail/mbox.c                   |    2 +-
 mail/quit.c                   |   12 +-
 mail/reply.c                  |    4 +-
 mail/set.c                    |    3 +-
 mail/source.c                 |   20 ++-
 mail/testsuite/mail/write.exp |    6 +-
 mail/touch.c                  |    6 +-
 mail/undelete.c               |    2 +
 mail/util.c                   |    2 +-
 16 files changed, 527 insertions(+), 233 deletions(-)

diff --git a/NEWS b/NEWS
index 29bb08a..b5524bf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU mailutils NEWS -- history of user-visible changes. 2009-07-11
+GNU mailutils NEWS -- history of user-visible changes. 2009-07-12
 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 
 2008, 2009 Free Software Foundation, Inc.
 See the end of file for copying conditions.
@@ -29,6 +29,37 @@ information.
 
 * Mail
 
+** The -f option
+
+The semantics of -f (--file) option fully complies to the POSIX
+standard. Namely, this option instructs mail to read messages
+from the file named by the first non-optional command line
+argument. Therefore, the following four usage patterns are
+entirely equivalent:
+
+  mail -fin mymbox
+  mail -f mymbox -in
+  mail --file -in mymbox
+  mail --file -i mymbox -n
+
+In addition, the form
+
+  mail --file=mymbox
+
+is also allowed.  
+
+** The -F option
+
+The -F option (record outgoing messages in a file named after the
+first recipient) is implemented.
+
+** error locations
+
+Diagnostic messages issued while processing `source' command
+include file locations, in compliance with the GNU standards. This
+also includes diagnostics issued during processing of the
+system or user configuration file.
+
 ** envelope command
 
 The env[elope] command displays the SMTP envelopes of the messages
diff --git a/doc/texinfo/programs.texi b/doc/texinfo/programs.texi
index 1c21a52..d5aa430 100644
--- a/doc/texinfo/programs.texi
+++ b/doc/texinfo/programs.texi
@@ -2189,9 +2189,8 @@ See @ref{Composing Mail}, for a detailed description of 
this behavior.
 
 If the command line contained no email addresses, @command{mail} switches
 to reading mode. In this mode it allows to read and manipulate the
-contents of a mailbox. The URL of the mailbox to operate upon is
-taken from the argument of @option{--file} command line option. If it
-is not specified, the user's system mailbox is assumed. For more
+contents of the user system mailbox. The @option{--file} (@option{-f})
+command line option allows to specify another mailbox name. For more
 detail, see @ref{Reading Mail}.
 
 In contrast to other GNU Mailutils programs, @command{mail} does not
@@ -2237,19 +2236,18 @@ Execute @var{command} before opening the mailbox. Any 
number of
 @option{--exec} options can be given. The commands will be executed
 after sourcing configuration files (@pxref{Mail Configuration Files}),
 but before opening the mailbox. 
address@hidden --exec
address@hidden address@hidden
address@hidden address@hidden
-Operate on mailbox @var{file}. If this option is not specified, the default
-is user's system mailbox. If it is specified without argument, the
-default is @file{$HOME/mbox}.
address@hidden note}, that there should be no whitespace between the
-short variant of the option (@option{-f}), and its parameter. Similarly,
-when using long option (@option{--file}), its argument must be preceded by
-equal sign.
address@hidden -f
address@hidden --file
+Operate on the mailbox given by the first non-optional command line
+argument. If there is no such argument, read messages from the
+user's @file{mbox} file. @xref{Reading Mail} for more details about
+using this option.
 @item -F
 @itemx --byname
-Save messages according to sender. Currently this option is not implemented.
+Record outgoing messages in a file named after the first recipient.
+The name is the login-name portion of the address found first on the
address@hidden:} line in the mail header. This option sets the @samp{byname}
+variable, which see (@xref{byname}).
 @item -H
 @itemx --headers
 Print header summary to stdout and exit.
@@ -2628,10 +2626,15 @@ invoking @command{mail}:
 @table @code
 @item mail
 To read messages from your system mailbox.
address@hidden mail --file
-To read messages from your mailbox (@file{$HOME/mbox}).
address@hidden mail address@hidden
address@hidden mail -f
address@hidden mail --file
+To read messages from your mailbox (@file{$HOME/mbox}).  If the
address@hidden option (see below) is also given, read messages
+from that user's @file{mbox}.
address@hidden mail -f @var{path_to_mailbox}
address@hidden mail --file @var{path_to_mailbox}
 To read messages from the specified mailbox.
address@hidden mail -u @var{user}
 @item mail address@hidden
 To read messages from the system mailbox belonging to @var{user}.
 @end table
@@ -2641,6 +2644,25 @@ to use the last variant of invocation, unless you are a 
super-user.
 Similarly, the last but one variant is also greatly affected by the
 permissions the target mailbox has.
 
+Notice that @var{path_to_mailbox} is not an argument to
address@hidden (@option{-f}) option, but rather the first
+non-optional argument on the command line. Therefore, the
+following three invocations are equivalent:
+
address@hidden
+$ mail -fin mymbox
+$ mail -f mymbox -in
+$ mail --file -in mymbox
+$ mail --file -i mymbox -n
address@hidden smallexample
+
+Additionally, for conformance to the GNU standards, the
+following form is also accepted:
+
address@hidden
+$ mail --file=mymbox -i -n
address@hidden smallexample
+
 Unless you have started mail with @option{--norc} command line option,
 it will read the contents of the system-wide configuration file.
 Then it reads the contents of user configuration file, if any.
@@ -3509,6 +3531,19 @@ message, the next one will be typed automatically.
 When set, every occurrence of @code{!} in arguments to @code{!}
 command is replaced with the last executed command.
 
address@hidden
address@hidden byname
address@hidden: Boolean
address@hidden: Unset
address@hidden byname, mail variable
+
+Record outgoing messages in a file named after the first recipient.
+The name is the login-name portion of the address found first on the
address@hidden:} line in the mail header. This variable overrides the
address@hidden variable.
+
+It is set by the @option{--byname} (@option{-F}) command line option.
+
 @anchor{datefield}
 @item datefield
 @*Type: Boolean.
@@ -3563,6 +3598,20 @@ if @code{crt} is set without a value, then the height of 
the terminal
 screen is used to compute the threshold. The number of lines on
 screen is controlled by @code{screen} variable.
 
address@hidden debug
address@hidden: String to boolean
address@hidden: Not set
address@hidden debug, mail variable
+
+Sets mailutils debug level.  If set to string, the value must be a
+valid Mailutils debugging specification.  @xref{Debug Statement}, for
+a description.
+
+If unset (i.e. @code{set nodebug}), clears and disables all debugging
+information.  If set to @samp{true} (i.e. @code{set debug}), sets
+maximum debugging (@samp{<trace7}) on mailbox and its underlying
+objects.
+
 @item decode-fallback
 @*Type: String.
 @*Default: @samp{none}.
diff --git a/mail/from.c b/mail/from.c
index 383ae56..add2643 100644
--- a/mail/from.c
+++ b/mail/from.c
@@ -98,16 +98,18 @@ mail_from0 (msgset_t *mspec, mu_message_t msg, void *data)
   
   if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_MBOXED))
     cflag = 'M';
+  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_PRESERVED))
+    cflag = 'P';
   else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED))
     cflag = '*';
   else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_TAGGED))
     cflag = 'T';
-  else if (mu_attribute_is_read (attr))
+  else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SHOWN))
     cflag = 'R';
-  else if (mu_attribute_is_seen (attr))
-    cflag = 'U';
   else if (mu_attribute_is_recent (attr))
     cflag = 'N';
+  else if (!mu_attribute_is_read (attr))
+    cflag = 'U';
   else
     cflag = ' ';
 
diff --git a/mail/hold.c b/mail/hold.c
index 2c74fab..aaa580c 100644
--- a/mail/hold.c
+++ b/mail/hold.c
@@ -30,6 +30,7 @@ hold0 (msgset_t *mspec, mu_message_t msg, void *data)
 
   mu_message_get_attribute (msg, &attr);
   mu_attribute_unset_userflag (attr, MAIL_ATTRIBUTE_MBOXED);
+  mu_attribute_set_userflag (attr, MAIL_ATTRIBUTE_PRESERVED);
 
   set_cursor (mspec->msg_part[0]);
   
diff --git a/mail/mail.c b/mail/mail.c
index ff98d9c..0d95323 100644
--- a/mail/mail.c
+++ b/mail/mail.c
@@ -30,13 +30,18 @@ static mu_list_t command_list;   /* List of commands to be 
executed after parsin
                                 command line */
 
 const char *program_version = "mail (" PACKAGE_STRING ")";
-static char doc[] = N_("GNU mail -- the standard /bin/mail interface");
-static char args_doc[] = N_("[address...]");
+static char doc[] = N_("GNU mail -- process mail messages.\n"
+"If -f or --file is given, mail operates on the mailbox named "
+"by the first argument, or the user's mbox, if no argument given.\n");
+static char args_doc[] = N_("[address...]\n-f [OPTION...] [file]\n--file 
[OPTION...] [file]\n--file=file [OPTION...]");
+
+#define F_OPTION 256
 
 static struct argp_option options[] = {
+  { NULL,     'f', 0,      OPTION_HIDDEN, NULL, 0 },
+  {"file",    F_OPTION,    "FILE",   OPTION_ARG_OPTIONAL|OPTION_HIDDEN, 0},
+
   {"exist",   'e', 0,      0, N_("Return true if mail exists"), 0},
-  {"file",    'f', N_("URL"), OPTION_ARG_OPTIONAL,
-                             N_("Operate on given mailbox URL (default 
~/mbox)"), 0},
   {"byname",  'F', 0,      0, N_("Save messages according to sender"), 0},
   {"headers", 'H', 0,      0, N_("Write a header summary and exit"), 0},
   {"ignore",  'i', 0,      0, N_("Ignore interrupts"), 0},
@@ -56,12 +61,16 @@ static struct argp_option options[] = {
 };
 
 
+#define HINT_SEND_MODE   0x1
+#define HINT_FILE_OPTION 0x2
+
 struct arguments
 {
-  char **args;
+  int argc;
+  char **argv;
   char *file;
   char *user;
-  int send_mode;
+  int hint;
 };
 
 static error_t
@@ -72,32 +81,20 @@ parse_opt (int key, char *arg, struct argp_state *state)
   switch (key)
     {
     case 'a':
-      args->send_mode = 1;
+      args->hint |= HINT_SEND_MODE;
       send_append_header (arg);
       break;
       
     case 'e':
       util_cache_command (&command_list, "setq mode=exist");
       break;
-      
-    case 'f':
-      if (arg != NULL)
+
+    case F_OPTION:
+      if (arg)
        args->file = arg;
-      /* People often tend to separate -f option from its argument
-        with a whitespace. This heuristics tries to catch the
-        error: */
-      else if (state->next < state->argc
-              && state->argv[state->next][0] != '-')
-       args->file = state->argv[state->next++];
-      else
-       {
-         int len;
-         char *home = getenv("HOME");
-         len = strlen (home) + strlen ("/mbox") + 1;
-         args->file = xmalloc(len * sizeof (char));
-         strcpy (args->file, home);
-         strcat (args->file, "/mbox");
-       }
+      /* fall through */
+    case 'f':
+      args->hint |= HINT_FILE_OPTION;
       break;
       
     case 'p':
@@ -130,9 +127,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
       break;
       
     case 's':
+      args->hint |= HINT_SEND_MODE;
       send_append_header2 (MU_HEADER_SUBJECT, arg, COMPOSE_REPLACE);
       util_cache_command (&command_list, "set noasksub");
-      args->send_mode = 1;
       break;
       
     case 'u':
@@ -144,20 +141,43 @@ parse_opt (int key, char *arg, struct argp_state *state)
       break;
       
     case 'F':
-      /* FIXME */
-      util_cache_command (&command_list, "setq byname");
+      util_cache_command (&command_list, "set byname");
       break;
 
     case ARGP_KEY_ARG:
-      args->args = realloc (args->args,
+      args->argv = realloc (args->argv,
                            sizeof (char *) * (state->arg_num + 2));
-      args->args[state->arg_num] = arg;
-      args->args[state->arg_num + 1] = NULL;
-      args->send_mode = 1;
+      args->argv[state->arg_num] = arg;
+      args->argv[state->arg_num + 1] = NULL;
+      args->argc = state->arg_num + 1;
       break;
 
     case ARGP_KEY_FINI:
-      if (args->send_mode)
+      if ((args->hint & (HINT_SEND_MODE|HINT_FILE_OPTION)) ==
+         (HINT_SEND_MODE|HINT_FILE_OPTION))
+       argp_error (state, _("conflicting options"));
+      else if (args->hint & HINT_FILE_OPTION)
+       {
+         if (args->file)
+           {
+             if (args->argc > 1)
+               argp_error (state,
+                           _("-f requires at most one command line argument"));
+           }
+         else if (args->argc)
+           {
+             args->file = args->argv[0];
+         
+             if (args->argc > 1)
+               argp_error (state,
+                           _("-f requires at most one command line argument"));
+           }
+         else if (args->user)
+           asprintf (&args->file, "~/%s/mbox", args->user);
+         else
+           args->file = "~/mbox";
+       }
+      else if (args->argc || (args->hint & HINT_SEND_MODE))
        util_cache_command (&command_list, "setq mode=send");
       break;
       
@@ -230,7 +250,7 @@ static char *default_setup[] = {
   "set noautoprint",
   "set nobang",
   "set nocmd",
-  "set nodebug",
+  /*  "set nodebug",*/
   "set nodot",
   "set escape=~",
   "set noflipr",
@@ -281,11 +301,19 @@ static char *default_setup[] = {
   "set nullbodymsg=\"" N_("Null message body; hope that's ok") "\"",
   
   /* These settings are not yet used */
-  "set nodebug",
   "set noonehop",
   "set nosendwait",
 };
 
+static int
+mail_diag_stderr_printer (void *data, mu_log_level_t level, const char *buf)
+{
+  if (level != MU_DIAG_ERROR)
+    fprintf (stderr, "%s: ", mu_diag_level_to_string (level));
+  fputs (buf, stderr);
+  return 0;
+}
+
 int
 main (int argc, char **argv)
 {
@@ -345,14 +373,15 @@ main (int argc, char **argv)
     char *mailer_name = alloca (strlen ("sendmail:")
                                + strlen (PATH_SENDMAIL) + 1);
     sprintf (mailer_name, "sendmail:%s", PATH_SENDMAIL);
-    mailvar_set ("sendmail", mailer_name, mailvar_type_string, 
MOPTF_OVERWRITE);
+    mailvar_set ("sendmail", mailer_name, mailvar_type_string,
+                MOPTF_OVERWRITE);
   }
 
-
-  args.args = NULL;
+  args.argc = 0;
+  args.argv = NULL;
   args.file = NULL;
   args.user = NULL;
-  args.send_mode = 0;
+  args.hint = 0;
   
   /* argument parsing */
 #ifdef WITH_TLS
@@ -369,7 +398,14 @@ main (int argc, char **argv)
 
   util_run_cached_commands (&command_list);
 
-  if (!interactive)
+  if (interactive)
+    {
+      mu_debug_t debug;
+
+      mu_diag_get_debug (&debug);
+      mu_debug_set_print (debug, mail_diag_stderr_printer, NULL);
+    }
+  else
     {
       util_do_command ("set nocrt");
       util_do_command ("set noasksub");
@@ -384,60 +420,33 @@ main (int argc, char **argv)
   /* Interactive mode */
 
   ml_readline_init ();
-  mail_set_my_name(args.user);
+  mail_set_my_name (args.user);
 
   /* Mode is just sending */
   if (strcmp (mode, "send") == 0)
     {
       /* FIXME: set cmd to "mail [add1...]" */
       char *buf = NULL;
-      int num = 0;
       int rc;
-      if (args.args != NULL)
-       while (args.args[num] != NULL)
-         num++;
-      mu_argcv_string (num, args.args, &buf);
+
+      mu_argcv_string (args.argc, args.argv, &buf);
       rc = util_do_command ("mail %s", buf);
       return mailvar_get (NULL, "mailx", mailvar_type_boolean, 0) ? rc : 0;
     }
   /* Or acting as a normal reader */
   else 
     {
-      /* open the mailbox */
-      if (args.file == NULL)
+      if ((rc = mu_mailbox_create_default (&mbox, args.file)) != 0)
        {
-         if (args.user)
-           {
-             char *p = xmalloc (strlen (args.user) + 2);
-             p[0] = '%';
-             strcpy (p + 1, args.user);
-             rc = mu_mailbox_create_default (&mbox, p);
-             free (p);
-           }
+         if (args.file)
+           util_error (_("Cannot create mailbox %s: %s"), args.file,
+                       mu_strerror (rc));
          else
-           rc = mu_mailbox_create_default (&mbox, NULL);
-         if (rc != 0)
-           {
-             util_error (_("Cannot create mailbox for %s: %s"), args.user,
-                         mu_strerror (rc));
-             exit (EXIT_FAILURE);
-           }
-       }
-      else if ((rc = mu_mailbox_create_default (&mbox, args.file)) != 0)
-       {
-         util_error (_("Cannot create mailbox %s: %s"), args.file,
-                     mu_strerror (rc));
+           util_error (_("Cannot create mailbox: %s"),
+                       mu_strerror (rc));
          exit (EXIT_FAILURE);
        }
 
-      /* Could we enable this at runtime, via the a set environment?  */
-      if (0)
-       {
-         mu_debug_t debug = NULL;
-         mu_mailbox_get_debug (mbox, &debug);
-         mu_debug_set_level (debug, MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT));
-       }
-
       if ((rc = mu_mailbox_open (mbox, MU_STREAM_RDWR|MU_STREAM_CREAT)) != 0)
        {
          mu_url_t url = NULL;
@@ -547,7 +556,7 @@ mail_warranty (int argc MU_ARG_UNUSED, char **argv 
MU_ARG_UNUSED)
 {
   fputs (_("GNU Mailutils -- a suite of utilities for electronic mail\n"
            "Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,\n"
-           "2007 Free Software Foundation, Inc.\n\n"),
+           "2007, 2009 Free Software Foundation, Inc.\n\n"),
            ofile);
   fputs (
   _("   GNU Mailutils is free software; you can redistribute it and/or 
modify\n"
diff --git a/mail/mail.h b/mail/mail.h
index cc9a4a7..b6e4c39 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -344,6 +344,7 @@ extern void mailvar_variable_format (FILE *fp,
 
 #define MOPTF_OVERWRITE 0x001
 #define MOPTF_QUIET     0x002
+#define MOPTF_UNSET     0x004
 extern int mailvar_set (const char *name, void *value,
                      enum mailvar_type type, int flags);
 extern int util_isdeleted (size_t msgno);
@@ -426,9 +427,11 @@ extern char *readline (char *prompt);
 
 /* Message attributes */
 #define MAIL_ATTRIBUTE_MBOXED   0x0001
-#define MAIL_ATTRIBUTE_SAVED    0x0002
-#define MAIL_ATTRIBUTE_TAGGED   0x0004
-#define MAIL_ATTRIBUTE_SHOWN    0x0008
+#define MAIL_ATTRIBUTE_PRESERVED 0x0002
+#define MAIL_ATTRIBUTE_SAVED    0x0004
+#define MAIL_ATTRIBUTE_TAGGED   0x0008
+#define MAIL_ATTRIBUTE_SHOWN    0x0010
+#define MAIL_ATTRIBUTE_TOUCHED  0x0020
 
 extern void ml_attempted_completion_over (void);
 
diff --git a/mail/mailvar.c b/mail/mailvar.c
index 6550b39..d101ec8 100644
--- a/mail/mailvar.c
+++ b/mail/mailvar.c
@@ -20,160 +20,245 @@
 #define MAILVAR_RDONLY 0x0002
 #define MAILVAR_HIDDEN 0x0004
 
+#define MAILVAR_TYPEMASK(type) (1<<(8+(type)))
+
 struct mailvar_symbol
 {
   struct mailvar_variable var;
-  enum mailvar_type type;
   int flags;
   char *descr;
+  void (*handler) (struct mailvar_variable *);
 };
 
 mu_list_t mailvar_list = NULL;
 
+static void set_decode_fallback (struct mailvar_variable *);
+static void set_replyregex (struct mailvar_variable *);
+static void set_screen (struct mailvar_variable *);
+static void set_debug (struct mailvar_variable *);
+  
 struct mailvar_symbol mailvar_tab[] =
   {
+    /* FIXME: */
+    { { "allnet", }, MAILVAR_HIDDEN },
+    
     /* For compatibility with other mailx implementations.
        Never used, always true. */
-    { { "append", }, mailvar_type_boolean, MAILVAR_RDONLY,
+    { { "append", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean) | MAILVAR_RDONLY,
       N_("messages saved in mbox are appended to the end rather than 
prepended") },
-    { { "appenddeadletter", }, mailvar_type_boolean, 0,
+    { { "appenddeadletter", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("append the contents of canceled letter to dead.letter file") },
-    { { "askbcc", }, mailvar_type_boolean, 0,
+    { { "askbcc", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("prompt user for bcc before composing the message") },
-    { { "askcc", }, mailvar_type_boolean, 0, 
+    { { "askcc", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("prompt user for cc before composing the message") },
-    { { "ask", }, mailvar_type_boolean, 0,
+    { { "ask", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("prompt user for subject before composing the message") },
-    { { "asksub", }, mailvar_type_whatever, MAILVAR_ALIAS, NULL },
-    { { "autoinc", }, mailvar_type_boolean, 0,
+    { { "asksub", }, MAILVAR_ALIAS, NULL },
+    { { "autoinc", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("automatically incorporate newly arrived messages")},
-    { { "autoprint", }, mailvar_type_boolean, 0,
+    { { "autoprint", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("delete command behaves like dp") },
-    { { "bang", }, mailvar_type_boolean, 0,
+    { { "byname" },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
+      N_("record outgoing messages in a file named after the first recipient; "
+        "overrides the `record' variable") },
+    { { "bang", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("replace every occurrence of ! in arguments to the shell command"
         " with the last executed command") },
-    { { "charset", }, mailvar_type_string, 0,
+    { { "charset", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("output character set for decoded header fields") },
-    { { "cmd", }, mailvar_type_string, 0,
+    { { "cmd", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("default shell command for pipe") },
-    { { "columns", }, mailvar_type_number, 0,
+    { { "columns", },
+      MAILVAR_TYPEMASK (mailvar_type_number),
       N_("number of columns on terminal screen") },
-    { { "crt", }, mailvar_type_number, 0,
+    { { "crt", },
+      MAILVAR_TYPEMASK (mailvar_type_number) |
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("if numeric, sets the minimum number of output lines needed "
         "to engage paging; if boolean, use the height of the terminal "
         "screen to compute the threshold") },
-    { { "datefield", }, mailvar_type_boolean, 0,
+    { { "datefield", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("get date from the `Date:' header, instead of the envelope") },
-    { { "dot", }, mailvar_type_boolean, 0,
+    { { "debug", },
+      MAILVAR_TYPEMASK (mailvar_type_string) |
+        MAILVAR_TYPEMASK (mailvar_type_boolean),
+      N_("set Mailutils debug level"),
+      set_debug },
+    { { "decode-fallback", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
+      N_("how to represent characters that cannot be rendered using the "
+        "current character set"),
+      set_decode_fallback },
+    { { "dot", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("input message is terminated with a dot alone on a line") },
-    { { "editheaders", }, mailvar_type_boolean, 0,
+    { { "editheaders", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("allow to edit message headers while composing") },
-    { { "emptystart", }, mailvar_type_boolean, 0,
+    { { "emptystart", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("start interactive mode if the mailbox is empty") },
-    { { "escape", }, mailvar_type_string, 0,
+    { { "escape", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("character denoting escapes") },
-    { { "flipr", }, mailvar_type_boolean, 0,
+    { { "flipr", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("swap the meaning of reply and Reply commands") },
-    { { "folder", }, mailvar_type_string, 0,
+    { { "folder", },
+      MAILVAR_TYPEMASK (mailvar_type_string), 
       N_("folder directory name") },
-    { { "fromfield", }, mailvar_type_boolean, 0,
+    { { "fromfield", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("get sender address from the `From:' header, instead of "
         "the envelope") },
-    { { "gnu-last-command", }, mailvar_type_boolean, MAILVAR_RDONLY,
+    { { "gnu-last-command", },
+      MAILVAR_TYPEMASK (mailvar_type_string) | MAILVAR_RDONLY,
       N_("last executed command line") },
-    { { "header", }, mailvar_type_boolean, 0,
+    { { "header", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("run the `headers' command after entering interactive mode") },
-    { { "hold", }, mailvar_type_boolean, 0,
+    { { "hold", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("hold the read or saved messages in the system mailbox") },
-    { { "ignore", }, mailvar_type_boolean, 0,
+    { { "ignore", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("ignore keyboard interrupts when composing messages") },
-    { { "ignoreeof", }, mailvar_type_boolean, 0,
+    { { "ignoreeof", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("typing the EOF character terminates the letter being composed") },
-    { { "indentprefix", }, mailvar_type_string, 0,
+    { { "indentprefix", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("string used by the ~m escape for indenting quoted messages") },
-    { { "inplacealiases", }, mailvar_type_boolean, 0,
+    { { "inplacealiases", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("expand aliases in the address header field "
         "before entering send mode") },
     /* For compatibility with other mailx implementations.
        Never used, always true. */
-    { { "keep", }, mailvar_type_boolean, MAILVAR_RDONLY,
+    { { "keep", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean) | MAILVAR_RDONLY,
       N_("truncate the user's system mailbox when it is empty") },
-    { { "keepsave", }, mailvar_type_boolean, 0,
+    { { "keepsave", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("keep saved messages in system mailbox too") },
-    { { "mailx", }, mailvar_type_boolean, 0,
+    { { "mailx", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("enable mailx compatibility mode") },
-    { { "metamail", }, mailvar_type_boolean, 0,
+    { { "metamail", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("interpret the content of message parts; if set to a string "
         "specifies the name of the externam metamail command") },
-    { { "metoo", }, mailvar_type_boolean, 0,
+    { { "metoo", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("do not remove sender addresses from the recipient list") },
-    { { "mimenoask", }, mailvar_type_string, 0,
+    { { "mimenoask", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("a comma-separated list of MIME types for which "
         "no confirmation is needed before running metamail interpreter") },
-    { { "mode", }, mailvar_type_string, MAILVAR_RDONLY,
+    { { "mode", },
+      MAILVAR_TYPEMASK (mailvar_type_string) | MAILVAR_RDONLY,
       N_("the name of current operation mode") },
-    { { "nullbody", }, mailvar_type_boolean, 0,
+    { { "nullbody", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("accept messages with an empty body") },
-    { { "nullbodymsg", }, mailvar_type_string, 0,
+    { { "nullbodymsg", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("display this text when sending a message with empty body") },
-    { { "outfolder", }, mailvar_type_string, 0,
+    { { "outfolder", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("keep created files in this folder") },
-    { { "page", }, mailvar_type_boolean, 0,
+    { { "page", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("pipe command terminates each message with a linefeed") },
-    { { "prompt", }, mailvar_type_string, 0,
+    { { "prompt", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("command prompt sequence") },
-    { { "quit", }, mailvar_type_boolean, 0,
+    { { "quit", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("keyboard interrupts terminate the program") },
-    { { "rc", }, mailvar_type_boolean, 0,
+    { { "rc", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("read the system-wide configuration file upon startup") },
-    { { "readonly", }, mailvar_type_boolean, 0,
+    { { "readonly", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("mailboxes are opened in readonly mode") },
-    { { "record", }, mailvar_type_string, 0,
+    { { "record", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("save outgoing messages in this file") },
-    { { "recursivealiases", }, mailvar_type_boolean, 0,
+    { { "recursivealiases", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("recursively expand aliases") },
-    { { "regex", }, mailvar_type_boolean, 0,
+    { { "regex", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("use regular expressions in message specifications") },
-    { { "replyprefix", }, mailvar_type_string, 0,
+    { { "replyprefix", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("prefix for the subject line of a reply message") },
-    { { "replyregex", }, mailvar_type_string, 0,
-      N_("regexp for recognizing subject lines of reply messages") },
-    { { "save", }, mailvar_type_boolean, 0,
+    { { "replyregex", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
+      N_("regexp for recognizing subject lines of reply messages"),
+      set_replyregex },
+    { { "save", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("stored aborted messages in the user's dead.file") },
-    { { "screen", }, mailvar_type_number, 0,
-      N_("number of lines on terminal screen") },
-    { { "sendmail", }, mailvar_type_string, 0,
+    { { "screen", },
+      MAILVAR_TYPEMASK (mailvar_type_number),
+      N_("number of lines on terminal screen"),
+      set_screen },
+    { { "sendmail", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("URL of the mail transport agent") },
     /* FIXME: Not yet used. */
-    { { "sendwait", }, mailvar_type_boolean, MAILVAR_HIDDEN, NULL },
-    { { "sign", }, mailvar_type_string, 0,
+    { { "sendwait", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean) | MAILVAR_HIDDEN, NULL },
+    { { "sign", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("signature for use with the ~a command") },
-    { { "Sign", }, mailvar_type_string, 0,
+    { { "Sign", },
+      MAILVAR_TYPEMASK (mailvar_type_string),
       N_("signature for use with the ~A command") },
-    { { "showenvelope", }, mailvar_type_boolean, 0,
+    { { "showenvelope", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("`print' command includes the SMTP envelope in its output") },
-    { { "showto", }, mailvar_type_boolean, 0,
+    { { "showto", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("if the message was sent by the user, print its recipient address "
         "in the header summary") },
-    { { "toplines", }, mailvar_type_number, 0,
+    { { "toplines", },
+      MAILVAR_TYPEMASK (mailvar_type_number),
       N_("number of lines to be displayed by `top' or `Top'") },
-    { { "verbose", }, mailvar_type_boolean, 0,
-      N_("verbosely trace the process of message delivery") },
-    { { "xmailer", }, mailvar_type_boolean, 0,
-      N_("add the `X-Mailer' header to the outgoing messages") },
-
-    { { "variable-pretty-print", }, mailvar_type_boolean, 0,
+    { { "variable-pretty-print", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("print variables with short descriptions") },
-    { { "varpp", }, mailvar_type_whatever, MAILVAR_ALIAS },
-    { { "variable-strict", }, mailvar_type_boolean, 0,
+    { { "varpp", }, MAILVAR_ALIAS },
+    { { "variable-strict", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
       N_("perform strict checking when setting options") },
-    { { "varstrict", }, mailvar_type_whatever, MAILVAR_ALIAS },
+    { { "varstrict", }, MAILVAR_ALIAS },
+    { { "verbose", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
+      N_("verbosely trace the process of message delivery") },
+    { { "xmailer", },
+      MAILVAR_TYPEMASK (mailvar_type_boolean),
+      N_("add the `X-Mailer' header to the outgoing messages") },
 
     /* These will be implemented later */
-    { { "debug", }, mailvar_type_whatever, MAILVAR_HIDDEN, NULL },
-    { { "onehop", }, mailvar_type_whatever, MAILVAR_HIDDEN, NULL },
+    { { "onehop", }, MAILVAR_HIDDEN, NULL },
 
-    { { "quiet", }, mailvar_type_boolean, MAILVAR_HIDDEN,
+    { { "quiet", }, MAILVAR_TYPEMASK (mailvar_type_boolean) | MAILVAR_HIDDEN,
       "suppresses the printing of the version when first invoked" },
     
     { { NULL }, }
@@ -381,12 +466,12 @@ mailvar_set (const char *variable, void *value, enum 
mailvar_type type,
             int flags)
 {
   struct mailvar_variable *var;
+  const struct mailvar_symbol *sym = find_mailvar_symbol (variable);
+  int unset = flags & MOPTF_UNSET;
   
   if (!(flags & MOPTF_QUIET)
       && mailvar_get (NULL, "variable-strict", mailvar_type_boolean, 0) == 0)
     {
-      const struct mailvar_symbol *sym = find_mailvar_symbol (variable);
-
       if (!sym)
        mu_diag_output (MU_DIAG_WARNING, _("setting unknown variable %s"),
                        variable);
@@ -396,64 +481,149 @@ mailvar_set (const char *variable, void *value, enum 
mailvar_type type,
                    variable);
          return 1;
        }
+      else if (!(sym->flags & MAILVAR_TYPEMASK (type))
+              && !unset)
+       {
+         mu_error (_("Wrong type for %s"), variable);
+         return 1;
+       }
     }
 
-  var = mailvar_find_variable (variable, 1);
+  var = mailvar_find_variable (variable, !unset);
 
   if (!var || (var->set && !(flags & MOPTF_OVERWRITE)))
     return 0;
 
   mailvar_variable_reset (var);
-  
-  var->type = type;
-  if (value)
+  if (!unset)
     {
-      var->set = 1;
-      switch (type)
+      var->type = type;
+      if (value)
        {
-       case mailvar_type_number:
-         var->value.number = *(int*)value;
-         break;
+         var->set = 1;
+         switch (type)
+           {
+           case mailvar_type_number:
+             var->value.number = *(int*)value;
+             break;
          
-       case mailvar_type_string:
-         var->value.string = strdup (value);
-         break;
+           case mailvar_type_string:
+             var->value.string = strdup (value);
+             break;
          
-       case mailvar_type_boolean:
-         var->value.bool = *(int*)value;
-         break;
+           case mailvar_type_boolean:
+             var->value.bool = *(int*)value;
+             break;
                  
-       default:
-         abort();
+           default:
+             abort();
+           }
        }
     }
     
   /* Special handling for some variables */
-  if (strcmp (variable, "replyregex") == 0)
-    { 
-      int rc;
-      char *err;
-             
-      if ((rc = mu_unre_set_regex (value, 0, &err)))
+  if (sym && sym->flags & MAILVAR_TYPEMASK (type) && sym->handler)
+    sym->handler (var);
+  
+  return 0;
+}
+
+
+static void
+set_decode_fallback (struct mailvar_variable *var)
+{
+  if (mu_set_default_fallback (var->value.string))
+    mu_error (_("Incorrect value for decode-fallback"));
+}
+
+static void
+set_replyregex (struct mailvar_variable *var)
+{
+  int rc;
+  char *err;
+  
+  if ((rc = mu_unre_set_regex (var->value.string, 0, &err)))
+    {
+      if (err)
+       mu_error ("%s: %s", mu_strerror (rc), err);
+      else
+       mu_error ("%s", mu_strerror (rc));
+    }
+}
+
+static void
+set_screen (struct mailvar_variable *var)
+{
+  page_invalidate (1);
+}
+
+static void
+set_mailbox_debug_level (mu_log_level_t level)
+{
+  if (mbox)
+    {
+      mu_debug_t mdbg;
+      mu_mailbox_get_debug (mbox, &mdbg);
+      mu_debug_set_level (mdbg, level);
+    }
+}  
+
+#define DEFAULT_DEBUG_LEVEL  \
+  (MU_DEBUG_INHERIT | MU_DEBUG_LEVEL_UPTO (MU_DEBUG_TRACE7))
+
+static void
+set_debug (struct mailvar_variable *var)
+{
+  int rc;
+  int argc;
+  char **argv;
+  int i;
+  mu_debug_t dbg;
+
+  mu_global_debug_clear_level (NULL);
+  set_mailbox_debug_level (0);
+
+  if (var->type == mailvar_type_boolean)
+    {
+      if (var->set)
        {
-         fprintf (stderr, "%s", mu_strerror (rc));
-         if (err)
-           {
-             fprintf (stderr, "%s", err);
-             free (err);
-           }
-         fprintf (stderr, "\n");
+         /* FIXME: What to set here? 
+            mu_global_debug_set_level ("*", DEFAULT_DEBUG_LEVEL); */
+         set_mailbox_debug_level (DEFAULT_DEBUG_LEVEL);
        }
+      return;
     }
-  else if (strcmp (variable, "decode-fallback") == 0)
+  
+  mu_diag_get_debug (&dbg);
+  
+  rc = mu_argcv_get (var->value.string, ";", NULL, &argc, &argv);
+  if (rc)
     {
-      if (mu_set_default_fallback (value))
-       mu_error (_("Incorrect value for decode-fallback"));
+      mu_error (_("Cannot parse string: %s"), mu_strerror (rc));
+      return;
+    }
+
+  for (i = 0; i < argc; i++)
+    {
+      char *p;
+      mu_log_level_t level = MU_DEBUG_INHERIT;
+      char *object_name = argv[i];
+      
+      for (p = object_name; *p && *p != '='; p++)
+       ;
+
+      if (*p == '=')
+       {
+         *p++ = 0;
+         mu_debug_level_from_string (p, &level, dbg);
+       }
+      else
+       level |= MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT);
+      
+      if (strcmp (object_name, "mailbox") == 0)
+       set_mailbox_debug_level (level);
+      mu_global_debug_set_level (object_name, level);
     }
-  else if (strcmp (variable, "screen") == 0)
-    page_invalidate (1);
-  
-  return 0;
 }
 
 
@@ -654,6 +824,7 @@ static void
 describe_symbol (FILE *out, int width, const struct mailvar_symbol *sym)
 {
   int n;
+  int i, t;
   const struct mailvar_symbol *ali;
 
   n = fprintf (out, "%s", sym->var.name);
@@ -667,7 +838,18 @@ describe_symbol (FILE *out, int width, const struct 
mailvar_symbol *sym)
     }
   fputc ('\n', out);
   
-  fprintf (out, _("Type: %s\n"), gettext (typestr[sym->type]));
+  fprintf (out, _("Type: "));
+  for (i = 0, t = 0; i < sizeof (typestr) / sizeof (typestr[0]); i++)
+    if (sym->flags & MAILVAR_TYPEMASK (i))
+      {
+       if (t++)
+         fprintf (out, " %s ", _("or"));
+       fprintf (out, "%s", gettext (typestr[i]));
+      }
+  if (!t)
+    fprintf (out, "%s", gettext (typestr[0]));
+  fputc ('\n', out);
+  
   fprintf (out, "%s", _("Current value: "));
   mailvar_variable_format (out, &sym->var, _("[not set]"));
 
diff --git a/mail/mbox.c b/mail/mbox.c
index eac2ae4..e1d66b7 100644
--- a/mail/mbox.c
+++ b/mail/mbox.c
@@ -28,8 +28,8 @@ mbox0 (msgset_t *mspec, mu_message_t msg, void *data)
   mu_attribute_t attr;
 
   mu_message_get_attribute (msg, &attr);
+  mu_attribute_unset_userflag (attr, MAIL_ATTRIBUTE_PRESERVED);
   mu_attribute_set_userflag (attr, MAIL_ATTRIBUTE_MBOXED);
-  util_mark_read (msg);
   
   set_cursor (mspec->msg_part[0]);
   
diff --git a/mail/quit.c b/mail/quit.c
index 524ecc7..3d98890 100644
--- a/mail/quit.c
+++ b/mail/quit.c
@@ -87,6 +87,7 @@ mail_mbox_commit ()
        /* The mailbox we are closing is not a system one (%). Raise
           hold flag */
        hold = 1;
+       keepsave = 1;
       }
     mu_mailbox_destroy (&mb);
   }
@@ -102,7 +103,12 @@ mail_mbox_commit ()
          && (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_MBOXED)
              || (!hold
                  && !mu_attribute_is_deleted (attr)
-                 && mu_attribute_is_read (attr))))
+                 && !mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_PRESERVED)
+                 && ((mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED)
+                      && keepsave)
+                     || (!mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED)
+                         && (mu_attribute_is_userflag (attr, 
MAIL_ATTRIBUTE_SHOWN)
+                             || mu_attribute_is_userflag (attr, 
MAIL_ATTRIBUTE_TOUCHED)))))))
        {
          int status;
          
@@ -136,7 +142,9 @@ mail_mbox_commit ()
        }
       else if (mu_attribute_is_deleted (attr))
        /* Skip this one */;
-      else if (!keepsave && mu_attribute_is_userflag (attr, 
MAIL_ATTRIBUTE_SAVED))
+      else if (!keepsave
+              && !mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_PRESERVED)
+              && mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED))
        mu_attribute_set_deleted (attr);
       else if (mu_attribute_is_read (attr))
        mu_attribute_set_seen (attr);
diff --git a/mail/reply.c b/mail/reply.c
index 2fc9e97..880844d 100644
--- a/mail/reply.c
+++ b/mail/reply.c
@@ -123,7 +123,9 @@ reply0 (msgset_t *mspec, mu_message_t msg, void *data)
   
   make_in_reply_to (&env, msg);
   make_references (&env, msg);
-  status = mail_send0 (&env, 0);
+  status = mail_send0 (&env,
+                      mailvar_get (NULL, "byname", mailvar_type_boolean, 0)
+                                    == 0);
   compose_destroy (&env);
 
   return status;
diff --git a/mail/set.c b/mail/set.c
index 8f51f46..6dfed55 100644
--- a/mail/set.c
+++ b/mail/set.c
@@ -48,7 +48,8 @@ mail_set (int argc, char **argv)
          
          if (!strncmp ("no", argv[i], 2) && !value)
            {
-             mailvar_set (&argv[i][2], NULL, mailvar_type_boolean, flags);
+             mailvar_set (&argv[i][2], NULL, mailvar_type_boolean,
+                          flags | MOPTF_UNSET);
            }
          else if (value)
            {
diff --git a/mail/source.c b/mail/source.c
index 9abf2d7..ddbb809 100644
--- a/mail/source.c
+++ b/mail/source.c
@@ -18,21 +18,25 @@
 
 #include "mail.h"
 
-
 static char *
 source_readline (void *closure, int cont MU_ARG_UNUSED)
 {
   FILE *fp = closure;
   size_t s = 0;
   char *buf = NULL;
+  mu_debug_t debug;
+  struct mu_debug_locus locus;
   
   if (getline (&buf, &s, fp) >= 0)
     {
-      int len = strlen (buf);
-      if (buf[len-1] == '\n')
-       buf[len-1] = '\0';
+      mu_rtrim_class (buf, MU_CTYPE_SPACE);
+
+      mu_diag_get_debug (&debug);
+      mu_debug_get_locus (debug, &locus);
+      mu_debug_set_locus (debug, locus.file, locus.line + 1);
       return buf;
     }
+  
   return NULL;
 }
   
@@ -45,11 +49,12 @@ mail_source (int argc, char **argv)
 {
   FILE *fp;
   int save_term;
+  mu_debug_t debug;
   
   if (argc != 2)
     {
       /* TRANSLATORS: 'source' is a command name. Do not translate it! */
-      util_error (_("source requires an argument"));
+      util_error (_("source requires a single argument"));
       return 1;
     }
   
@@ -63,8 +68,11 @@ mail_source (int argc, char **argv)
 
   save_term = interactive;
   interactive = 0;
-  mail_mainloop(source_readline, fp, 0);
+  mu_diag_get_debug (&debug);
+  mu_debug_set_locus (debug, argv[1], 0);
+  mail_mainloop (source_readline, fp, 0);
   interactive = save_term;
+  mu_debug_set_locus (debug, NULL, 0);
   fclose (fp);
   return 0;
 }
diff --git a/mail/testsuite/mail/write.exp b/mail/testsuite/mail/write.exp
index 168fa7e..85b1d16 100644
--- a/mail/testsuite/mail/write.exp
+++ b/mail/testsuite/mail/write.exp
@@ -1,6 +1,6 @@
 # -*- tcl -*-
 # This file is part of Mailutils testsuite.
-# Copyright (C) 2002, 2007 Free Software Foundation
+# Copyright (C) 2002, 2007, 2009 Free Software Foundation
 #  
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -74,7 +74,7 @@ mail_test "headers" \
        " *   2 Bar                Fri Dec 28 23:28  16/579   Re: Jabberwocky"
 
 mail_test -noprompt "quit" \
-         "Held 0 messages in $MU_SPOOL_DIR/mbox"
+         "Held 2 messages in $MU_SPOOL_DIR/mbox"
 
 # Examine its contents
 mail_start -reuse-spool "--file=$MU_FOLDER_DIR/three"
@@ -88,7 +88,7 @@ mail_test "Save" \
        "\"$MU_FOLDER_DIR/gray\"  12/425"
 
 mail_test "file \"$MU_FOLDER_DIR/gray\"" \
-       "Held 1 message in $MU_FOLDER_DIR/three"
+       "Held 2 messages in $MU_FOLDER_DIR/three"
 
 mail_test "headers" \
        ">N   1 Sergey Poznyakoff  Tue Jul 16 12:11  12/425   MBOX"
diff --git a/mail/touch.c b/mail/touch.c
index 78d763b..2911098 100644
--- a/mail/touch.c
+++ b/mail/touch.c
@@ -30,11 +30,7 @@ touch0 (msgset_t *mspec, mu_message_t msg, void *data)
   mu_attribute_t attr = NULL;
   
   mu_message_get_attribute (msg, &attr);
-  if (!mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED))
-    {
-      mu_attribute_set_userflag (attr, MAIL_ATTRIBUTE_MBOXED);
-      util_mark_read (msg);
-    }
+  mu_attribute_set_userflag (attr, MAIL_ATTRIBUTE_TOUCHED);
   
   set_cursor (mspec->msg_part[0]);
   return 0;
diff --git a/mail/undelete.c b/mail/undelete.c
index 1db365f..e877394 100644
--- a/mail/undelete.c
+++ b/mail/undelete.c
@@ -29,6 +29,8 @@ undelete0 (msgset_t *mspec, mu_message_t msg, void *data)
 
   mu_message_get_attribute (msg, &attr);
   mu_attribute_unset_deleted (attr);
+  mu_attribute_unset_userflag (attr, MAIL_ATTRIBUTE_PRESERVED);
+  mu_attribute_unset_userflag (attr, MAIL_ATTRIBUTE_MBOXED);
   util_mark_read (msg);
   cond_page_invalidate (mspec->msg_part[0]);
 
diff --git a/mail/util.c b/mail/util.c
index 6bd4a97..5faea74 100644
--- a/mail/util.c
+++ b/mail/util.c
@@ -713,7 +713,7 @@ util_outfolder_name (char *str)
   return strdup (str);
 }
 
-/* Save an outgoing message. "savefile" allows to override the setting
+/* Save an outgoing message. The SAVEFILE argument overrides the setting
    of the "record" variable. */
 void
 util_save_outgoing (mu_message_t msg, char *savefile)


hooks/post-receive
-- 
GNU Mailutils




reply via email to

[Prev in Thread] Current Thread [Next in Thread]