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.
Showing
8 changed files
with
490 additions
and
291 deletions
... | @@ -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 | }; | ... | ... |
-
Please register or sign in to post a comment