Commit af202127 af20212718728b315449ff35685772302883fc3d by Sergey Poznyakoff

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.
1 parent edb05144
...@@ -236,7 +236,6 @@ Reading Mail ...@@ -236,7 +236,6 @@ Reading Mail
236 @command{movemail} --- Moves Mail from the User Maildrop to the Local File 236 @command{movemail} --- Moves Mail from the User Maildrop to the Local File
237 237
238 * Movemail Configuration:: 238 * Movemail Configuration::
239 * Movemail Options:: Description of the Available Options
240 * Ownership:: Setting Destination Mailbox Ownership 239 * Ownership:: Setting Destination Mailbox Ownership
241 * Summary:: Short Movemail Invocation Summary 240 * Summary:: Short Movemail Invocation Summary
242 241
......
...@@ -2742,7 +2742,7 @@ is being sent, etc. ...@@ -2742,7 +2742,7 @@ is being sent, etc.
2742 @item trace6 2742 @item trace6
2743 When used together with @samp{prot}, displays security-sensitive 2743 When used together with @samp{prot}, displays security-sensitive
2744 information (such as passwords, user keys, etc). in plaintext. By 2744 information (such as passwords, user keys, etc). in plaintext. By
2745 default, such information is replaced with asteriscs to reduce the 2745 default, such information is replaced with asterisks to reduce the
2746 possibility of security compromise. 2746 possibility of security compromise.
2747 @item trace7 2747 @item trace7
2748 When used together with @samp{prot}, displays the @dfn{payload} 2748 When used together with @samp{prot}, displays the @dfn{payload}
...@@ -2795,10 +2795,10 @@ configuration file statements: ...@@ -2795,10 +2795,10 @@ configuration file statements:
2795 2795
2796 @multitable @columnfractions 0.3 0.6 2796 @multitable @columnfractions 0.3 0.6
2797 @headitem Statement @tab Reference 2797 @headitem Statement @tab Reference
2798 @item debug @tab @xref{Debug Statement}. 2798 @item debug @tab @xref{debug statement}.
2799 @item tls @tab @xref{TLS Statement}. 2799 @item tls @tab @xref{tls statement}.
2800 @item mailbox @tab @xref{Mailbox Statement}. 2800 @item mailbox @tab @xref{mailbox statement}.
2801 @item locking @tab @xref{Locking Statement}. 2801 @item locking @tab @xref{locking statement}.
2802 @end multitable 2802 @end multitable
2803 2803
2804 @subheading @command{frm} 2804 @subheading @command{frm}
...@@ -2907,10 +2907,9 @@ contents of the user system mailbox. The @option{--file} (@option{-f}) ...@@ -2907,10 +2907,9 @@ contents of the user system mailbox. The @option{--file} (@option{-f})
2907 command line option allows to specify another mailbox name. For more 2907 command line option allows to specify another mailbox name. For more
2908 detail, see @ref{Reading Mail}. 2908 detail, see @ref{Reading Mail}.
2909 2909
2910 In contrast to other GNU Mailutils programs, @command{mail} does not 2910 In addition to the Mailutils configuration file, @command{mail} loads
2911 use the Mailutils configuration file. Instead, it uses the traditional 2911 the traditional @samp{mailrc}-style configuration files. @xref{Mail
2912 @samp{mailrc}-style configuration. @xref{Mail Configuration Files}, 2912 Configuration Files}, for a detailed description of their format.
2913 for a detailed description of its format.
2914 2913
2915 @menu 2914 @menu
2916 * Invoking Mail:: Command Line Options. 2915 * Invoking Mail:: Command Line Options.
...@@ -2934,49 +2933,72 @@ General usage of @command{mail} program is: ...@@ -2934,49 +2933,72 @@ General usage of @command{mail} program is:
2934 If [@var{address}...] part is present, @command{mail} switches to 2933 If [@var{address}...] part is present, @command{mail} switches to
2935 mail sending mode, otherwise it operates in mail reading mode. 2934 mail sending mode, otherwise it operates in mail reading mode.
2936 2935
2937 The program uses following option groups: @FIXME-xref{mailbox}. 2936 @command{Mail} understands the following command line options:
2938
2939 @command{Mail} understands following command line options:
2940 2937
2941 @table @option 2938 @table @option
2942 @item -e 2939 @item -A @var{file}
2943 @itemx --exist 2940 @itemx --attach=@var{file}
2944 Return true if the mailbox contains some messages. Return false 2941 Attach @var{file} to the composed message. The encoding and content
2945 otherwise. 2942 type are controlled by the @option{--encoding} and
2946 This is useful for writing shell scripts. 2943 @option{--content-type} options, correspondingly.
2944
2945 @item -a @var{header}:@var{value}
2946 @itemx --append=@var{header}:@var{value}
2947 Append the given header to the composed message.
2948
2949 @item --content-type=@var{type}
2950 This options sets the content type to be used by all subsequent
2951 @option{--attach} options.
2952
2947 @item -E @var{command} 2953 @item -E @var{command}
2948 @itemx --exec=@var{command} 2954 @itemx --exec=@var{command}
2949 Execute @var{command} before opening the mailbox. Any number of 2955 Execute @var{command} before opening the mailbox. Any number of
2950 @option{--exec} options can be given. The commands will be executed 2956 @option{--exec} options can be given. The commands will be executed
2951 after sourcing configuration files (@pxref{Mail Configuration Files}), 2957 after sourcing configuration files (@pxref{Mail Configuration Files}),
2952 but before opening the mailbox. 2958 but before opening the mailbox.
2953 @item -f 2959
2954 @itemx --file 2960 @item -e
2955 Operate on the mailbox given by the first non-optional command line 2961 @itemx --exist
2956 argument. If there is no such argument, read messages from the 2962 Return true if the mailbox contains some messages. Return false
2957 user's @file{mbox} file. @xref{Reading Mail}, for more details about 2963 otherwise.
2958 using this option. 2964
2965 This is useful for writing shell scripts.
2966
2967 @item --encoding=@var{enc}
2968 Sets content transfer encoding for use by the subsequent
2969 @option{--attach} options.
2970
2959 @item -F 2971 @item -F
2960 @itemx --byname 2972 @itemx --byname
2961 Record outgoing messages in a file named after the first recipient. 2973 Record outgoing messages in a file named after the first recipient.
2962 The name is the login-name portion of the address found first on the 2974 The name is the login-name portion of the address found first on the
2963 @samp{To:} line in the mail header. This option sets the @samp{byname} 2975 @samp{To:} line in the mail header. This option sets the @samp{byname}
2964 variable, which see (@pxref{byname}). 2976 variable, which see (@pxref{byname}).
2977
2978 @item -f
2979 @itemx --file
2980 Operate on the mailbox given by the first non-optional command line
2981 argument. If there is no such argument, read messages from the
2982 user's @file{mbox} file. @xref{Reading Mail}, for more details about
2983 using this option.
2984
2965 @item -H 2985 @item -H
2966 @itemx --headers 2986 @itemx --headers
2967 Print header summary to stdout and exit. 2987 Print header summary to stdout and exit.
2988
2968 @item -i 2989 @item -i
2969 @itemx --ignore 2990 @itemx --ignore
2970 Ignore interrupts. 2991 Ignore interrupts when composing the message.
2971 @item -m @var{path} 2992
2972 @itemx --mail-spool=@var{path}
2973 Set path to the mailspool directory
2974 @item -n
2975 @itemx --norc
2976 Do not read the system-wide mailrc file. @xref{Mail Configuration Files}.
2977 @item -N 2993 @item -N
2978 @itemx --nosum 2994 @itemx --nosum
2979 Do not display initial header summary. 2995 Do not display initial header summary.
2996
2997 @item -n
2998 @itemx --norc
2999 Do not read the system-wide mailrc file. @xref{Mail Configuration
3000 Files}.
3001
2980 @item -p 3002 @item -p
2981 @itemx --print 3003 @itemx --print
2982 @itemx --read 3004 @itemx --read
...@@ -2990,18 +3012,26 @@ quit ...@@ -2990,18 +3012,26 @@ quit
2990 @end example 3012 @end example
2991 @noindent 3013 @noindent
2992 except that @command{mail --print} does not change status of the messages. 3014 except that @command{mail --print} does not change status of the messages.
2993 @item -r @var{address} 3015
2994 @itemx --return-address=@var{address}
2995 Sets the return email address for outgoing mail. @xref{return-address}.
2996 @item -q 3016 @item -q
2997 @itemx --quit 3017 @itemx --quit
2998 Cause interrupts to terminate program. 3018 Cause interrupts to terminate program.
3019
3020 @item -r @var{address}
3021 @itemx --return-address=@var{address}
3022 Sets the return email address for outgoing mail.
3023 @xref{return-address}.
3024
2999 @item -s @var{subj} 3025 @item -s @var{subj}
3000 @itemx --subject=@var{subj} 3026 @itemx --subject=@var{subj}
3001 Send a message with a Subject of @var{subj}. Valid only in sending mode. 3027 Send a message with a Subject of @var{subj}. Valid only in sending
3028 mode.
3029
3002 @item -t 3030 @item -t
3003 @itemx --to 3031 @itemx --to
3004 Switch to sending mode. 3032 Read recipients from the message header. Ignore addresses listed in
3033 the command line.
3034
3005 @item -u @var{user} 3035 @item -u @var{user}
3006 @itemx --user=@var{user} 3036 @itemx --user=@var{user}
3007 Operate on @var{user}'s mailbox. This is equivalent to: 3037 Operate on @var{user}'s mailbox. This is equivalent to:
...@@ -3013,16 +3043,11 @@ mail -f/@var{spool_path}/@var{user} ...@@ -3013,16 +3043,11 @@ mail -f/@var{spool_path}/@var{user}
3013 @noindent 3043 @noindent
3014 with @var{spool_path} being the full path to your mailspool directory 3044 with @var{spool_path} being the full path to your mailspool directory
3015 @*(@file{/var/spool/mail} or @file{/var/mail} on most systems). 3045 @*(@file{/var/spool/mail} or @file{/var/mail} on most systems).
3016 @item -?
3017 @itemx --help
3018 Display a help message.
3019 @item --usage
3020 Display a short usage summary.
3021 @item -V
3022 @itemx --version
3023 Print program version and exit.
3024 @end table 3046 @end table
3025 3047
3048 The program also understands the common mailutils options
3049 (@pxref{Common Options}.
3050
3026 @node Specifying Messages 3051 @node Specifying Messages
3027 @subsection How to Specify Message Sets 3052 @subsection How to Specify Message Sets
3028 3053
...@@ -3136,6 +3161,7 @@ The actual escape character may be changed by setting the value of ...@@ -3136,6 +3161,7 @@ The actual escape character may be changed by setting the value of
3136 * Modifying the Headers:: 3161 * Modifying the Headers::
3137 * Enclosing Another Message:: 3162 * Enclosing Another Message::
3138 * Adding a File to the Message:: 3163 * Adding a File to the Message::
3164 * Attaching a File to the Message::
3139 * Printing And Saving the Message:: 3165 * Printing And Saving the Message::
3140 * Signing the Message:: 3166 * Signing the Message::
3141 * Printing Another Message:: 3167 * Printing Another Message::
...@@ -3194,6 +3220,7 @@ the headers as well. ...@@ -3194,6 +3220,7 @@ the headers as well.
3194 @node Modifying the Headers 3220 @node Modifying the Headers
3195 @subsubsection Modifying the Headers: ~h, ~t, ~c, ~b, ~s 3221 @subsubsection Modifying the Headers: ~h, ~t, ~c, ~b, ~s
3196 3222
3223 @cindex ~t, mail escape
3197 To add new addresses to the list of message recipients, use @samp{~t} 3224 To add new addresses to the list of message recipients, use @samp{~t}
3198 command, e.g.: 3225 command, e.g.:
3199 3226
...@@ -3201,15 +3228,19 @@ command, e.g.: ...@@ -3201,15 +3228,19 @@ command, e.g.:
3201 ~t name1@@domain.net name2 3228 ~t name1@@domain.net name2
3202 @end example 3229 @end example
3203 3230
3231 @cindex ~c, mail escape
3232 @cindex ~b, mail escape
3204 To add addresses to @code{Cc} or @code{Bcc}, use @samp{~c} or @samp{~b} 3233 To add addresses to @code{Cc} or @code{Bcc}, use @samp{~c} or @samp{~b}
3205 escapes respectively. 3234 escapes respectively.
3206 3235
3236 @cindex ~s, mail escape
3207 To change the @code{Subject} header, use @samp{~s} escape, e.g.: 3237 To change the @code{Subject} header, use @samp{~s} escape, e.g.:
3208 3238
3209 @example 3239 @example
3210 ~s "Re: your message" 3240 ~s "Re: your message"
3211 @end example 3241 @end example
3212 3242
3243 @cindex ~h, mail escape
3213 Finally, to edit all headers, type @samp{~h} escape. This will present 3244 Finally, to edit all headers, type @samp{~h} escape. This will present
3214 you with the values of @code{To}, @code{Cc}, @code{Bcc}, and 3245 you with the values of @code{To}, @code{Cc}, @code{Bcc}, and
3215 @code{Subject} headers allowing to edit them with normal text editing 3246 @code{Subject} headers allowing to edit them with normal text editing
...@@ -3235,6 +3266,8 @@ prepended to each line enclosed. ...@@ -3235,6 +3266,8 @@ prepended to each line enclosed.
3235 @node Adding a File to the Message 3266 @node Adding a File to the Message
3236 @subsubsection Adding a File to the Message: ~r and ~d 3267 @subsubsection Adding a File to the Message: ~r and ~d
3237 3268
3269 @cindex ~r, mail escape
3270 @cindex ~<, mail escape
3238 To append the contents of file @var{filename} to the message, type 3271 To append the contents of file @var{filename} to the message, type
3239 3272
3240 @example 3273 @example
...@@ -3248,12 +3281,56 @@ or ...@@ -3248,12 +3281,56 @@ or
3248 @end example 3281 @end example
3249 @noindent 3282 @noindent
3250 3283
3284 @cindex ~d, mail escape
3251 The @samp{~d} escape is a shorthand for 3285 The @samp{~d} escape is a shorthand for
3252 3286
3253 @example 3287 @example
3254 ~r dead.letter 3288 ~r dead.letter
3255 @end example 3289 @end example
3256 3290
3291 @node Attaching a File to the Message
3292 @subsubsection Attaching a File to the Message
3293 @cindex ~+, mail escape
3294 The @samp{~+} escape attaches a file to the message. It takes one to
3295 three arguments. The first argument supplies the name of the file to
3296 attach:
3297
3298 @example
3299 ~+ myfile.txt
3300 @end example
3301
3302 The file will be attached with default content-type
3303 @samp{application/octet-stream}, and encoding @samp{base64}
3304 (these can be altered by the @option{--content-type} and
3305 @option{--encoding} command line options, correspondingly).
3306
3307 Optional second argument defines the content type to be used instead
3308 of the default one. Optional third argument defines the encoding,
3309 e.g.:
3310
3311 @example
3312 ~+ myfile.html text/html base64
3313 @end example
3314
3315 @cindex ~l, mail escape
3316 To list the files attached so far, use the @samp{~l} escape:
3317
3318 @example
3319 ~l
3320 1 myfile.html text/html base64
3321 @end example
3322
3323 Each line of the listing contains the ordinal number of the attachment,
3324 the name of the file, content-type and transfer encoding used.
3325
3326 @cindex ~^, mail escape
3327 The @samp{~^} escape removes attachments. Its argument is the number
3328 of the attachment to remove, e.g.:
3329
3330 @example
3331 ~^ 1
3332 @end example
3333
3257 @node Printing And Saving the Message 3334 @node Printing And Saving the Message
3258 @subsubsection Printing And Saving the Message 3335 @subsubsection Printing And Saving the Message
3259 @kyindex ~p, mail escape 3336 @kyindex ~p, mail escape
...@@ -4692,7 +4769,7 @@ The program is started with the @option{--print} (@option{-p}) command ...@@ -4692,7 +4769,7 @@ The program is started with the @option{--print} (@option{-p}) command
4692 line option (@pxref{Invoking Mail}). 4769 line option (@pxref{Invoking Mail}).
4693 4770
4694 @item read 4771 @item read
4695 The progran operates in read mode. This is the default. 4772 The program operates in read mode. This is the default.
4696 4773
4697 @item send 4774 @item send
4698 The program operates in send mode. This means it was given one or more 4775 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, ...@@ -4992,7 +5069,7 @@ variables. Also, if the user is trying to set an unknown variable,
4992 @*Type: Boolean. 5069 @*Type: Boolean.
4993 @*Default: False. 5070 @*Default: False.
4994 5071
4995 If this variable is set, the listing ouput by @command{set} contains short 5072 If this variable is set, the listing output by @command{set} contains short
4996 descriptions before each variable. @xref{Setting and Unsetting the Variables}. 5073 descriptions before each variable. @xref{Setting and Unsetting the Variables}.
4997 5074
4998 @kwindex verbose 5075 @kwindex verbose
...@@ -5021,8 +5098,9 @@ X-Mailer: mail (GNU Mailutils @value{VERSION}) ...@@ -5021,8 +5098,9 @@ X-Mailer: mail (GNU Mailutils @value{VERSION})
5021 @node Mail Configuration Files 5098 @node Mail Configuration Files
5022 @subsection Personal and System-wide Configuration Files 5099 @subsection Personal and System-wide Configuration Files
5023 5100
5024 Upon startup, @command{mail} reads the contents of the two command files: 5101 After processing the usual Mailutils configuration files
5025 the system-wide configuration file, and the user's configuration 5102 (@pxref{configuration}), @command{mail} reads the contents of the two
5103 command files: the system-wide command file, and the user's command
5026 file. Each line read from these files is processed like a usual 5104 file. Each line read from these files is processed like a usual
5027 @command{mail} command. 5105 @command{mail} command.
5028 5106
...@@ -5040,7 +5118,6 @@ package via @option{--with-mail-rc} option. It defaults to ...@@ -5040,7 +5118,6 @@ package via @option{--with-mail-rc} option. It defaults to
5040 @node messages 5118 @node messages
5041 @section @command{messages} --- Count the Number of Messages in a Mailbox 5119 @section @command{messages} --- Count the Number of Messages in a Mailbox
5042 @pindex messages 5120 @pindex messages
5043 @UNREVISED
5044 5121
5045 @command{Messages} prints on standard output the number of messages 5122 @command{Messages} prints on standard output the number of messages
5046 contained in each folder specified in command line. If no folders 5123 contained in each folder specified in command line. If no folders
...@@ -5055,18 +5132,19 @@ Number of messages in @var{folder}: @var{number} ...@@ -5055,18 +5132,19 @@ Number of messages in @var{folder}: @var{number}
5055 where @var{folder} represents the folder name, @var{number} represents 5132 where @var{folder} represents the folder name, @var{number} represents
5056 the number of messages. 5133 the number of messages.
5057 5134
5058 Following configuration file statements affect the behaviour of 5135 The following configuration file statements affect the behaviour of
5059 @command{messages}: 5136 @command{messages}:
5060 5137
5061 @multitable @columnfractions 0.3 0.6 5138 @multitable @columnfractions 0.3 0.6
5062 @headitem Statement @tab Reference 5139 @headitem Statement @tab Reference
5063 @item debug @tab @xref{Debug Statement}. 5140 @item debug @tab @xref{debug statement}.
5064 @item tls @tab @xref{TLS Statement}. 5141 @item tls @tab @xref{tls statement}.
5065 @item mailbox @tab @xref{Mailbox Statement}. 5142 @item mailbox @tab @xref{mailbox statement}.
5066 @item locking @tab @xref{Locking Statement}. 5143 @item locking @tab @xref{locking statement}.
5067 @end multitable 5144 @end multitable
5068 5145
5069 The program accepts following command line options: 5146 In addition to the common mailutils options (@pxref{Common Options}),
5147 the program accepts the following command line options:
5070 5148
5071 @table @option 5149 @table @option
5072 @item -q 5150 @item -q
...@@ -5074,22 +5152,12 @@ The program accepts following command line options: ...@@ -5074,22 +5152,12 @@ The program accepts following command line options:
5074 @itemx -s 5152 @itemx -s
5075 @itemx --silent 5153 @itemx --silent
5076 Be quiet. Display only number of messages per mailbox, without leading text. 5154 Be quiet. Display only number of messages per mailbox, without leading text.
5077 @item -?
5078 @itemx --help
5079 Output help message and exit.
5080 @item --usage
5081 Output short usage summary and exit.
5082 @item -V
5083 @itemx --version
5084 Output program version and exit.
5085 @end table 5155 @end table
5086 5156
5087 @page 5157 @page
5088 @node movemail 5158 @node movemail
5089 @section @command{movemail} --- Moves Mail from the User Maildrop to the Local File 5159 @section @command{movemail} --- Moves Mail from the User Maildrop to the Local File
5090 @pindex movemail 5160 @pindex movemail
5091 @UNREVISED
5092
5093 The purpose of @command{movemail}, as its name implies, is to move mail 5161 The purpose of @command{movemail}, as its name implies, is to move mail
5094 from one location to another. For example, the following invocation: 5162 from one location to another. For example, the following invocation:
5095 5163
...@@ -5100,11 +5168,10 @@ movemail /var/mail/smith INBOX ...@@ -5100,11 +5168,10 @@ movemail /var/mail/smith INBOX
5100 @noindent 5168 @noindent
5101 moves messages from file @file{/var/mail/smith} to file @file{INBOX}. 5169 moves messages from file @file{/var/mail/smith} to file @file{INBOX}.
5102 5170
5103 You will probably never have to run this program manually. It is 5171 The program was initially intended as a replacement for
5104 intended as a replacement for @command{movemail} from GNU Emacs. The 5172 @command{movemail} from GNU Emacs. The @command{movemail} program is
5105 @command{movemail} program is run by Emacs @code{Rmail} 5173 run by Emacs @code{Rmail} module. @xref{Rmail,,,emacs,Reading Mail
5106 module. @xref{Rmail,,,emacs,Reading Mail with Rmail}, for detailed 5174 with Rmail}, for detailed description of @code{Rmail} interface.
5107 description of @code{Rmail} interface.
5108 5175
5109 Mailutils version of @command{movemail} is fully 5176 Mailutils version of @command{movemail} is fully
5110 backward-compatible with its Emacs predecessor, so it should run 5177 backward-compatible with its Emacs predecessor, so it should run
...@@ -5113,18 +5180,21 @@ starting from 22.1 contain improved @code{Rmail} interface and ...@@ -5113,18 +5180,21 @@ starting from 22.1 contain improved @code{Rmail} interface and
5113 are able to take advantage of all new features mailutils 5180 are able to take advantage of all new features mailutils
5114 @command{movemail} provides. 5181 @command{movemail} provides.
5115 5182
5183 Apart from that use, @command{movemail} proved to be a useful tool for
5184 incorporating mail from remote mailboxes into the local one. See
5185 @uref{http://mailutils.org/wiki/Fetching_Mail_with_Movemail, Fetching
5186 Mail with Movemail}, for a detailed discussion with usage recipes.
5187
5116 @menu 5188 @menu
5117 * Movemail Configuration:: 5189 * Movemail Configuration::
5118 * Movemail Options:: Description of the Available Options
5119 * Ownership:: Setting Destination Mailbox Ownership 5190 * Ownership:: Setting Destination Mailbox Ownership
5120 * Summary:: Short Movemail Invocation Summary 5191 * Summary:: Short Movemail Invocation Summary
5121 @end menu 5192 @end menu
5122 5193
5123 @node Movemail Configuration 5194 @node Movemail Configuration
5124 @subsection Movemail Configuration 5195 @subsection Movemail Configuration
5125 @UNREVISED 5196 @cindex movemail, configuration
5126 5197 The following configuration file statements affect the behavior of
5127 Following configuration file statements affect the behavior of
5128 @command{movemail}: 5198 @command{movemail}:
5129 5199
5130 @deffn {Movemail Config} preserve @var{bool} 5200 @deffn {Movemail Config} preserve @var{bool}
...@@ -5139,7 +5209,7 @@ If @var{bool} is @samp{true}, reverse message sorting order. ...@@ -5139,7 +5209,7 @@ If @var{bool} is @samp{true}, reverse message sorting order.
5139 If @var{bool} is @samp{true}, output information used by Emacs rmail interface. 5209 If @var{bool} is @samp{true}, output information used by Emacs rmail interface.
5140 @end deffn 5210 @end deffn
5141 5211
5142 @deffn {Movemail Config} ignore-erros @var{bool} 5212 @deffn {Movemail Config} ignore-errors @var{bool}
5143 Continue moving messages after errors. By default, 5213 Continue moving messages after errors. By default,
5144 @command{mailfromd} exits immediately if it cannot copy a message. 5214 @command{mailfromd} exits immediately if it cannot copy a message.
5145 @end deffn 5215 @end deffn
...@@ -5149,6 +5219,7 @@ Set program identifier, i.e. a string which will prefix all ...@@ -5149,6 +5219,7 @@ Set program identifier, i.e. a string which will prefix all
5149 diagnostic messages issued by the program. By default, program 5219 diagnostic messages issued by the program. By default, program
5150 name is used. 5220 name is used.
5151 5221
5222 @anchor{movemail-program-id}
5152 The @var{fmt} is a format string that may contain references to the 5223 The @var{fmt} is a format string that may contain references to the
5153 following variables (@pxref{Variables}): 5224 following variables (@pxref{Variables}):
5154 5225
...@@ -5224,101 +5295,145 @@ Make destination mailbox owned by @var{user}. ...@@ -5224,101 +5295,145 @@ Make destination mailbox owned by @var{user}.
5224 @end table 5295 @end table
5225 @end deffn 5296 @end deffn
5226 5297
5227 @multitable @columnfractions 0.3 0.6 5298 @deffn {Movemail Config} max-messages @var{count}
5228 @headitem Statement @tab Reference 5299 Defines upper limit on the number of moved messages. Movemail will
5229 @item debug @tab @xref{Debug Statement}. 5300 stop after transferring @var{count} messages.
5230 @item tls @tab @xref{TLS Statement}.
5231 @item mailbox @tab @xref{Mailbox Statement}.
5232 @item locking @tab @xref{Locking Statement}.
5233 @item pam @tab @xref{PAM Statement}.
5234 @item sql @tab @xref{SQL Statement}.
5235 @item virtdomain @tab @xref{Virtdomain Statement}.
5236 @item radius @tab @xref{Radius Statement}.
5237 @item ldap @tab @xref{LDAP Statement}.
5238 @item auth @tab @xref{Auth Statement}.
5239 @end multitable
5240 5301
5241 @node Movemail Options 5302 By default, the number of messages is not limited.
5242 @subsection Movemail Options 5303 @end deffn
5243 @UNREVISED
5244 5304
5245 This subsection discusses @command{movemail} options from the point of 5305 @anchor{movemail-onerror}
5246 view of an Emacs @code{Rmail} user. 5306 @deffn {Movemail Config} onerror @var{actions}
5307 Defines what to do if an error occurs when transferring a message.
5308 @var{actions} is a list of one or more of the following keywords:
5247 5309
5248 To set various options to @command{movemail} from @code{Rmail}, use 5310 @table @asis
5249 @code{rmail-movemail-flags} variable, or @samp{Rmail Movemail Flags} 5311 @item abort
5250 section from the menu. 5312 Abort the transfer and terminate the program. This is the default
5313 action.
5251 5314
5252 Some POP servers return messages in reversed order. To fix the 5315 @item skip
5253 order, use @option{-p} option or its synonym @option{--reverse}. 5316 Skip to the next message.
5254 5317
5255 If the remote server supports @acronym{TLS} encryption, use 5318 @item delete
5256 @option{--tls} to instruct @command{movemail} to initiate encrypted 5319 Delete the affected message.
5257 connection. 5320
5321 @item count
5322 Count this message as processed.
5323 @end table
5324
5325 Each keyword can be prefixed with @samp{no} to reverse its meaning.
5326 @end deffn
5327
5328 The following standard Mailutils statements are supported:
5329
5330 @multitable @columnfractions 0.3 0.6
5331 @headitem Statement @tab Reference
5332 @item debug @tab @xref{debug statement}.
5333 @item tls @tab @xref{tls statement}.
5334 @item mailbox @tab @xref{mailbox statement}.
5335 @item locking @tab @xref{locking statement}.
5336 @item pam @tab @xref{pam statement}.
5337 @item sql @tab @xref{sql statement}.
5338 @item virtdomain @tab @xref{virtdomain statement}.
5339 @item radius @tab @xref{radius statement}.
5340 @item ldap @tab @xref{ldap statement}.
5341 @item auth @tab @xref{auth statement}.
5342 @end multitable
5258 5343
5259 @node Ownership 5344 @node Ownership
5260 @subsection Setting Destination Mailbox Ownership 5345 @subsection Setting Destination Mailbox Ownership
5261 @UNREVISED 5346 @UNREVISED
5262 5347
5263
5264 @node Summary 5348 @node Summary
5265 @subsection Movemail Usage Summary 5349 @subsection Movemail Usage Summary
5266 5350
5267 @example 5351 @example
5268 movemail [@var{option}...] @var{inbox} @var{destfile} [@var{remote-password}] 5352 movemail [@var{option}...] @var{inbox} @var{destfile} [@var{password}]
5269 @end example 5353 @end example
5270 5354
5271 The first argument, @var{inbox}, is the @acronym{url} (@FIXME-pxref{URL}) of 5355 The first argument, @var{inbox}, is the @acronym{url} (@pxref{Mailbox}) of
5272 the source mailbox. The second argument, @var{destfile}, traditionally 5356 the source mailbox. The second argument, @var{destfile}, traditionally
5273 means destination file, i.e. the UNIX mailbox to copy messages 5357 means destination file, i.e. the UNIX mailbox to copy messages
5274 to. However, mailutils @command{movemail} extends the meaning of this 5358 to. However, mailutils @command{movemail} extends the meaning of this
5275 parameter. You may actually specify any valid @acronym{URL} as 5359 parameter. You may actually specify any valid @acronym{url} as
5276 @var{destfile} parameter.@footnote{Rmail does not use this 5360 @var{destfile} parameter.@footnote{Rmail does not use this
5277 feature}. Finally, optional third argument is a traditional way of 5361 feature}.
5278 specifying user passwords for remote (@acronym{POP} or @acronym{IMAP}) 5362
5279 mailboxes. 5363 For compatibility with older implementations of @command{movemail},
5364 the @var{source} argument can also have the form:
5365
5366 @example
5367 po:@var{username}[:@var{pop-server}]
5368 @end example
5369
5370 @noindent
5371 where @var{pop-server} is the IP address or hostname of a POP3 server
5372 to connect to and @var{username} is the name of the user on that
5373 server. The password is then supplied by the third argument.
5280 5374
5281 Following is the summary of available command line options: 5375 It is equivalent to the following URL:
5376
5377 @example
5378 pop://@var{username}[:@var{password}]@@@var{pop-server}
5379 @end example
5380
5381 In fact, whenever @var{source} refers to a remote mailbox, the
5382 @var{password} argument can be used to pass the password. However,
5383 the safer @dfn{ticket} method is of course preferred.
5384
5385 Options are one or more of the following:
5282 5386
5283 @table @option 5387 @table @option
5284 @item --emacs 5388 @item --emacs
5285 Output information used by Emacs rmail interface 5389 Output information used by Emacs @code{rmail} interface.
5286 5390
5287 @item --ignore-errors 5391 @item --ignore-errors
5288 Continue moving messages after an error occurs. 5392 Try to continue after errors.
5393
5394 @item --max-messages=@var{count}
5395 Process at most @var{count} messages.
5396
5397 @item --notify
5398 Enable biff notification.
5399
5400 @item --onerror=@var{kw}[,@var{kw}...]
5401 What to do on errors. @xref{movemail-onerror, onerror statement}, for
5402 a description of @var{kw}.
5403
5404 @item -P @var{modelist}
5405 @itemx --owner=@var{modelist}
5406 Control mailbox ownership. @var{modelist} is a comma-separated list
5407 of one or more ownership change methods.
5408 @xref{mailbox-ownership-methods}, for a description of available
5409 methods.
5410
5411 This option is useful only when running @command{movemail} as root.
5289 5412
5290 @item -p 5413 @item -p
5291 @itemx --preserve 5414 @itemx --preserve
5292 @itemx --keep-messages 5415 @itemx --keep-messages
5293 Preserve the source mailbox 5416 Don't remove transferred messages from the source mailbox.
5294 5417
5295 @item --program-id=@var{fmt} 5418 @item --program-id=@var{fmt}
5296 Set program identifier for diagnostic purposes. See @ref{Movemail 5419 Set program identifier for diagnostics (default: the program name).
5297 Configuration,program-id}, for a detailed discussion of this feature. 5420 @xref{movemail-program-id}, for a description of its argument.
5298 5421
5299 @item -r 5422 @item -r
5300 @itemx --reverse 5423 @itemx --reverse
5301 Reverse the sorting order 5424 Reverse the order of retrieved messages.
5302
5303 @item --tls[=@var{bool}]
5304 Enable (default) or disable TLS support
5305 5425
5306 @item -u 5426 @item -u
5307 @item --uidl 5427 @itemx --uidl
5308 Use UIDLs to avoid downloading the same message twice. 5428 Use UIDLs to avoid downloading the same message twice.
5309 5429
5310 @item -P @var{method-list}
5311 @itemx --owner=@var{method-list}
5312 Define list of methods for setting ownership of the destination
5313 mailbox. @xref{mailbox-ownership-methods}, for a description of
5314 @var{method-list}. This option is useful only when running
5315 @command{movemail} as root.
5316
5317 @item -v 5430 @item -v
5318 @item --verbose 5431 @itemx --verbose
5319 Increase verbosity level. 5432 Increase verbosity level.
5320 @end table 5433 @end table
5321 5434
5435 The common options are also understood (@pxref{Common Options}).
5436
5322 @page 5437 @page
5323 @node readmsg 5438 @node readmsg
5324 @section @command{readmsg} --- Extract Messages from a Folder 5439 @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. ...@@ -5398,6 +5513,8 @@ A whitespace or coma separated list of header names to show per message.
5398 Default is @option{--weedlist="From Subject Date To CC Apparently-"}. 5513 Default is @option{--weedlist="From Subject Date To CC Apparently-"}.
5399 @end table 5514 @end table
5400 5515
5516 See also @ref{Common Options}.
5517
5401 @node Conf-readmsg 5518 @node Conf-readmsg
5402 @subsection Configuration of @command{readmsg}. 5519 @subsection Configuration of @command{readmsg}.
5403 5520
...@@ -7997,7 +8114,7 @@ run: ...@@ -7997,7 +8114,7 @@ run:
7997 mailutils filter --list 8114 mailutils filter --list
7998 @end example 8115 @end example
7999 8116
8000 Filters are applied in the order of their appearence, from left to 8117 Filters are applied in the order of their appearance, from left to
8001 right and operate in encode mode. The plus sign has the same meaning 8118 right and operate in encode mode. The plus sign has the same meaning
8002 as pipe in shell. The default mode can be changed using the 8119 as pipe in shell. The default mode can be changed using the
8003 @option{--decode} (@option{-d}) and @option{--encode} (@option{-e}) options. 8120 @option{--decode} (@option{-d}) and @option{--encode} (@option{-e}) options.
...@@ -8050,7 +8167,7 @@ configuration file processing. ...@@ -8050,7 +8167,7 @@ configuration file processing.
8050 @node mailutils acl 8167 @node mailutils acl
8051 @subsection mailutils acl 8168 @subsection mailutils acl
8052 The @command{mailutils acl} command tests Mailutils Access Control Lists. By 8169 The @command{mailutils acl} command tests Mailutils Access Control Lists. By
8053 default it reads ACL from the Mailutils configiration file section 8170 default it reads ACL from the Mailutils configuration file section
8054 @samp{acl}. The command takes a list of IP addresses as its 8171 @samp{acl}. The command takes a list of IP addresses as its
8055 arguments, applies the ACL to each of them in turn and prints the result. 8172 arguments, applies the ACL to each of them in turn and prints the result.
8056 8173
...@@ -8166,7 +8283,7 @@ smtp://bar@@gnu.org: /home/@var{user}/.mu-tickets:2: smtp://bar:***@@gnu.org ...@@ -8166,7 +8283,7 @@ smtp://bar@@gnu.org: /home/@var{user}/.mu-tickets:2: smtp://bar:***@@gnu.org
8166 @end example 8283 @end example
8167 8284
8168 As you see, even in that case the tool hides the actual password part 8285 As you see, even in that case the tool hides the actual password part
8169 by replacing it with three asteriscs. If you are working in a secure 8286 by replacing it with three asterisks. If you are working in a secure
8170 environment, you can tell @command{mu wicket} to show passwords as 8287 environment, you can tell @command{mu wicket} to show passwords as
8171 well, by supplying the @option{-v} option twice. 8288 well, by supplying the @option{-v} option twice.
8172 8289
...@@ -8395,7 +8512,7 @@ As of version @value{VERSION}, @command{mailutils dbm} supports two formats ...@@ -8395,7 +8512,7 @@ As of version @value{VERSION}, @command{mailutils dbm} supports two formats
8395 for dumping DBM databases. Both formats are line-oriented. Comments 8512 for dumping DBM databases. Both formats are line-oriented. Comments
8396 are introduced with a sharp (@samp{#}) sign in the column 0 of a line, 8513 are introduced with a sharp (@samp{#}) sign in the column 0 of a line,
8397 followed by at least one white space character (space or tab). Sharp 8514 followed by at least one white space character (space or tab). Sharp
8398 sign followed by a colon (@samp{#:}) introduces a @dfn{paragmatic 8515 sign followed by a colon (@samp{#:}) introduces a @dfn{pragmatic
8399 comment}, which carries some additional information to the loader. 8516 comment}, which carries some additional information to the loader.
8400 8517
8401 @anchor{dump version 0.0} 8518 @anchor{dump version 0.0}
......
...@@ -37,119 +37,26 @@ dump_headers (mu_stream_t out, compose_env_t *env) ...@@ -37,119 +37,26 @@ dump_headers (mu_stream_t out, compose_env_t *env)
37 mu_stream_destroy (&stream); 37 mu_stream_destroy (&stream);
38 } 38 }
39 39
40 #define STATE_INIT 0
41 #define STATE_READ 1
42 #define STATE_BODY 2
43
44 static int 40 static int
45 parse_headers (mu_stream_t input, compose_env_t *env) 41 check_headers (mu_stream_t input, compose_env_t *env)
46 { 42 {
47 int status; 43 char *p;
48 mu_header_t header;
49 char *name = NULL;
50 char *value = NULL;
51 int state = STATE_INIT;
52 char *buf = NULL;
53 size_t size = 0, n;
54 int errcnt = 0, line = 0;
55 44
56 if ((status = mu_header_create (&header, NULL, 0)) != 0)
57 {
58 mu_error (_("Cannot create header: %s"), mu_strerror (status));
59 return 1;
60 }
61
62 mu_stream_seek (input, 0, MU_SEEK_SET, NULL); 45 mu_stream_seek (input, 0, MU_SEEK_SET, NULL);
63 while (state != STATE_BODY && 46 switch (parse_headers (input, env))
64 errcnt == 0 &&
65 mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0)
66 { 47 {
67 mu_rtrim_class (buf, MU_CTYPE_SPACE); 48 case parse_headers_ok:
68 49 return 0;
69 line++; 50 case parse_headers_fatal:
70 switch (state) 51 return -1;
71 { 52 case parse_headers_error:
72 case STATE_INIT: 53 break;
73 if (!buf[0] || mu_isspace (buf[0]))
74 continue;
75 else
76 state = STATE_READ;
77 /*FALLTHRU*/
78
79 case STATE_READ:
80 if (buf[0] == 0)
81 state = STATE_BODY;
82 else if (mu_isspace (buf[0]))
83 {
84 /* A continuation line */
85 if (name)
86 {
87 char *p = NULL;
88 mu_asprintf (&p, "%s\n%s", value, buf);
89 free (value);
90 value = p;
91 }
92 else
93 {
94 mu_error (_("%d: not a header line"), line);
95 errcnt++;
96 }
97 }
98 else
99 {
100 char *p;
101
102 if (name)
103 {
104 mu_header_set_value (header, name, value[0] ? value : NULL, 0);
105 free (name);
106 free (value);
107 name = value = NULL;
108 }
109 p = strchr (buf, ':');
110 if (p)
111 {
112 *p++ = 0;
113 while (*p && mu_isspace (*p))
114 p++;
115 value = mu_strdup (p);
116 name = mu_strdup (buf);
117 }
118 else
119 {
120 mu_error (_("%d: not a header line"), line);
121 errcnt++;
122 }
123 }
124 break;
125 }
126 } 54 }
127 55
128 free (buf); 56 p = ml_readline (_("Edit again?"));
129 if (name) 57 return mu_true_answer_p (p);
130 { 58 }
131 mu_header_set_value (header, name, value, 0); 59
132 free (name);
133 free (value);
134 }
135
136 if (errcnt)
137 {
138 char *p;
139
140 mu_header_destroy (&header);
141 p = ml_readline (_("Edit again?"));
142 if (mu_true_answer_p (p) == 1)
143 return -1;
144 else
145 return 1;
146 }
147
148 mu_header_destroy (&env->header);
149 env->header = header;
150 return 0;
151 }
152
153 static void 60 static void
154 escape_continue (void) 61 escape_continue (void)
155 { 62 {
...@@ -386,7 +293,7 @@ escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env) ...@@ -386,7 +293,7 @@ escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env)
386 return rc; 293 return rc;
387 } 294 }
388 } 295 }
389 while ((rc = parse_headers (tempstream, env)) < 0); 296 while (check_headers (tempstream, env));
390 } 297 }
391 else 298 else
392 { 299 {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
23 mu_mailbox_t mbox; /* Mailbox being operated upon */ 23 mu_mailbox_t mbox; /* Mailbox being operated upon */
24 size_t total; /* Total number of messages in the mailbox */ 24 size_t total; /* Total number of messages in the mailbox */
25 int interactive; /* Is the session interactive */ 25 int interactive; /* Is the session interactive */
26 int read_recipients; /* Read recipients from the message (mail -t) */
26 27
27 static mu_list_t command_list;/* List of commands to be executed after parsing 28 static mu_list_t command_list;/* List of commands to be executed after parsing
28 command line */ 29 command line */
...@@ -72,6 +73,8 @@ cli_command_option (struct mu_parseopt *po, struct mu_option *opt, ...@@ -72,6 +73,8 @@ cli_command_option (struct mu_parseopt *po, struct mu_option *opt,
72 break; 73 break;
73 74
74 case 't': 75 case 't':
76 read_recipients = 1;
77 util_cache_command (&command_list, "set editheaders");
75 util_cache_command (&command_list, "setq mode=send"); 78 util_cache_command (&command_list, "setq mode=send");
76 break; 79 break;
77 80
...@@ -186,7 +189,7 @@ static struct mu_option mail_options[] = { ...@@ -186,7 +189,7 @@ static struct mu_option mail_options[] = {
186 mu_c_string, NULL, cli_subject }, 189 mu_c_string, NULL, cli_subject },
187 190
188 { "to", 't', NULL, MU_OPTION_DEFAULT, 191 { "to", 't', NULL, MU_OPTION_DEFAULT,
189 N_("precede message by a list of addresses"), 192 N_("read recipients from the message header"),
190 mu_c_string, NULL, cli_command_option }, 193 mu_c_string, NULL, cli_command_option },
191 194
192 { "user", 'u', N_("USER"), MU_OPTION_DEFAULT, 195 { "user", 'u', N_("USER"), MU_OPTION_DEFAULT,
...@@ -227,7 +230,7 @@ static struct mu_cli_setup cli = { ...@@ -227,7 +230,7 @@ static struct mu_cli_setup cli = {
227 options, 230 options,
228 NULL, 231 NULL,
229 N_("GNU mail -- process mail messages.\n" 232 N_("GNU mail -- process mail messages.\n"
230 "If -f or --file is given, mail operates on the mailbox named " 233 "If -f or --file is given, mail operates on the mailbox named "
231 "by the first argument, or the user's mbox, if no argument given."), 234 "by the first argument, or the user's mbox, if no argument given."),
232 N_("[address...]"), 235 N_("[address...]"),
233 alt_args, 236 alt_args,
...@@ -421,6 +424,12 @@ main (int argc, char **argv) ...@@ -421,6 +424,12 @@ main (int argc, char **argv)
421 /* argument parsing */ 424 /* argument parsing */
422 mu_cli (argc, argv, &cli, mail_capa, NULL, &argc, &argv); 425 mu_cli (argc, argv, &cli, mail_capa, NULL, &argc, &argv);
423 426
427 if (read_recipients)
428 {
429 argv += argc;
430 argc = 0;
431 }
432
424 if ((hint & (HINT_SEND_MODE|HINT_FILE_OPTION)) == 433 if ((hint & (HINT_SEND_MODE|HINT_FILE_OPTION)) ==
425 (HINT_SEND_MODE|HINT_FILE_OPTION)) 434 (HINT_SEND_MODE|HINT_FILE_OPTION))
426 { 435 {
......
...@@ -288,6 +288,15 @@ extern int escape_attach (int argc, char **argv, compose_env_t *env); ...@@ -288,6 +288,15 @@ extern int escape_attach (int argc, char **argv, compose_env_t *env);
288 extern int escape_remove_attachment (int argc, char **argv, 288 extern int escape_remove_attachment (int argc, char **argv,
289 compose_env_t *env); 289 compose_env_t *env);
290 290
291 enum
292 {
293 parse_headers_ok,
294 parse_headers_error,
295 parse_headers_fatal
296 };
297
298 extern int parse_headers (mu_stream_t input, compose_env_t *env);
299
291 /* Cursor */ 300 /* Cursor */
292 extern void set_cursor (unsigned value); 301 extern void set_cursor (unsigned value);
293 extern size_t get_cursor (void); 302 extern size_t get_cursor (void);
......
...@@ -488,8 +488,42 @@ mail_send (int argc, char **argv) ...@@ -488,8 +488,42 @@ mail_send (int argc, char **argv)
488 compose_init (&env); 488 compose_init (&env);
489 489
490 if (argc < 2) 490 if (argc < 2)
491 compose_header_set (&env, MU_HEADER_TO, ml_readline_with_intr ("To: "), 491 {
492 COMPOSE_REPLACE); 492 if (interactive)
493 compose_header_set (&env, MU_HEADER_TO, ml_readline_with_intr ("To: "),
494 COMPOSE_REPLACE);
495 else if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0))
496 {
497 if (parse_headers (mu_strin, &env) != parse_headers_ok)
498 {
499 mu_error ("%s", _("Errors parsing message"));
500 exit (EXIT_FAILURE);
501 }
502 if (add_header_list)
503 {
504 mu_iterator_t itr;
505 mu_list_get_iterator (add_header_list, &itr);
506 for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
507 mu_iterator_next (itr))
508 {
509 struct add_header *hp;
510 int mode;
511 if (mu_iterator_current (itr, (void**) &hp))
512 break;
513 mode = hp->mode;
514 if (mu_header_sget_value (env.header, hp->name, NULL) == 0)
515 mode = COMPOSE_REPLACE;
516 compose_header_set (&env, hp->name, hp->value, hp->mode);
517 }
518 mu_iterator_destroy (&itr);
519 }
520 }
521 else
522 {
523 mu_error ("%s", _("No recipients specified"));
524 exit (EXIT_FAILURE);
525 }
526 }
493 else 527 else
494 { 528 {
495 while (--argc) 529 while (--argc)
...@@ -511,27 +545,137 @@ mail_send (int argc, char **argv) ...@@ -511,27 +545,137 @@ mail_send (int argc, char **argv)
511 } 545 }
512 } 546 }
513 547
514 if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0)) 548 if (interactive)
515 read_cc_bcc (&env); 549 {
516 550 if (mailvar_get (NULL, "mailx", mailvar_type_boolean, 0))
517 if (mailvar_get (NULL, "asksub", mailvar_type_boolean, 0) == 0) 551 read_cc_bcc (&env);
518 compose_header_set (&env, MU_HEADER_SUBJECT,
519 ml_readline_with_intr ("Subject: "), COMPOSE_REPLACE);
520 552
553 if (mailvar_get (NULL, "asksub", mailvar_type_boolean, 0) == 0)
554 compose_header_set (&env, MU_HEADER_SUBJECT,
555 ml_readline_with_intr ("Subject: "),
556 COMPOSE_REPLACE);
557 }
558
521 status = mail_send0 (&env, save_to); 559 status = mail_send0 (&env, save_to);
522 compose_destroy (&env); 560 compose_destroy (&env);
523 return status; 561 return status;
524 } 562 }
563
564 int
565 parse_headers (mu_stream_t input, compose_env_t *env)
566 {
567 int status;
568 mu_header_t header;
569 char *name = NULL;
570 char *value = NULL;
571 enum { STATE_INIT, STATE_READ, STATE_BODY } state = STATE_INIT;
572 char *buf = NULL;
573 size_t size = 0, n;
574 int errcnt = 0, line = 0;
575
576 if ((status = mu_header_create (&header, NULL, 0)) != 0)
577 {
578 mu_error (_("Cannot create header: %s"), mu_strerror (status));
579 return parse_headers_fatal;
580 }
581
582 while (state != STATE_BODY &&
583 errcnt == 0 &&
584 mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0)
585 {
586 mu_rtrim_class (buf, MU_CTYPE_SPACE);
587
588 line++;
589 switch (state)
590 {
591 case STATE_INIT:
592 if (!buf[0] || mu_isspace (buf[0]))
593 continue;
594 else
595 state = STATE_READ;
596 /*FALLTHRU*/
597
598 case STATE_READ:
599 if (buf[0] == 0)
600 state = STATE_BODY;
601 else if (mu_isspace (buf[0]))
602 {
603 /* A continuation line */
604 if (name)
605 {
606 char *p = NULL;
607 mu_asprintf (&p, "%s\n%s", value, buf);
608 free (value);
609 value = p;
610 }
611 else
612 {
613 mu_error (_("%d: not a header line"), line);
614 errcnt++;
615 }
616 }
617 else
618 {
619 char *p;
620
621 if (name)
622 {
623 mu_header_set_value (header, name, value[0] ? value : NULL, 0);
624 free (name);
625 free (value);
626 name = value = NULL;
627 }
628 p = strchr (buf, ':');
629 if (p)
630 {
631 *p++ = 0;
632 while (*p && mu_isspace (*p))
633 p++;
634 value = mu_strdup (p);
635 name = mu_strdup (buf);
636 }
637 else
638 {
639 mu_error (_("%d: not a header line"), line);
640 errcnt++;
641 }
642 }
643 break;
644
645 default:
646 abort ();
647 }
648 }
649
650 free (buf);
651 if (name)
652 {
653 mu_header_set_value (header, name, value, 0);
654 free (name);
655 free (value);
656 }
657
658 if (errcnt)
659 {
660 mu_header_destroy (&header);
661 return parse_headers_error;
662 }
663
664 mu_header_destroy (&env->header);
665 env->header = header;
666 return parse_headers_ok;
667 }
668
525 669
526 void 670 void
527 compose_init (compose_env_t * env) 671 compose_init (compose_env_t *env)
528 { 672 {
529 memset (env, 0, sizeof (*env)); 673 memset (env, 0, sizeof (*env));
530 mu_list_foreach (add_header_list, seed_headers, env); 674 mu_list_foreach (add_header_list, seed_headers, env);
531 } 675 }
532 676
533 int 677 int
534 compose_header_set (compose_env_t * env, const char *name, 678 compose_header_set (compose_env_t *env, const char *name,
535 const char *value, int mode) 679 const char *value, int mode)
536 { 680 {
537 int status; 681 int status;
...@@ -601,7 +745,7 @@ compose_header_set (compose_env_t * env, const char *name, ...@@ -601,7 +745,7 @@ compose_header_set (compose_env_t * env, const char *name,
601 } 745 }
602 746
603 char * 747 char *
604 compose_header_get (compose_env_t * env, char *name, char *defval) 748 compose_header_get (compose_env_t *env, char *name, char *defval)
605 { 749 {
606 char *p; 750 char *p;
607 751
......
...@@ -226,8 +226,8 @@ static const struct mail_escape_entry mail_escape_table[] = { ...@@ -226,8 +226,8 @@ static const struct mail_escape_entry mail_escape_table[] = {
226 {"!", "!", "![shell-command]", escape_shell }, 226 {"!", "!", "![shell-command]", escape_shell },
227 {":", ":", ":[mail-command]", escape_command }, 227 {":", ":", ":[mail-command]", escape_command },
228 {"-", "-", "-[mail-command]", escape_command }, 228 {"-", "-", "-[mail-command]", escape_command },
229 {"+", "+", "+[name [content-type [encoding]]]", escape_attach }, 229 {"+", "+", "+name [content-type [encoding]]", escape_attach },
230 {"^", "^", "^[N]", escape_remove_attachment }, 230 {"^", "^", "^N", escape_remove_attachment },
231 {"?", "?", "?", escape_help }, 231 {"?", "?", "?", escape_help },
232 {"A", "A", "A", escape_sign }, 232 {"A", "A", "A", escape_sign },
233 {"a", "a", "a", escape_sign }, 233 {"a", "a", "a", escape_sign },
......
...@@ -194,51 +194,54 @@ set_mailbox_ownership_list (char const *str) ...@@ -194,51 +194,54 @@ set_mailbox_ownership_list (char const *str)
194 } 194 }
195 195
196 static int 196 static int
197 set_onerror_action (char const *str) 197 set_onerror_action (void *item, void *data)
198 { 198 {
199 struct mu_wordsplit ws; 199 char *str = item;
200 static struct mu_kwd onerror_kw[] = { 200
201 { "skip", ONERROR_SKIP },
202 { "delete", ONERROR_DELETE },
203 { "count", ONERROR_COUNT },
204 { NULL }
205 };
206 int i, flag;
207
208 if (strcmp (str, "abort") == 0) 201 if (strcmp (str, "abort") == 0)
202 onerror_flags = 0;
203 else
209 { 204 {
210 onerror_flags = 0; 205 static struct mu_kwd onerror_kw[] = {
211 return 0; 206 { "skip", ONERROR_SKIP },
212 } 207 { "delete", ONERROR_DELETE },
213 ws.ws_delim = ","; 208 { "count", ONERROR_COUNT },
214 if (mu_wordsplit (str, &ws, 209 { NULL }
215 MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | 210 };
216 MU_WRDSF_DELIM | MU_WRDSF_WS)) 211 int flag, clr = 0;
217 { 212
218 mu_error (_("cannot split argument: %s"), mu_wordsplit_strerror (&ws)); 213 if (strncmp (str, "no", 2) == 0)
219 return 1;
220 }
221 for (i = 0; i < ws.ws_wordc; i++)
222 {
223 int clr = 0;
224 char *name = ws.ws_wordv[i];
225
226 if (strncmp (name, "no", 2) == 0)
227 { 214 {
228 clr = 1; 215 clr = 1;
229 name += 2; 216 str += 2;
217 }
218 if (mu_kwd_xlat_name (onerror_kw, str, &flag))
219 {
220 mu_error (_("unknown keyword: %s"), str);
221 return 1;
230 } 222 }
231 if (mu_kwd_xlat_name (onerror_kw, name, &flag))
232 mu_error (_("unknown keyword: %s"), ws.ws_wordv[i]);
233 if (clr) 223 if (clr)
234 onerror_flags &= ~flag; 224 onerror_flags &= ~flag;
235 else 225 else
236 onerror_flags |= flag; 226 onerror_flags |= flag;
237 } 227 }
238 mu_wordsplit_free (&ws);
239 return 0; 228 return 0;
240 } 229 }
241 230
231 static int
232 set_onerror_actions (char const *str)
233 {
234 mu_list_t list;
235 int rc;
236
237 mu_list_create (&list);
238 mu_list_set_destroy_item (list, mu_list_free_item);
239 mu_string_split (str, ",", list);
240 rc = mu_list_foreach (list, set_onerror_action, NULL);
241 mu_list_destroy (&list);
242 return rc;
243 }
244
242 static void 245 static void
243 cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt, 246 cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt,
244 char const *arg) 247 char const *arg)
...@@ -250,7 +253,7 @@ cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt, ...@@ -250,7 +253,7 @@ cli_mailbox_ownership (struct mu_parseopt *po, struct mu_option *opt,
250 static void 253 static void
251 cli_onerror (struct mu_parseopt *po, struct mu_option *opt, char const *arg) 254 cli_onerror (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
252 { 255 {
253 if (set_onerror_action (arg)) 256 if (set_onerror_actions (arg))
254 exit (po->po_exit_error); 257 exit (po->po_exit_error);
255 } 258 }
256 259
...@@ -327,9 +330,20 @@ cb_mailbox_ownership (void *data, mu_config_value_t *val) ...@@ -327,9 +330,20 @@ cb_mailbox_ownership (void *data, mu_config_value_t *val)
327 static int 330 static int
328 cb_onerror (void *data, mu_config_value_t *val) 331 cb_onerror (void *data, mu_config_value_t *val)
329 { 332 {
330 if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) 333 switch (val->type)
331 return 1; 334 {
332 return set_onerror_action (val->v.string); 335 case MU_CFG_LIST:
336 mu_list_foreach (val->v.list, set_onerror_action, NULL);
337 break;
338
339 case MU_CFG_STRING:
340 set_onerror_actions (val->v.string);
341 break;
342
343 default:
344 mu_error ("%s", _("too many arguments"));
345 }
346 return 0;
333 } 347 }
334 348
335 struct mu_cfg_param movemail_cfg_param[] = { 349 struct mu_cfg_param movemail_cfg_param[] = {
...@@ -360,12 +374,12 @@ struct mu_cfg_param movemail_cfg_param[] = { ...@@ -360,12 +374,12 @@ struct mu_cfg_param movemail_cfg_param[] = {
360 { "ignore-errors", mu_c_bool, &ignore_errors, 0, NULL, 374 { "ignore-errors", mu_c_bool, &ignore_errors, 0, NULL,
361 N_("Continue after an error.") }, 375 N_("Continue after an error.") },
362 { "onerror", mu_cfg_callback, NULL, 0, cb_onerror, 376 { "onerror", mu_cfg_callback, NULL, 0, cb_onerror,
363 N_("What to do after an error. Argument is a comma-separated list of:\n" 377 N_("What to do after an error. Argument is a list of:\n"
378 " abort - terminate the program (the default)\n"
364 " skip - skip to the next message\n" 379 " skip - skip to the next message\n"
365 " delete - delete this one and to the next message\n" 380 " delete - delete this one and to the next message\n"
366 " count - count this message as processed\n" 381 " count - count this message as processed\n"
367 "Each keyword can be prefixed with \"no\" to reverse its meaning\n" 382 "Each keyword can be prefixed with \"no\" to reverse its meaning."),
368 "Setting onerror=abort reverts to the default behavior."),
369 N_("arg: list") }, 383 N_("arg: list") },
370 { NULL } 384 { NULL }
371 }; 385 };
......