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=af20212718728b315449ff35685772302883fc3d The branch, master has been updated via af20212718728b315449ff35685772302883fc3d (commit) from edb05144ade1984e28d88cfaea7c2fb0ec675f5b (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 af20212718728b315449ff35685772302883fc3d Author: Sergey Poznyakoff <g...@gnu.org.ua> Date: Fri Nov 4 18:00:14 2016 +0200 Fix operation of mail -t; some other minor fixes * mail/escape.c (parse_headers): Moved to send.c (check_headers): New function. (escape_continue): Use check_headers. * mail/mail.c (read_recipients): New variable. The -t option sets read_recipients and editheaders * mail/mail.h (parse_headers): New proto. * mail/send.c: Special handling for -t option. (parse_headers): New function. * movemail/movemail.c (onerror statement): Accept a list as argument. * doc/texinfo/mailutils.texi: Update. * doc/texinfo/programs.texi: Update. ----------------------------------------------------------------------- Summary of changes: doc/texinfo/mailutils.texi | 1 - doc/texinfo/programs.texi | 377 +++++++++++++++++++++++++++++--------------- mail/escape.c | 121 ++------------ mail/mail.c | 13 +- mail/mail.h | 9 ++ mail/send.c | 166 +++++++++++++++++-- mail/table.c | 4 +- movemail/movemail.c | 90 ++++++----- 8 files changed, 490 insertions(+), 291 deletions(-) diff --git a/doc/texinfo/mailutils.texi b/doc/texinfo/mailutils.texi index c9fac62..636b973 100644 --- a/doc/texinfo/mailutils.texi +++ b/doc/texinfo/mailutils.texi @@ -236,7 +236,6 @@ Reading Mail @command{movemail} --- Moves Mail from the User Maildrop to the Local File * Movemail Configuration:: -* Movemail Options:: Description of the Available Options * Ownership:: Setting Destination Mailbox Ownership * Summary:: Short Movemail Invocation Summary diff --git a/doc/texinfo/programs.texi b/doc/texinfo/programs.texi index c3612b4..d116fcc 100644 --- a/doc/texinfo/programs.texi +++ b/doc/texinfo/programs.texi @@ -2742,7 +2742,7 @@ is being sent, etc. @item trace6 When used together with @samp{prot}, displays security-sensitive information (such as passwords, user keys, etc). in plaintext. By -default, such information is replaced with asteriscs to reduce the +default, such information is replaced with asterisks to reduce the possibility of security compromise. @item trace7 When used together with @samp{prot}, displays the @dfn{payload} @@ -2795,10 +2795,10 @@ configuration file statements: @multitable @columnfractions 0.3 0.6 @headitem Statement @tab Reference -@item debug @tab @xref{Debug Statement}. -@item tls @tab @xref{TLS Statement}. -@item mailbox @tab @xref{Mailbox Statement}. -@item locking @tab @xref{Locking Statement}. +@item debug @tab @xref{debug statement}. +@item tls @tab @xref{tls statement}. +@item mailbox @tab @xref{mailbox statement}. +@item locking @tab @xref{locking statement}. @end multitable @subheading @command{frm} @@ -2907,10 +2907,9 @@ 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 -use the Mailutils configuration file. Instead, it uses the traditional -@samp{mailrc}-style configuration. @xref{Mail Configuration Files}, -for a detailed description of its format. +In addition to the Mailutils configuration file, @command{mail} loads +the traditional @samp{mailrc}-style configuration files. @xref{Mail +Configuration Files}, for a detailed description of their format. @menu * Invoking Mail:: Command Line Options. @@ -2934,49 +2933,72 @@ General usage of @command{mail} program is: If [@var{address}...] part is present, @command{mail} switches to mail sending mode, otherwise it operates in mail reading mode. -The program uses following option groups: @FIXME-xref{mailbox}. - -@command{Mail} understands following command line options: +@command{Mail} understands the following command line options: @table @option -@item -e -@itemx --exist -Return true if the mailbox contains some messages. Return false -otherwise. -This is useful for writing shell scripts. +@item -A @var{file} +@itemx --attach=@var{file} +Attach @var{file} to the composed message. The encoding and content +type are controlled by the @option{--encoding} and +@option{--content-type} options, correspondingly. + +@item -a @var{header}:@var{value} +@itemx --append=@var{header}:@var{value} +Append the given header to the composed message. + +@item --content-type=@var{type} +This options sets the content type to be used by all subsequent +@option{--attach} options. + @item -E @var{command} @itemx --exec=@var{command} 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. -@item -f -@itemx --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 -e +@itemx --exist +Return true if the mailbox contains some messages. Return false +otherwise. + +This is useful for writing shell scripts. + +@item --encoding=@var{enc} +Sets content transfer encoding for use by the subsequent +@option{--attach} options. + @item -F @itemx --byname 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 @samp{To:} line in the mail header. This option sets the @samp{byname} variable, which see (@pxref{byname}). + +@item -f +@itemx --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 -H @itemx --headers Print header summary to stdout and exit. + @item -i @itemx --ignore -Ignore interrupts. -@item -m @var{path} -@itemx --mail-spool=@var{path} -Set path to the mailspool directory -@item -n -@itemx --norc -Do not read the system-wide mailrc file. @xref{Mail Configuration Files}. +Ignore interrupts when composing the message. + @item -N @itemx --nosum Do not display initial header summary. + +@item -n +@itemx --norc +Do not read the system-wide mailrc file. @xref{Mail Configuration +Files}. + @item -p @itemx --print @itemx --read @@ -2990,18 +3012,26 @@ quit @end example @noindent except that @command{mail --print} does not change status of the messages. -@item -r @var{address} -@itemx --return-address=@var{address} -Sets the return email address for outgoing mail. @xref{return-address}. + @item -q @itemx --quit Cause interrupts to terminate program. + +@item -r @var{address} +@itemx --return-address=@var{address} +Sets the return email address for outgoing mail. +@xref{return-address}. + @item -s @var{subj} @itemx --subject=@var{subj} -Send a message with a Subject of @var{subj}. Valid only in sending mode. +Send a message with a Subject of @var{subj}. Valid only in sending +mode. + @item -t @itemx --to -Switch to sending mode. +Read recipients from the message header. Ignore addresses listed in +the command line. + @item -u @var{user} @itemx --user=@var{user} Operate on @var{user}'s mailbox. This is equivalent to: @@ -3013,16 +3043,11 @@ mail -f/@var{spool_path}/@var{user} @noindent with @var{spool_path} being the full path to your mailspool directory @*(@file{/var/spool/mail} or @file{/var/mail} on most systems). -@item -? -@itemx --help -Display a help message. -@item --usage -Display a short usage summary. -@item -V -@itemx --version -Print program version and exit. @end table +The program also understands the common mailutils options +(@pxref{Common Options}. + @node Specifying Messages @subsection How to Specify Message Sets @@ -3136,6 +3161,7 @@ The actual escape character may be changed by setting the value of * Modifying the Headers:: * Enclosing Another Message:: * Adding a File to the Message:: +* Attaching a File to the Message:: * Printing And Saving the Message:: * Signing the Message:: * Printing Another Message:: @@ -3194,6 +3220,7 @@ the headers as well. @node Modifying the Headers @subsubsection Modifying the Headers: ~h, ~t, ~c, ~b, ~s +@cindex ~t, mail escape To add new addresses to the list of message recipients, use @samp{~t} command, e.g.: @@ -3201,15 +3228,19 @@ command, e.g.: ~t name1@@domain.net name2 @end example +@cindex ~c, mail escape +@cindex ~b, mail escape To add addresses to @code{Cc} or @code{Bcc}, use @samp{~c} or @samp{~b} escapes respectively. +@cindex ~s, mail escape To change the @code{Subject} header, use @samp{~s} escape, e.g.: @example ~s "Re: your message" @end example +@cindex ~h, mail escape Finally, to edit all headers, type @samp{~h} escape. This will present you with the values of @code{To}, @code{Cc}, @code{Bcc}, and @code{Subject} headers allowing to edit them with normal text editing @@ -3235,6 +3266,8 @@ prepended to each line enclosed. @node Adding a File to the Message @subsubsection Adding a File to the Message: ~r and ~d +@cindex ~r, mail escape +@cindex ~<, mail escape To append the contents of file @var{filename} to the message, type @example @@ -3248,12 +3281,56 @@ or @end example @noindent +@cindex ~d, mail escape The @samp{~d} escape is a shorthand for @example ~r dead.letter @end example +@node Attaching a File to the Message +@subsubsection Attaching a File to the Message +@cindex ~+, mail escape +The @samp{~+} escape attaches a file to the message. It takes one to +three arguments. The first argument supplies the name of the file to +attach: + +@example +~+ myfile.txt +@end example + +The file will be attached with default content-type +@samp{application/octet-stream}, and encoding @samp{base64} +(these can be altered by the @option{--content-type} and +@option{--encoding} command line options, correspondingly). + +Optional second argument defines the content type to be used instead +of the default one. Optional third argument defines the encoding, +e.g.: + +@example +~+ myfile.html text/html base64 +@end example + +@cindex ~l, mail escape +To list the files attached so far, use the @samp{~l} escape: + +@example +~l + 1 myfile.html text/html base64 +@end example + +Each line of the listing contains the ordinal number of the attachment, +the name of the file, content-type and transfer encoding used. + +@cindex ~^, mail escape +The @samp{~^} escape removes attachments. Its argument is the number +of the attachment to remove, e.g.: + +@example +~^ 1 +@end example + @node Printing And Saving the Message @subsubsection Printing And Saving the Message @kyindex ~p, mail escape @@ -4692,7 +4769,7 @@ The program is started with the @option{--print} (@option{-p}) command line option (@pxref{Invoking Mail}). @item read -The progran operates in read mode. This is the default. +The program operates in read mode. This is the default. @item send The program operates in send mode. This means it was given one or more @@ -4992,7 +5069,7 @@ variables. Also, if the user is trying to set an unknown variable, @*Type: Boolean. @*Default: False. -If this variable is set, the listing ouput by @command{set} contains short +If this variable is set, the listing output by @command{set} contains short descriptions before each variable. @xref{Setting and Unsetting the Variables}. @kwindex verbose @@ -5021,8 +5098,9 @@ X-Mailer: mail (GNU Mailutils @value{VERSION}) @node Mail Configuration Files @subsection Personal and System-wide Configuration Files -Upon startup, @command{mail} reads the contents of the two command files: -the system-wide configuration file, and the user's configuration +After processing the usual Mailutils configuration files +(@pxref{configuration}), @command{mail} reads the contents of the two +command files: the system-wide command file, and the user's command file. Each line read from these files is processed like a usual @command{mail} command. @@ -5040,7 +5118,6 @@ package via @option{--with-mail-rc} option. It defaults to @node messages @section @command{messages} --- Count the Number of Messages in a Mailbox @pindex messages -@UNREVISED @command{Messages} prints on standard output the number of messages contained in each folder specified in command line. If no folders @@ -5055,18 +5132,19 @@ Number of messages in @var{folder}: @var{number} where @var{folder} represents the folder name, @var{number} represents the number of messages. -Following configuration file statements affect the behaviour of +The following configuration file statements affect the behaviour of @command{messages}: @multitable @columnfractions 0.3 0.6 @headitem Statement @tab Reference -@item debug @tab @xref{Debug Statement}. -@item tls @tab @xref{TLS Statement}. -@item mailbox @tab @xref{Mailbox Statement}. -@item locking @tab @xref{Locking Statement}. +@item debug @tab @xref{debug statement}. +@item tls @tab @xref{tls statement}. +@item mailbox @tab @xref{mailbox statement}. +@item locking @tab @xref{locking statement}. @end multitable -The program accepts following command line options: +In addition to the common mailutils options (@pxref{Common Options}), +the program accepts the following command line options: @table @option @item -q @@ -5074,22 +5152,12 @@ The program accepts following command line options: @itemx -s @itemx --silent Be quiet. Display only number of messages per mailbox, without leading text. -@item -? -@itemx --help -Output help message and exit. -@item --usage -Output short usage summary and exit. -@item -V -@itemx --version -Output program version and exit. @end table @page @node movemail @section @command{movemail} --- Moves Mail from the User Maildrop to the Local File @pindex movemail -@UNREVISED - The purpose of @command{movemail}, as its name implies, is to move mail from one location to another. For example, the following invocation: @@ -5100,11 +5168,10 @@ movemail /var/mail/smith INBOX @noindent moves messages from file @file{/var/mail/smith} to file @file{INBOX}. -You will probably never have to run this program manually. It is -intended as a replacement for @command{movemail} from GNU Emacs. The -@command{movemail} program is run by Emacs @code{Rmail} -module. @xref{Rmail,,,emacs,Reading Mail with Rmail}, for detailed -description of @code{Rmail} interface. +The program was initially intended as a replacement for +@command{movemail} from GNU Emacs. The @command{movemail} program is +run by Emacs @code{Rmail} module. @xref{Rmail,,,emacs,Reading Mail +with Rmail}, for detailed description of @code{Rmail} interface. Mailutils version of @command{movemail} is fully backward-compatible with its Emacs predecessor, so it should run @@ -5113,18 +5180,21 @@ starting from 22.1 contain improved @code{Rmail} interface and are able to take advantage of all new features mailutils @command{movemail} provides. +Apart from that use, @command{movemail} proved to be a useful tool for +incorporating mail from remote mailboxes into the local one. See +@uref{http://mailutils.org/wiki/Fetching_Mail_with_Movemail, Fetching +Mail with Movemail}, for a detailed discussion with usage recipes. + @menu * Movemail Configuration:: -* Movemail Options:: Description of the Available Options * Ownership:: Setting Destination Mailbox Ownership * Summary:: Short Movemail Invocation Summary @end menu @node Movemail Configuration @subsection Movemail Configuration -@UNREVISED - -Following configuration file statements affect the behavior of +@cindex movemail, configuration +The following configuration file statements affect the behavior of @command{movemail}: @deffn {Movemail Config} preserve @var{bool} @@ -5139,7 +5209,7 @@ If @var{bool} is @samp{true}, reverse message sorting order. If @var{bool} is @samp{true}, output information used by Emacs rmail interface. @end deffn -@deffn {Movemail Config} ignore-erros @var{bool} +@deffn {Movemail Config} ignore-errors @var{bool} Continue moving messages after errors. By default, @command{mailfromd} exits immediately if it cannot copy a message. @end deffn @@ -5149,6 +5219,7 @@ Set program identifier, i.e. a string which will prefix all diagnostic messages issued by the program. By default, program name is used. +@anchor{movemail-program-id} The @var{fmt} is a format string that may contain references to the following variables (@pxref{Variables}): @@ -5224,101 +5295,145 @@ Make destination mailbox owned by @var{user}. @end table @end deffn -@multitable @columnfractions 0.3 0.6 -@headitem Statement @tab Reference -@item debug @tab @xref{Debug Statement}. -@item tls @tab @xref{TLS Statement}. -@item mailbox @tab @xref{Mailbox Statement}. -@item locking @tab @xref{Locking Statement}. -@item pam @tab @xref{PAM Statement}. -@item sql @tab @xref{SQL Statement}. -@item virtdomain @tab @xref{Virtdomain Statement}. -@item radius @tab @xref{Radius Statement}. -@item ldap @tab @xref{LDAP Statement}. -@item auth @tab @xref{Auth Statement}. -@end multitable +@deffn {Movemail Config} max-messages @var{count} +Defines upper limit on the number of moved messages. Movemail will +stop after transferring @var{count} messages. -@node Movemail Options -@subsection Movemail Options -@UNREVISED +By default, the number of messages is not limited. +@end deffn -This subsection discusses @command{movemail} options from the point of -view of an Emacs @code{Rmail} user. +@anchor{movemail-onerror} +@deffn {Movemail Config} onerror @var{actions} +Defines what to do if an error occurs when transferring a message. +@var{actions} is a list of one or more of the following keywords: -To set various options to @command{movemail} from @code{Rmail}, use -@code{rmail-movemail-flags} variable, or @samp{Rmail Movemail Flags} -section from the menu. +@table @asis +@item abort +Abort the transfer and terminate the program. This is the default +action. -Some POP servers return messages in reversed order. To fix the -order, use @option{-p} option or its synonym @option{--reverse}. +@item skip +Skip to the next message. -If the remote server supports @acronym{TLS} encryption, use -@option{--tls} to instruct @command{movemail} to initiate encrypted -connection. +@item delete +Delete the affected message. + +@item count +Count this message as processed. +@end table + +Each keyword can be prefixed with @samp{no} to reverse its meaning. +@end deffn + +The following standard Mailutils statements are supported: + +@multitable @columnfractions 0.3 0.6 +@headitem Statement @tab Reference +@item debug @tab @xref{debug statement}. +@item tls @tab @xref{tls statement}. +@item mailbox @tab @xref{mailbox statement}. +@item locking @tab @xref{locking statement}. +@item pam @tab @xref{pam statement}. +@item sql @tab @xref{sql statement}. +@item virtdomain @tab @xref{virtdomain statement}. +@item radius @tab @xref{radius statement}. +@item ldap @tab @xref{ldap statement}. +@item auth @tab @xref{auth statement}. +@end multitable @node Ownership @subsection Setting Destination Mailbox Ownership @UNREVISED - @node Summary @subsection Movemail Usage Summary @example -movemail [@var{option}...] @var{inbox} @var{destfile} [@var{remote-password}] +movemail [@var{option}...] @var{inbox} @var{destfile} [@var{password}] @end example -The first argument, @var{inbox}, is the @acronym{url} (@FIXME-pxref{URL}) of +The first argument, @var{inbox}, is the @acronym{url} (@pxref{Mailbox}) of the source mailbox. The second argument, @var{destfile}, traditionally means destination file, i.e. the UNIX mailbox to copy messages to. However, mailutils @command{movemail} extends the meaning of this -parameter. You may actually specify any valid @acronym{URL} as +parameter. You may actually specify any valid @acronym{url} as @var{destfile} parameter.@footnote{Rmail does not use this -feature}. Finally, optional third argument is a traditional way of -specifying user passwords for remote (@acronym{POP} or @acronym{IMAP}) -mailboxes. +feature}. + +For compatibility with older implementations of @command{movemail}, +the @var{source} argument can also have the form: + +@example +po:@var{username}[:@var{pop-server}] +@end example + +@noindent +where @var{pop-server} is the IP address or hostname of a POP3 server +to connect to and @var{username} is the name of the user on that +server. The password is then supplied by the third argument. -Following is the summary of available command line options: +It is equivalent to the following URL: + +@example +pop://@var{username}[:@var{password}]@@@var{pop-server} +@end example + +In fact, whenever @var{source} refers to a remote mailbox, the +@var{password} argument can be used to pass the password. However, +the safer @dfn{ticket} method is of course preferred. + +Options are one or more of the following: @table @option @item --emacs -Output information used by Emacs rmail interface +Output information used by Emacs @code{rmail} interface. @item --ignore-errors -Continue moving messages after an error occurs. +Try to continue after errors. + +@item --max-messages=@var{count} +Process at most @var{count} messages. + +@item --notify +Enable biff notification. + +@item --onerror=@var{kw}[,@var{kw}...] +What to do on errors. @xref{movemail-onerror, onerror statement}, for +a description of @var{kw}. + +@item -P @var{modelist} +@itemx --owner=@var{modelist} +Control mailbox ownership. @var{modelist} is a comma-separated list +of one or more ownership change methods. +@xref{mailbox-ownership-methods}, for a description of available +methods. + +This option is useful only when running @command{movemail} as root. @item -p @itemx --preserve @itemx --keep-messages -Preserve the source mailbox +Don't remove transferred messages from the source mailbox. @item --program-id=@var{fmt} -Set program identifier for diagnostic purposes. See @ref{Movemail -Configuration,program-id}, for a detailed discussion of this feature. +Set program identifier for diagnostics (default: the program name). +@xref{movemail-program-id}, for a description of its argument. @item -r @itemx --reverse -Reverse the sorting order - -@item --tls[=@var{bool}] -Enable (default) or disable TLS support +Reverse the order of retrieved messages. @item -u -@item --uidl +@itemx --uidl Use UIDLs to avoid downloading the same message twice. -@item -P @var{method-list} -@itemx --owner=@var{method-list} -Define list of methods for setting ownership of the destination -mailbox. @xref{mailbox-ownership-methods}, for a description of -@var{method-list}. This option is useful only when running -@command{movemail} as root. - @item -v -@item --verbose +@itemx --verbose Increase verbosity level. @end table +The common options are also understood (@pxref{Common Options}). + @page @node readmsg @section @command{readmsg} --- Extract Messages from a Folder @@ -5398,6 +5513,8 @@ A whitespace or coma separated list of header names to show per message. Default is @option{--weedlist="From Subject Date To CC Apparently-"}. @end table +See also @ref{Common Options}. + @node Conf-readmsg @subsection Configuration of @command{readmsg}. @@ -7997,7 +8114,7 @@ run: mailutils filter --list @end example -Filters are applied in the order of their appearence, from left to +Filters are applied in the order of their appearance, from left to right and operate in encode mode. The plus sign has the same meaning as pipe in shell. The default mode can be changed using the @option{--decode} (@option{-d}) and @option{--encode} (@option{-e}) options. @@ -8050,7 +8167,7 @@ configuration file processing. @node mailutils acl @subsection mailutils acl The @command{mailutils acl} command tests Mailutils Access Control Lists. By -default it reads ACL from the Mailutils configiration file section +default it reads ACL from the Mailutils configuration file section @samp{acl}. The command takes a list of IP addresses as its arguments, applies the ACL to each of them in turn and prints the result. @@ -8166,7 +8283,7 @@ smtp://bar@@gnu.org: /home/@var{user}/.mu-tickets:2: smtp://bar:***@@gnu.org @end example As you see, even in that case the tool hides the actual password part -by replacing it with three asteriscs. If you are working in a secure +by replacing it with three asterisks. If you are working in a secure environment, you can tell @command{mu wicket} to show passwords as well, by supplying the @option{-v} option twice. @@ -8395,7 +8512,7 @@ As of version @value{VERSION}, @command{mailutils dbm} supports two formats for dumping DBM databases. Both formats are line-oriented. Comments are introduced with a sharp (@samp{#}) sign in the column 0 of a line, followed by at least one white space character (space or tab). Sharp -sign followed by a colon (@samp{#:}) introduces a @dfn{paragmatic +sign followed by a colon (@samp{#:}) introduces a @dfn{pragmatic comment}, which carries some additional information to the loader. @anchor{dump version 0.0} diff --git a/mail/escape.c b/mail/escape.c index c07d29a..4c337e0 100644 --- a/mail/escape.c +++ b/mail/escape.c @@ -37,119 +37,26 @@ dump_headers (mu_stream_t out, compose_env_t *env) mu_stream_destroy (&stream); } -#define STATE_INIT 0 -#define STATE_READ 1 -#define STATE_BODY 2 - static int -parse_headers (mu_stream_t input, compose_env_t *env) +check_headers (mu_stream_t input, compose_env_t *env) { - int status; - mu_header_t header; - char *name = NULL; - char *value = NULL; - int state = STATE_INIT; - char *buf = NULL; - size_t size = 0, n; - int errcnt = 0, line = 0; + char *p; - if ((status = mu_header_create (&header, NULL, 0)) != 0) - { - mu_error (_("Cannot create header: %s"), mu_strerror (status)); - return 1; - } - mu_stream_seek (input, 0, MU_SEEK_SET, NULL); - while (state != STATE_BODY && - errcnt == 0 && - mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0) + switch (parse_headers (input, env)) { - mu_rtrim_class (buf, MU_CTYPE_SPACE); - - line++; - switch (state) - { - case STATE_INIT: - if (!buf[0] || mu_isspace (buf[0])) - continue; - else - state = STATE_READ; - /*FALLTHRU*/ - - case STATE_READ: - if (buf[0] == 0) - state = STATE_BODY; - else if (mu_isspace (buf[0])) - { - /* A continuation line */ - if (name) - { - char *p = NULL; - mu_asprintf (&p, "%s\n%s", value, buf); - free (value); - value = p; - } - else - { - mu_error (_("%d: not a header line"), line); - errcnt++; - } - } - else - { - char *p; - - if (name) - { - mu_header_set_value (header, name, value[0] ? value : NULL, 0); - free (name); - free (value); - name = value = NULL; - } - p = strchr (buf, ':'); - if (p) - { - *p++ = 0; - while (*p && mu_isspace (*p)) - p++; - value = mu_strdup (p); - name = mu_strdup (buf); - } - else - { - mu_error (_("%d: not a header line"), line); - errcnt++; - } - } - break; - } + case parse_headers_ok: + return 0; + case parse_headers_fatal: + return -1; + case parse_headers_error: + break; } - free (buf); - if (name) - { - mu_header_set_value (header, name, value, 0); - free (name); - free (value); - } - - if (errcnt) - { - char *p; - - mu_header_destroy (&header); - p = ml_readline (_("Edit again?")); - if (mu_true_answer_p (p) == 1) - return -1; - else - return 1; - } - - mu_header_destroy (&env->header); - env->header = header; - return 0; -} - + p = ml_readline (_("Edit again?")); + return mu_true_answer_p (p); +} + static void escape_continue (void) { @@ -386,7 +293,7 @@ escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env) return rc; } } - while ((rc = parse_headers (tempstream, env)) < 0); + while (check_headers (tempstream, env)); } else { diff --git a/mail/mail.c b/mail/mail.c index cd8c466..6a80425 100644 --- a/mail/mail.c +++ b/mail/mail.c @@ -23,6 +23,7 @@ mu_mailbox_t mbox; /* Mailbox being operated upon */ size_t total; /* Total number of messages in the mailbox */ int interactive; /* Is the session interactive */ +int read_recipients; /* Read recipients from the message (mail -t) */ static mu_list_t command_list;/* List of commands to be executed after parsing command line */ @@ -72,6 +73,8 @@ cli_command_option (struct mu_parseopt *po, struct mu_option *opt, break; case 't': + read_recipients = 1; + util_cache_command (&command_list, "set editheaders"); util_cache_command (&command_list, "setq mode=send"); break; @@ -186,7 +189,7 @@ static struct mu_option mail_options[] = { mu_c_string, NULL, cli_subject }, { "to", 't', NULL, MU_OPTION_DEFAULT, - N_("precede message by a list of addresses"), + N_("read recipients from the message header"), mu_c_string, NULL, cli_command_option }, { "user", 'u', N_("USER"), MU_OPTION_DEFAULT, @@ -227,7 +230,7 @@ static struct mu_cli_setup cli = { options, NULL, N_("GNU mail -- process mail messages.\n" -"If -f or --file is given, mail operates on the mailbox named " + "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_("[address...]"), alt_args, @@ -421,6 +424,12 @@ main (int argc, char **argv) /* argument parsing */ mu_cli (argc, argv, &cli, mail_capa, NULL, &argc, &argv); + if (read_recipients) + { + argv += argc; + argc = 0; + } + if ((hint & (HINT_SEND_MODE|HINT_FILE_OPTION)) == (HINT_SEND_MODE|HINT_FILE_OPTION)) { diff --git a/mail/mail.h b/mail/mail.h index b589d3e..0c4465f 100644 --- a/mail/mail.h +++ b/mail/mail.h @@ -288,6 +288,15 @@ extern int escape_attach (int argc, char **argv, compose_env_t *env); extern int escape_remove_attachment (int argc, char **argv, compose_env_t *env); +enum + { + parse_headers_ok, + parse_headers_error, + parse_headers_fatal + }; + +extern int parse_headers (mu_stream_t input, compose_env_t *env); + /* Cursor */ extern void set_cursor (unsigned value); extern size_t get_cursor (void); diff --git a/mail/send.c b/mail/send.c index c2ed4e4..8a39d08 100644 --- a/mail/send.c +++ b/mail/send.c @@ -488,8 +488,42 @@ mail_send (int argc, char **argv) compose_init (&env); if (argc < 2) - compose_header_set (&env, MU_HEADER_TO, ml_readline_with_intr ("To: "), - COMPOSE_REPLACE); + { + if (interactive) + compose_header_set (&env, MU_HEADER_TO, ml_readline_with_intr ("To: "), + COMPOSE_REPLACE); + else if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0)) + { + if (parse_headers (mu_strin, &env) != parse_headers_ok) + { + mu_error ("%s", _("Errors parsing message")); + exit (EXIT_FAILURE); + } + if (add_header_list) + { + mu_iterator_t itr; + mu_list_get_iterator (add_header_list, &itr); + for (mu_iterator_first (itr); !mu_iterator_is_done (itr); + mu_iterator_next (itr)) + { + struct add_header *hp; + int mode; + if (mu_iterator_current (itr, (void**) &hp)) + break; + mode = hp->mode; + if (mu_header_sget_value (env.header, hp->name, NULL) == 0) + mode = COMPOSE_REPLACE; + compose_header_set (&env, hp->name, hp->value, hp->mode); + } + mu_iterator_destroy (&itr); + } + } + else + { + mu_error ("%s", _("No recipients specified")); + exit (EXIT_FAILURE); + } + } else { while (--argc) @@ -511,27 +545,137 @@ mail_send (int argc, char **argv) } } - if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0)) - read_cc_bcc (&env); - - if (mailvar_get (NULL, "asksub", mailvar_type_boolean, 0) == 0) - compose_header_set (&env, MU_HEADER_SUBJECT, - ml_readline_with_intr ("Subject: "), COMPOSE_REPLACE); + if (interactive) + { + if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0)) + read_cc_bcc (&env); + if (mailvar_get (NULL, "asksub", mailvar_type_boolean, 0) == 0) + compose_header_set (&env, MU_HEADER_SUBJECT, + ml_readline_with_intr ("Subject: "), + COMPOSE_REPLACE); + } + status = mail_send0 (&env, save_to); compose_destroy (&env); return status; } + +int +parse_headers (mu_stream_t input, compose_env_t *env) +{ + int status; + mu_header_t header; + char *name = NULL; + char *value = NULL; + enum { STATE_INIT, STATE_READ, STATE_BODY } state = STATE_INIT; + char *buf = NULL; + size_t size = 0, n; + int errcnt = 0, line = 0; + + if ((status = mu_header_create (&header, NULL, 0)) != 0) + { + mu_error (_("Cannot create header: %s"), mu_strerror (status)); + return parse_headers_fatal; + } + + while (state != STATE_BODY && + errcnt == 0 && + mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0) + { + mu_rtrim_class (buf, MU_CTYPE_SPACE); + + line++; + switch (state) + { + case STATE_INIT: + if (!buf[0] || mu_isspace (buf[0])) + continue; + else + state = STATE_READ; + /*FALLTHRU*/ + + case STATE_READ: + if (buf[0] == 0) + state = STATE_BODY; + else if (mu_isspace (buf[0])) + { + /* A continuation line */ + if (name) + { + char *p = NULL; + mu_asprintf (&p, "%s\n%s", value, buf); + free (value); + value = p; + } + else + { + mu_error (_("%d: not a header line"), line); + errcnt++; + } + } + else + { + char *p; + + if (name) + { + mu_header_set_value (header, name, value[0] ? value : NULL, 0); + free (name); + free (value); + name = value = NULL; + } + p = strchr (buf, ':'); + if (p) + { + *p++ = 0; + while (*p && mu_isspace (*p)) + p++; + value = mu_strdup (p); + name = mu_strdup (buf); + } + else + { + mu_error (_("%d: not a header line"), line); + errcnt++; + } + } + break; + + default: + abort (); + } + } + + free (buf); + if (name) + { + mu_header_set_value (header, name, value, 0); + free (name); + free (value); + } + + if (errcnt) + { + mu_header_destroy (&header); + return parse_headers_error; + } + + mu_header_destroy (&env->header); + env->header = header; + return parse_headers_ok; +} + void -compose_init (compose_env_t * env) +compose_init (compose_env_t *env) { memset (env, 0, sizeof (*env)); mu_list_foreach (add_header_list, seed_headers, env); } int -compose_header_set (compose_env_t * env, const char *name, +compose_header_set (compose_env_t *env, const char *name, const char *value, int mode) { int status; @@ -601,7 +745,7 @@ compose_header_set (compose_env_t * env, const char *name, } char * -compose_header_get (compose_env_t * env, char *name, char *defval) +compose_header_get (compose_env_t *env, char *name, char *defval) { char *p; diff --git a/mail/table.c b/mail/table.c index b5ffa03..4c3f4f7 100644 --- a/mail/table.c +++ b/mail/table.c @@ -226,8 +226,8 @@ static const struct mail_escape_entry mail_escape_table[] = { {"!", "!", "![shell-command]", escape_shell }, {":", ":", ":[mail-command]", escape_command }, {"-", "-", "-[mail-command]", escape_command }, - {"+", "+", "+[name [content-type [encoding]]]", escape_attach }, - {"^", "^", "^[N]", escape_remove_attachment }, + {"+", "+", "+name [content-type [encoding]]", escape_attach }, + {"^", "^", "^N", escape_remove_attachment }, {"?", "?", "?", escape_help }, {"A", "A", "A", escape_sign }, {"a", "a", "a", escape_sign }, diff --git a/movemail/movemail.c b/movemail/movemail.c index 6935763..7037ce9 100644 --- a/movemail/movemail.c +++ b/movemail/movemail.c @@ -194,51 +194,54 @@ set_mailbox_ownership_list (char const *str) } static int -set_onerror_action (char const *str) +set_onerror_action (void *item, void *data) { - struct mu_wordsplit ws; - static struct mu_kwd onerror_kw[] = { - { "skip", ONERROR_SKIP }, - { "delete", ONERROR_DELETE }, - { "count", ONERROR_COUNT }, - { NULL } - }; - int i, flag; - + char *str = item; + if (strcmp (str, "abort") == 0) + onerror_flags = 0; + else { - onerror_flags = 0; - return 0; - } - ws.ws_delim = ","; - if (mu_wordsplit (str, &ws, - MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | - MU_WRDSF_DELIM | MU_WRDSF_WS)) - { - mu_error (_("cannot split argument: %s"), mu_wordsplit_strerror (&ws)); - return 1; - } - for (i = 0; i < ws.ws_wordc; i++) - { - int clr = 0; - char *name = ws.ws_wordv[i]; - - if (strncmp (name, "no", 2) == 0) + static struct mu_kwd onerror_kw[] = { + { "skip", ONERROR_SKIP }, + { "delete", ONERROR_DELETE }, + { "count", ONERROR_COUNT }, + { NULL } + }; + int flag, clr = 0; + + if (strncmp (str, "no", 2) == 0) { clr = 1; - name += 2; + str += 2; + } + if (mu_kwd_xlat_name (onerror_kw, str, &flag)) + { + mu_error (_("unknown keyword: %s"), str); + return 1; } - if (mu_kwd_xlat_name (onerror_kw, name, &flag)) - mu_error (_("unknown keyword: %s"), ws.ws_wordv[i]); if (clr) onerror_flags &= ~flag; else onerror_flags |= flag; } - mu_wordsplit_free (&ws); return 0; } +static int +set_onerror_actions (char const *str) +{ + mu_list_t list; + int rc; + + mu_list_create (&list); + mu_list_set_destroy_item (list, mu_list_free_item); + mu_string_split (str, ",", list); + rc = mu_list_foreach (list, set_onerror_action, NULL); + mu_list_destroy (&list); + return rc; +} + static void cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt, char const *arg) @@ -250,7 +253,7 @@ cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt, static void cli_onerror (struct mu_parseopt *po, struct mu_option *opt, char const *arg) { - if (set_onerror_action (arg)) + if (set_onerror_actions (arg)) exit (po->po_exit_error); } @@ -327,9 +330,20 @@ cb_mailbox_ownership (void *data, mu_config_value_t *val) static int cb_onerror (void *data, mu_config_value_t *val) { - if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) - return 1; - return set_onerror_action (val->v.string); + switch (val->type) + { + case MU_CFG_LIST: + mu_list_foreach (val->v.list, set_onerror_action, NULL); + break; + + case MU_CFG_STRING: + set_onerror_actions (val->v.string); + break; + + default: + mu_error ("%s", _("too many arguments")); + } + return 0; } struct mu_cfg_param movemail_cfg_param[] = { @@ -360,12 +374,12 @@ struct mu_cfg_param movemail_cfg_param[] = { { "ignore-errors", mu_c_bool, &ignore_errors, 0, NULL, N_("Continue after an error.") }, { "onerror", mu_cfg_callback, NULL, 0, cb_onerror, - N_("What to do after an error. Argument is a comma-separated list of:\n" + N_("What to do after an error. Argument is a list of:\n" + " abort - terminate the program (the default)\n" " skip - skip to the next message\n" " delete - delete this one and to the next message\n" " count - count this message as processed\n" - "Each keyword can be prefixed with \"no\" to reverse its meaning\n" - "Setting onerror=abort reverts to the default behavior."), + "Each keyword can be prefixed with \"no\" to reverse its meaning."), N_("arg: list") }, { NULL } }; hooks/post-receive -- GNU Mailutils _______________________________________________ Commit-mailutils mailing list Commit-mailutils@gnu.org https://lists.gnu.org/mailman/listinfo/commit-mailutils