Finish conversion of MH utilities to mh_parseopt
This finishes work started at commit bc73fc65. * include/mailutils/opt.h (mu_option_cache) <cache_arg>: Made const. * libmailutils/opt/opt.c (mu_option_cache_destroy): Don't free cache_arg. * doc/texinfo/mu-mh.texi: Update. * po/POTFILES.in: Remove obsolete files. * mh/tests/refile.at: Don't use double-dash options. * mh/mh_getopt.c (mh_opt_set_folder): New function. * mh/mh_getopt.h: Likewise. * mh/mhn.c: Convert to mh_getopt. * mh/mhparam.c: Likewise. * mh/mhpath.c: Likewise. * mh/mhseq.c: Likewise. * mh/msgchk.c: Likewise. * mh/pick.c: Likewise. * mh/pick.h: Likewise. * mh/pick.y: Likewise. * mh/prompter.c: Likewise. * mh/refile.c: Likewise. * mh/repl.c: Likewise. * mh/rmf.c: Likewise. * mh/rmm.c: Likewise. * mh/scan.c: Likewise. * mh/send.c: Likewise. * mh/show.c: Likewise. * mh/sortm.c: Likewise. * mh/whatnow.c: Likewise. * mh/whom.c: Likewise.
Showing
26 changed files
with
1144 additions
and
2026 deletions
... | @@ -27,9 +27,6 @@ distribution directory. | ... | @@ -27,9 +27,6 @@ distribution directory. |
27 | @subsection Major differences between Mailutils MH and other MH implementations | 27 | @subsection Major differences between Mailutils MH and other MH implementations |
28 | 28 | ||
29 | @enumerate 1 | 29 | @enumerate 1 |
30 | @item All programs use usual GNU long options. The support for MH single-dash | ||
31 | options is provided for backward compatibility; | ||
32 | |||
33 | @item UUCP addresses are not supported; | 30 | @item UUCP addresses are not supported; |
34 | 31 | ||
35 | @item Mailutils supports a set of new format specifications | 32 | @item Mailutils supports a set of new format specifications |
... | @@ -38,6 +35,12 @@ options is provided for backward compatibility; | ... | @@ -38,6 +35,12 @@ options is provided for backward compatibility; |
38 | @item Mailutils provides a set of new profile variables | 35 | @item Mailutils provides a set of new profile variables |
39 | (@pxref{Profile Variable Diffs}); | 36 | (@pxref{Profile Variable Diffs}); |
40 | 37 | ||
38 | @item All programs recognize @option{--help} and @option{--version} options | ||
39 | |||
40 | These options are recognized only if no other arguments are present in | ||
41 | the command line. Abbreviations are not recognized. This makes Mailutils | ||
42 | MH implementation compatible with the standard usage for GNU tools. | ||
43 | |||
41 | @item Several programs behave differently (@pxref{Program | 44 | @item Several programs behave differently (@pxref{Program |
42 | Diffs}); | 45 | Diffs}); |
43 | 46 | ||
... | @@ -150,7 +153,7 @@ This expression is used in default @file{replcomps} and | ... | @@ -150,7 +153,7 @@ This expression is used in default @file{replcomps} and |
150 | @deftypefn {MH Format} boolean rcpt (@samp{to} | @samp{cc} | @samp{me} | @samp{all}) | 153 | @deftypefn {MH Format} boolean rcpt (@samp{to} | @samp{cc} | @samp{me} | @samp{all}) |
151 | 154 | ||
152 | This function returns true if the given element is present in the | 155 | This function returns true if the given element is present in the |
153 | recipient mask (as modified by @option{--cc} or @option{--nocc} options) and | 156 | recipient mask (as modified by @option{-cc} or @option{-nocc} options) and |
154 | false otherwise. It is used in default formats for @command{repl} and | 157 | false otherwise. It is used in default formats for @command{repl} and |
155 | @command{comp}, e.g.: | 158 | @command{comp}, e.g.: |
156 | 159 | ||
... | @@ -159,7 +162,7 @@ false otherwise. It is used in default formats for @command{repl} and | ... | @@ -159,7 +162,7 @@ false otherwise. It is used in default formats for @command{repl} and |
159 | @end smallexample | 162 | @end smallexample |
160 | 163 | ||
161 | Notice that this means that usual @file{replcomps} file will be ignoring | 164 | Notice that this means that usual @file{replcomps} file will be ignoring |
162 | @option{--cc} and @option{--nocc} options, unless it has been modified | 165 | @option{-cc} and @option{-nocc} options, unless it has been modified |
163 | as shown above. | 166 | as shown above. |
164 | @end deftypefn | 167 | @end deftypefn |
165 | 168 | ||
... | @@ -226,12 +229,12 @@ RAND @command{anno} displays the prompt anyway. | ... | @@ -226,12 +229,12 @@ RAND @command{anno} displays the prompt anyway. |
226 | 229 | ||
227 | The utility is able to burst both RFC 934 digest messages and MIME | 230 | The utility is able to burst both RFC 934 digest messages and MIME |
228 | multipart messages. It provides two additional command line options: | 231 | multipart messages. It provides two additional command line options: |
229 | @option{--recurse} and @option{--length}. | 232 | @option{-recurse} and @option{-length}. |
230 | 233 | ||
231 | The @option{--recurse} option instructs the utility to recursively | 234 | The @option{-recurse} option instructs the utility to recursively |
232 | expand the digest. | 235 | expand the digest. |
233 | 236 | ||
234 | The @option{--length} option can be used to set the minimal encapsulation | 237 | The @option{-length} option can be used to set the minimal encapsulation |
235 | boundary length for RFC 934 digests. Default length is 1, | 238 | boundary length for RFC 934 digests. Default length is 1, |
236 | i.e. encountering one dash immediately following a newline triggers | 239 | i.e. encountering one dash immediately following a newline triggers |
237 | digest decoding. It is OK for messages that follow RFC 934 | 240 | digest decoding. It is OK for messages that follow RFC 934 |
... | @@ -239,12 +242,12 @@ specification. However, many user agents do not precisely follow it, | ... | @@ -239,12 +242,12 @@ specification. However, many user agents do not precisely follow it, |
239 | in particular, they often do not escape lines starting with a dash by | 242 | in particular, they often do not escape lines starting with a dash by |
240 | @samp{- } sequence. @command{Mailman} is one of such agents. To cope | 243 | @samp{- } sequence. @command{Mailman} is one of such agents. To cope |
241 | with such digests you can set encapsulation boundary length to a higher | 244 | with such digests you can set encapsulation boundary length to a higher |
242 | value. For example, @command{bounce --length=8} has been found to be | 245 | value. For example, @command{bounce -length 8} has been found to be |
243 | sufficient for most Mailman-generated digests. | 246 | sufficient for most Mailman-generated digests. |
244 | 247 | ||
245 | @item comp | 248 | @item comp |
246 | 249 | ||
247 | Understands @option{--build} option. | 250 | Understands @option{-build} option. |
248 | 251 | ||
249 | @item fmtdump | 252 | @item fmtdump |
250 | 253 | ||
... | @@ -252,24 +255,24 @@ This command is not provided. Use @option{fmtcheck} instead. | ... | @@ -252,24 +255,24 @@ This command is not provided. Use @option{fmtcheck} instead. |
252 | 255 | ||
253 | @item inc | 256 | @item inc |
254 | @itemize @bullet | 257 | @itemize @bullet |
255 | @item The @option{--moveto} option. | 258 | @item The @option{-moveto} option. |
256 | The @option{--moveto} option instructs @command{inc} to move | 259 | The @option{-moveto} option instructs @command{inc} to move |
257 | messages into another folder after incorporating them. This option | 260 | messages into another folder after incorporating them. This option |
258 | has effect only if the @option{--truncate} option has also been | 261 | has effect only if the @option{-truncate} option has also been |
259 | specified and the underlying mailbox supports the @samp{move} | 262 | specified and the underlying mailbox supports the @samp{move} |
260 | operation. Currently only @samp{imap} and @samp{imaps} mailboxes | 263 | operation. Currently only @samp{imap} and @samp{imaps} mailboxes |
261 | support it. For example, the following command moves incorporated | 264 | support it. For example, the following command moves incorporated |
262 | messages into the @samp{archive} folder: | 265 | messages into the @samp{archive} folder: |
263 | 266 | ||
264 | @example | 267 | @example |
265 | inc --file imaps://imap.gmail.com --moveto=archive | 268 | inc -file imaps://imap.gmail.com -moveto=archive |
266 | @end example | 269 | @end example |
267 | 270 | ||
268 | The @samp{moveto} URL parameter can be used instead of this option, | 271 | The @samp{moveto} URL parameter can be used instead of this option, |
269 | e.g.: | 272 | e.g.: |
270 | 273 | ||
271 | @example | 274 | @example |
272 | inc --file 'imaps://imap.gmail.com;moveto=archive' | 275 | inc -file 'imaps://imap.gmail.com;moveto=archive' |
273 | @end example | 276 | @end example |
274 | 277 | ||
275 | @item Multiple sources | 278 | @item Multiple sources |
... | @@ -294,7 +297,7 @@ Moves incorporated messages into another folder. This was discussed | ... | @@ -294,7 +297,7 @@ Moves incorporated messages into another folder. This was discussed |
294 | above. | 297 | above. |
295 | 298 | ||
296 | @item nomoveto | 299 | @item nomoveto |
297 | Disables the previous @option{--moveto} option. | 300 | Disables the previous @option{-moveto} option. |
298 | 301 | ||
299 | @item truncate[=@var{bool}] | 302 | @item truncate[=@var{bool}] |
300 | Controls source mailbox truncation. If @var{bool} is not given or it is | 303 | Controls source mailbox truncation. If @var{bool} is not given or it is |
... | @@ -333,13 +336,13 @@ The following format variables are silently ignored: @samp{center}, | ... | @@ -333,13 +336,13 @@ The following format variables are silently ignored: @samp{center}, |
333 | @itemize @bullet | 336 | @itemize @bullet |
334 | 337 | ||
335 | @item New option | 338 | @item New option |
336 | New option @option{--compose} forces @command{mhn} editing mode. This | 339 | New option @option{-compose} forces @command{mhn} editing mode. This |
337 | is also the default mode. This differs from the standard | 340 | is also the default mode. This differs from the standard |
338 | @command{mhn}, which switches to the editing mode only if no other | 341 | @command{mhn}, which switches to the editing mode only if no other |
339 | options were given and the input file name coincides with the value of | 342 | options were given and the input file name coincides with the value of |
340 | @env{mhdraft} environment variable. | 343 | @env{mhdraft} environment variable. |
341 | 344 | ||
342 | @item Show mode (@option{--show}) | 345 | @item Show mode (@option{-show}) |
343 | If an appropriate mhn-show-type[/subtype] was not found, GNU @command{mhn} | 346 | If an appropriate mhn-show-type[/subtype] was not found, GNU @command{mhn} |
344 | prints the decoded message content using @code{moreproc} | 347 | prints the decoded message content using @code{moreproc} |
345 | variable. Standard @command{mhn} in this case used to print @samp{don't | 348 | variable. Standard @command{mhn} in this case used to print @samp{don't |
... | @@ -349,47 +352,28 @@ The default behaviour is to pipe the content to the standard input | ... | @@ -349,47 +352,28 @@ The default behaviour is to pipe the content to the standard input |
349 | of the mhn-show-type[/subtype] command. This is altered to using a | 352 | of the mhn-show-type[/subtype] command. This is altered to using a |
350 | temporary file if the command contains @code{%f} or @code{%F} escapes. | 353 | temporary file if the command contains @code{%f} or @code{%F} escapes. |
351 | 354 | ||
352 | @item Store mode (@option{--store}) | 355 | @item Store mode (@option{-store}) |
353 | If the @code{Content-Disposition} header contains @samp{filename=}, | 356 | If the @code{Content-Disposition} header contains @samp{filename=}, |
354 | and @command{mhn} is invoked with @option{--auto} switch, it | 357 | and @command{mhn} is invoked with @option{-auto} switch, it |
355 | transforms the file name into the absolute notation and uses it only | 358 | transforms the file name into the absolute notation and uses it only |
356 | if it lies below the current mhn-storage directory. Standard | 359 | if it lies below the current mhn-storage directory. Standard |
357 | @command{mhn} only requires that the file name do not begin with @samp{/}. | 360 | @command{mhn} only requires that the file name do not begin with @samp{/}. |
358 | 361 | ||
359 | Before saving a message part, GNU @command{mhn} checks if the file already | 362 | Before saving a message part, GNU @command{mhn} checks if the file already |
360 | exists. If so, it asks whether the user wishes to rewrite it. This | 363 | exists. If so, it asks whether the user wishes to rewrite it. This |
361 | behaviour is disabled when @option{--quiet} option was given. | 364 | behaviour is disabled when @option{-quiet} option was given. |
362 | @end itemize | 365 | @end itemize |
363 | 366 | ||
364 | @item mhparam | 367 | @item mhparam |
365 | 368 | ||
366 | The @option{--all} mode does not display commented out entries. | 369 | The @option{-all} mode does not display commented out entries. |
367 | 370 | ||
368 | @item pick | 371 | @item pick |
369 | 372 | ||
370 | The command line syntax @option{--@var{component} @var{string}}) is | 373 | New command line option @option{-cflags} allows to control the type of |
371 | recognized only if at least one of the following conditions is met: | ||
372 | |||
373 | @itemize @bullet | ||
374 | @item The word @var{component} contains at least one capital letter. | ||
375 | E.g. @option{--User-Agent Mailutils}. | ||
376 | |||
377 | @item The word @var{component} ends with a colon, as in | ||
378 | @option{user-agent: Mailutils}. | ||
379 | |||
380 | @item Standard input is not connected to a terminal. | ||
381 | @end itemize | ||
382 | |||
383 | The GNU syntax for component matching is: | ||
384 | |||
385 | @smallexample | ||
386 | pick --component @var{field} --pattern @var{string} | ||
387 | @end smallexample | ||
388 | |||
389 | New command line option @option{--cflags} allows to control the type of | ||
390 | regular expressions used. The option must occur right before | 374 | regular expressions used. The option must occur right before |
391 | @option{--pattern} or @option{--component} option (or one of its | 375 | @option{--@var{component} @var{pattern}} or equivalent construct (like |
392 | aliases, like @option{--cc}, @option{--from}, etc.) | 376 | @option{-cc}, @option{-from}, etc.) |
393 | 377 | ||
394 | The argument to this option is a string of type specifications: | 378 | The argument to this option is a string of type specifications: |
395 | 379 | ||
... | @@ -402,24 +386,24 @@ The argument to this option is a string of type specifications: | ... | @@ -402,24 +386,24 @@ The argument to this option is a string of type specifications: |
402 | 386 | ||
403 | Default is @samp{EI}. | 387 | Default is @samp{EI}. |
404 | 388 | ||
405 | The flags remain in effect until the next occurrence of @option{--cflags} | 389 | The flags remain in effect until the next occurrence of @option{-cflags} |
406 | option. | 390 | option. |
407 | 391 | ||
408 | Sample usage: | 392 | Sample usage: |
409 | 393 | ||
410 | @smallexample | 394 | @smallexample |
411 | pick --cflag BC --subject '*a string' | 395 | pick -cflag BC -subject '*a string' |
412 | @end smallexample | 396 | @end smallexample |
413 | 397 | ||
414 | The date comparison options (@option{--before} and @option{--after} | 398 | The date comparison options (@option{-before} and @option{-after} |
415 | accept date specifications in a wide variety of formats, e.g.: | 399 | accept date specifications in a wide variety of formats, e.g.: |
416 | 400 | ||
417 | @smallexample | 401 | @smallexample |
418 | pick --after 20030301 | 402 | pick -after 20030301 |
419 | pick --after 2003-03-01 | 403 | pick -after 2003-03-01 |
420 | pick --after 01-mar-2003 | 404 | pick -after 01-mar-2003 |
421 | pick --after 2003-mar-01 | 405 | pick -after 2003-mar-01 |
422 | pick --before '1 year ago' | 406 | pick -before '1 year ago' |
423 | etc... | 407 | etc... |
424 | @end smallexample | 408 | @end smallexample |
425 | 409 | ||
... | @@ -454,11 +438,11 @@ will add it automatically. | ... | @@ -454,11 +438,11 @@ will add it automatically. |
454 | @item | 438 | @item |
455 | Linking messages between folders goes against the logic of Mailutils, | 439 | Linking messages between folders goes against the logic of Mailutils, |
456 | so @command{refile} never makes links even if called with | 440 | so @command{refile} never makes links even if called with |
457 | @option{--link} option. The latter is actually a synonym for @option{--copy}, | 441 | @option{-link} option. The latter is actually a synonym for @option{-copy}, |
458 | which preserves the original message. | 442 | which preserves the original message. |
459 | 443 | ||
460 | @item | 444 | @item |
461 | The @option{--preserve} option is not implemented. It is retained for backward | 445 | The @option{-preserve} option is not implemented. It is retained for backward |
462 | compatibility only. | 446 | compatibility only. |
463 | 447 | ||
464 | @item | 448 | @item |
... | @@ -467,7 +451,7 @@ Message specs and folder names may be interspersed. | ... | @@ -467,7 +451,7 @@ Message specs and folder names may be interspersed. |
467 | 451 | ||
468 | @item repl | 452 | @item repl |
469 | 453 | ||
470 | Understands @option{--use} option. Disposition shell provides | 454 | Understands @option{-use} option. Disposition shell provides |
471 | @code{use} command. | 455 | @code{use} command. |
472 | 456 | ||
473 | @item rmm | 457 | @item rmm |
... | @@ -491,14 +475,14 @@ rmmproc: | ... | @@ -491,14 +475,14 @@ rmmproc: |
491 | 475 | ||
492 | @item sortm | 476 | @item sortm |
493 | 477 | ||
494 | New option @option{--numfield} specifies numeric comparison for the | 478 | New option @option{-numfield} specifies numeric comparison for the |
495 | given field. | 479 | given field. |
496 | 480 | ||
497 | Any number of @option{--datefield}, @option{--textfield} and | 481 | Any number of @option{-datefield}, @option{-textfield} and |
498 | @option{--numfield} options may be given, thus allowing to build sort | 482 | @option{-numfield} options may be given, thus allowing to build sort |
499 | criteria of arbitrary complexity. | 483 | criteria of arbitrary complexity. |
500 | 484 | ||
501 | The order of @option{--.*field} options sets the ordering priority. This | 485 | The order of @option{-.*field} options sets the ordering priority. This |
502 | differs from the behaviour of the standard @command{sortm}, which | 486 | differs from the behaviour of the standard @command{sortm}, which |
503 | always orders datefield-major, textfield-minor. | 487 | always orders datefield-major, textfield-minor. |
504 | 488 | ||
... | @@ -506,11 +490,11 @@ Apart from sorting the mailfolder the following actions may be | ... | @@ -506,11 +490,11 @@ Apart from sorting the mailfolder the following actions may be |
506 | specified: | 490 | specified: |
507 | 491 | ||
508 | @table @option | 492 | @table @option |
509 | @item --list | 493 | @item -list |
510 | List the ordered messages using a format string given by | 494 | List the ordered messages using a format string given by |
511 | @option{--form} or @option{--format} option. | 495 | @option{-form} or @option{-format} option. |
512 | 496 | ||
513 | @item --dry-run | 497 | @item -dry-run |
514 | Do not actually sort messages, rather print what would have been | 498 | Do not actually sort messages, rather print what would have been |
515 | done. This is useful for debugging purposes. | 499 | done. This is useful for debugging purposes. |
516 | @end table | 500 | @end table | ... | ... |
... | @@ -71,7 +71,7 @@ typedef struct mu_option_cache *mu_option_cache_ptr_t; | ... | @@ -71,7 +71,7 @@ typedef struct mu_option_cache *mu_option_cache_ptr_t; |
71 | struct mu_option_cache | 71 | struct mu_option_cache |
72 | { | 72 | { |
73 | struct mu_option *cache_opt; | 73 | struct mu_option *cache_opt; |
74 | char *cache_arg; | 74 | char const *cache_arg; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | #define MU_PARSEOPT_DEFAULT 0 | 77 | #define MU_PARSEOPT_DEFAULT 0 | ... | ... |
... | @@ -136,7 +136,6 @@ static void | ... | @@ -136,7 +136,6 @@ static void |
136 | mu_option_cache_destroy (void *ptr) | 136 | mu_option_cache_destroy (void *ptr) |
137 | { | 137 | { |
138 | struct mu_option_cache *cache = ptr; | 138 | struct mu_option_cache *cache = ptr; |
139 | free (cache->cache_arg); | ||
140 | free (cache); | 139 | free (cache); |
141 | } | 140 | } |
142 | 141 | ||
... | @@ -150,7 +149,7 @@ add_option_cache (struct mu_parseopt *po, struct mu_option *opt, | ... | @@ -150,7 +149,7 @@ add_option_cache (struct mu_parseopt *po, struct mu_option *opt, |
150 | { | 149 | { |
151 | struct mu_option_cache *cache = mu_alloc (sizeof (*cache)); | 150 | struct mu_option_cache *cache = mu_alloc (sizeof (*cache)); |
152 | cache->cache_opt = opt; | 151 | cache->cache_opt = opt; |
153 | cache->cache_arg = arg ? mu_strdup (arg) : NULL; | 152 | cache->cache_arg = arg; |
154 | 153 | ||
155 | if ((po->po_flags & MU_PARSEOPT_IMMEDIATE) | 154 | if ((po->po_flags & MU_PARSEOPT_IMMEDIATE) |
156 | || (opt->opt_flags & MU_OPTION_IMMEDIATE)) | 155 | || (opt->opt_flags & MU_OPTION_IMMEDIATE)) |
... | @@ -774,7 +773,7 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, | ... | @@ -774,7 +773,7 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, |
774 | free (errmsg); | 773 | free (errmsg); |
775 | 774 | ||
776 | if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT)) | 775 | if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT)) |
777 | exit (EXIT_ERROR); | 776 | exit (po->po_exit_error); |
778 | } | 777 | } |
779 | } | 778 | } |
780 | } | 779 | } | ... | ... |
... | @@ -79,6 +79,23 @@ augment_argv (int *pargc, char ***pargv) | ... | @@ -79,6 +79,23 @@ augment_argv (int *pargc, char ***pargv) |
79 | } | 79 | } |
80 | 80 | ||
81 | static void | 81 | static void |
82 | process_std_options (int argc, char **argv, struct mu_parseopt *po) | ||
83 | { | ||
84 | if (argc != 1) | ||
85 | return; | ||
86 | if (strcmp (argv[0], "--help") == 0) | ||
87 | { | ||
88 | mu_program_help (po, mu_strout); | ||
89 | exit (0); | ||
90 | } | ||
91 | if (strcmp (argv[0], "--version") == 0) | ||
92 | { | ||
93 | mu_program_version (po, mu_strout); | ||
94 | exit (0); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | static void | ||
82 | process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po) | 99 | process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po) |
83 | { | 100 | { |
84 | int i, j; | 101 | int i, j; |
... | @@ -109,8 +126,9 @@ process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po) | ... | @@ -109,8 +126,9 @@ process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po) |
109 | *pargc = j; | 126 | *pargc = j; |
110 | } | 127 | } |
111 | 128 | ||
112 | static void | 129 | void |
113 | set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | 130 | mh_opt_set_folder (struct mu_parseopt *po, struct mu_option *opt, |
131 | char const *arg) | ||
114 | { | 132 | { |
115 | mh_set_current_folder (arg); | 133 | mh_set_current_folder (arg); |
116 | } | 134 | } |
... | @@ -118,7 +136,45 @@ set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ... | @@ -118,7 +136,45 @@ set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
118 | static struct mu_option folder_option[] = { | 136 | static struct mu_option folder_option[] = { |
119 | { "folder", 0, NULL, MU_OPTION_DEFAULT, | 137 | { "folder", 0, NULL, MU_OPTION_DEFAULT, |
120 | N_("set current folder"), | 138 | N_("set current folder"), |
121 | mu_c_string, NULL, set_folder }, | 139 | mu_c_string, NULL, mh_opt_set_folder }, |
140 | MU_OPTION_END | ||
141 | }; | ||
142 | |||
143 | void | ||
144 | mh_version_hook (struct mu_parseopt *po, mu_stream_t stream) | ||
145 | { | ||
146 | extern const char mu_version_copyright[]; | ||
147 | #ifdef GIT_DESCRIBE | ||
148 | mu_stream_printf (stream, "%s (GNU MH, %s) %s [%s]\n", | ||
149 | mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, | ||
150 | GIT_DESCRIBE); | ||
151 | #else | ||
152 | mu_stream_printf (stream, "%s (GNU MH, %s) %s\n", mu_program_name, | ||
153 | PACKAGE_NAME, PACKAGE_VERSION); | ||
154 | #endif | ||
155 | /* TRANSLATORS: Translate "(C)" to the copyright symbol | ||
156 | (C-in-a-circle), if this symbol is available in the user's | ||
157 | locale. Otherwise, do not translate "(C)"; leave it as-is. */ | ||
158 | mu_stream_printf (stream, mu_version_copyright, _("(C)")); | ||
159 | mu_stream_printf (stream, _("\ | ||
160 | \n\ | ||
161 | License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\n\ | ||
162 | There is NO WARRANTY, to the extent permitted by law.\n\ | ||
163 | \n\ | ||
164 | ")); | ||
165 | } | ||
166 | |||
167 | static void | ||
168 | fn_version (struct mu_parseopt *po, struct mu_option *opt, char const *unused) | ||
169 | { | ||
170 | mu_program_version (po, mu_strout); | ||
171 | exit (0); | ||
172 | } | ||
173 | |||
174 | static struct mu_option version_option[] = { | ||
175 | { "version", 0, NULL, MU_OPTION_DEFAULT, | ||
176 | N_("print program version"), | ||
177 | mu_c_string, NULL, fn_version }, | ||
122 | MU_OPTION_END | 178 | MU_OPTION_END |
123 | }; | 179 | }; |
124 | 180 | ||
... | @@ -132,7 +188,7 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, | ... | @@ -132,7 +188,7 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, |
132 | struct mu_parseopt po; | 188 | struct mu_parseopt po; |
133 | struct mu_option *optv[3]; | 189 | struct mu_option *optv[3]; |
134 | struct getopt_data getopt_data; | 190 | struct getopt_data getopt_data; |
135 | char const *args[2]; | 191 | char const *args[3]; |
136 | int flags = MU_PARSEOPT_SINGLE_DASH | MU_PARSEOPT_IMMEDIATE; | 192 | int flags = MU_PARSEOPT_SINGLE_DASH | MU_PARSEOPT_IMMEDIATE; |
137 | int i; | 193 | int i; |
138 | 194 | ||
... | @@ -177,6 +233,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, | ... | @@ -177,6 +233,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, |
177 | //po.po_extra_info = gnu_general_help_url; | 233 | //po.po_extra_info = gnu_general_help_url; |
178 | //flags |= MU_PARSEOPT_EXTRA_INFO; | 234 | //flags |= MU_PARSEOPT_EXTRA_INFO; |
179 | 235 | ||
236 | po.po_version_hook = mh_version_hook; | ||
237 | flags |= MU_PARSEOPT_VERSION_HOOK; | ||
238 | |||
180 | mu_set_program_name (argv[0]); | 239 | mu_set_program_name (argv[0]); |
181 | mh_init (); | 240 | mh_init (); |
182 | augment_argv (&argc, &argv); | 241 | augment_argv (&argc, &argv); |
... | @@ -184,7 +243,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, | ... | @@ -184,7 +243,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, |
184 | i = 0; | 243 | i = 0; |
185 | if (mhflags & MH_GETOPT_DEFAULT_FOLDER) | 244 | if (mhflags & MH_GETOPT_DEFAULT_FOLDER) |
186 | optv[i++] = folder_option; | 245 | optv[i++] = folder_option; |
187 | optv[i++] = options; | 246 | if (options) |
247 | optv[i++] = options; | ||
248 | optv[i++] = version_option; | ||
188 | optv[i] = NULL; | 249 | optv[i] = NULL; |
189 | 250 | ||
190 | if (mu_parseopt (&po, argc, argv, optv, flags)) | 251 | if (mu_parseopt (&po, argc, argv, optv, flags)) |
... | @@ -193,6 +254,8 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, | ... | @@ -193,6 +254,8 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, |
193 | argc -= po.po_arg_start; | 254 | argc -= po.po_arg_start; |
194 | argv += po.po_arg_start; | 255 | argv += po.po_arg_start; |
195 | 256 | ||
257 | process_std_options (argc, argv, &po); | ||
258 | |||
196 | process_folder_arg (&argc, argv, &po); | 259 | process_folder_arg (&argc, argv, &po); |
197 | 260 | ||
198 | if (!argdoc && argc) | 261 | if (!argdoc && argc) | ... | ... |
... | @@ -35,5 +35,7 @@ void mh_opt_find_file (struct mu_parseopt *po, struct mu_option *opt, | ... | @@ -35,5 +35,7 @@ void mh_opt_find_file (struct mu_parseopt *po, struct mu_option *opt, |
35 | char const *arg); | 35 | char const *arg); |
36 | void mh_opt_read_formfile (struct mu_parseopt *po, struct mu_option *opt, | 36 | void mh_opt_read_formfile (struct mu_parseopt *po, struct mu_option *opt, |
37 | char const *arg); | 37 | char const *arg); |
38 | void mh_opt_set_folder (struct mu_parseopt *po, struct mu_option *opt, | ||
39 | char const *arg); | ||
38 | 40 | ||
39 | 41 | ... | ... |
... | @@ -22,99 +22,9 @@ | ... | @@ -22,99 +22,9 @@ |
22 | #include <mailutils/mime.h> | 22 | #include <mailutils/mime.h> |
23 | #include <setjmp.h> | 23 | #include <setjmp.h> |
24 | 24 | ||
25 | static char doc[] = N_("GNU MH mhn")"\v" | 25 | static char prog_doc[] = N_("GNU MH mhn"); |
26 | N_("Options marked with `*' are not yet implemented.\n\ | ||
27 | Use -help to obtain the list of traditional MH options."); | ||
28 | static char args_doc[] = N_("[MSGLIST]"); | 26 | static char args_doc[] = N_("[MSGLIST]"); |
29 | 27 | ||
30 | static struct argp_option options[] = { | ||
31 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
32 | N_("specify folder to operate upon"), 0}, | ||
33 | {"file", ARG_FILE, N_("FILE"), 0, | ||
34 | N_("specify file to operate upon"), 0}, | ||
35 | |||
36 | #define GRID 10 | ||
37 | {N_("MIME editing options"), 0, NULL, OPTION_DOC, NULL, GRID}, | ||
38 | {"compose", ARG_COMPOSE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
39 | N_("compose the MIME message (default)"), GRID+1}, | ||
40 | {"build", 0, NULL, OPTION_ALIAS, | ||
41 | NULL, GRID+1 }, | ||
42 | {"nocompose", ARG_NOCOMPOSE, NULL, OPTION_HIDDEN, NULL, GRID+1}, | ||
43 | {"nobuild", ARG_NOCOMPOSE, NULL, OPTION_HIDDEN|OPTION_ALIAS, | ||
44 | NULL, GRID+1}, | ||
45 | #undef GRID | ||
46 | #define GRID 20 | ||
47 | {N_("Listing options"), 0, NULL, OPTION_DOC, NULL, GRID}, | ||
48 | {"list", ARG_LIST, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
49 | N_("list the table of contents"), GRID+1 }, | ||
50 | {"nolist", ARG_NOLIST, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
51 | {"headers", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
52 | N_("print the banner above the listing"), GRID+1 }, | ||
53 | {"noheaders", ARG_NOHEADERS, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
54 | {"realsize", ARG_REALSIZE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
55 | N_("list the decoded sizes"), GRID+1 }, | ||
56 | {"norealsize", ARG_NOREALSIZE, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
57 | #undef GRID | ||
58 | #define GRID 40 | ||
59 | {N_("Display options"), 0, NULL, OPTION_DOC, NULL, GRID}, | ||
60 | {"show", ARG_SHOW, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
61 | N_("display the contents of the messages"), GRID+1}, | ||
62 | {"noshow", ARG_NOSHOW, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
63 | {"serialonly", ARG_SERIALONLY, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
64 | N_("* display messages serially"), GRID+1}, | ||
65 | {"noserialonly", ARG_NOSERIALONLY, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
66 | {"form", ARG_FORM, N_("FILE"), 0, | ||
67 | N_("read mhl format from FILE"), GRID+1}, | ||
68 | {"pause", ARG_PAUSE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
69 | N_("pause prior to displaying content"), GRID+1}, | ||
70 | {"nopause", ARG_NOPAUSE, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
71 | #undef GRID | ||
72 | #define GRID 50 | ||
73 | {N_("Saving options"), 0, NULL, OPTION_DOC, NULL, GRID}, | ||
74 | {"store", ARG_STORE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
75 | N_("write extracted message parts to disk"), GRID+1}, | ||
76 | {"nostore", ARG_NOSTORE, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
77 | {"auto", ARG_AUTO, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
78 | N_("use filenames from the content headers"), GRID+1}, | ||
79 | {"noauto", ARG_NOAUTO, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
80 | {"charset", ARG_CHARSET, N_("NAME"), 0, | ||
81 | N_("use this charset to represent attachment file names"), GRID+1}, | ||
82 | #undef GRID | ||
83 | #define GRID 60 | ||
84 | {N_("Other options"), 0, NULL, OPTION_DOC, NULL, GRID}, | ||
85 | {"part", ARG_PART, N_("PART"), 0, | ||
86 | N_("limit the scope of the operation to the given part"), GRID+1}, | ||
87 | {"type", ARG_TYPE, N_("CONTENT"), 0, | ||
88 | N_("operate on message part with given multipart content"), GRID+1 }, | ||
89 | {"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
90 | N_("print additional information"), GRID+1 }, | ||
91 | {"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
92 | {"quiet", ARG_QUIET, 0, 0, | ||
93 | N_("be quiet"), GRID+1}, | ||
94 | #undef GRID | ||
95 | {NULL} | ||
96 | }; | ||
97 | |||
98 | /* Traditional MH options */ | ||
99 | struct mh_option mh_option[] = { | ||
100 | { "file", MH_OPT_ARG, "filename" }, | ||
101 | { "compose" }, | ||
102 | { "build" }, | ||
103 | { "list", MH_OPT_BOOL }, | ||
104 | { "headers", MH_OPT_BOOL }, | ||
105 | { "realsize", MH_OPT_BOOL }, | ||
106 | { "show", MH_OPT_BOOL }, | ||
107 | { "serialonly", MH_OPT_BOOL }, | ||
108 | { "form", MH_OPT_ARG, "formfile" }, | ||
109 | { "pause", MH_OPT_BOOL }, | ||
110 | { "store", MH_OPT_BOOL }, | ||
111 | { "auto", MH_OPT_BOOL }, | ||
112 | { "part", MH_OPT_ARG, "part" }, | ||
113 | { "type", MH_OPT_ARG, "type" }, | ||
114 | { "verbose", MH_OPT_BOOL }, | ||
115 | { NULL } | ||
116 | }; | ||
117 | |||
118 | typedef struct _msg_part *msg_part_t; | 28 | typedef struct _msg_part *msg_part_t; |
119 | 29 | ||
120 | static msg_part_t msg_part_create (size_t num); | 30 | static msg_part_t msg_part_create (size_t num); |
... | @@ -124,28 +34,22 @@ static void msg_part_incr (msg_part_t p); | ... | @@ -124,28 +34,22 @@ static void msg_part_incr (msg_part_t p); |
124 | static void msg_part_decr (msg_part_t p); | 34 | static void msg_part_decr (msg_part_t p); |
125 | static void msg_part_set_subpart (msg_part_t p, size_t subpart); | 35 | static void msg_part_set_subpart (msg_part_t p, size_t subpart); |
126 | static void msg_part_print (msg_part_t p, int width); | 36 | static void msg_part_print (msg_part_t p, int width); |
127 | static msg_part_t msg_part_parse (char *str); | 37 | static msg_part_t msg_part_parse (char const *str); |
128 | static int msg_part_level (msg_part_t p); | 38 | static int msg_part_level (msg_part_t p); |
129 | static size_t msg_part_subpart (msg_part_t p, int level); | 39 | static size_t msg_part_subpart (msg_part_t p, int level); |
130 | 40 | ||
131 | enum mhn_mode | 41 | static int compose_option; |
132 | { | 42 | static int list_option; |
133 | mode_compose, | 43 | static int show_option; |
134 | mode_list, | 44 | static int store_option; |
135 | mode_show, | ||
136 | mode_store, | ||
137 | }; | ||
138 | |||
139 | static enum mhn_mode mode = mode_compose; | ||
140 | 45 | ||
141 | #define OPT_HEADERS 001 | 46 | static int headers_option = 1; |
142 | #define OPT_REALSIZE 002 | 47 | static int realsize_option; |
143 | #define OPT_AUTO 004 | 48 | static int auto_option; |
144 | #define OPT_SERIALONLY 010 | 49 | /*static int serialonly_option;*/ |
145 | #define OPT_VERBOSE 020 | 50 | static int verbose_option; |
146 | #define OPT_QUIET 040 | 51 | static int quiet_option; |
147 | 52 | ||
148 | static int mode_options = OPT_HEADERS; | ||
149 | static int pause_option = -1; /* -pause option. -1 means "not given" */ | 53 | static int pause_option = -1; /* -pause option. -1 means "not given" */ |
150 | static char *formfile; | 54 | static char *formfile; |
151 | static char *content_type; | 55 | static char *content_type; |
... | @@ -260,173 +164,88 @@ _get_content_encoding (mu_header_t hdr, char **value) | ... | @@ -260,173 +164,88 @@ _get_content_encoding (mu_header_t hdr, char **value) |
260 | *value = encoding; | 164 | *value = encoding; |
261 | return 0; | 165 | return 0; |
262 | } | 166 | } |
263 | 167 | ||
264 | static error_t | 168 | static void |
265 | opt_handler (int key, char *arg, struct argp_state *state) | 169 | set_part (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
266 | { | 170 | { |
267 | switch (key) | 171 | req_part = msg_part_parse (arg); |
268 | { | ||
269 | case ARG_FOLDER: | ||
270 | mh_set_current_folder (arg); | ||
271 | break; | ||
272 | |||
273 | case ARG_FILE: | ||
274 | input_file = arg; | ||
275 | break; | ||
276 | |||
277 | /* Operation mode */ | ||
278 | case ARG_COMPOSE: | ||
279 | if (is_true (arg)) | ||
280 | { | ||
281 | mode = mode_compose; | ||
282 | break; | ||
283 | } | ||
284 | /*FALLTHRU*/ | ||
285 | case ARG_NOCOMPOSE: | ||
286 | if (mode == mode_compose) | ||
287 | mode = mode_compose; | ||
288 | break; | ||
289 | |||
290 | case ARG_LIST: | ||
291 | if (is_true (arg)) | ||
292 | { | ||
293 | mode = mode_list; | ||
294 | break; | ||
295 | } | ||
296 | /*FALLTHRU*/ | ||
297 | case ARG_NOLIST: | ||
298 | if (mode == mode_list) | ||
299 | mode = mode_compose; | ||
300 | break; | ||
301 | |||
302 | case ARG_SHOW: | ||
303 | if (is_true (arg)) | ||
304 | { | ||
305 | mode = mode_show; | ||
306 | break; | ||
307 | } | ||
308 | /*FALLTHRU*/ | ||
309 | case ARG_NOSHOW: | ||
310 | if (mode == mode_show) | ||
311 | mode = mode_compose; | ||
312 | break; | ||
313 | |||
314 | case ARG_STORE: | ||
315 | if (is_true (arg)) | ||
316 | { | ||
317 | mode = mode_store; | ||
318 | break; | ||
319 | } | ||
320 | /*FALLTHRU*/ | ||
321 | case ARG_NOSTORE: | ||
322 | if (mode == mode_store) | ||
323 | mode = mode_compose; | ||
324 | break; | ||
325 | |||
326 | /* List options */ | ||
327 | case ARG_HEADER: | ||
328 | if (is_true (arg)) | ||
329 | { | ||
330 | mode_options |= OPT_HEADERS; | ||
331 | break; | ||
332 | } | ||
333 | /*FALLTHRU*/ | ||
334 | case ARG_NOHEADERS: | ||
335 | mode_options &= ~OPT_HEADERS; | ||
336 | break; | ||
337 | |||
338 | case ARG_REALSIZE: | ||
339 | if (is_true (arg)) | ||
340 | { | ||
341 | mode_options |= OPT_REALSIZE; | ||
342 | break; | ||
343 | } | ||
344 | /*FALLTHRU*/ | ||
345 | case ARG_NOREALSIZE: | ||
346 | mode_options &= ~OPT_REALSIZE; | ||
347 | break; | ||
348 | |||
349 | /* Display options */ | ||
350 | |||
351 | case ARG_SERIALONLY: | ||
352 | mh_opt_notimpl_warning ("-[no]serialonly"); | ||
353 | if (is_true (arg)) | ||
354 | { | ||
355 | mode_options |= OPT_SERIALONLY; | ||
356 | break; | ||
357 | } | ||
358 | /*FALLTHRU*/ | ||
359 | case ARG_NOSERIALONLY: | ||
360 | mode_options &= ~OPT_SERIALONLY; | ||
361 | break; | ||
362 | |||
363 | case ARG_PAUSE: | ||
364 | pause_option = is_true (arg); | ||
365 | break; | ||
366 | |||
367 | case ARG_NOPAUSE: | ||
368 | pause_option = 0; | ||
369 | break; | ||
370 | |||
371 | /* Store options */ | ||
372 | case ARG_AUTO: | ||
373 | if (is_true (arg)) | ||
374 | { | ||
375 | mode_options |= OPT_AUTO; | ||
376 | break; | ||
377 | } | ||
378 | /*FALLTHRU*/ | ||
379 | case ARG_NOAUTO: | ||
380 | mode_options &= ~OPT_AUTO; | ||
381 | break; | ||
382 | |||
383 | case ARG_FORM: | ||
384 | mh_find_file (arg, &formfile); | ||
385 | break; | ||
386 | |||
387 | /* Common options */ | ||
388 | case ARG_VERBOSE: | ||
389 | if (is_true (arg)) | ||
390 | { | ||
391 | mode_options |= OPT_VERBOSE; | ||
392 | break; | ||
393 | } | ||
394 | /*FALLTHRU*/ | ||
395 | case ARG_NOVERBOSE: | ||
396 | mode_options &= ~OPT_VERBOSE; | ||
397 | break; | ||
398 | |||
399 | case ARG_TYPE: | ||
400 | sfree (&content_type); | ||
401 | sfree (&content_subtype); | ||
402 | split_content (arg, &content_type, &content_subtype); | ||
403 | break; | ||
404 | |||
405 | case ARG_PART: | ||
406 | req_part = msg_part_parse (arg); | ||
407 | break; | ||
408 | |||
409 | case ARG_QUIET: | ||
410 | mode_options |= OPT_QUIET; | ||
411 | break; | ||
412 | |||
413 | case ARG_CHARSET: | ||
414 | charset = arg; | ||
415 | break; | ||
416 | |||
417 | case ARGP_KEY_FINI: | ||
418 | if (!formfile) | ||
419 | mh_find_file ("mhl.headers", &formfile); | ||
420 | if (!isatty (0)) | ||
421 | pause_option = 0; | ||
422 | break; | ||
423 | |||
424 | default: | ||
425 | return ARGP_ERR_UNKNOWN; | ||
426 | } | ||
427 | return 0; | ||
428 | } | 172 | } |
429 | 173 | ||
174 | static void | ||
175 | set_type (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
176 | { | ||
177 | sfree (&content_type); | ||
178 | sfree (&content_subtype); | ||
179 | split_content (arg, &content_type, &content_subtype); | ||
180 | } | ||
181 | |||
182 | static struct mu_option options[] = { | ||
183 | { "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
184 | N_("specify folder to operate upon"), | ||
185 | mu_c_string, NULL, mh_opt_set_folder }, | ||
186 | { "file", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
187 | N_("specify file to operate upon"), | ||
188 | mu_c_string, &input_file }, | ||
189 | |||
190 | MU_OPTION_GROUP (N_("MIME editing options")), | ||
191 | { "compose", 0, NULL, MU_OPTION_DEFAULT, | ||
192 | N_("compose the MIME message (default)"), | ||
193 | mu_c_bool, &compose_option }, | ||
194 | { "build", 0, NULL, MU_OPTION_ALIAS }, | ||
195 | |||
196 | MU_OPTION_GROUP (N_("Listing options")), | ||
197 | { "list", 0, NULL, MU_OPTION_DEFAULT, | ||
198 | N_("list the table of contents"), | ||
199 | mu_c_bool, &list_option }, | ||
200 | { "headers", 0, NULL, MU_OPTION_DEFAULT, | ||
201 | N_("print the banner above the listing"), | ||
202 | mu_c_bool, &headers_option }, | ||
203 | { "realsize", 0, NULL, MU_OPTION_DEFAULT, | ||
204 | N_("list the decoded sizes"), | ||
205 | mu_c_bool, &realsize_option }, | ||
206 | |||
207 | MU_OPTION_GROUP (N_("Display options")), | ||
208 | { "show", 0, NULL, MU_OPTION_DEFAULT, | ||
209 | N_("display the contents of the messages"), | ||
210 | mu_c_bool, &show_option }, | ||
211 | { "serialonly", 0, NULL, MU_OPTION_HIDDEN, | ||
212 | "", | ||
213 | mu_c_bool, NULL, mh_opt_notimpl_warning }, | ||
214 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
215 | N_("read mhl format from FILE"), | ||
216 | mu_c_string, &formfile, mh_opt_find_file }, | ||
217 | { "pause", 0, NULL, MU_OPTION_DEFAULT, | ||
218 | N_("pause prior to displaying content"), | ||
219 | mu_c_bool, &pause_option }, | ||
220 | |||
221 | MU_OPTION_GROUP (N_("Saving options")), | ||
222 | { "store", 0, NULL, MU_OPTION_DEFAULT, | ||
223 | N_("write extracted message parts to disk"), | ||
224 | mu_c_bool, &store_option }, | ||
225 | { "auto", 0, NULL, MU_OPTION_DEFAULT, | ||
226 | N_("use filenames from the content headers"), | ||
227 | mu_c_bool, &auto_option }, | ||
228 | { "charset", 0, N_("NAME"), MU_OPTION_DEFAULT, | ||
229 | N_("use this charset to represent attachment file names"), | ||
230 | mu_c_string, &charset }, | ||
231 | |||
232 | MU_OPTION_GROUP (N_("Other options")), | ||
233 | { "part", 0, N_("PART"), MU_OPTION_DEFAULT, | ||
234 | N_("limit the scope of the operation to the given part"), | ||
235 | mu_c_string, NULL, set_part }, | ||
236 | { "type", 0, N_("CONTENT"), MU_OPTION_DEFAULT, | ||
237 | N_("operate on message part with given multipart content"), | ||
238 | mu_c_string, NULL, set_type }, | ||
239 | { "verbose", 0, NULL, MU_OPTION_DEFAULT, | ||
240 | N_("print additional information"), | ||
241 | mu_c_bool, &verbose_option }, | ||
242 | { "quiet", 0, NULL, MU_OPTION_DEFAULT, | ||
243 | N_("be quiet"), | ||
244 | mu_c_bool, &quiet_option }, | ||
245 | |||
246 | MU_OPTION_END | ||
247 | }; | ||
248 | |||
430 | 249 | ||
431 | /* *********************** Message part functions ************************* */ | 250 | /* *********************** Message part functions ************************* */ |
432 | 251 | ||
... | @@ -555,7 +374,7 @@ msg_part_format_pool (mu_opool_t pool, msg_part_t p) | ... | @@ -555,7 +374,7 @@ msg_part_format_pool (mu_opool_t pool, msg_part_t p) |
555 | } | 374 | } |
556 | 375 | ||
557 | msg_part_t | 376 | msg_part_t |
558 | msg_part_parse (char *str) | 377 | msg_part_parse (char const *str) |
559 | { | 378 | { |
560 | msg_part_t p = msg_part_create (0); | 379 | msg_part_t p = msg_part_create (0); |
561 | 380 | ||
... | @@ -1267,7 +1086,7 @@ mhn_message_size (mu_message_t msg, mu_off_t *psize) | ... | @@ -1267,7 +1086,7 @@ mhn_message_size (mu_message_t msg, mu_off_t *psize) |
1267 | 1086 | ||
1268 | *psize = 0; | 1087 | *psize = 0; |
1269 | mu_message_get_body (msg, &body); | 1088 | mu_message_get_body (msg, &body); |
1270 | if (mode_options & OPT_REALSIZE) | 1089 | if (realsize_option) |
1271 | { | 1090 | { |
1272 | mu_stream_t dstr = NULL, bstr = NULL; | 1091 | mu_stream_t dstr = NULL, bstr = NULL; |
1273 | 1092 | ||
... | @@ -1389,7 +1208,7 @@ mhn_list () | ... | @@ -1389,7 +1208,7 @@ mhn_list () |
1389 | { | 1208 | { |
1390 | int rc; | 1209 | int rc; |
1391 | 1210 | ||
1392 | if (mode_options & OPT_HEADERS) | 1211 | if (headers_option) |
1393 | printf (_(" msg part type/subtype size description\n")); | 1212 | printf (_(" msg part type/subtype size description\n")); |
1394 | 1213 | ||
1395 | if (message) | 1214 | if (message) |
... | @@ -1672,7 +1491,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, | ... | @@ -1672,7 +1491,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, |
1672 | if (mu_message_is_multipart (msg, &ismime) == 0 && ismime) | 1491 | if (mu_message_is_multipart (msg, &ismime) == 0 && ismime) |
1673 | return 0; | 1492 | return 0; |
1674 | 1493 | ||
1675 | if (mode_options & OPT_AUTO) | 1494 | if (auto_option) |
1676 | { | 1495 | { |
1677 | char *val; | 1496 | char *val; |
1678 | int rc = mu_message_aget_decoded_attachment_name (msg, charset, | 1497 | int rc = mu_message_aget_decoded_attachment_name (msg, charset, |
... | @@ -1773,7 +1592,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, | ... | @@ -1773,7 +1592,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, |
1773 | printf (_("storing message %s part %s as file %s\n"), | 1592 | printf (_("storing message %s part %s as file %s\n"), |
1774 | prefix, partstr, name); | 1593 | prefix, partstr, name); |
1775 | 1594 | ||
1776 | if (!(mode_options & OPT_QUIET) && access (name, R_OK) == 0) | 1595 | if (!quiet_option && access (name, R_OK) == 0) |
1777 | { | 1596 | { |
1778 | int ok; | 1597 | int ok; |
1779 | 1598 | ||
... | @@ -2939,17 +2758,18 @@ int | ... | @@ -2939,17 +2758,18 @@ int |
2939 | main (int argc, char **argv) | 2758 | main (int argc, char **argv) |
2940 | { | 2759 | { |
2941 | int rc; | 2760 | int rc; |
2942 | int index; | ||
2943 | 2761 | ||
2944 | MU_APP_INIT_NLS (); | 2762 | MU_APP_INIT_NLS (); |
2945 | 2763 | ||
2946 | mh_argp_init (); | 2764 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
2947 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 2765 | if (!formfile) |
2948 | opt_handler, NULL, &index); | 2766 | mh_find_file ("mhl.headers", &formfile); |
2949 | 2767 | if (!isatty (0)) | |
2950 | argc -= index; | 2768 | pause_option = 0; |
2951 | argv += index; | ||
2952 | 2769 | ||
2770 | if (!compose_option && !list_option && !show_option && !store_option) | ||
2771 | show_option = 1; | ||
2772 | |||
2953 | signal (SIGPIPE, SIG_IGN); | 2773 | signal (SIGPIPE, SIG_IGN); |
2954 | 2774 | ||
2955 | if (input_file) | 2775 | if (input_file) |
... | @@ -2966,45 +2786,36 @@ main (int argc, char **argv) | ... | @@ -2966,45 +2786,36 @@ main (int argc, char **argv) |
2966 | if (!message) | 2786 | if (!message) |
2967 | return 1; | 2787 | return 1; |
2968 | } | 2788 | } |
2969 | else if (mode == mode_compose) | 2789 | |
2790 | if (compose_option) | ||
2970 | { | 2791 | { |
2971 | if (argc > 1) | 2792 | if (argc > 1) |
2972 | { | 2793 | { |
2973 | mu_error (_("extra arguments")); | 2794 | mu_error (_("extra arguments")); |
2974 | return 1; | 2795 | return 1; |
2975 | } | 2796 | } |
2976 | input_file = mh_expand_name (mu_folder_directory (), | 2797 | if (!input_file) |
2977 | argc == 1 ? argv[0] : "draft", NAME_ANY); | 2798 | { |
2978 | message = mh_file_to_message (NULL, input_file); | 2799 | input_file = mh_expand_name (mu_folder_directory (), |
2979 | if (!message) | 2800 | argc == 1 |
2980 | return 1; | 2801 | ? argv[0] : "draft", NAME_ANY); |
2802 | message = mh_file_to_message (NULL, input_file); | ||
2803 | if (!message) | ||
2804 | return 1; | ||
2805 | } | ||
2806 | rc = mhn_compose (); | ||
2981 | } | 2807 | } |
2982 | else | 2808 | else |
2983 | { | 2809 | { |
2984 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); | 2810 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); |
2985 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); | 2811 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); |
2986 | } | 2812 | /* FIXME: Combine the three */ |
2987 | 2813 | if (list_option) | |
2988 | switch (mode) | 2814 | rc = mhn_list (); |
2989 | { | 2815 | if (show_option) |
2990 | case mode_compose: | 2816 | rc |= mhn_show (); |
2991 | rc = mhn_compose (); | 2817 | if (store_option) |
2992 | break; | 2818 | rc |= mhn_store (); |
2993 | |||
2994 | case mode_list: | ||
2995 | rc = mhn_list (); | ||
2996 | break; | ||
2997 | |||
2998 | case mode_show: | ||
2999 | rc = mhn_show (); | ||
3000 | break; | ||
3001 | |||
3002 | case mode_store: | ||
3003 | rc = mhn_store (); | ||
3004 | break; | ||
3005 | |||
3006 | default: | ||
3007 | abort (); | ||
3008 | } | 2819 | } |
3009 | return rc ? 1 : 0; | 2820 | return rc ? 1 : 0; |
3010 | } | 2821 | } | ... | ... |
... | @@ -19,48 +19,22 @@ | ... | @@ -19,48 +19,22 @@ |
19 | 19 | ||
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | 21 | ||
22 | static char doc[] = N_("GNU MH mhparam")"\v" | 22 | static char prog_doc[] = N_("GNU MH mhparam"); |
23 | N_("Use -help to obtain the list of traditional MH options."); | ||
24 | static char args_doc[] = N_("[COMPONENT [COMPONENT...]]"); | 23 | static char args_doc[] = N_("[COMPONENT [COMPONENT...]]"); |
25 | 24 | ||
26 | /* GNU options */ | ||
27 | static struct argp_option options[] = { | ||
28 | {"all", ARG_ALL, NULL, 0, | ||
29 | N_("display all components from the MH profile. All other arguments are ignored")}, | ||
30 | {"component", ARG_COMPONENT, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
31 | N_("always display the component name") }, | ||
32 | { 0 } | ||
33 | }; | ||
34 | |||
35 | /* Traditional MH options */ | ||
36 | struct mh_option mh_option[] = { | ||
37 | { "all" }, | ||
38 | { "component", MH_OPT_BOOL }, | ||
39 | { NULL } | ||
40 | }; | ||
41 | |||
42 | static int display_all; | 25 | static int display_all; |
43 | static int display_comp_name = -1; | 26 | static int display_comp_name = -1; |
44 | 27 | ||
45 | static error_t | 28 | static struct mu_option options[] = { |
46 | opt_handler (int key, char *arg, struct argp_state *state) | 29 | { "all", 0, NULL, MU_OPTION_DEFAULT, |
47 | { | 30 | N_("display all components from the MH profile. All other arguments are ignored"), |
48 | switch (key) | 31 | mu_c_bool, &display_all }, |
49 | { | 32 | { "component", 0, NULL, MU_OPTION_DEFAULT, |
50 | case ARG_ALL: | 33 | N_("always display the component name"), |
51 | display_all = 1; | 34 | mu_c_bool, &display_comp_name }, |
52 | break; | 35 | MU_OPTION_END |
53 | 36 | }; | |
54 | case ARG_COMPONENT: | 37 | |
55 | display_comp_name = is_true (arg); | ||
56 | break; | ||
57 | |||
58 | default: | ||
59 | return ARGP_ERR_UNKNOWN; | ||
60 | } | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static struct { | 38 | static struct { |
65 | char *comp; | 39 | char *comp; |
66 | char *val; | 40 | char *val; |
... | @@ -81,7 +55,8 @@ mhparam_defval (char *comp) | ... | @@ -81,7 +55,8 @@ mhparam_defval (char *comp) |
81 | } | 55 | } |
82 | 56 | ||
83 | int | 57 | int |
84 | mhparam_iterator (const char *comp, const char *value, void *data MU_ARG_UNUSED) | 58 | mhparam_iterator (const char *comp, const char *value, |
59 | void *data MU_ARG_UNUSED) | ||
85 | { | 60 | { |
86 | if (display_comp_name) | 61 | if (display_comp_name) |
87 | printf("%s:\t", comp); | 62 | printf("%s:\t", comp); |
... | @@ -112,14 +87,10 @@ mhparam (char *comp) | ... | @@ -112,14 +87,10 @@ mhparam (char *comp) |
112 | int | 87 | int |
113 | main (int argc, char **argv) | 88 | main (int argc, char **argv) |
114 | { | 89 | { |
115 | int index; | ||
116 | |||
117 | /* Native Language Support */ | 90 | /* Native Language Support */ |
118 | MU_APP_INIT_NLS (); | 91 | MU_APP_INIT_NLS (); |
119 | 92 | ||
120 | mh_argp_init (); | 93 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
121 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
122 | opt_handler, NULL, &index); | ||
123 | 94 | ||
124 | if (display_all) | 95 | if (display_all) |
125 | { | 96 | { |
... | @@ -129,11 +100,13 @@ main (int argc, char **argv) | ... | @@ -129,11 +100,13 @@ main (int argc, char **argv) |
129 | } | 100 | } |
130 | else | 101 | else |
131 | { | 102 | { |
103 | int i; | ||
104 | |||
132 | if (display_comp_name == -1) | 105 | if (display_comp_name == -1) |
133 | display_comp_name = argc - index > 1; | 106 | display_comp_name = argc > 1; |
134 | 107 | ||
135 | for (; index < argc; index++) | 108 | for (i = 0; i < argc; i++) |
136 | mhparam (argv[index]); | 109 | mhparam (argv[i]); |
137 | } | 110 | } |
138 | return 0; | 111 | return 0; |
139 | } | 112 | } | ... | ... |
... | @@ -19,37 +19,9 @@ | ... | @@ -19,37 +19,9 @@ |
19 | 19 | ||
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | 21 | ||
22 | static char doc[] = N_("GNU MH mhpath")"\v" | 22 | static char prog_doc[] = N_("GNU MH mhpath"); |
23 | N_("Use -help to obtain the list of traditional MH options."); | ||
24 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); | 23 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); |
25 | 24 | ||
26 | /* GNU options */ | ||
27 | static struct argp_option options[] = { | ||
28 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
29 | N_("specify folder to operate upon")}, | ||
30 | { 0 } | ||
31 | }; | ||
32 | |||
33 | /* Traditional MH options */ | ||
34 | struct mh_option mh_option[] = { | ||
35 | { NULL } | ||
36 | }; | ||
37 | |||
38 | static error_t | ||
39 | opt_handler (int key, char *arg, struct argp_state *state) | ||
40 | { | ||
41 | switch (key) | ||
42 | { | ||
43 | case ARG_FOLDER: | ||
44 | mh_set_current_folder (arg); | ||
45 | break; | ||
46 | |||
47 | default: | ||
48 | return ARGP_ERR_UNKNOWN; | ||
49 | } | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static int | 25 | static int |
54 | mhpath (size_t num, mu_message_t msg, void *data) | 26 | mhpath (size_t num, mu_message_t msg, void *data) |
55 | { | 27 | { |
... | @@ -63,7 +35,6 @@ mhpath (size_t num, mu_message_t msg, void *data) | ... | @@ -63,7 +35,6 @@ mhpath (size_t num, mu_message_t msg, void *data) |
63 | int | 35 | int |
64 | main (int argc, char **argv) | 36 | main (int argc, char **argv) |
65 | { | 37 | { |
66 | int index = 0; | ||
67 | mu_mailbox_t mbox = NULL; | 38 | mu_mailbox_t mbox = NULL; |
68 | mu_url_t url = NULL; | 39 | mu_url_t url = NULL; |
69 | char *mhdir; | 40 | char *mhdir; |
... | @@ -75,9 +46,8 @@ main (int argc, char **argv) | ... | @@ -75,9 +46,8 @@ main (int argc, char **argv) |
75 | /* Native Language Support */ | 46 | /* Native Language Support */ |
76 | MU_APP_INIT_NLS (); | 47 | MU_APP_INIT_NLS (); |
77 | 48 | ||
78 | mh_argp_init (); | 49 | mh_getopt (&argc, &argv, NULL, MH_GETOPT_DEFAULT_FOLDER, |
79 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 50 | args_doc, prog_doc, NULL); |
80 | opt_handler, NULL, &index); | ||
81 | 51 | ||
82 | current_folder = mh_current_folder (); | 52 | current_folder = mh_current_folder (); |
83 | /* If the only argument is `+', your MH Path is output; this | 53 | /* If the only argument is `+', your MH Path is output; this |
... | @@ -98,7 +68,7 @@ main (int argc, char **argv) | ... | @@ -98,7 +68,7 @@ main (int argc, char **argv) |
98 | 68 | ||
99 | /* If no `msgs' are specified, mhpath outputs the folder pathname | 69 | /* If no `msgs' are specified, mhpath outputs the folder pathname |
100 | instead. */ | 70 | instead. */ |
101 | if (index == argc) | 71 | if (argc == 0) |
102 | { | 72 | { |
103 | printf ("%s\n", mhdir); | 73 | printf ("%s\n", mhdir); |
104 | exit (0); | 74 | exit (0); |
... | @@ -112,7 +82,7 @@ main (int argc, char **argv) | ... | @@ -112,7 +82,7 @@ main (int argc, char **argv) |
112 | The "new" message may not be used as part of a message | 82 | The "new" message may not be used as part of a message |
113 | range. */ | 83 | range. */ |
114 | 84 | ||
115 | if (argc - index == 1 && strcmp (argv[index], "new") == 0) | 85 | if (argc == 1 && strcmp (argv[0], "new") == 0) |
116 | { | 86 | { |
117 | mu_message_t msg = NULL; | 87 | mu_message_t msg = NULL; |
118 | size_t num; | 88 | size_t num; |
... | @@ -126,7 +96,7 @@ main (int argc, char **argv) | ... | @@ -126,7 +96,7 @@ main (int argc, char **argv) |
126 | /* Mhpath expands and sorts the message list `msgs' and | 96 | /* Mhpath expands and sorts the message list `msgs' and |
127 | writes the full pathnames of the messages to the standard | 97 | writes the full pathnames of the messages to the standard |
128 | output separated by newlines. */ | 98 | output separated by newlines. */ |
129 | mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur"); | 99 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); |
130 | status = mu_msgset_foreach_message (msgset, mhpath, mhdir); | 100 | status = mu_msgset_foreach_message (msgset, mhpath, mhdir); |
131 | mu_mailbox_close (mbox); | 101 | mu_mailbox_close (mbox); |
132 | mu_mailbox_destroy (&mbox); | 102 | mu_mailbox_destroy (&mbox); | ... | ... |
... | @@ -18,51 +18,21 @@ | ... | @@ -18,51 +18,21 @@ |
18 | 18 | ||
19 | #include <mh.h> | 19 | #include <mh.h> |
20 | 20 | ||
21 | static char doc[] = N_("GNU MH mhseq")"\v" | 21 | static char prog_doc[] = N_("GNU MH mhseq"); |
22 | N_("Use -help to obtain the list of traditional MH options."); | ||
23 | static char args_doc[] = N_("[SEQUENCE]"); | 22 | static char args_doc[] = N_("[SEQUENCE]"); |
24 | 23 | ||
25 | static struct argp_option options[] = { | ||
26 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
27 | N_("specify the folder to use")}, | ||
28 | { "uids", 'u', NULL, 0, | ||
29 | N_("show message UIDs (default)")}, | ||
30 | { "numbers", 'n', NULL, 0, | ||
31 | N_("show message numbers") }, | ||
32 | { NULL } | ||
33 | }; | ||
34 | |||
35 | /* Traditional MH options */ | ||
36 | struct mh_option mh_option[] = { | ||
37 | { "uid" }, | ||
38 | { NULL } | ||
39 | }; | ||
40 | |||
41 | static int uid_option = 1; | 24 | static int uid_option = 1; |
42 | 25 | ||
43 | static error_t | 26 | static struct mu_option options[] = { |
44 | opt_handler (int key, char *arg, struct argp_state *state) | 27 | { "uids", 0, NULL, MU_OPTION_DEFAULT, |
45 | { | 28 | N_("show message UIDs (default)"), |
46 | switch (key) | 29 | mu_c_int, &uid_option, NULL, "1" }, |
47 | { | 30 | { "numbers", 0, NULL, MU_OPTION_DEFAULT, |
48 | case ARG_FOLDER: | 31 | N_("show message numbers"), |
49 | mh_set_current_folder (arg); | 32 | mu_c_int, &uid_option, NULL, "0" }, |
50 | break; | 33 | MU_OPTION_END |
51 | 34 | }; | |
52 | case 'n': | 35 | |
53 | uid_option = 0; | ||
54 | break; | ||
55 | |||
56 | case 'u': | ||
57 | uid_option = 1; | ||
58 | break; | ||
59 | |||
60 | default: | ||
61 | return ARGP_ERR_UNKNOWN; | ||
62 | } | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int | 36 | static int |
67 | _print_number (size_t n, void *data) | 37 | _print_number (size_t n, void *data) |
68 | { | 38 | { |
... | @@ -73,19 +43,15 @@ _print_number (size_t n, void *data) | ... | @@ -73,19 +43,15 @@ _print_number (size_t n, void *data) |
73 | int | 43 | int |
74 | main (int argc, char **argv) | 44 | main (int argc, char **argv) |
75 | { | 45 | { |
76 | int index; | ||
77 | mu_mailbox_t mbox; | 46 | mu_mailbox_t mbox; |
78 | mu_msgset_t msgset; | 47 | mu_msgset_t msgset; |
79 | 48 | ||
80 | /* Native Language Support */ | 49 | /* Native Language Support */ |
81 | MU_APP_INIT_NLS (); | 50 | MU_APP_INIT_NLS (); |
82 | 51 | ||
83 | mh_argp_init (); | 52 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
84 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 53 | args_doc, prog_doc, NULL); |
85 | opt_handler, NULL, &index); | ||
86 | 54 | ||
87 | argc -= index; | ||
88 | argv += index; | ||
89 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); | 55 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); |
90 | 56 | ||
91 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); | 57 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); | ... | ... |
... | @@ -21,42 +21,9 @@ | ... | @@ -21,42 +21,9 @@ |
21 | #include "mailutils/datetime.h" | 21 | #include "mailutils/datetime.h" |
22 | #include <pwd.h> | 22 | #include <pwd.h> |
23 | 23 | ||
24 | static char doc[] = N_("GNU MH msgchk")"\v" | 24 | static char prog_doc[] = N_("GNU MH msgchk"); |
25 | N_("Use -help to obtain the list of traditional MH options."); | ||
26 | static char args_doc[] = N_("USER [USER...]"); | 25 | static char args_doc[] = N_("USER [USER...]"); |
27 | 26 | ||
28 | /* GNU options */ | ||
29 | static struct argp_option options[] = { | ||
30 | {"date", ARG_DATE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
31 | N_("print out the last date mail was read") }, | ||
32 | {"nodate", ARG_NODATE, NULL, OPTION_HIDDEN, | ||
33 | N_("don't print out the last date mail was read") }, | ||
34 | {"notify", ARG_NOTIFY, "all|mail|nomail", 0, | ||
35 | N_("produce a message upon these events") }, | ||
36 | {"nonotify", ARG_NONOTIFY, "all|mail|nomail", 0, | ||
37 | N_("disable notification") }, | ||
38 | {"host", ARG_HOST, N_("URL"), 0, | ||
39 | N_("check mail on this host or URL") }, | ||
40 | {"user", ARG_USER, N_("NAME"), 0, | ||
41 | N_("set user name for remote mailbox access") }, | ||
42 | {"apop", ARG_APOP, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
43 | N_("enable APOP") }, | ||
44 | {"noapop", ARG_NOAPOP, NULL, OPTION_HIDDEN, | ||
45 | N_("disable APOP") }, | ||
46 | {NULL} | ||
47 | }; | ||
48 | |||
49 | /* Traditional MH options */ | ||
50 | struct mh_option mh_option[] = { | ||
51 | { "date", MH_OPT_BOOL }, | ||
52 | { "notify", MH_OPT_ARG, "all|mail|nomail" }, | ||
53 | { "nonotify", MH_OPT_ARG, "all|mail|nomail" }, | ||
54 | { "host", MH_OPT_ARG, "host-or-url" }, | ||
55 | { "user", MH_OPT_ARG, "name" }, | ||
56 | { "apop", MH_OPT_BOOL }, | ||
57 | { NULL } | ||
58 | }; | ||
59 | |||
60 | int date_option = 1; | 27 | int date_option = 1; |
61 | int apop_option; | 28 | int apop_option; |
62 | char *remote_host; | 29 | char *remote_host; |
... | @@ -75,55 +42,53 @@ static struct mu_kwd notifytab[] = { | ... | @@ -75,55 +42,53 @@ static struct mu_kwd notifytab[] = { |
75 | { NULL } | 42 | { NULL } |
76 | }; | 43 | }; |
77 | 44 | ||
78 | static error_t | 45 | static void |
79 | opt_handler (int key, char *arg, struct argp_state *state) | 46 | set_notify (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
80 | { | 47 | { |
81 | int n; | 48 | int n; |
82 | 49 | if (mu_kwd_xlat_name (notifytab, arg, &n)) | |
83 | switch (key) | ||
84 | { | 50 | { |
85 | case ARG_DATE: | 51 | mu_parseopt_error (po, "unknown notify argument: %s", arg); |
86 | date_option = is_true (arg); | 52 | exit (po->po_exit_error); |
87 | break; | ||
88 | |||
89 | case ARG_NODATE: | ||
90 | date_option = 0; | ||
91 | break; | ||
92 | |||
93 | case ARG_APOP: | ||
94 | apop_option = is_true (arg); | ||
95 | break; | ||
96 | |||
97 | case ARG_NOAPOP: | ||
98 | apop_option = 0; | ||
99 | break; | ||
100 | |||
101 | case ARG_NOTIFY: | ||
102 | if (mu_kwd_xlat_name (notifytab, arg, &n)) | ||
103 | argp_error (state, "unknown notify argument: %s", arg); | ||
104 | notify |= n; | ||
105 | break; | ||
106 | |||
107 | case ARG_NONOTIFY: | ||
108 | if (mu_kwd_xlat_name (notifytab, arg, &n)) | ||
109 | argp_error (state, "unknown notify argument: %s", arg); | ||
110 | notify &= ~n; | ||
111 | break; | ||
112 | |||
113 | case ARG_USER: | ||
114 | remote_user = arg; | ||
115 | break; | ||
116 | |||
117 | case ARG_HOST: | ||
118 | remote_host = arg; | ||
119 | break; | ||
120 | |||
121 | default: | ||
122 | return ARGP_ERR_UNKNOWN; | ||
123 | } | 53 | } |
124 | return 0; | 54 | notify |= n; |
125 | } | 55 | } |
126 | 56 | ||
57 | static void | ||
58 | clr_notify (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
59 | { | ||
60 | int n; | ||
61 | if (mu_kwd_xlat_name (notifytab, arg, &n)) | ||
62 | { | ||
63 | mu_parseopt_error (po, "unknown notify argument: %s", arg); | ||
64 | exit (po->po_exit_error); | ||
65 | } | ||
66 | notify &= ~n; | ||
67 | } | ||
68 | |||
69 | static struct mu_option options[] = { | ||
70 | { "date", 0, NULL, MU_OPTION_DEFAULT, | ||
71 | N_("print out the last date mail was read"), | ||
72 | mu_c_bool, &date_option }, | ||
73 | { "notify", 0, "all|mail|nomail", MU_OPTION_DEFAULT, | ||
74 | N_("produce a message upon these events"), | ||
75 | mu_c_string, NULL, set_notify }, | ||
76 | { "nonotify", 0, "all|mail|nomail", MU_OPTION_DEFAULT, | ||
77 | N_("disable notification"), | ||
78 | mu_c_string, NULL, clr_notify }, | ||
79 | { "host", 0, N_("URL"), MU_OPTION_DEFAULT, | ||
80 | N_("check mail on this host or URL"), | ||
81 | mu_c_string, &remote_host }, | ||
82 | { "user", 0, N_("NAME"), MU_OPTION_DEFAULT, | ||
83 | N_("set user name for remote mailbox access"), | ||
84 | mu_c_string, &remote_user }, | ||
85 | { "apop", 0, NULL, MU_OPTION_DEFAULT, | ||
86 | N_("enable APOP"), | ||
87 | mu_c_bool, &apop_option }, | ||
88 | |||
89 | MU_OPTION_END | ||
90 | }; | ||
91 | |||
127 | static char * | 92 | static char * |
128 | attach_auth_ticket (mu_mailbox_t mbox) | 93 | attach_auth_ticket (mu_mailbox_t mbox) |
129 | { | 94 | { |
... | @@ -185,7 +150,7 @@ checkmail (const char *username, int personal) | ... | @@ -185,7 +150,7 @@ checkmail (const char *username, int personal) |
185 | { | 150 | { |
186 | static mu_url_t pop_hint; | 151 | static mu_url_t pop_hint; |
187 | 152 | ||
188 | if (pop_hint) | 153 | if (!pop_hint) |
189 | { | 154 | { |
190 | rc = mu_url_create (&pop_hint, "pop://"); | 155 | rc = mu_url_create (&pop_hint, "pop://"); |
191 | if (rc) | 156 | if (rc) |
... | @@ -382,17 +347,11 @@ checkmail (const char *username, int personal) | ... | @@ -382,17 +347,11 @@ checkmail (const char *username, int personal) |
382 | int | 347 | int |
383 | main (int argc, char **argv) | 348 | main (int argc, char **argv) |
384 | { | 349 | { |
385 | int index; | ||
386 | int rc = 0; | 350 | int rc = 0; |
387 | 351 | ||
388 | MU_APP_INIT_NLS (); | 352 | MU_APP_INIT_NLS (); |
389 | |||
390 | mh_argp_init (); | ||
391 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
392 | opt_handler, NULL, &index); | ||
393 | 353 | ||
394 | argc -= index; | 354 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
395 | argv += index; | ||
396 | 355 | ||
397 | if (argc == 0) | 356 | if (argc == 0) |
398 | { | 357 | { | ... | ... |
... | @@ -22,119 +22,11 @@ | ... | @@ -22,119 +22,11 @@ |
22 | #include <pick.h> | 22 | #include <pick.h> |
23 | #include <pick-gram.h> | 23 | #include <pick-gram.h> |
24 | 24 | ||
25 | static char doc[] = N_("GNU MH pick")"\v" | 25 | static char prog_doc[] = N_("GNU MH pick"); |
26 | N_("Compatibility syntax for picking a matching component is:\n\ | 26 | static char args_doc[] = N_("[--COMPONENT PATTERN]... [MSGLIST]"); |
27 | \n\ | ||
28 | --Component pattern\n\ | ||
29 | \n\ | ||
30 | where Component is the component name, containing at least one capital\n\ | ||
31 | letter or followed by a colon, e.g.:\n\ | ||
32 | \n\ | ||
33 | --User-Agent Mailutils\n\ | ||
34 | --user-agent: Mailutils\n\ | ||
35 | \n\ | ||
36 | Use -help to obtain a list of traditional MH options."); | ||
37 | static char args_doc[] = N_("[MSGLIST]"); | ||
38 | |||
39 | /* GNU options */ | ||
40 | static struct argp_option options[] = { | ||
41 | #define GRID 10 | ||
42 | { "folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
43 | N_("specify folder to operate upon"), GRID }, | ||
44 | #undef GRID | ||
45 | |||
46 | #define GRID 20 | ||
47 | { N_("Search patterns"), 0, NULL, OPTION_DOC, NULL, GRID }, | ||
48 | { "component", ARG_COMPONENT, N_("FIELD"), 0, | ||
49 | N_("search the named header field"), GRID+1}, | ||
50 | { "pattern", ARG_PATTERN, N_("STRING"), 0, | ||
51 | N_("set pattern to look for"), GRID+1 }, | ||
52 | { "search", 0, NULL, OPTION_ALIAS, NULL, GRID+1 }, | ||
53 | { "cflags", ARG_CFLAGS, N_("STRING"), 0, | ||
54 | N_("flags controlling the type of regular expressions. STRING must consist of one or more of the following letters: B=basic, E=extended, I=ignore case, C=case sensitive. Default is \"EI\". The flags remain in effect until the next occurrence of --cflags option. The option must occur right before --pattern or --component option (or its alias)."), GRID+1 }, | ||
55 | { "cc", ARG_CC, N_("STRING"), 0, | ||
56 | N_("same as --component cc --pattern STRING"), GRID+1 }, | ||
57 | { "date", ARG_DATE, N_("STRING"), 0, | ||
58 | N_("same as --component date --pattern STRING"), GRID+1 }, | ||
59 | { "from", ARG_FROM, N_("STRING"), 0, | ||
60 | N_("same as --component from --pattern STRING"), GRID+1 }, | ||
61 | { "subject", ARG_SUBJECT, N_("STRING"), 0, | ||
62 | N_("same as --component subject --pattern STRING"), GRID+1 }, | ||
63 | { "to", ARG_TO, N_("STRING"), 0, | ||
64 | N_("same as --component to --pattern STRING"), GRID+1 }, | ||
65 | #undef GRID | ||
66 | |||
67 | #define GRID 30 | ||
68 | { N_("Date constraint operations"), 0, NULL, OPTION_DOC, NULL, GRID }, | ||
69 | { "datefield",ARG_DATEFIELD, N_("STRING"), 0, | ||
70 | N_("search in the named date header field (default is `Date:')"), GRID+1 }, | ||
71 | { "after", ARG_AFTER, N_("DATE"), 0, | ||
72 | N_("match messages after the given date"), GRID+1 }, | ||
73 | { "before", ARG_BEFORE, N_("DATE"), 0, | ||
74 | N_("match messages before the given date"), GRID+1 }, | ||
75 | #undef GRID | ||
76 | |||
77 | #define GRID 40 | ||
78 | { N_("Logical operations and grouping"), 0, NULL, OPTION_DOC, NULL, GRID }, | ||
79 | { "and", ARG_AND, NULL, 0, | ||
80 | N_("logical AND (default)"), GRID+1 }, | ||
81 | { "or", ARG_OR, NULL, 0, | ||
82 | N_("logical OR"), GRID+1 }, | ||
83 | { "not", ARG_NOT, NULL, 0, | ||
84 | N_("logical NOT"), GRID+1 }, | ||
85 | { "lbrace", ARG_LBRACE, NULL, 0, | ||
86 | N_("open group"), GRID+1 }, | ||
87 | { "(", 0, NULL, OPTION_ALIAS, NULL, GRID+1 }, | ||
88 | { "rbrace", ARG_RBRACE, NULL, 0, | ||
89 | N_("close group"), GRID+1}, | ||
90 | { ")", 0, NULL, OPTION_ALIAS, NULL, GRID+1 }, | ||
91 | #undef GRID | ||
92 | |||
93 | #define GRID 50 | ||
94 | { N_("Operations over the selected messages"), 0, NULL, OPTION_DOC, NULL, | ||
95 | GRID }, | ||
96 | { "list", ARG_LIST, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
97 | N_("list the numbers of the selected messages (default)"), GRID+1 }, | ||
98 | { "nolist", ARG_NOLIST, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
99 | { "sequence", ARG_SEQUENCE, N_("NAME"), 0, | ||
100 | N_("add matching messages to the given sequence"), GRID+1 }, | ||
101 | { "public", ARG_PUBLIC, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
102 | N_("create public sequence"), GRID+1 }, | ||
103 | { "nopublic", ARG_NOPUBLIC, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
104 | { "zero", ARG_ZERO, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
105 | N_("empty the sequence before adding messages"), GRID+1 }, | ||
106 | { "nozero", ARG_NOZERO, NULL, OPTION_HIDDEN, "", GRID+1 }, | ||
107 | #undef GRID | ||
108 | |||
109 | { NULL } | ||
110 | |||
111 | }; | ||
112 | 27 | ||
113 | /* Traditional MH options */ | 28 | static int public_option = 1; |
114 | struct mh_option mh_option[] = { | 29 | static int zero_option = 0; |
115 | { "component", MH_OPT_ARG, "field" }, | ||
116 | { "pattern", MH_OPT_ARG, "pattern" }, | ||
117 | { "search", MH_OPT_ARG, "pattern" }, | ||
118 | { "cc", MH_OPT_ARG, "pattern" }, | ||
119 | { "date", MH_OPT_ARG, "pattern" }, | ||
120 | { "from", MH_OPT_ARG, "pattern" }, | ||
121 | { "subject", MH_OPT_ARG, "pattern" }, | ||
122 | { "to", MH_OPT_ARG, "pattern" }, | ||
123 | { "datefield", MH_OPT_ARG, "field" }, | ||
124 | { "after", MH_OPT_ARG, "date" }, | ||
125 | { "before", MH_OPT_ARG, "date" }, | ||
126 | { "and" }, | ||
127 | { "or" }, | ||
128 | { "not" }, | ||
129 | { "lbrace" }, | ||
130 | { "rbrace" }, | ||
131 | |||
132 | { "list", MH_OPT_BOOL }, | ||
133 | { "sequence", MH_OPT_ARG, "name" }, | ||
134 | { "public", MH_OPT_BOOL }, | ||
135 | { "zero", MH_OPT_BOOL }, | ||
136 | { NULL } | ||
137 | }; | ||
138 | 30 | ||
139 | static int list = 1; | 31 | static int list = 1; |
140 | static int seq_flags = 0; /* Create public sequences; | 32 | static int seq_flags = 0; /* Create public sequences; |
... | @@ -146,138 +38,177 @@ static mu_list_t lexlist; /* List of input tokens */ | ... | @@ -146,138 +38,177 @@ static mu_list_t lexlist; /* List of input tokens */ |
146 | static mu_msgset_t picked_message_uids; | 38 | static mu_msgset_t picked_message_uids; |
147 | 39 | ||
148 | static void | 40 | static void |
149 | add_sequence (char *name) | 41 | add_component_name (struct mu_parseopt *po, struct mu_option *opt, |
42 | char const *arg) | ||
150 | { | 43 | { |
151 | if (!seq_list && mu_list_create (&seq_list)) | 44 | pick_add_token (&lexlist, T_COMP, arg); |
152 | { | 45 | } |
153 | mu_error (_("cannot create sequence list")); | 46 | |
154 | exit (1); | 47 | static void |
155 | } | 48 | add_component_pattern (struct mu_parseopt *po, struct mu_option *opt, |
156 | mu_list_append (seq_list, name); | 49 | char const *arg) |
50 | { | ||
51 | pick_add_token (&lexlist, T_STRING, arg); | ||
157 | } | 52 | } |
158 | 53 | ||
159 | static error_t | 54 | static void |
160 | opt_handler (int key, char *arg, struct argp_state *state) | 55 | add_cflags (struct mu_parseopt *po, struct mu_option *opt, |
56 | char const *arg) | ||
57 | { | ||
58 | pick_add_token (&lexlist, T_CFLAGS, arg); | ||
59 | } | ||
60 | |||
61 | static void | ||
62 | add_comp_match (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
63 | { | ||
64 | pick_add_token (&lexlist, T_COMP, opt->opt_default); | ||
65 | pick_add_token (&lexlist, T_STRING, arg); | ||
66 | } | ||
67 | |||
68 | static void | ||
69 | add_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
161 | { | 70 | { |
162 | switch (key) | 71 | pick_add_token (&lexlist, T_DATEFIELD, arg); |
72 | } | ||
73 | |||
74 | static void | ||
75 | add_after (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
76 | { | ||
77 | pick_add_token (&lexlist, T_AFTER, NULL); | ||
78 | pick_add_token (&lexlist, T_STRING, arg); | ||
79 | } | ||
80 | |||
81 | static void | ||
82 | add_before (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
83 | { | ||
84 | pick_add_token (&lexlist, T_BEFORE, NULL); | ||
85 | pick_add_token (&lexlist, T_STRING, arg); | ||
86 | } | ||
87 | |||
88 | static void | ||
89 | add_and (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
90 | { | ||
91 | pick_add_token (&lexlist, T_AND, NULL); | ||
92 | } | ||
93 | |||
94 | static void | ||
95 | add_or (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
96 | { | ||
97 | pick_add_token (&lexlist, T_OR, NULL); | ||
98 | } | ||
99 | |||
100 | static void | ||
101 | add_not (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
102 | { | ||
103 | pick_add_token (&lexlist, T_NOT, NULL); | ||
104 | } | ||
105 | |||
106 | static void | ||
107 | add_lbrace (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
108 | { | ||
109 | pick_add_token (&lexlist, T_LBRACE, NULL); | ||
110 | } | ||
111 | |||
112 | static void | ||
113 | add_rbrace (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
114 | { | ||
115 | pick_add_token (&lexlist, T_RBRACE, NULL); | ||
116 | } | ||
117 | |||
118 | static void | ||
119 | add_to_sequence (struct mu_parseopt *po, struct mu_option *opt, | ||
120 | char const *arg) | ||
121 | { | ||
122 | if (!seq_list && mu_list_create (&seq_list)) | ||
163 | { | 123 | { |
164 | case ARG_FOLDER: | 124 | mu_error (_("cannot create sequence list")); |
165 | mh_set_current_folder (arg); | 125 | exit (1); |
166 | break; | ||
167 | |||
168 | case ARG_SEQUENCE: | ||
169 | add_sequence (arg); | ||
170 | list = 0; | ||
171 | break; | ||
172 | |||
173 | case ARG_LIST: | ||
174 | list = is_true (arg); | ||
175 | break; | ||
176 | |||
177 | case ARG_NOLIST: | ||
178 | list = 0; | ||
179 | break; | ||
180 | |||
181 | case ARG_COMPONENT: | ||
182 | pick_add_token (&lexlist, T_COMP, arg); | ||
183 | break; | ||
184 | |||
185 | case ARG_PATTERN: | ||
186 | pick_add_token (&lexlist, T_STRING, arg); | ||
187 | break; | ||
188 | |||
189 | case ARG_CC: | ||
190 | pick_add_token (&lexlist, T_COMP, "cc"); | ||
191 | pick_add_token (&lexlist, T_STRING, arg); | ||
192 | break; | ||
193 | |||
194 | case ARG_DATE: | ||
195 | pick_add_token (&lexlist, T_COMP, "date"); | ||
196 | pick_add_token (&lexlist, T_STRING, arg); | ||
197 | break; | ||
198 | |||
199 | case ARG_FROM: | ||
200 | pick_add_token (&lexlist, T_COMP, "from"); | ||
201 | pick_add_token (&lexlist, T_STRING, arg); | ||
202 | break; | ||
203 | |||
204 | case ARG_SUBJECT: | ||
205 | pick_add_token (&lexlist, T_COMP, "subject"); | ||
206 | pick_add_token (&lexlist, T_STRING, arg); | ||
207 | break; | ||
208 | |||
209 | case ARG_TO: | ||
210 | pick_add_token (&lexlist, T_COMP, "to"); | ||
211 | pick_add_token (&lexlist, T_STRING, arg); | ||
212 | break; | ||
213 | |||
214 | case ARG_DATEFIELD: | ||
215 | pick_add_token (&lexlist, T_DATEFIELD, arg); | ||
216 | break; | ||
217 | |||
218 | case ARG_AFTER: | ||
219 | pick_add_token (&lexlist, T_AFTER, NULL); | ||
220 | pick_add_token (&lexlist, T_STRING, arg); | ||
221 | break; | ||
222 | |||
223 | case ARG_BEFORE: | ||
224 | pick_add_token (&lexlist, T_BEFORE, NULL); | ||
225 | pick_add_token (&lexlist, T_STRING, arg); | ||
226 | break; | ||
227 | |||
228 | case ARG_AND: | ||
229 | pick_add_token (&lexlist, T_AND, NULL); | ||
230 | break; | ||
231 | |||
232 | case ARG_OR: | ||
233 | pick_add_token (&lexlist, T_OR, NULL); | ||
234 | break; | ||
235 | |||
236 | case ARG_NOT: | ||
237 | pick_add_token (&lexlist, T_NOT, NULL); | ||
238 | break; | ||
239 | |||
240 | case ARG_LBRACE: | ||
241 | pick_add_token (&lexlist, T_LBRACE, NULL); | ||
242 | break; | ||
243 | |||
244 | case ARG_RBRACE: | ||
245 | pick_add_token (&lexlist, T_RBRACE, NULL); | ||
246 | break; | ||
247 | |||
248 | case ARG_CFLAGS: | ||
249 | pick_add_token (&lexlist, T_CFLAGS, arg); | ||
250 | break; | ||
251 | |||
252 | case ARG_PUBLIC: | ||
253 | if (is_true (arg)) | ||
254 | seq_flags &= ~SEQ_PRIVATE; | ||
255 | else | ||
256 | seq_flags |= SEQ_PRIVATE; | ||
257 | break; | ||
258 | |||
259 | case ARG_NOPUBLIC: | ||
260 | seq_flags |= SEQ_PRIVATE; | ||
261 | break; | ||
262 | |||
263 | case ARG_ZERO: | ||
264 | if (is_true (arg)) | ||
265 | seq_flags |= SEQ_ZERO; | ||
266 | else | ||
267 | seq_flags &= ~SEQ_ZERO; | ||
268 | break; | ||
269 | |||
270 | case ARG_NOZERO: | ||
271 | seq_flags &= ~SEQ_ZERO; | ||
272 | break; | ||
273 | |||
274 | default: | ||
275 | return ARGP_ERR_UNKNOWN; | ||
276 | } | 126 | } |
277 | 127 | mu_list_append (seq_list, mu_strdup (arg)); | |
278 | return 0; | 128 | list = 0; |
279 | } | 129 | } |
280 | 130 | ||
131 | static struct mu_option options[] = { | ||
132 | MU_OPTION_GROUP (N_("Search patterns")), | ||
133 | { "component", 0, N_("FIELD"), MU_OPTION_DEFAULT, | ||
134 | N_("search the named header field"), | ||
135 | mu_c_string, NULL, add_component_name }, | ||
136 | { "pattern", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
137 | N_("set pattern to look for"), | ||
138 | mu_c_string, NULL, add_component_pattern }, | ||
139 | { "search", 0, NULL, MU_OPTION_ALIAS }, | ||
140 | { "cflags", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
141 | N_("flags controlling the type of regular expressions. " | ||
142 | "STRING must consist of one or more of the following letters: " | ||
143 | "B=basic, E=extended, I=ignore case, C=case sensitive. " | ||
144 | "Default is \"EI\". The flags remain in effect until the next " | ||
145 | "occurrence of --cflags option. The option must occur right " | ||
146 | "before --pattern or --component option (or its alias)."), | ||
147 | mu_c_string, NULL, add_cflags }, | ||
148 | { "cc", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
149 | N_("search for Cc matching STRING"), | ||
150 | mu_c_string, NULL, add_comp_match, "cc" }, | ||
151 | { "date", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
152 | N_("search for Date matching STRING"), | ||
153 | mu_c_string, NULL, add_comp_match, "date" }, | ||
154 | { "from", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
155 | N_("search for From matching STRING"), | ||
156 | mu_c_string, NULL, add_comp_match, "from" }, | ||
157 | { "subject", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
158 | N_("search for Subject matching STRING"), | ||
159 | mu_c_string, NULL, add_comp_match, "subject" }, | ||
160 | { "to", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
161 | N_("search for To matching STRING"), | ||
162 | mu_c_string, NULL, add_comp_match, "to" }, | ||
163 | |||
164 | MU_OPTION_GROUP (N_("Date constraint operations")), | ||
165 | { "datefield", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
166 | N_("search in the named date header field (default is `Date:')"), | ||
167 | mu_c_string, NULL, add_datefield }, | ||
168 | { "after", 0, N_("DATE"), MU_OPTION_DEFAULT, | ||
169 | N_("match messages after the given date"), | ||
170 | mu_c_string, NULL, add_after }, | ||
171 | { "before", 0, N_("DATE"), MU_OPTION_DEFAULT, | ||
172 | N_("match messages before the given date"), | ||
173 | mu_c_string, NULL, add_before }, | ||
174 | |||
175 | MU_OPTION_GROUP (N_("Logical operations and grouping")), | ||
176 | { "and", 0, NULL, MU_OPTION_DEFAULT, | ||
177 | N_("logical AND (default)"), | ||
178 | mu_c_string, NULL, add_and }, | ||
179 | { "or", 0, NULL, MU_OPTION_DEFAULT, | ||
180 | N_("logical OR"), | ||
181 | mu_c_string, NULL, add_or }, | ||
182 | { "not", 0, NULL, MU_OPTION_DEFAULT, | ||
183 | N_("logical NOT"), | ||
184 | mu_c_string, NULL, add_not }, | ||
185 | { "lbrace", 0, NULL, MU_OPTION_DEFAULT, | ||
186 | N_("open group"), | ||
187 | mu_c_string, NULL, add_lbrace }, | ||
188 | { "(", 0, NULL, MU_OPTION_ALIAS }, | ||
189 | { "rbrace", 0, NULL, MU_OPTION_DEFAULT, | ||
190 | N_("close group"), | ||
191 | mu_c_string, NULL, add_rbrace }, | ||
192 | { ")", 0, NULL, MU_OPTION_ALIAS }, | ||
193 | |||
194 | MU_OPTION_GROUP (N_("Operations over the selected messages")), | ||
195 | { "list", 0, NULL, MU_OPTION_ALIAS, | ||
196 | N_("list the numbers of the selected messages (default)"), | ||
197 | mu_c_bool, &list }, | ||
198 | { "sequence", 0, N_("NAME"), MU_OPTION_DEFAULT, | ||
199 | N_("add matching messages to the given sequence"), | ||
200 | mu_c_string, NULL, add_to_sequence }, | ||
201 | { "public", 0, NULL, MU_OPTION_DEFAULT, | ||
202 | N_("create public sequence"), | ||
203 | mu_c_bool, &public_option }, | ||
204 | { "zero", 0, NULL, MU_OPTION_DEFAULT, | ||
205 | N_("empty the sequence before adding messages"), | ||
206 | mu_c_bool, &zero_option }, | ||
207 | |||
208 | MU_OPTION_END | ||
209 | |||
210 | }; | ||
211 | |||
281 | static int | 212 | static int |
282 | pick_message (size_t num, mu_message_t msg, void *data) | 213 | pick_message (size_t num, mu_message_t msg, void *data) |
283 | { | 214 | { |
... | @@ -301,89 +232,56 @@ action_add (void *item, void *data) | ... | @@ -301,89 +232,56 @@ action_add (void *item, void *data) |
301 | return 0; | 232 | return 0; |
302 | } | 233 | } |
303 | 234 | ||
304 | void | 235 | static void |
305 | pick_help_hook (void) | 236 | parse_comp_match (int *pargc, char **argv) |
306 | { | 237 | { |
307 | printf ("\n"); | 238 | int i, j; |
308 | printf (_("To match another component, use:\n\n")); | 239 | int argc = *pargc; |
309 | printf (_(" --Component pattern\n\n")); | ||
310 | printf (_("Note, that the component name must either be capitalized,\n" | ||
311 | "or followed by a colon.\n")); | ||
312 | printf ("\n"); | ||
313 | } | ||
314 | |||
315 | /* NOTICE: For compatibility with RAND MH we have to support | ||
316 | the following command line syntax: | ||
317 | |||
318 | --COMP STRING | ||
319 | |||
320 | where `COMP' may be any string and which is equivalent to | ||
321 | `--component FIELD --pattern STRING'. Obviously this is in conflict | ||
322 | with the usual GNU long options paradigm which requires that any | ||
323 | unrecognized long option produce an error. The following | ||
324 | compromise solution is used: | ||
325 | |||
326 | The arguments `--COMP STRING' is recognized as a component matching | ||
327 | request if any of the following conditions is met: | ||
328 | |||
329 | 1. The word `COMP' contains at least one capital letter. E.g.: | ||
330 | 240 | ||
331 | --User-Agent Mailutils | 241 | for (i = j = 0; i < argc; i++) |
332 | 242 | { | |
333 | 2. The word `COMP' ends with a colon, e.g.: | 243 | if (strncmp (argv[i], "--", 2) == 0) |
334 | 244 | { | |
335 | --user-agent: Mailutils | 245 | if (++i < argc) |
336 | 246 | { | |
337 | 3. Standard input is not connected to a terminal. This is always | 247 | pick_add_token (&lexlist, T_COMP, argv[i-1] + 2); |
338 | true when pick is invoked from mh-pick.el Emacs module. | 248 | pick_add_token (&lexlist, T_STRING, argv[i]); |
339 | */ | 249 | } |
250 | else | ||
251 | { | ||
252 | mu_error (_("%s: must be followed by a pattern"), argv[i-1]); | ||
253 | exit (1); | ||
254 | } | ||
255 | } | ||
256 | else | ||
257 | argv[j++] = argv[i]; | ||
258 | } | ||
259 | argv[j] = NULL; | ||
260 | *pargc = j; | ||
261 | } | ||
340 | 262 | ||
341 | int | 263 | int |
342 | main (int argc, char **argv) | 264 | main (int argc, char **argv) |
343 | { | 265 | { |
344 | int status; | 266 | int status; |
345 | int index; | ||
346 | mu_mailbox_t mbox; | 267 | mu_mailbox_t mbox; |
347 | mu_msgset_t msgset; | 268 | mu_msgset_t msgset; |
348 | int interactive = mh_interactive_mode_p (); | ||
349 | 269 | ||
350 | MU_APP_INIT_NLS (); | 270 | MU_APP_INIT_NLS (); |
351 | 271 | ||
352 | for (index = 1; index < argc; index++) | 272 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
353 | { | 273 | args_doc, prog_doc, NULL); |
354 | int colon = 0, cpos; | 274 | |
355 | if (argv[index][0] == '-' && argv[index][1] == '-' && | 275 | parse_comp_match (&argc, argv); |
356 | !strchr (argv[index], '=') && | 276 | |
357 | (!interactive || | ||
358 | (colon = argv[index][cpos = strlen (argv[index]) - 1] == ':') || | ||
359 | *mu_str_skip_class_comp (argv[index], MU_CTYPE_UPPER)) && | ||
360 | index + 1 < argc) | ||
361 | { | ||
362 | if (colon) | ||
363 | { | ||
364 | cpos -= 2; | ||
365 | mu_asprintf (&argv[index], "--component=%*.*s", cpos, cpos, | ||
366 | argv[index] + 2); | ||
367 | } | ||
368 | else | ||
369 | mu_asprintf (&argv[index], "--component=%s", argv[index] + 2); | ||
370 | mu_asprintf (&argv[index + 1], "--pattern=%s", argv[index + 1]); | ||
371 | index++; | ||
372 | } | ||
373 | } | ||
374 | mh_help_hook = pick_help_hook; | ||
375 | mh_argp_init (); | ||
376 | mh_argp_parse (&argc, &argv, 0, options, mh_option, | ||
377 | args_doc, doc, opt_handler, NULL, &index); | ||
378 | if (pick_parse (lexlist)) | 277 | if (pick_parse (lexlist)) |
379 | return 1; | 278 | return 1; |
380 | 279 | ||
280 | seq_flags = (public_option ? 0 : SEQ_PRIVATE) | (zero_option ? SEQ_ZERO : 0); | ||
281 | |||
381 | mbox = mh_open_folder (mh_current_folder (), | 282 | mbox = mh_open_folder (mh_current_folder (), |
382 | seq_list ? MU_STREAM_RDWR : MU_STREAM_READ); | 283 | seq_list ? MU_STREAM_RDWR : MU_STREAM_READ); |
383 | 284 | ||
384 | argc -= index; | ||
385 | argv += index; | ||
386 | |||
387 | if (seq_list) | 285 | if (seq_list) |
388 | mu_msgset_create (&picked_message_uids, NULL, MU_MSGSET_UID); | 286 | mu_msgset_create (&picked_message_uids, NULL, MU_MSGSET_UID); |
389 | 287 | ... | ... |
... | @@ -56,6 +56,6 @@ struct node | ... | @@ -56,6 +56,6 @@ struct node |
56 | } v; | 56 | } v; |
57 | }; | 57 | }; |
58 | 58 | ||
59 | void pick_add_token (mu_list_t *list, int tok, char *val); | 59 | void pick_add_token (mu_list_t *list, int tok, char const *val); |
60 | int pick_parse (mu_list_t toklist); | 60 | int pick_parse (mu_list_t toklist); |
61 | int pick_eval (mu_message_t msg); | 61 | int pick_eval (mu_message_t msg); | ... | ... |
... | @@ -189,28 +189,28 @@ tokname (int tok) | ... | @@ -189,28 +189,28 @@ tokname (int tok) |
189 | switch (tok) | 189 | switch (tok) |
190 | { | 190 | { |
191 | case T_DATEFIELD: | 191 | case T_DATEFIELD: |
192 | return "--datefield"; | 192 | return "-datefield"; |
193 | 193 | ||
194 | case T_BEFORE: | 194 | case T_BEFORE: |
195 | return "--before"; | 195 | return "-before"; |
196 | 196 | ||
197 | case T_AFTER: | 197 | case T_AFTER: |
198 | return "--after"; | 198 | return "-after"; |
199 | 199 | ||
200 | case T_LBRACE: | 200 | case T_LBRACE: |
201 | return "--lbrace"; | 201 | return "-lbrace"; |
202 | 202 | ||
203 | case T_RBRACE: | 203 | case T_RBRACE: |
204 | return "--rbrace"; | 204 | return "-rbrace"; |
205 | 205 | ||
206 | case T_OR: | 206 | case T_OR: |
207 | return "--or"; | 207 | return "-or"; |
208 | 208 | ||
209 | case T_AND: | 209 | case T_AND: |
210 | return "--and"; | 210 | return "-and"; |
211 | 211 | ||
212 | case T_NOT: | 212 | case T_NOT: |
213 | return "--not"; | 213 | return "-not"; |
214 | } | 214 | } |
215 | return NULL; | 215 | return NULL; |
216 | } | 216 | } |
... | @@ -236,7 +236,7 @@ yyerror (const char *s) | ... | @@ -236,7 +236,7 @@ yyerror (const char *s) |
236 | } | 236 | } |
237 | 237 | ||
238 | void | 238 | void |
239 | pick_add_token (mu_list_t *list, int tok, char *val) | 239 | pick_add_token (mu_list_t *list, int tok, char const *val) |
240 | { | 240 | { |
241 | struct token *tp; | 241 | struct token *tp; |
242 | int rc; | 242 | int rc; | ... | ... |
... | @@ -19,98 +19,33 @@ | ... | @@ -19,98 +19,33 @@ |
19 | #include <mh.h> | 19 | #include <mh.h> |
20 | #include "prompter.h" | 20 | #include "prompter.h" |
21 | 21 | ||
22 | static char doc[] = N_("GNU MH prompter")"\v" | 22 | static char prog_doc[] = N_("GNU MH prompter"); |
23 | N_("Use -help to obtain the list of traditional MH options."); | ||
24 | static char args_doc[] = N_("FILE"); | 23 | static char args_doc[] = N_("FILE"); |
25 | 24 | ||
26 | enum { | ||
27 | ARG_ERASE=256, | ||
28 | ARG_KILL, | ||
29 | ARG_PREPEND, | ||
30 | ARG_NOPREPEND, | ||
31 | ARG_RAPID, | ||
32 | ARG_NORAPID, | ||
33 | ARG_DOTEOF, | ||
34 | ARG_NODOTEOF | ||
35 | }; | ||
36 | |||
37 | static struct argp_option options[] = { | ||
38 | { "erase", ARG_ERASE, N_("CHAR"), 0, | ||
39 | N_("set erase character") }, | ||
40 | { "kill", ARG_KILL, N_("CHAR"), 0, | ||
41 | N_("set kill character") }, | ||
42 | { "prepend", ARG_PREPEND, N_("BOOL"), 0, | ||
43 | N_("prepend user input to the message body") }, | ||
44 | { "noprepend", ARG_NOPREPEND, NULL, OPTION_HIDDEN, | ||
45 | NULL }, | ||
46 | { "rapid", ARG_RAPID, N_("BOOL"), 0, | ||
47 | N_("do not display message body") }, | ||
48 | { "norapid", ARG_NORAPID, NULL, OPTION_HIDDEN, | ||
49 | NULL }, | ||
50 | { "doteof", ARG_DOTEOF, N_("BOOL"), 0, | ||
51 | N_("a period on a line marks end-of-file") }, | ||
52 | { "nodoteof", ARG_NODOTEOF, NULL, OPTION_HIDDEN, | ||
53 | NULL }, | ||
54 | { NULL } | ||
55 | }; | ||
56 | |||
57 | struct mh_option mh_option[] = { | ||
58 | { "erase", MH_OPT_ARG, "chr" }, | ||
59 | { "kill", MH_OPT_ARG, "chr" }, | ||
60 | { "prepend", MH_OPT_BOOL }, | ||
61 | { "rapid", MH_OPT_BOOL }, | ||
62 | { "doteof", MH_OPT_BOOL }, | ||
63 | { NULL } | ||
64 | }; | ||
65 | |||
66 | char *erase_seq; | 25 | char *erase_seq; |
67 | char *kill_seq; | 26 | char *kill_seq; |
68 | int prepend_option; | 27 | int prepend_option; |
69 | int rapid_option; | 28 | int rapid_option; |
70 | int doteof_option; | 29 | int doteof_option; |
71 | 30 | ||
72 | static error_t | 31 | static struct mu_option options[] = { |
73 | opt_handler (int key, char *arg, struct argp_state *state) | 32 | { "erase", 0, N_("CHAR"), MU_OPTION_DEFAULT, |
74 | { | 33 | N_("set erase character"), |
75 | switch (key) | 34 | mu_c_string, &erase_seq }, |
76 | { | 35 | { "kill", 0, N_("CHAR"), MU_OPTION_DEFAULT, |
77 | case ARG_ERASE: | 36 | N_("set kill character"), |
78 | erase_seq = arg; | 37 | mu_c_string, &kill_seq }, |
79 | break; | 38 | { "prepend", 0, NULL, MU_OPTION_DEFAULT, |
80 | 39 | N_("prepend user input to the message body"), | |
81 | case ARG_KILL: | 40 | mu_c_bool, &prepend_option }, |
82 | kill_seq = arg; | 41 | { "rapid", 0, NULL, MU_OPTION_DEFAULT, |
83 | break; | 42 | N_("do not display message body"), |
84 | 43 | mu_c_bool, &rapid_option }, | |
85 | case ARG_PREPEND: | 44 | { "doteof", 0, NULL, MU_OPTION_DEFAULT, |
86 | prepend_option = is_true (arg); | 45 | N_("a period on a line marks end-of-file"), |
87 | break; | 46 | mu_c_bool, &doteof_option }, |
88 | 47 | MU_OPTION_END | |
89 | case ARG_NOPREPEND: | 48 | }; |
90 | prepend_option = 0; | ||
91 | break; | ||
92 | |||
93 | case ARG_RAPID: | ||
94 | rapid_option = is_true (arg); | ||
95 | break; | ||
96 | |||
97 | case ARG_NORAPID: | ||
98 | rapid_option = 0; | ||
99 | break; | ||
100 | |||
101 | case ARG_DOTEOF: | ||
102 | doteof_option = is_true (arg); | ||
103 | break; | ||
104 | |||
105 | case ARG_NODOTEOF: | ||
106 | doteof_option = 0; | ||
107 | break; | ||
108 | |||
109 | default: | ||
110 | return ARGP_ERR_UNKNOWN; | ||
111 | } | ||
112 | return 0; | ||
113 | } | ||
114 | 49 | ||
115 | static int | 50 | static int |
116 | is_empty_string (const char *str) | 51 | is_empty_string (const char *str) |
... | @@ -142,7 +77,6 @@ mu_stream_t strout; | ... | @@ -142,7 +77,6 @@ mu_stream_t strout; |
142 | int | 77 | int |
143 | main (int argc, char **argv) | 78 | main (int argc, char **argv) |
144 | { | 79 | { |
145 | int index; | ||
146 | int rc; | 80 | int rc; |
147 | mu_stream_t in, tmp; | 81 | mu_stream_t in, tmp; |
148 | mu_message_t msg; | 82 | mu_message_t msg; |
... | @@ -156,16 +90,20 @@ main (int argc, char **argv) | ... | @@ -156,16 +90,20 @@ main (int argc, char **argv) |
156 | 90 | ||
157 | MU_APP_INIT_NLS (); | 91 | MU_APP_INIT_NLS (); |
158 | 92 | ||
159 | mh_argp_init (); | 93 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
160 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
161 | opt_handler, NULL, &index); | ||
162 | 94 | ||
163 | if (index == argc) | 95 | if (argc == 0) |
164 | { | 96 | { |
165 | mu_error (_("file name not given")); | 97 | mu_error (_("file name not given")); |
166 | exit (1); | 98 | exit (1); |
167 | } | 99 | } |
168 | file = argv[index]; | 100 | else if (argc > 1) |
101 | { | ||
102 | mu_error (_("too many arguments")); | ||
103 | exit (1); | ||
104 | } | ||
105 | |||
106 | file = argv[0]; | ||
169 | 107 | ||
170 | prompter_init (); | 108 | prompter_init (); |
171 | if (erase_seq) | 109 | if (erase_seq) |
... | @@ -178,7 +116,7 @@ main (int argc, char **argv) | ... | @@ -178,7 +116,7 @@ main (int argc, char **argv) |
178 | mu_error (_("cannot open stdout: %s"), mu_strerror (rc)); | 116 | mu_error (_("cannot open stdout: %s"), mu_strerror (rc)); |
179 | return 1; | 117 | return 1; |
180 | } | 118 | } |
181 | 119 | ||
182 | if ((rc = mu_file_stream_create (&in, file, MU_STREAM_RDWR))) | 120 | if ((rc = mu_file_stream_create (&in, file, MU_STREAM_RDWR))) |
183 | { | 121 | { |
184 | mu_error (_("cannot open input file `%s': %s"), | 122 | mu_error (_("cannot open input file `%s': %s"), |
... | @@ -186,14 +124,13 @@ main (int argc, char **argv) | ... | @@ -186,14 +124,13 @@ main (int argc, char **argv) |
186 | return 1; | 124 | return 1; |
187 | } | 125 | } |
188 | rc = mu_stream_to_message (in, &msg); | 126 | rc = mu_stream_to_message (in, &msg); |
189 | mu_stream_unref (in); | ||
190 | if (rc) | 127 | if (rc) |
191 | { | 128 | { |
192 | mu_error (_("input stream %s is not a message (%s)"), | 129 | mu_error (_("input stream %s is not a message (%s)"), |
193 | file, mu_strerror (rc)); | 130 | file, mu_strerror (rc)); |
194 | return 1; | 131 | return 1; |
195 | } | 132 | } |
196 | 133 | ||
197 | if ((rc = mu_temp_file_stream_create (&tmp, NULL, 0))) | 134 | if ((rc = mu_temp_file_stream_create (&tmp, NULL, 0))) |
198 | { | 135 | { |
199 | mu_error (_("Cannot open temporary file: %s"), | 136 | mu_error (_("Cannot open temporary file: %s"), | ... | ... |
... | @@ -23,39 +23,9 @@ | ... | @@ -23,39 +23,9 @@ |
23 | #include <errno.h> | 23 | #include <errno.h> |
24 | #include <fcntl.h> | 24 | #include <fcntl.h> |
25 | 25 | ||
26 | static char doc[] = N_("GNU MH refile")"\v" | 26 | static char prog_doc[] = N_("GNU MH refile"); |
27 | N_("Options marked with `*' are not yet implemented.\n\ | ||
28 | Use -help to obtain the list of traditional MH options."); | ||
29 | static char args_doc[] = N_("MSGLIST FOLDER [FOLDER...]"); | 27 | static char args_doc[] = N_("MSGLIST FOLDER [FOLDER...]"); |
30 | 28 | ||
31 | /* GNU options */ | ||
32 | static struct argp_option options[] = { | ||
33 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
34 | N_("specify folder to operate upon")}, | ||
35 | {"draft", ARG_DRAFT, NULL, 0, | ||
36 | N_("use <mh-dir>/draft as the source message")}, | ||
37 | {"copy", ARG_LINK, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
38 | N_("preserve the source folder copy")}, | ||
39 | {"link", 0, NULL, OPTION_ALIAS, NULL}, | ||
40 | {"preserve", ARG_PRESERVE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
41 | N_("* try to preserve message sequence numbers")}, | ||
42 | {"source", ARG_SOURCE, N_("FOLDER"), 0, | ||
43 | N_("specify source folder; it will become the current folder after the program exits")}, | ||
44 | {"src", 0, NULL, OPTION_ALIAS, NULL}, | ||
45 | {"file", ARG_FILE, N_("FILE"), 0, N_("use FILE as the source message")}, | ||
46 | { 0 } | ||
47 | }; | ||
48 | |||
49 | /* Traditional MH options */ | ||
50 | struct mh_option mh_option[] = { | ||
51 | { "file", MH_OPT_ARG, "input-file"}, | ||
52 | { "draft" }, | ||
53 | { "link", MH_OPT_BOOL }, | ||
54 | { "preserve", MH_OPT_BOOL }, | ||
55 | { "src", MH_OPT_ARG, "folder" }, | ||
56 | { NULL } | ||
57 | }; | ||
58 | |||
59 | int link_flag = 0; | 29 | int link_flag = 0; |
60 | int preserve_flag = 0; | 30 | int preserve_flag = 0; |
61 | char *source_file = NULL; | 31 | char *source_file = NULL; |
... | @@ -72,9 +42,40 @@ add_folder (const char *folder) | ... | @@ -72,9 +42,40 @@ add_folder (const char *folder) |
72 | } | 42 | } |
73 | mu_list_append (folder_name_list, mu_strdup (folder)); | 43 | mu_list_append (folder_name_list, mu_strdup (folder)); |
74 | } | 44 | } |
45 | |||
46 | static void | ||
47 | add_folder_option (struct mu_parseopt *po, struct mu_option *opt, | ||
48 | const char *arg) | ||
49 | { | ||
50 | add_folder (arg); | ||
51 | } | ||
75 | 52 | ||
53 | static struct mu_option options[] = { | ||
54 | { "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
55 | N_("specify folder to operate upon"), | ||
56 | mu_c_string, NULL, add_folder_option }, | ||
57 | { "draft", 0, NULL, MU_OPTION_DEFAULT, | ||
58 | N_("use <mh-dir>/draft as the source message"), | ||
59 | mu_c_string, &source_file, NULL, "draft" }, | ||
60 | { "copy", 0, NULL, MU_OPTION_DEFAULT, | ||
61 | N_("preserve the source folder copy"), | ||
62 | mu_c_bool, &link_flag }, | ||
63 | { "link", 0, NULL, MU_OPTION_ALIAS }, | ||
64 | { "preserve", 0, NULL, MU_OPTION_HIDDEN, | ||
65 | N_("try to preserve message sequence numbers"), | ||
66 | mu_c_string, NULL, mh_opt_notimpl_warning }, | ||
67 | { "source", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
68 | N_("specify source folder; it will become the current folder after the program exits"), | ||
69 | mu_c_string, NULL, mh_opt_set_folder }, | ||
70 | { "src", 0, NULL, MU_OPTION_ALIAS }, | ||
71 | { "file", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
72 | N_("use FILE as the source message"), | ||
73 | mu_c_string, &source_file }, | ||
74 | MU_OPTION_END | ||
75 | }; | ||
76 | |||
76 | void | 77 | void |
77 | open_folders () | 78 | open_folders (void) |
78 | { | 79 | { |
79 | int rc; | 80 | int rc; |
80 | mu_iterator_t itr; | 81 | mu_iterator_t itr; |
... | @@ -139,47 +140,11 @@ _close_folder (void *unused, mu_mailbox_t mbox) | ... | @@ -139,47 +140,11 @@ _close_folder (void *unused, mu_mailbox_t mbox) |
139 | } | 140 | } |
140 | 141 | ||
141 | void | 142 | void |
142 | close_folders () | 143 | close_folders (void) |
143 | { | 144 | { |
144 | enumerate_folders (_close_folder, NULL); | 145 | enumerate_folders (_close_folder, NULL); |
145 | } | 146 | } |
146 | 147 | ||
147 | static int | ||
148 | opt_handler (int key, char *arg, struct argp_state *state) | ||
149 | { | ||
150 | switch (key) | ||
151 | { | ||
152 | case ARG_FOLDER: | ||
153 | add_folder (arg); | ||
154 | break; | ||
155 | |||
156 | case ARG_DRAFT: | ||
157 | source_file = "draft"; | ||
158 | break; | ||
159 | |||
160 | case ARG_LINK: | ||
161 | link_flag = is_true(arg); | ||
162 | break; | ||
163 | |||
164 | case ARG_PRESERVE: | ||
165 | mh_opt_notimpl_warning ("-preserve"); | ||
166 | preserve_flag = is_true(arg); | ||
167 | break; | ||
168 | |||
169 | case ARG_SOURCE: | ||
170 | mh_set_current_folder (arg); | ||
171 | break; | ||
172 | |||
173 | case ARG_FILE: | ||
174 | source_file = arg; | ||
175 | break; | ||
176 | |||
177 | default: | ||
178 | return ARGP_ERR_UNKNOWN; | ||
179 | } | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | void | 148 | void |
184 | refile_folder (void *data, mu_mailbox_t mbox) | 149 | refile_folder (void *data, mu_mailbox_t mbox) |
185 | { | 150 | { |
... | @@ -216,7 +181,6 @@ refile_iterator (size_t num, mu_message_t msg, void *data) | ... | @@ -216,7 +181,6 @@ refile_iterator (size_t num, mu_message_t msg, void *data) |
216 | int | 181 | int |
217 | main (int argc, char **argv) | 182 | main (int argc, char **argv) |
218 | { | 183 | { |
219 | int index; | ||
220 | mu_msgset_t msgset; | 184 | mu_msgset_t msgset; |
221 | mu_mailbox_t mbox; | 185 | mu_mailbox_t mbox; |
222 | int status, i, j; | 186 | int status, i, j; |
... | @@ -224,13 +188,7 @@ main (int argc, char **argv) | ... | @@ -224,13 +188,7 @@ main (int argc, char **argv) |
224 | /* Native Language Support */ | 188 | /* Native Language Support */ |
225 | MU_APP_INIT_NLS (); | 189 | MU_APP_INIT_NLS (); |
226 | 190 | ||
227 | mh_argp_init (); | 191 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
228 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
229 | opt_handler, NULL, &index); | ||
230 | |||
231 | argc -= index; | ||
232 | argv += index; | ||
233 | |||
234 | /* Collect any surplus folders */ | 192 | /* Collect any surplus folders */ |
235 | for (i = j = 0; i < argc; i++) | 193 | for (i = j = 0; i < argc; i++) |
236 | { | 194 | { | ... | ... |
... | @@ -22,89 +22,9 @@ | ... | @@ -22,89 +22,9 @@ |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <unistd.h> | 23 | #include <unistd.h> |
24 | 24 | ||
25 | static char doc[] = N_("GNU MH repl")"\v" | 25 | static char prog_doc[] = N_("GNU MH repl"); |
26 | N_("Options marked with `*' are not yet implemented.\n\ | ||
27 | Use -help to obtain the list of traditional MH options."); | ||
28 | static char args_doc[] = N_("[+FOLDER] [MESSAGE]"); | 26 | static char args_doc[] = N_("[+FOLDER] [MESSAGE]"); |
29 | 27 | ||
30 | |||
31 | /* GNU options */ | ||
32 | static struct argp_option options[] = { | ||
33 | {"annotate", ARG_ANNOTATE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
34 | N_("add Replied: header to the message being replied to")}, | ||
35 | {"build", ARG_BUILD, 0, 0, | ||
36 | N_("build the draft and quit immediately")}, | ||
37 | {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0, | ||
38 | N_("specify the folder for message drafts")}, | ||
39 | {"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0, | ||
40 | N_("undo the effect of the last --draftfolder option")}, | ||
41 | {"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0, | ||
42 | N_("invoke the draftmessage facility")}, | ||
43 | {"cc", ARG_CC, "{all|to|cc|me}", 0, | ||
44 | N_("specify whom to place on the Cc: list of the reply")}, | ||
45 | {"nocc", ARG_NOCC, "{all|to|cc|me}", 0, | ||
46 | N_("specify whom to remove from the Cc: list of the reply")}, | ||
47 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, N_("specify folder to operate upon")}, | ||
48 | {"group", ARG_GROUP, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
49 | N_("construct a group or followup reply") }, | ||
50 | {"editor", ARG_EDITOR, N_("PROG"), 0, N_("set the editor program to use")}, | ||
51 | {"noedit", ARG_NOEDIT, 0, 0, N_("suppress the initial edit")}, | ||
52 | {"fcc", ARG_FCC, N_("FOLDER"), 0, N_("set the folder to receive Fcc's")}, | ||
53 | {"filter", ARG_FILTER, N_("MHL-FILTER"), 0, | ||
54 | N_("set the mhl filter to preprocess the body of the message being replied")}, | ||
55 | {"form", ARG_FORM, N_("FILE"), 0, N_("read format from given file")}, | ||
56 | {"format", ARG_FORMAT, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
57 | N_("include a copy of the message being replied; the message will be processed using either the default filter \"mhl.reply\", or the filter specified by --filter option") }, | ||
58 | {"noformat", ARG_NOFORMAT, 0, OPTION_HIDDEN, "" }, | ||
59 | {"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
60 | N_("* annotate the message in place")}, | ||
61 | {"query", ARG_QUERY, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
62 | N_("* query for addresses to place in To: and Cc: lists")}, | ||
63 | {"width", ARG_WIDTH, N_("NUMBER"), 0, N_("set output width")}, | ||
64 | {"whatnowproc", ARG_WHATNOWPROC, N_("PROG"), 0, | ||
65 | N_("set the replacement for whatnow program")}, | ||
66 | {"nowhatnowproc", ARG_NOWHATNOWPROC, NULL, 0, | ||
67 | N_("don't run whatnowproc")}, | ||
68 | {"use", ARG_USE, N_("BOOL"), OPTION_ARG_OPTIONAL, N_("use draft file preserved after the last session") }, | ||
69 | { 0 } | ||
70 | }; | ||
71 | |||
72 | /* Traditional MH options */ | ||
73 | struct mh_option mh_option[] = { | ||
74 | { "annotate", MH_OPT_BOOL }, | ||
75 | { "build" }, | ||
76 | { "cc", MH_OPT_ARG, "all/to/cc/me"}, | ||
77 | { "nocc", MH_OPT_ARG, "all/to/cc/me"}, | ||
78 | { "form", MH_OPT_ARG, "formatfile"}, | ||
79 | { "width", MH_OPT_ARG, "number"}, | ||
80 | { "draftfolder", MH_OPT_ARG, "folder"}, | ||
81 | { "nodraftfolder" }, | ||
82 | { "draftmessage" }, | ||
83 | { "editor", MH_OPT_ARG, "program"}, | ||
84 | { "noedit" }, | ||
85 | { "fcc", MH_OPT_ARG, "folder"}, | ||
86 | { "filter", MH_OPT_ARG, "program"}, | ||
87 | { "format", MH_OPT_BOOL }, | ||
88 | { "group", MH_OPT_BOOL }, | ||
89 | { "inplace", MH_OPT_BOOL }, | ||
90 | { "query", MH_OPT_BOOL }, | ||
91 | { "whatnowproc", MH_OPT_ARG, "program"}, | ||
92 | { "nowhatnowproc" }, | ||
93 | { NULL } | ||
94 | }; | ||
95 | |||
96 | static char default_format_str[] = | ||
97 | "%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)" | ||
98 | "%<(nonnull)%(void(width))%(putaddr To: )\\n%>" | ||
99 | "%(lit)%<(rcpt to)%(formataddr{to})%>%<(rcpt cc)%(formataddr{cc})%>%<(rcpt me)%(formataddr(me))%>" | ||
100 | "%<(nonnull)%(void(width))%(putaddr cc: )\\n%>" | ||
101 | "%<{fcc}Fcc: %{fcc}\\n%>" | ||
102 | "%<{subject}Subject: Re: %(unre{subject})\\n%>" | ||
103 | "%(lit)%(concat(in_reply_to))%<(nonnull)%(void(width))%(printhdr In-reply-to: )\\n%>" | ||
104 | "%(lit)%(concat(references))%<(nonnull)%(void(width))%(printhdr References: )\\n%>" | ||
105 | "X-Mailer: MH \\(%(package_string)\\)\\n" | ||
106 | "--------\n"; | ||
107 | |||
108 | static char *format_str = NULL; | 28 | static char *format_str = NULL; |
109 | static mh_format_t format; | 29 | static mh_format_t format; |
110 | static int width = 80; | 30 | static int width = 80; |
... | @@ -114,12 +34,11 @@ static int initial_edit = 1; | ... | @@ -114,12 +34,11 @@ static int initial_edit = 1; |
114 | static const char *whatnowproc; | 34 | static const char *whatnowproc; |
115 | static mu_msgset_t msgset; | 35 | static mu_msgset_t msgset; |
116 | static mu_mailbox_t mbox; | 36 | static mu_mailbox_t mbox; |
117 | static int build_only = 0; /* --build flag */ | 37 | static int build_only = 0; /* -build flag */ |
118 | static int nowhatnowproc = 0; /* --nowhatnowproc */ | 38 | static int nowhatnowproc = 0; /* -nowhatnowproc */ |
119 | static int query_mode = 0; /* --query flag */ | 39 | static int use_draft = 0; /* -use flag */ |
120 | static int use_draft = 0; /* --use flag */ | 40 | static char *mhl_filter = NULL; /* -filter flag */ |
121 | static char *mhl_filter = NULL; /* --filter flag */ | 41 | static int annotate; /* -annotate flag */ |
122 | static int annotate; /* --annotate flag */ | ||
123 | static char *draftmessage = "new"; | 42 | static char *draftmessage = "new"; |
124 | static const char *draftfolder = NULL; | 43 | static const char *draftfolder = NULL; |
125 | static mu_opool_t fcc_pool; | 44 | static mu_opool_t fcc_pool; |
... | @@ -136,146 +55,136 @@ decode_cc_flag (const char *opt, const char *arg) | ... | @@ -136,146 +55,136 @@ decode_cc_flag (const char *opt, const char *arg) |
136 | } | 55 | } |
137 | return rc; | 56 | return rc; |
138 | } | 57 | } |
58 | |||
59 | static void | ||
60 | set_cc (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
61 | { | ||
62 | rcpt_mask |= decode_cc_flag ("-cc", arg); | ||
63 | } | ||
64 | |||
65 | static void | ||
66 | clr_cc (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
67 | { | ||
68 | rcpt_mask &= ~decode_cc_flag ("-nocc", arg); | ||
69 | } | ||
139 | 70 | ||
140 | static error_t | 71 | static void |
141 | opt_handler (int key, char *arg, struct argp_state *state) | 72 | set_fcc (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
142 | { | 73 | { |
143 | switch (key) | 74 | if (!has_fcc) |
144 | { | 75 | { |
145 | case ARGP_KEY_INIT: | 76 | mu_opool_create (&fcc_pool, 1); |
146 | draftfolder = mh_global_profile_get ("Draft-Folder", NULL); | 77 | has_fcc = 1; |
147 | whatnowproc = mh_global_profile_get ("whatnowproc", NULL); | 78 | } |
148 | break; | 79 | else |
149 | 80 | mu_opool_append (fcc_pool, ", ", 2); | |
150 | case ARG_ANNOTATE: | 81 | mu_opool_appendz (fcc_pool, arg); |
151 | annotate = is_true (arg); | 82 | } |
152 | break; | ||
153 | |||
154 | case ARG_BUILD: | ||
155 | build_only = 1; | ||
156 | break; | ||
157 | |||
158 | case ARG_CC: | ||
159 | rcpt_mask |= decode_cc_flag ("-cc", arg); | ||
160 | break; | ||
161 | 83 | ||
162 | case ARG_NOCC: | 84 | static void |
163 | rcpt_mask &= ~decode_cc_flag ("-nocc", arg); | 85 | set_whatnowproc (struct mu_parseopt *po, struct mu_option *opt, |
164 | break; | 86 | char const *arg) |
165 | 87 | { | |
166 | case ARG_DRAFTFOLDER: | 88 | whatnowproc = mu_strdup (arg); |
167 | draftfolder = arg; | 89 | nowhatnowproc = 0; |
168 | break; | 90 | } |
169 | |||
170 | case ARG_EDITOR: | ||
171 | wh_env.editor = arg; | ||
172 | break; | ||
173 | |||
174 | case ARG_FOLDER: | ||
175 | mh_set_current_folder (arg); | ||
176 | break; | ||
177 | 91 | ||
178 | case ARG_FORM: | 92 | static void |
93 | set_group (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
94 | { | ||
95 | if (strcmp (arg, "1") == 0) | ||
96 | { | ||
97 | if (mh_read_formfile ("replgroupcomps", &format_str)) | ||
98 | exit (1); | ||
99 | rcpt_mask |= RCPT_ALL; | ||
100 | } | ||
101 | else | ||
102 | { | ||
179 | free (format_str); | 103 | free (format_str); |
180 | format_str = NULL; | 104 | format_str = NULL; |
181 | if (mh_read_formfile (arg, &format_str)) | ||
182 | exit (1); | ||
183 | break; | ||
184 | |||
185 | case ARG_GROUP: | ||
186 | if (is_true (arg)) | ||
187 | { | ||
188 | if (mh_read_formfile ("replgroupcomps", &format_str)) | ||
189 | exit (1); | ||
190 | rcpt_mask |= RCPT_ALL; | ||
191 | } | ||
192 | else | ||
193 | { | ||
194 | free (format_str); | ||
195 | format_str = NULL; | ||
196 | } | ||
197 | break; | ||
198 | |||
199 | case ARG_DRAFTMESSAGE: | ||
200 | draftmessage = arg; | ||
201 | break; | ||
202 | |||
203 | case ARG_USE: | ||
204 | use_draft = is_true (arg); | ||
205 | break; | ||
206 | |||
207 | case ARG_WIDTH: | ||
208 | width = strtoul (arg, NULL, 0); | ||
209 | if (!width) | ||
210 | { | ||
211 | argp_error (state, _("invalid width")); | ||
212 | exit (1); | ||
213 | } | ||
214 | break; | ||
215 | |||
216 | case ARG_NODRAFTFOLDER: | ||
217 | draftfolder = NULL; | ||
218 | break; | ||
219 | |||
220 | case ARG_NOEDIT: | ||
221 | initial_edit = 0; | ||
222 | break; | ||
223 | |||
224 | case ARG_QUERY: | ||
225 | query_mode = is_true (arg); | ||
226 | if (query_mode) | ||
227 | mh_opt_notimpl_warning ("-query"); | ||
228 | break; | ||
229 | |||
230 | case ARG_FILTER: | ||
231 | mh_find_file (arg, &mhl_filter); | ||
232 | break; | ||
233 | |||
234 | case ARG_FORMAT: | ||
235 | if (is_true (arg)) | ||
236 | mh_find_file ("mhl.repl", &mhl_filter); | ||
237 | else | ||
238 | mhl_filter = NULL; | ||
239 | break; | ||
240 | |||
241 | case ARG_NOFORMAT: | ||
242 | mhl_filter = NULL; | ||
243 | break; | ||
244 | |||
245 | case ARG_FCC: | ||
246 | if (!has_fcc) | ||
247 | { | ||
248 | mu_opool_create (&fcc_pool, 1); | ||
249 | has_fcc = 1; | ||
250 | } | ||
251 | else | ||
252 | mu_opool_append (fcc_pool, ", ", 2); | ||
253 | mu_opool_appendz (fcc_pool, arg); | ||
254 | break; | ||
255 | |||
256 | case ARG_INPLACE: | ||
257 | mh_opt_notimpl_warning ("-inplace"); | ||
258 | break; | ||
259 | |||
260 | case ARG_WHATNOWPROC: | ||
261 | whatnowproc = arg; | ||
262 | break; | ||
263 | |||
264 | case ARG_NOWHATNOWPROC: | ||
265 | nowhatnowproc = 1; | ||
266 | break; | ||
267 | |||
268 | case ARGP_KEY_FINI: | ||
269 | if (!format_str) | ||
270 | format_str = default_format_str; | ||
271 | break; | ||
272 | |||
273 | default: | ||
274 | return ARGP_ERR_UNKNOWN; | ||
275 | } | 105 | } |
276 | return 0; | ||
277 | } | 106 | } |
278 | 107 | ||
108 | static struct mu_option options[] = { | ||
109 | { "annotate", 0, NULL, MU_OPTION_DEFAULT, | ||
110 | N_("add Replied: header to the message being replied to"), | ||
111 | mu_c_bool, &annotate }, | ||
112 | { "build", 0, NULL, MU_OPTION_DEFAULT, | ||
113 | N_("build the draft and quit immediately"), | ||
114 | mu_c_bool, &build_only }, | ||
115 | { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
116 | N_("specify the folder for message drafts"), | ||
117 | mu_c_string, &draftfolder }, | ||
118 | { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT, | ||
119 | N_("undo the effect of the last --draftfolder option"), | ||
120 | mu_c_string, &draftfolder, mh_opt_clear_string }, | ||
121 | { "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT, | ||
122 | N_("invoke the draftmessage facility"), | ||
123 | mu_c_string, &draftmessage }, | ||
124 | { "cc", 0, "{all|to|cc|me}", 0, | ||
125 | N_("specify whom to place on the Cc: list of the reply"), | ||
126 | mu_c_string, NULL, set_cc }, | ||
127 | { "nocc", 0, "{all|to|cc|me}", 0, | ||
128 | N_("specify whom to remove from the Cc: list of the reply"), | ||
129 | mu_c_string, NULL, clr_cc }, | ||
130 | { "group", 0, NULL, MU_OPTION_DEFAULT, | ||
131 | N_("construct a group or followup reply"), | ||
132 | mu_c_string, NULL, set_group }, | ||
133 | { "editor", 0, N_("PROG"), MU_OPTION_DEFAULT, | ||
134 | N_("set the editor program to use"), | ||
135 | mu_c_string, &wh_env.editor }, | ||
136 | { "noedit", 0, NULL, MU_OPTION_DEFAULT, | ||
137 | N_("suppress the initial edit"), | ||
138 | mu_c_int, &initial_edit, NULL, "0" }, | ||
139 | { "fcc", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
140 | N_("set the folder to receive Fcc's"), | ||
141 | mu_c_string, NULL, set_fcc }, | ||
142 | { "filter", 0, N_("MHL-FILTER"), MU_OPTION_DEFAULT, | ||
143 | N_("set the mhl filter to preprocess the body of the message being replied"), | ||
144 | mu_c_string, &mhl_filter, mh_opt_find_file }, | ||
145 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
146 | N_("read format from given file") , | ||
147 | mu_c_string, &format_str, mh_opt_read_formfile }, | ||
148 | { "format", 0, NULL, MU_OPTION_DEFAULT, | ||
149 | N_("include a copy of the message being replied; the message will be processed using either the default filter \"mhl.reply\", or the filter specified by --filter option"), | ||
150 | mu_c_string, &mhl_filter, mh_opt_find_file, "mhl.repl" }, | ||
151 | { "noformat", 0, NULL, MU_OPTION_DEFAULT, | ||
152 | N_("cancels the effect of the recent -format option"), | ||
153 | mu_c_string, &mhl_filter, mh_opt_clear_string }, | ||
154 | { "inplace", 0, NULL, MU_OPTION_HIDDEN, | ||
155 | N_("annotate the message in place"), | ||
156 | mu_c_string, NULL, mh_opt_notimpl_warning }, | ||
157 | { "query", 0, NULL, MU_OPTION_HIDDEN, | ||
158 | N_("query for addresses to place in To: and Cc: lists"), | ||
159 | mu_c_string, NULL, mh_opt_notimpl_warning }, | ||
160 | { "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT, | ||
161 | N_("set output width"), | ||
162 | mu_c_int, &width }, | ||
163 | { "whatnowproc", 0, N_("PROG"), MU_OPTION_DEFAULT, | ||
164 | N_("set the replacement for whatnow program"), | ||
165 | mu_c_string, NULL, set_whatnowproc }, | ||
166 | { "nowhatnowproc", 0, NULL, MU_OPTION_DEFAULT, | ||
167 | N_("don't run whatnowproc"), | ||
168 | mu_c_int, &nowhatnowproc, NULL, "1" }, | ||
169 | { "use", 0, NULL, MU_OPTION_DEFAULT, | ||
170 | N_("use draft file preserved after the last session"), | ||
171 | mu_c_bool, &use_draft }, | ||
172 | |||
173 | MU_OPTION_END | ||
174 | }; | ||
175 | |||
176 | static char default_format_str[] = | ||
177 | "%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)" | ||
178 | "%<(nonnull)%(void(width))%(putaddr To: )\\n%>" | ||
179 | "%(lit)%<(rcpt to)%(formataddr{to})%>%<(rcpt cc)%(formataddr{cc})%>%<(rcpt me)%(formataddr(me))%>" | ||
180 | "%<(nonnull)%(void(width))%(putaddr cc: )\\n%>" | ||
181 | "%<{fcc}Fcc: %{fcc}\\n%>" | ||
182 | "%<{subject}Subject: Re: %(unre{subject})\\n%>" | ||
183 | "%(lit)%(concat(in_reply_to))%<(nonnull)%(void(width))%(printhdr In-reply-to: )\\n%>" | ||
184 | "%(lit)%(concat(references))%<(nonnull)%(void(width))%(printhdr References: )\\n%>" | ||
185 | "X-Mailer: MH \\(%(package_string)\\)\\n" | ||
186 | "--------\n"; | ||
187 | |||
279 | void | 188 | void |
280 | make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh) | 189 | make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh) |
281 | { | 190 | { |
... | @@ -396,15 +305,20 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh) | ... | @@ -396,15 +305,20 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh) |
396 | int | 305 | int |
397 | main (int argc, char **argv) | 306 | main (int argc, char **argv) |
398 | { | 307 | { |
399 | int index, rc; | 308 | int rc; |
400 | 309 | ||
401 | /* Native Language Support */ | 310 | /* Native Language Support */ |
402 | MU_APP_INIT_NLS (); | 311 | MU_APP_INIT_NLS (); |
403 | 312 | ||
404 | mh_argp_init (); | 313 | draftfolder = mh_global_profile_get ("Draft-Folder", NULL); |
314 | whatnowproc = mh_global_profile_get ("whatnowproc", NULL); | ||
315 | |||
316 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, | ||
317 | args_doc, prog_doc, NULL); | ||
318 | |||
319 | if (!format_str) | ||
320 | format_str = default_format_str; | ||
405 | 321 | ||
406 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
407 | opt_handler, NULL, &index); | ||
408 | if (mh_format_parse (format_str, &format)) | 322 | if (mh_format_parse (format_str, &format)) |
409 | { | 323 | { |
410 | mu_error (_("Bad format string")); | 324 | mu_error (_("Bad format string")); |
... | @@ -412,7 +326,7 @@ main (int argc, char **argv) | ... | @@ -412,7 +326,7 @@ main (int argc, char **argv) |
412 | } | 326 | } |
413 | 327 | ||
414 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); | 328 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); |
415 | mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur"); | 329 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); |
416 | if (!mh_msgset_single_message (msgset)) | 330 | if (!mh_msgset_single_message (msgset)) |
417 | { | 331 | { |
418 | mu_error (_("only one message at a time!")); | 332 | mu_error (_("only one message at a time!")); | ... | ... |
... | @@ -28,29 +28,9 @@ | ... | @@ -28,29 +28,9 @@ |
28 | 28 | ||
29 | #include <dirent.h> | 29 | #include <dirent.h> |
30 | 30 | ||
31 | static char doc[] = N_("GNU MH rmf")"\v" | 31 | static char prog_doc[] = N_("GNU MH rmf"); |
32 | N_("Use -help to obtain the list of traditional MH options."); | ||
33 | static char args_doc[] = N_("[+FOLDER]"); | 32 | static char args_doc[] = N_("[+FOLDER]"); |
34 | 33 | ||
35 | /* GNU options */ | ||
36 | static struct argp_option options[] = { | ||
37 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
38 | N_("specify the folder to delete")}, | ||
39 | {"interactive", ARG_INTERACTIVE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
40 | N_("interactive mode: ask for confirmation before removing each folder")}, | ||
41 | {"nointeractive", ARG_NOINTERACTIVE, NULL, OPTION_HIDDEN, ""}, | ||
42 | {"recursive", ARG_RECURSIVE, NULL, 0, | ||
43 | N_("recursively delete all subfolders")}, | ||
44 | {"norecursive", ARG_NORECURSIVE, NULL, OPTION_HIDDEN, ""}, | ||
45 | { 0 } | ||
46 | }; | ||
47 | |||
48 | /* Traditional MH options */ | ||
49 | struct mh_option mh_option[] = { | ||
50 | { "interactive", MH_OPT_BOOL }, | ||
51 | { 0 } | ||
52 | }; | ||
53 | |||
54 | int explicit_folder; /* Was the folder explicitly given */ | 34 | int explicit_folder; /* Was the folder explicitly given */ |
55 | int interactive; /* Ask for confirmation before deleting */ | 35 | int interactive; /* Ask for confirmation before deleting */ |
56 | int recursive; /* Recursively process all the sub-directories */ | 36 | int recursive; /* Recursively process all the sub-directories */ |
... | @@ -59,38 +39,26 @@ static char *cur_folder_path; /* Full pathname of the current folder */ | ... | @@ -59,38 +39,26 @@ static char *cur_folder_path; /* Full pathname of the current folder */ |
59 | static char *folder_name; /* Name of the (topmost) folder to be | 39 | static char *folder_name; /* Name of the (topmost) folder to be |
60 | deleted */ | 40 | deleted */ |
61 | 41 | ||
62 | static error_t | 42 | static void |
63 | opt_handler (int key, char *arg, struct argp_state *state) | 43 | set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
64 | { | 44 | { |
65 | switch (key) | 45 | explicit_folder = 1; |
66 | { | 46 | folder_name = mu_strdup (arg); |
67 | case ARG_FOLDER: | 47 | } |
68 | explicit_folder = 1; | 48 | |
69 | folder_name = arg; | 49 | static struct mu_option options[] = { |
70 | break; | 50 | { "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, |
71 | 51 | N_("specify the folder to delete"), | |
72 | case ARG_INTERACTIVE: | 52 | mu_c_string, NULL, set_folder }, |
73 | interactive = is_true (arg); | 53 | { "interactive", 0, NULL, MU_OPTION_DEFAULT, |
74 | break; | 54 | N_("interactive mode: ask for confirmation before removing each folder"), |
75 | 55 | mu_c_bool, &interactive }, | |
76 | case ARG_NOINTERACTIVE: | 56 | { "recursive", 0, NULL, MU_OPTION_DEFAULT, |
77 | interactive = 0; | 57 | N_("recursively delete all subfolders"), |
78 | break; | 58 | mu_c_bool, &recursive }, |
79 | 59 | MU_OPTION_END | |
80 | case ARG_RECURSIVE: | 60 | }; |
81 | recursive = is_true (arg); | 61 | |
82 | break; | ||
83 | |||
84 | case ARG_NORECURSIVE: | ||
85 | recursive = 0; | ||
86 | break; | ||
87 | |||
88 | default: | ||
89 | return ARGP_ERR_UNKNOWN; | ||
90 | } | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static char * | 62 | static char * |
95 | current_folder_path (void) | 63 | current_folder_path (void) |
96 | { | 64 | { |
... | @@ -185,9 +153,7 @@ main (int argc, char **argv) | ... | @@ -185,9 +153,7 @@ main (int argc, char **argv) |
185 | /* Native Language Support */ | 153 | /* Native Language Support */ |
186 | MU_APP_INIT_NLS (); | 154 | MU_APP_INIT_NLS (); |
187 | 155 | ||
188 | mh_argp_init (); | 156 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
189 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
190 | opt_handler, NULL, NULL); | ||
191 | 157 | ||
192 | cur_folder_path = current_folder_path (); | 158 | cur_folder_path = current_folder_path (); |
193 | 159 | ... | ... |
... | @@ -19,37 +19,9 @@ | ... | @@ -19,37 +19,9 @@ |
19 | 19 | ||
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | 21 | ||
22 | static char doc[] = N_("GNU MH rmm")"\v" | 22 | static char prog_doc[] = N_("GNU MH rmm"); |
23 | N_("Use -help to obtain the list of traditional MH options."); | ||
24 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); | 23 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); |
25 | 24 | ||
26 | /* GNU options */ | ||
27 | static struct argp_option options[] = { | ||
28 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
29 | N_("specify folder to operate upon")}, | ||
30 | { 0 } | ||
31 | }; | ||
32 | |||
33 | /* Traditional MH options */ | ||
34 | struct mh_option mh_option[] = { | ||
35 | { NULL } | ||
36 | }; | ||
37 | |||
38 | static error_t | ||
39 | opt_handler (int key, char *arg, struct argp_state *state) | ||
40 | { | ||
41 | switch (key) | ||
42 | { | ||
43 | case ARG_FOLDER: | ||
44 | mh_set_current_folder (arg); | ||
45 | break; | ||
46 | |||
47 | default: | ||
48 | return ARGP_ERR_UNKNOWN; | ||
49 | } | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static int | 25 | static int |
54 | rmm (size_t num, mu_message_t msg, void *data) | 26 | rmm (size_t num, mu_message_t msg, void *data) |
55 | { | 27 | { |
... | @@ -79,7 +51,6 @@ rmseq (const char *name, const char *value, void *data) | ... | @@ -79,7 +51,6 @@ rmseq (const char *name, const char *value, void *data) |
79 | int | 51 | int |
80 | main (int argc, char **argv) | 52 | main (int argc, char **argv) |
81 | { | 53 | { |
82 | int index = 0; | ||
83 | mu_mailbox_t mbox; | 54 | mu_mailbox_t mbox; |
84 | mu_msgset_t msgset; | 55 | mu_msgset_t msgset; |
85 | int status; | 56 | int status; |
... | @@ -88,13 +59,12 @@ main (int argc, char **argv) | ... | @@ -88,13 +59,12 @@ main (int argc, char **argv) |
88 | /* Native Language Support */ | 59 | /* Native Language Support */ |
89 | MU_APP_INIT_NLS (); | 60 | MU_APP_INIT_NLS (); |
90 | 61 | ||
91 | mh_argp_init (); | 62 | mh_getopt (&argc, &argv, NULL, MH_GETOPT_DEFAULT_FOLDER, |
92 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 63 | args_doc, prog_doc, NULL); |
93 | opt_handler, NULL, &index); | ||
94 | 64 | ||
95 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); | 65 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); |
96 | 66 | ||
97 | mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur"); | 67 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); |
98 | 68 | ||
99 | status = mu_msgset_foreach_message (msgset, rmm, NULL); | 69 | status = mu_msgset_foreach_message (msgset, rmm, NULL); |
100 | 70 | ... | ... |
... | @@ -26,7 +26,7 @@ | ... | @@ -26,7 +26,7 @@ |
26 | #include <time.h> | 26 | #include <time.h> |
27 | #include <mailutils/observer.h> | 27 | #include <mailutils/observer.h> |
28 | 28 | ||
29 | static char progdoc[] = N_("GNU MH scan"); | 29 | static char prog_doc[] = N_("GNU MH scan"); |
30 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); | 30 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); |
31 | 31 | ||
32 | static int clear; | 32 | static int clear; |
... | @@ -107,7 +107,7 @@ main (int argc, char **argv) | ... | @@ -107,7 +107,7 @@ main (int argc, char **argv) |
107 | MU_APP_INIT_NLS (); | 107 | MU_APP_INIT_NLS (); |
108 | 108 | ||
109 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, | 109 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
110 | args_doc, progdoc, NULL); | 110 | args_doc, prog_doc, NULL); |
111 | 111 | ||
112 | if (mh_format_parse (format_str, &format)) | 112 | if (mh_format_parse (format_str, &format)) |
113 | { | 113 | { | ... | ... |
... | @@ -23,91 +23,13 @@ | ... | @@ -23,91 +23,13 @@ |
23 | #include <stdarg.h> | 23 | #include <stdarg.h> |
24 | #include <pwd.h> | 24 | #include <pwd.h> |
25 | 25 | ||
26 | static char doc[] = N_("GNU MH send")"\v" | 26 | static char prog_doc[] = N_("GNU MH send"); |
27 | N_("Options marked with `*' are not yet implemented.\n\ | ||
28 | Use -help to obtain the list of traditional MH options."); | ||
29 | static char args_doc[] = N_("FILE [FILE...]"); | 27 | static char args_doc[] = N_("FILE [FILE...]"); |
30 | 28 | ||
31 | /* GNU options */ | ||
32 | static struct argp_option options[] = { | ||
33 | {"alias", ARG_ALIAS, N_("FILE"), 0, | ||
34 | N_("specify additional alias file") }, | ||
35 | {"draft", ARG_DRAFT, NULL, 0, | ||
36 | N_("use prepared draft") }, | ||
37 | {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0, | ||
38 | N_("specify the folder for message drafts") }, | ||
39 | {"draftmessage", ARG_DRAFTMESSAGE, N_("MSG"), 0, | ||
40 | N_("use MSG from the draftfolder as a draft") }, | ||
41 | {"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0, | ||
42 | N_("undo the effect of the last --draftfolder option") }, | ||
43 | {"filter", ARG_FILTER, N_("FILE"), 0, | ||
44 | N_("* use filter FILE to preprocess the body of the message") }, | ||
45 | {"nofilter", ARG_NOFILTER, NULL, 0, | ||
46 | N_("* undo the effect of the last --filter option") }, | ||
47 | {"format", ARG_FORMAT, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
48 | N_("* reformat To: and Cc: addresses") }, | ||
49 | {"noformat", ARG_NOFORMAT, NULL, OPTION_HIDDEN, "" }, | ||
50 | {"forward", ARG_FORWARD, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
51 | N_("* in case of failure forward the draft along with the failure notice to the sender") }, | ||
52 | {"noforward", ARG_NOFORWARD, NULL, OPTION_HIDDEN, "" }, | ||
53 | {"mime", ARG_MIME, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
54 | N_("* use MIME encapsulation") }, | ||
55 | {"nomime", ARG_NOMIME, NULL, OPTION_HIDDEN, "" }, | ||
56 | {"msgid", ARG_MSGID, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
57 | N_("add Message-ID: field") }, | ||
58 | {"nomsgid", ARG_NOMSGID, NULL, OPTION_HIDDEN, ""}, | ||
59 | {"push", ARG_PUSH, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
60 | N_("run in the background") }, | ||
61 | {"nopush", ARG_NOPUSH, NULL, OPTION_HIDDEN, "" }, | ||
62 | {"preserve", ARG_PRESERVE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
63 | N_("keep draft files") }, | ||
64 | {"keep", 0, NULL, OPTION_ALIAS, NULL}, | ||
65 | {"split", ARG_SPLIT, N_("SECONDS"), 0, | ||
66 | N_("split the draft into several partial messages and send them with SECONDS interval") }, | ||
67 | {"chunksize", ARG_CHUNKSIZE, N_("NUMBER"), 0, | ||
68 | N_("set the size of chunk for --split (in bytes)") }, | ||
69 | {"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
70 | N_("print the transcript of interactions with the transport system") }, | ||
71 | {"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "" }, | ||
72 | {"watch", ARG_WATCH, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
73 | N_("monitor the delivery of mail") }, | ||
74 | {"nowatch", ARG_NOWATCH, NULL, OPTION_HIDDEN, "" }, | ||
75 | {"width", ARG_WIDTH, N_("NUMBER"), 0, | ||
76 | N_("* make header fields no longer than NUMBER columns") }, | ||
77 | { 0 } | ||
78 | }; | ||
79 | |||
80 | /* Traditional MH options */ | ||
81 | struct mh_option mh_option[] = { | ||
82 | { "alias", MH_OPT_ARG, "aliasfile" }, | ||
83 | { "draft" }, | ||
84 | { "draftfolder", MH_OPT_ARG, "folder" }, | ||
85 | { "draftmessage", MH_OPT_ARG, "message" }, | ||
86 | { "nodraftfolder" }, | ||
87 | { "filter", MH_OPT_ARG, "filterfile" }, | ||
88 | { "nofilter" }, | ||
89 | { "format", MH_OPT_BOOL }, | ||
90 | { "forward", MH_OPT_BOOL }, | ||
91 | { "mime", MH_OPT_BOOL }, | ||
92 | { "msgid", MH_OPT_BOOL }, | ||
93 | { "push", MH_OPT_BOOL }, | ||
94 | { "preserve", MH_OPT_BOOL }, | ||
95 | { "keep", MH_OPT_BOOL }, | ||
96 | { "split", MH_OPT_ARG, "seconds" }, | ||
97 | { "verbose", MH_OPT_BOOL }, | ||
98 | { "watch", MH_OPT_BOOL }, | ||
99 | { "width" }, | ||
100 | { NULL } | ||
101 | }; | ||
102 | |||
103 | static const char *draftfolder; /* Use this draft folder */ | 29 | static const char *draftfolder; /* Use this draft folder */ |
104 | static int use_draftfolder = 1; | 30 | static int use_draftfolder = 1; |
105 | static int use_draft; | 31 | static int use_draft; |
106 | 32 | ||
107 | static int reformat_recipients; /* --format option */ | ||
108 | static int forward_notice; /* Forward the failure notice to the sender, | ||
109 | --forward flag */ | ||
110 | static int mime_encaps; /* Use MIME encapsulation */ | ||
111 | static int append_msgid; /* Append Message-ID: header */ | 33 | static int append_msgid; /* Append Message-ID: header */ |
112 | static int background; /* Operate in the background */ | 34 | static int background; /* Operate in the background */ |
113 | 35 | ||
... | @@ -117,7 +39,6 @@ static unsigned long split_interval; /* Interval in seconds between sending two | ... | @@ -117,7 +39,6 @@ static unsigned long split_interval; /* Interval in seconds between sending two |
117 | static size_t split_size = 76*632; /* Size of split parts */ | 39 | static size_t split_size = 76*632; /* Size of split parts */ |
118 | static int verbose; /* Produce verbose diagnostics */ | 40 | static int verbose; /* Produce verbose diagnostics */ |
119 | static int watch; /* Watch the delivery process */ | 41 | static int watch; /* Watch the delivery process */ |
120 | static unsigned width = 76; /* Maximum width of header fields */ | ||
121 | 42 | ||
122 | static int keep_files; /* Keep draft files */ | 43 | static int keep_files; /* Keep draft files */ |
123 | 44 | ||
... | @@ -128,147 +49,116 @@ static int keep_files; /* Keep draft files */ | ... | @@ -128,147 +49,116 @@ static int keep_files; /* Keep draft files */ |
128 | watch_printf c;\ | 49 | watch_printf c;\ |
129 | } while (0) | 50 | } while (0) |
130 | 51 | ||
131 | static int add_file (char *name); | 52 | static int add_file (char const *name); |
132 | static void mesg_list_fixup (void); | 53 | static void mesg_list_fixup (void); |
54 | |||
55 | static void | ||
56 | add_alias (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
57 | { | ||
58 | mh_alias_read (arg, 1); | ||
59 | } | ||
133 | 60 | ||
134 | static error_t | 61 | static void |
135 | opt_handler (int key, char *arg, struct argp_state *state) | 62 | set_draftfolder (struct mu_parseopt *po, struct mu_option *opt, |
63 | char const *arg) | ||
136 | { | 64 | { |
137 | char *p; | 65 | draftfolder = mu_strdup (arg); |
138 | 66 | use_draftfolder = 1; | |
139 | switch (key) | 67 | } |
140 | { | ||
141 | case ARG_ALIAS: | ||
142 | mh_alias_read (arg, 1); | ||
143 | break; | ||
144 | 68 | ||
145 | case ARG_CHUNKSIZE: | 69 | static void |
146 | split_size = strtoul (arg, &p, 10); | 70 | add_draftmessage (struct mu_parseopt *po, struct mu_option *opt, |
147 | if (*p) | 71 | char const *arg) |
148 | { | 72 | { |
149 | argp_error (state, "%s: %s", arg, _("invalid number")); | 73 | add_file (arg); |
150 | exit (1); | 74 | } |
151 | } | ||
152 | break; | ||
153 | |||
154 | case ARG_DRAFT: | ||
155 | use_draft = 1; | ||
156 | break; | ||
157 | |||
158 | case ARG_DRAFTFOLDER: | ||
159 | draftfolder = arg; | ||
160 | use_draftfolder = 1; | ||
161 | break; | ||
162 | |||
163 | case ARG_NODRAFTFOLDER: | ||
164 | draftfolder = NULL; | ||
165 | use_draftfolder = 0; | ||
166 | break; | ||
167 | |||
168 | case ARG_DRAFTMESSAGE: | ||
169 | add_file (arg); | ||
170 | break; | ||
171 | |||
172 | case ARG_FILTER: | ||
173 | mh_opt_notimpl ("-filter"); | ||
174 | break; | ||
175 | 75 | ||
176 | case ARG_NOFILTER: | 76 | static void |
177 | mh_opt_notimpl ("-nofilter"); | 77 | set_split_opt (struct mu_parseopt *po, struct mu_option *opt, |
178 | break; | 78 | char const *arg) |
179 | 79 | { | |
180 | case ARG_FORMAT: | 80 | char *errmsg; |
181 | mh_opt_notimpl_warning ("-format"); | 81 | int rc = mu_str_to_c (arg, opt->opt_type, opt->opt_ptr, &errmsg); |
182 | reformat_recipients = is_true (arg); | 82 | if (rc) |
183 | break; | 83 | { |
184 | 84 | char const *errtext; | |
185 | case ARG_NOFORMAT: | 85 | if (errmsg) |
186 | mh_opt_notimpl_warning ("-noformat"); | 86 | errtext = errmsg; |
187 | reformat_recipients = 0; | 87 | else |
188 | break; | 88 | errtext = mu_strerror (rc); |
189 | |||
190 | case ARG_FORWARD: | ||
191 | mh_opt_notimpl_warning ("-forward"); | ||
192 | forward_notice = is_true (arg); | ||
193 | break; | ||
194 | |||
195 | case ARG_NOFORWARD: | ||
196 | mh_opt_notimpl_warning ("-noforward"); | ||
197 | forward_notice = 0; | ||
198 | break; | ||
199 | |||
200 | case ARG_MIME: | ||
201 | mh_opt_notimpl_warning ("-mime"); | ||
202 | mime_encaps = is_true (arg); | ||
203 | break; | ||
204 | |||
205 | case ARG_NOMIME: | ||
206 | mh_opt_notimpl_warning ("-nomime"); | ||
207 | mime_encaps = 0; | ||
208 | break; | ||
209 | |||
210 | case ARG_MSGID: | ||
211 | append_msgid = is_true (arg); | ||
212 | break; | ||
213 | |||
214 | case ARG_NOMSGID: | ||
215 | append_msgid = 0; | ||
216 | break; | ||
217 | 89 | ||
218 | case ARG_PRESERVE: | 90 | mu_parseopt_error (po, "%s%s: %s", po->po_long_opt_start, |
219 | keep_files = is_true (arg); | 91 | opt->opt_long, errtext); |
220 | break; | 92 | free (errmsg); |
221 | 93 | ||
222 | case ARG_PUSH: | 94 | if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT)) |
223 | background = is_true (arg); | 95 | exit (po->po_exit_error); |
224 | break; | ||
225 | |||
226 | case ARG_NOPUSH: | ||
227 | background = 0; | ||
228 | break; | ||
229 | |||
230 | case ARG_SPLIT: | ||
231 | split_message = 1; | ||
232 | split_interval = strtoul (arg, &p, 10); | ||
233 | if (*p) | ||
234 | { | ||
235 | argp_error (state, "%s: %s", arg, _("invalid number")); | ||
236 | exit (1); | ||
237 | } | ||
238 | break; | ||
239 | |||
240 | case ARG_VERBOSE: | ||
241 | verbose = is_true (arg); | ||
242 | break; | ||
243 | |||
244 | case ARG_NOVERBOSE: | ||
245 | verbose = 0; | ||
246 | break; | ||
247 | |||
248 | case ARG_WATCH: | ||
249 | watch = is_true (arg); | ||
250 | break; | ||
251 | |||
252 | case ARG_NOWATCH: | ||
253 | watch = 0; | ||
254 | break; | ||
255 | |||
256 | case ARG_WIDTH: | ||
257 | mh_opt_notimpl_warning ("-width"); | ||
258 | width = strtoul (arg, &p, 10); | ||
259 | if (*p) | ||
260 | { | ||
261 | argp_error (state, _("invalid number")); | ||
262 | exit (1); | ||
263 | } | ||
264 | break; | ||
265 | |||
266 | default: | ||
267 | return ARGP_ERR_UNKNOWN; | ||
268 | } | 96 | } |
269 | return 0; | 97 | split_message = 1; |
270 | } | 98 | } |
271 | 99 | ||
100 | static struct mu_option options[] = { | ||
101 | { "alias", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
102 | N_("specify additional alias file"), | ||
103 | mu_c_string, NULL, add_alias }, | ||
104 | { "draft", 0, NULL, MU_OPTION_DEFAULT, | ||
105 | N_("use prepared draft"), | ||
106 | mu_c_bool, &use_draft }, | ||
107 | { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
108 | N_("specify the folder for message drafts"), | ||
109 | mu_c_string, NULL, set_draftfolder }, | ||
110 | { "draftmessage", 0, N_("MSG"), MU_OPTION_DEFAULT, | ||
111 | N_("use MSG from the draftfolder as a draft"), | ||
112 | mu_c_string, NULL, add_draftmessage }, | ||
113 | { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT, | ||
114 | N_("undo the effect of the last --draftfolder option"), | ||
115 | mu_c_int, &use_draftfolder, NULL, "1" }, | ||
116 | { "filter", 0, N_("FILE"), MU_OPTION_HIDDEN, | ||
117 | N_("use filter FILE to preprocess the body of the message"), | ||
118 | mu_c_string, NULL, mh_opt_notimpl }, | ||
119 | { "nofilter", 0, NULL, MU_OPTION_HIDDEN, | ||
120 | N_("undo the effect of the last --filter option"), | ||
121 | mu_c_string, NULL, mh_opt_notimpl }, | ||
122 | { "format", 0, NULL, MU_OPTION_HIDDEN, | ||
123 | N_("reformat To: and Cc: addresses"), | ||
124 | mu_c_string, NULL, mh_opt_notimpl_warning }, | ||
125 | { "noformat", 0, NULL, MU_OPTION_HIDDEN }, | ||
126 | { "forward", 0, NULL, MU_OPTION_HIDDEN, | ||
127 | N_("in case of failure forward the draft along with the failure notice to the sender"), | ||
128 | mu_c_string, NULL, mh_opt_notimpl_warning }, | ||
129 | { "noforward", 0, NULL, MU_OPTION_HIDDEN, "" }, | ||
130 | { "mime", 0, NULL, MU_OPTION_HIDDEN, | ||
131 | N_("use MIME encapsulation"), | ||
132 | mu_c_bool, NULL, mh_opt_notimpl_warning }, | ||
133 | { "msgid", 0, NULL, MU_OPTION_DEFAULT, | ||
134 | N_("add Message-ID: field"), | ||
135 | mu_c_bool, &append_msgid }, | ||
136 | { "push", 0, NULL, MU_OPTION_DEFAULT, | ||
137 | N_("run in the background"), | ||
138 | mu_c_bool, &background }, | ||
139 | { "preserve", 0, NULL, MU_OPTION_DEFAULT, | ||
140 | N_("keep draft files"), | ||
141 | mu_c_bool, &keep_files }, | ||
142 | { "keep", 0, NULL, MU_OPTION_ALIAS }, | ||
143 | { "split", 0, N_("SECONDS"), MU_OPTION_DEFAULT, | ||
144 | N_("split the draft into several partial messages and send them with SECONDS interval"), | ||
145 | mu_c_ulong, &split_interval, set_split_opt }, | ||
146 | { "chunksize", 0, N_("NUMBER"), MU_OPTION_DEFAULT, | ||
147 | N_("set the size of chunk for --split (in bytes)"), | ||
148 | mu_c_size, &split_size }, | ||
149 | { "verbose", 0, NULL, MU_OPTION_DEFAULT, | ||
150 | N_("print the transcript of interactions with the transport system"), | ||
151 | mu_c_bool, &verbose }, | ||
152 | { "watch", 0, NULL, MU_OPTION_DEFAULT, | ||
153 | N_("monitor the delivery of mail"), | ||
154 | mu_c_bool, &watch }, | ||
155 | { "width", 0, N_("NUMBER"), MU_OPTION_HIDDEN, | ||
156 | N_("make header fields no longer than NUMBER columns"), | ||
157 | mu_c_string, NULL, mh_opt_notimpl_warning }, | ||
158 | |||
159 | MU_OPTION_END | ||
160 | }; | ||
161 | |||
272 | static void | 162 | static void |
273 | watch_printf (const char *fmt, ...) | 163 | watch_printf (const char *fmt, ...) |
274 | { | 164 | { |
... | @@ -291,7 +181,7 @@ static mu_list_t mesg_list; | ... | @@ -291,7 +181,7 @@ static mu_list_t mesg_list; |
291 | static mu_property_t mts_profile; | 181 | static mu_property_t mts_profile; |
292 | 182 | ||
293 | int | 183 | int |
294 | add_file (char *name) | 184 | add_file (char const *name) |
295 | { | 185 | { |
296 | struct list_elt *elt; | 186 | struct list_elt *elt; |
297 | 187 | ||
... | @@ -859,17 +749,12 @@ int | ... | @@ -859,17 +749,12 @@ int |
859 | main (int argc, char **argv) | 749 | main (int argc, char **argv) |
860 | { | 750 | { |
861 | mu_mailbox_t mbox = NULL; | 751 | mu_mailbox_t mbox = NULL; |
862 | int index; | ||
863 | char *p; | 752 | char *p; |
864 | int rc; | 753 | int rc; |
865 | 754 | ||
866 | MU_APP_INIT_NLS (); | 755 | MU_APP_INIT_NLS (); |
867 | 756 | ||
868 | mh_argp_init (); | 757 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
869 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
870 | opt_handler, NULL, &index); | ||
871 | argc -= index; | ||
872 | argv += index; | ||
873 | 758 | ||
874 | mh_read_aliases (); | 759 | mh_read_aliases (); |
875 | /* Process the mtstailor file */ | 760 | /* Process the mtstailor file */ | ... | ... |
... | @@ -19,55 +19,9 @@ | ... | @@ -19,55 +19,9 @@ |
19 | 19 | ||
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | 21 | ||
22 | static char doc[] = N_("GNU MH show")"\v" | 22 | static char prog_doc[] = N_("GNU MH show"); |
23 | N_("Use -help to obtain the list of traditional MH options."); | ||
24 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); | 23 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); |
25 | 24 | ||
26 | #define ARG_PASS ARG_MAX | ||
27 | |||
28 | static struct argp_option options[] = { | ||
29 | {"draft", ARG_DRAFT, NULL, 0, | ||
30 | N_("show the draft file") }, | ||
31 | {"file", ARG_FILE, N_("FILE"), 0, | ||
32 | N_("show this file") }, | ||
33 | {"header", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
34 | N_("display a description of the message before the message itself") }, | ||
35 | {"noheader", ARG_HEADER, NULL, OPTION_HIDDEN, "" }, | ||
36 | {"showproc", ARG_SHOWPROC, N_("PROGRAM"), 0, | ||
37 | N_("use PROGRAM to show messages")}, | ||
38 | {"noshowproc", ARG_NOSHOWPROC, NULL, 0, | ||
39 | N_("disable the use of the \"showproc:\" profile component") }, | ||
40 | |||
41 | {"form", ARG_FORM, N_("FILE"), 0, | ||
42 | N_("read format from given file")}, | ||
43 | {"moreproc", ARG_MOREPROC, N_("PROG"), 0, | ||
44 | N_("use this PROG as pager"), }, | ||
45 | {"nomoreproc", ARG_NOMOREPROC, NULL, 0, | ||
46 | N_("disable the use of moreproc") }, | ||
47 | {"length", ARG_LENGTH, N_("NUMBER"), 0, | ||
48 | N_("set output screen length")}, | ||
49 | {"width", ARG_WIDTH, N_("NUMBER"), 0, | ||
50 | N_("set output width")}, | ||
51 | |||
52 | {NULL} | ||
53 | }; | ||
54 | |||
55 | /* Traditional MH options */ | ||
56 | struct mh_option mh_option[] = { | ||
57 | { "draft" }, | ||
58 | { "file", MH_OPT_ARG, "file" }, | ||
59 | { "header", MH_OPT_BOOL }, | ||
60 | { "showproc", MH_OPT_ARG, "program" }, | ||
61 | { "noshowproc" }, | ||
62 | { "form", MH_OPT_ARG, "formatfile"}, | ||
63 | { "width", MH_OPT_ARG, "number"}, | ||
64 | { "length", MH_OPT_ARG, "number"}, | ||
65 | { "moreproc", MH_OPT_ARG, "program"}, | ||
66 | { "nomoreproc" }, | ||
67 | |||
68 | { NULL } | ||
69 | }; | ||
70 | |||
71 | int use_draft; | 25 | int use_draft; |
72 | int use_showproc = 1; | 26 | int use_showproc = 1; |
73 | int header_option = 1; | 27 | int header_option = 1; |
... | @@ -100,71 +54,75 @@ insarg (char *arg) | ... | @@ -100,71 +54,75 @@ insarg (char *arg) |
100 | showargv[1] = p; | 54 | showargv[1] = p; |
101 | } | 55 | } |
102 | } | 56 | } |
103 | 57 | ||
104 | static const char * | 58 | static void |
105 | findopt (int key) | 59 | set_draft (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
106 | { | 60 | { |
107 | struct argp_option *p; | 61 | if (use_draft || file) |
108 | 62 | { | |
109 | for (p = options; p->name; p++) | 63 | mu_parseopt_error (po, _("only one file at a time!")); |
110 | if (p->key == key) | 64 | exit (po->po_exit_error); |
111 | return p->name; | 65 | } |
112 | abort (); | 66 | use_draft = 1; |
113 | } | 67 | } |
114 | 68 | ||
115 | static error_t | 69 | static void |
116 | opt_handler (int key, char *arg, struct argp_state *state) | 70 | set_file (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
117 | { | 71 | { |
118 | switch (key) | 72 | if (use_draft || file) |
119 | { | 73 | { |
120 | case ARG_FOLDER: | 74 | mu_parseopt_error (po, _("only one file at a time!")); |
121 | mh_set_current_folder (arg); | 75 | exit (po->po_exit_error); |
122 | break; | ||
123 | |||
124 | case ARG_DRAFT: | ||
125 | if (use_draft || file) | ||
126 | argp_error (state, _("only one file at a time!")); | ||
127 | use_draft = 1; | ||
128 | break; | ||
129 | |||
130 | case ARG_FILE: | ||
131 | if (use_draft || file) | ||
132 | argp_error (state, _("only one file at a time!")); | ||
133 | file = mh_expand_name (NULL, arg, NAME_FILE); | ||
134 | break; | ||
135 | |||
136 | case ARG_HEADER: | ||
137 | header_option = is_true (arg); | ||
138 | break; | ||
139 | |||
140 | case ARG_NOHEADER: | ||
141 | header_option = 0; | ||
142 | break; | ||
143 | |||
144 | case ARG_SHOWPROC: | ||
145 | showproc = arg; | ||
146 | break; | ||
147 | |||
148 | case ARG_NOSHOWPROC: | ||
149 | use_showproc = 0; | ||
150 | break; | ||
151 | |||
152 | case ARG_NOMOREPROC: | ||
153 | case ARG_FORM: | ||
154 | case ARG_MOREPROC: | ||
155 | case ARG_LENGTH: | ||
156 | case ARG_WIDTH: | ||
157 | addarg (findopt (key)); | ||
158 | if (arg) | ||
159 | addarg (arg); | ||
160 | break; | ||
161 | |||
162 | default: | ||
163 | return ARGP_ERR_UNKNOWN; | ||
164 | } | 76 | } |
165 | return 0; | 77 | file = mh_expand_name (NULL, arg, NAME_FILE); |
78 | } | ||
79 | |||
80 | static void | ||
81 | add_show_arg (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
82 | { | ||
83 | char *name = mu_alloc (strlen (opt->opt_long) + 2); | ||
84 | name[0] = '-'; | ||
85 | strcpy (name + 1, opt->opt_long); | ||
86 | addarg (name); | ||
87 | if (arg) | ||
88 | addarg (arg); | ||
166 | } | 89 | } |
167 | 90 | ||
91 | static struct mu_option options[] = { | ||
92 | { "draft", 0, NULL, MU_OPTION_DEFAULT, | ||
93 | N_("show the draft file"), | ||
94 | mu_c_string, NULL, set_draft }, | ||
95 | { "file", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
96 | N_("show this file"), | ||
97 | mu_c_string, NULL, set_file }, | ||
98 | { "header", 0, NULL, MU_OPTION_DEFAULT, | ||
99 | N_("display a description of the message before the message itself"), | ||
100 | mu_c_bool, &header_option }, | ||
101 | { "showproc", 0, N_("PROGRAM"), MU_OPTION_DEFAULT, | ||
102 | N_("use PROGRAM to show messages"), | ||
103 | mu_c_string, &showproc }, | ||
104 | { "noshowproc", 0, NULL, MU_OPTION_DEFAULT, | ||
105 | N_("disable the use of the \"showproc:\" profile component"), | ||
106 | mu_c_int, &use_showproc, NULL, "0" }, | ||
107 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
108 | N_("read format from given file"), | ||
109 | mu_c_string, NULL, add_show_arg }, | ||
110 | { "moreproc", 0, N_("PROG"), MU_OPTION_DEFAULT, | ||
111 | N_("use this PROG as pager"), | ||
112 | mu_c_string, NULL, add_show_arg }, | ||
113 | { "nomoreproc", 0, NULL, MU_OPTION_DEFAULT, | ||
114 | N_("disable the use of moreproc"), | ||
115 | mu_c_string, NULL, add_show_arg }, | ||
116 | { "length", 0, N_("NUMBER"), MU_OPTION_DEFAULT, | ||
117 | N_("set output screen length"), | ||
118 | mu_c_string, NULL, add_show_arg }, | ||
119 | { "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT, | ||
120 | N_("set output width"), | ||
121 | mu_c_string, NULL, add_show_arg }, | ||
122 | |||
123 | MU_OPTION_END | ||
124 | }; | ||
125 | |||
168 | static int | 126 | static int |
169 | resolve_mime (size_t num, mu_message_t msg, void *data) | 127 | resolve_mime (size_t num, mu_message_t msg, void *data) |
170 | { | 128 | { |
... | @@ -222,7 +180,6 @@ checkfile (char *file) | ... | @@ -222,7 +180,6 @@ checkfile (char *file) |
222 | int | 180 | int |
223 | main (int argc, char **argv) | 181 | main (int argc, char **argv) |
224 | { | 182 | { |
225 | int index = 0; | ||
226 | mu_mailbox_t mbox; | 183 | mu_mailbox_t mbox; |
227 | mu_msgset_t msgset; | 184 | mu_msgset_t msgset; |
228 | const char *p; | 185 | const char *p; |
... | @@ -233,15 +190,13 @@ main (int argc, char **argv) | ... | @@ -233,15 +190,13 @@ main (int argc, char **argv) |
233 | showargmax = 2; | 190 | showargmax = 2; |
234 | showargc = 1; | 191 | showargc = 1; |
235 | showargv = mu_calloc (showargmax, sizeof showargv[0]); | 192 | showargv = mu_calloc (showargmax, sizeof showargv[0]); |
193 | |||
194 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, | ||
195 | args_doc, prog_doc, NULL); | ||
196 | |||
236 | 197 | ||
237 | mh_argp_init (); | ||
238 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
239 | opt_handler, NULL, &index); | ||
240 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); | 198 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); |
241 | 199 | ||
242 | argc -= index; | ||
243 | argv += index; | ||
244 | |||
245 | if (use_draft || file) | 200 | if (use_draft || file) |
246 | { | 201 | { |
247 | if (argc) | 202 | if (argc) | ... | ... |
... | @@ -22,72 +22,10 @@ | ... | @@ -22,72 +22,10 @@ |
22 | #include <unistd.h> | 22 | #include <unistd.h> |
23 | #include <signal.h> | 23 | #include <signal.h> |
24 | 24 | ||
25 | static char doc[] = N_("GNU MH sortm")"\v" | 25 | static char prog_doc[] = N_("GNU MH sortm")"\v" |
26 | N_("Use -help to obtain the list of traditional MH options."); | 26 | N_("Use -help to obtain the list of traditional MH options."); |
27 | static char args_doc[] = N_("[MSGLIST]"); | 27 | static char args_doc[] = N_("[MSGLIST]"); |
28 | 28 | ||
29 | #define ARG_QUICKSORT 1024 | ||
30 | #define ARG_SHELL 1025 | ||
31 | |||
32 | /* GNU options */ | ||
33 | static struct argp_option options[] = { | ||
34 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
35 | N_("specify folder to operate upon")}, | ||
36 | |||
37 | {N_("Setting sort keys:"), 0, NULL, OPTION_DOC, NULL, 0}, | ||
38 | {"datefield", ARG_DATEFIELD, N_("STRING"), 0, | ||
39 | N_("sort on the date field (default `Date:')"), 10}, | ||
40 | {"nodatefield", ARG_NODATEFIELD, NULL, 0, | ||
41 | N_("undo the effect of the last --datefield option"), 10}, | ||
42 | {"limit", ARG_LIMIT, N_("DAYS"), 0, | ||
43 | N_("consider two datefields equal if their difference lies within the given nuber of DAYS."), 11}, | ||
44 | {"nolimit", ARG_NOLIMIT, NULL, 0, | ||
45 | N_("undo the effect of the last --limit option"), 11}, | ||
46 | {"textfield", ARG_TEXTFIELD, N_("STRING"), 0, | ||
47 | N_("sort on the text field"), 15}, | ||
48 | {"notextfield", ARG_NOTEXTFIELD, NULL, 0, | ||
49 | N_("undo the effect of the last --textfield option"), 15}, | ||
50 | {"numfield", ARG_NUMFIELD, N_("STRING"), 0, | ||
51 | N_("sort on the numeric field"), 16}, | ||
52 | |||
53 | {N_("Actions:"), 0, NULL, OPTION_DOC, NULL, 16}, | ||
54 | {"reorder", ARG_REORDER, 0, 0, | ||
55 | N_("reorder the messages (default)"), 20 }, | ||
56 | {"dry-run", ARG_DRY_RUN, 0, 0, | ||
57 | N_("do not do anything, only show what would have been done"), 20 }, | ||
58 | {"list", ARG_LIST, 0, 0, | ||
59 | N_("list the sorted messages"), 20 }, | ||
60 | {"form", ARG_FORM, N_("FILE"), 0, | ||
61 | N_("read format from given file"), 23}, | ||
62 | {"format", ARG_FORMAT, N_("FORMAT"), 0, | ||
63 | N_("use this format string"), 23}, | ||
64 | |||
65 | {"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
66 | N_("verbosely list executed actions"), 30 }, | ||
67 | {"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "" }, | ||
68 | |||
69 | {N_("Select sort algorithm:"), 0, NULL, OPTION_DOC, NULL, 30}, | ||
70 | |||
71 | {"shell", ARG_SHELL, 0, 0, | ||
72 | N_("use shell algorithm"), 40 }, | ||
73 | {"quicksort", ARG_QUICKSORT, 0, 0, | ||
74 | N_("use quicksort algorithm (default)"), 40 }, | ||
75 | |||
76 | { NULL }, | ||
77 | }; | ||
78 | |||
79 | /* Traditional MH options */ | ||
80 | struct mh_option mh_option[] = { | ||
81 | { "datefield", MH_OPT_ARG, "field" }, | ||
82 | { "nodatefield" }, | ||
83 | { "textfield", MH_OPT_ARG, "field" }, | ||
84 | { "notextfield" }, | ||
85 | { "limit", MH_OPT_ARG, "days" }, | ||
86 | { "nolimit" }, | ||
87 | { "verbose", MH_OPT_BOOL }, | ||
88 | { NULL }, | ||
89 | }; | ||
90 | |||
91 | static int limit; | 29 | static int limit; |
92 | static int verbose; | 30 | static int verbose; |
93 | static mu_mailbox_t mbox; | 31 | static mu_mailbox_t mbox; |
... | @@ -98,115 +36,175 @@ static size_t msgcount; | ... | @@ -98,115 +36,175 @@ static size_t msgcount; |
98 | 36 | ||
99 | static size_t current_num; | 37 | static size_t current_num; |
100 | 38 | ||
101 | #define ACTION_REORDER 0 | 39 | enum |
102 | #define ACTION_DRY_RUN 1 | 40 | { |
103 | #define ACTION_LIST 2 | 41 | ACTION_REORDER, |
104 | 42 | ACTION_DRY_RUN, | |
105 | static int algorithm = ARG_QUICKSORT; | 43 | ACTION_LIST |
44 | }; | ||
45 | |||
46 | enum | ||
47 | { | ||
48 | algo_quicksort, | ||
49 | algo_shell | ||
50 | }; | ||
51 | static int algorithm = algo_quicksort; | ||
106 | static int action = ACTION_REORDER; | 52 | static int action = ACTION_REORDER; |
107 | static char *format_str = mh_list_format; | 53 | static char *format_str = mh_list_format; |
108 | static mh_format_t format; | 54 | static mh_format_t format; |
109 | 55 | ||
110 | typedef int (*compfun) (void *, void *); | 56 | typedef int (*compfun) (void *, void *); |
111 | static void addop (char *field, compfun comp); | 57 | static void addop (char const *field, compfun comp); |
112 | static void remop (compfun comp); | 58 | static void remop (compfun comp); |
113 | static int comp_text (void *a, void *b); | 59 | static int comp_text (void *a, void *b); |
114 | static int comp_date (void *a, void *b); | 60 | static int comp_date (void *a, void *b); |
115 | static int comp_number (void *a, void *b); | 61 | static int comp_number (void *a, void *b); |
62 | |||
63 | static void | ||
64 | add_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
65 | { | ||
66 | addop (arg, comp_date); | ||
67 | } | ||
116 | 68 | ||
117 | static error_t | 69 | static void |
118 | opt_handler (int key, char *arg, struct argp_state *state) | 70 | add_numfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
119 | { | 71 | { |
120 | switch (key) | 72 | addop (arg, comp_number); |
121 | { | 73 | } |
122 | case ARG_FOLDER: | ||
123 | mh_set_current_folder (arg); | ||
124 | break; | ||
125 | |||
126 | case ARG_DATEFIELD: | ||
127 | addop (arg, comp_date); | ||
128 | break; | ||
129 | |||
130 | case ARG_NUMFIELD: | ||
131 | addop (arg, comp_number); | ||
132 | break; | ||
133 | 74 | ||
134 | case ARG_NODATEFIELD: | 75 | static void |
135 | remop (comp_date); | 76 | add_textfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
136 | break; | 77 | { |
137 | 78 | addop (arg, comp_text); | |
138 | case ARG_TEXTFIELD: | 79 | } |
139 | addop (arg, comp_text); | ||
140 | break; | ||
141 | |||
142 | case ARG_NOTEXTFIELD: | ||
143 | remop (comp_text); | ||
144 | break; | ||
145 | |||
146 | case ARG_LIMIT: | ||
147 | limit = strtoul (arg, NULL, 0); | ||
148 | break; | ||
149 | |||
150 | case ARG_NOLIMIT: | ||
151 | limit = -1; | ||
152 | break; | ||
153 | |||
154 | case ARG_VERBOSE: | ||
155 | if (!arg || mu_isalpha (arg[0])) | ||
156 | verbose = is_true (arg); | ||
157 | else | ||
158 | verbose = arg[0] - '0'; | ||
159 | break; | ||
160 | |||
161 | case ARG_NOVERBOSE: | ||
162 | verbose = 0; | ||
163 | break; | ||
164 | |||
165 | case ARG_FORM: | ||
166 | mh_read_formfile (arg, &format_str); | ||
167 | break; | ||
168 | |||
169 | case ARG_FORMAT: | ||
170 | format_str = arg; | ||
171 | break; | ||
172 | 80 | ||
173 | case ARG_REORDER: | 81 | static void |
174 | action = ACTION_REORDER; | 82 | rem_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
175 | break; | 83 | { |
176 | 84 | remop (comp_date); | |
177 | case ARG_LIST: | 85 | } |
178 | action = ACTION_LIST; | ||
179 | break; | ||
180 | 86 | ||
181 | case ARG_DRY_RUN: | 87 | static void |
182 | action = ACTION_DRY_RUN; | 88 | rem_numfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
183 | if (!verbose) | 89 | { |
184 | verbose = 1; | 90 | remop (comp_number); |
185 | break; | 91 | } |
186 | 92 | ||
187 | case ARG_SHELL: | 93 | static void |
188 | case ARG_QUICKSORT: | 94 | rem_textfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
189 | algorithm = key; | 95 | { |
190 | break; | 96 | remop (comp_text); |
191 | 97 | } | |
192 | default: | 98 | |
193 | return ARGP_ERR_UNKNOWN; | 99 | static void |
194 | } | 100 | set_action_reorder (struct mu_parseopt *po, struct mu_option *opt, |
195 | return 0; | 101 | char const *arg) |
102 | { | ||
103 | action = ACTION_REORDER; | ||
104 | } | ||
105 | |||
106 | static void | ||
107 | set_action_list (struct mu_parseopt *po, struct mu_option *opt, | ||
108 | char const *arg) | ||
109 | { | ||
110 | action = ACTION_LIST; | ||
196 | } | 111 | } |
197 | 112 | ||
113 | static void | ||
114 | set_action_dry_run (struct mu_parseopt *po, struct mu_option *opt, | ||
115 | char const *arg) | ||
116 | { | ||
117 | action = ACTION_DRY_RUN; | ||
118 | if (!verbose) | ||
119 | verbose = 1; | ||
120 | } | ||
121 | |||
122 | static void | ||
123 | set_algo_shell (struct mu_parseopt *po, struct mu_option *opt, | ||
124 | char const *arg) | ||
125 | { | ||
126 | algorithm = algo_shell; | ||
127 | } | ||
128 | |||
129 | static void | ||
130 | set_algo_quicksort (struct mu_parseopt *po, struct mu_option *opt, | ||
131 | char const *arg) | ||
132 | { | ||
133 | algorithm = algo_quicksort; | ||
134 | } | ||
135 | |||
136 | static struct mu_option options[] = { | ||
137 | MU_OPTION_GROUP (N_("Setting sort keys:")), | ||
138 | { "datefield", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
139 | N_("sort on the date field (default `Date:')"), | ||
140 | mu_c_string, NULL, add_datefield }, | ||
141 | { "nodatefield", 0, NULL, MU_OPTION_DEFAULT, | ||
142 | N_("don't sort on the date field"), | ||
143 | mu_c_string, NULL, rem_datefield }, | ||
144 | { "limit", 0, N_("DAYS"), MU_OPTION_DEFAULT, | ||
145 | N_("consider two datefields equal if their difference lies within the given nuber of DAYS."), | ||
146 | mu_c_int, &limit }, | ||
147 | { "nolimit", 0, NULL, MU_OPTION_DEFAULT, | ||
148 | N_("undo the effect of the last -limit option"), | ||
149 | mu_c_int, &limit, NULL, "-1" }, | ||
150 | { "textfield", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
151 | N_("sort on the text field"), | ||
152 | mu_c_string, NULL, add_textfield }, | ||
153 | { "notextfield", 0, NULL, MU_OPTION_DEFAULT, | ||
154 | N_("don't sort on the text field"), | ||
155 | mu_c_string, NULL, rem_textfield }, | ||
156 | { "numfield", 0, N_("STRING"), MU_OPTION_DEFAULT, | ||
157 | N_("sort on the numeric field"), | ||
158 | mu_c_string, NULL, add_numfield }, | ||
159 | { "nonumfield", 0, NULL, MU_OPTION_DEFAULT, | ||
160 | N_("don't sort on the numeric field"), | ||
161 | mu_c_string, NULL, rem_numfield }, | ||
162 | |||
163 | MU_OPTION_GROUP (N_("Actions:")), | ||
164 | { "reorder", 0, NULL, MU_OPTION_DEFAULT, | ||
165 | N_("reorder the messages (default)"), | ||
166 | mu_c_string, NULL, set_action_reorder }, | ||
167 | { "dry-run", 0, NULL, MU_OPTION_DEFAULT, | ||
168 | N_("do not do anything, only show what would have been done"), | ||
169 | mu_c_string, NULL, set_action_dry_run }, | ||
170 | { "list", 0, NULL, MU_OPTION_DEFAULT, | ||
171 | N_("list the sorted messages"), | ||
172 | mu_c_string, NULL, set_action_list }, | ||
173 | |||
174 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
175 | N_("read format from given file"), | ||
176 | mu_c_string, &format_str, mh_opt_read_formfile }, | ||
177 | { "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT, | ||
178 | N_("use this format string"), | ||
179 | mu_c_string, &format_str }, | ||
180 | |||
181 | { "verbose", 0, NULL, MU_OPTION_DEFAULT, | ||
182 | N_("verbosely list executed actions"), | ||
183 | mu_c_bool, &verbose }, | ||
184 | |||
185 | MU_OPTION_GROUP (N_("Select sort algorithm:")), | ||
186 | { "shell", 0, NULL, MU_OPTION_DEFAULT, | ||
187 | N_("use shell algorithm"), | ||
188 | mu_c_string, NULL, set_algo_shell }, | ||
189 | |||
190 | { "quicksort", 0, NULL, MU_OPTION_DEFAULT, | ||
191 | N_("use quicksort algorithm (default)"), | ||
192 | mu_c_string, NULL, set_algo_quicksort }, | ||
193 | |||
194 | MU_OPTION_END | ||
195 | }; | ||
198 | 196 | ||
199 | /* *********************** Comparison functions **************************** */ | 197 | /* *********************** Comparison functions **************************** */ |
200 | struct comp_op | 198 | struct comp_op |
201 | { | 199 | { |
202 | char *field; | 200 | char const *field; |
203 | compfun comp; | 201 | compfun comp; |
204 | }; | 202 | }; |
205 | 203 | ||
206 | static mu_list_t oplist; | 204 | static mu_list_t oplist; |
207 | 205 | ||
208 | static void | 206 | static void |
209 | addop (char *field, compfun comp) | 207 | addop (char const *field, compfun comp) |
210 | { | 208 | { |
211 | struct comp_op *op = mu_alloc (sizeof (*op)); | 209 | struct comp_op *op = mu_alloc (sizeof (*op)); |
212 | 210 | ||
... | @@ -497,11 +495,11 @@ sort () | ... | @@ -497,11 +495,11 @@ sort () |
497 | 495 | ||
498 | switch (algorithm) | 496 | switch (algorithm) |
499 | { | 497 | { |
500 | case ARG_QUICKSORT: | 498 | case algo_quicksort: |
501 | qsort (msgarr, msgcount, sizeof (msgarr[0]), comp); | 499 | qsort (msgarr, msgcount, sizeof (msgarr[0]), comp); |
502 | break; | 500 | break; |
503 | 501 | ||
504 | case ARG_SHELL: | 502 | case algo_shell: |
505 | shell_sort (); | 503 | shell_sort (); |
506 | break; | 504 | break; |
507 | } | 505 | } |
... | @@ -599,19 +597,17 @@ fill_msgarr (mu_msgset_t msgset) | ... | @@ -599,19 +597,17 @@ fill_msgarr (mu_msgset_t msgset) |
599 | } | 597 | } |
600 | 598 | ||
601 | 599 | ||
602 | /* Main */ | ||
603 | |||
604 | int | 600 | int |
605 | main (int argc, char **argv) | 601 | main (int argc, char **argv) |
606 | { | 602 | { |
607 | int index; | ||
608 | mu_url_t url; | 603 | mu_url_t url; |
609 | mu_msgset_t msgset; | 604 | mu_msgset_t msgset; |
610 | 605 | ||
611 | MU_APP_INIT_NLS (); | 606 | MU_APP_INIT_NLS (); |
612 | mh_argp_init (); | 607 | |
613 | mh_argp_parse (&argc, &argv, 0, options, mh_option, | 608 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
614 | args_doc, doc, opt_handler, NULL, &index); | 609 | args_doc, prog_doc, NULL); |
610 | |||
615 | if (!oplist) | 611 | if (!oplist) |
616 | addop ("date", comp_date); | 612 | addop ("date", comp_date); |
617 | 613 | ||
... | @@ -627,9 +623,6 @@ main (int argc, char **argv) | ... | @@ -627,9 +623,6 @@ main (int argc, char **argv) |
627 | if (memcmp (mbox_path, "mh:", 3) == 0) | 623 | if (memcmp (mbox_path, "mh:", 3) == 0) |
628 | mbox_path += 3; | 624 | mbox_path += 3; |
629 | 625 | ||
630 | argc -= index; | ||
631 | argv += index; | ||
632 | |||
633 | mh_mailbox_get_cur (mbox, ¤t_num); | 626 | mh_mailbox_get_cur (mbox, ¤t_num); |
634 | 627 | ||
635 | mh_msgset_parse (&msgset, mbox, argc, argv, "all"); | 628 | mh_msgset_parse (&msgset, mbox, argc, argv, "all"); | ... | ... |
... | @@ -53,11 +53,11 @@ Mail/inbox/5 | ... | @@ -53,11 +53,11 @@ Mail/inbox/5 |
53 | Mail/inbox/6 | 53 | Mail/inbox/6 |
54 | ]) | 54 | ]) |
55 | 55 | ||
56 | MH_CHECK([refile --copy],[refile02 refile--copy],[ | 56 | MH_CHECK([refile -copy],[refile02 refile-copy],[ |
57 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | 57 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) |
58 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty,[Mail/teaparty]) | 58 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty,[Mail/teaparty]) |
59 | echo 'Current-Folder: teaparty' > Mail/context | 59 | echo 'Current-Folder: teaparty' > Mail/context |
60 | refile --copy 3 4 +inbox || exit $? | 60 | refile -copy 3 4 +inbox || exit $? |
61 | find Mail/inbox -name '[[0-9]]' | sort | 61 | find Mail/inbox -name '[[0-9]]' | sort |
62 | cmp Mail/inbox/6 Mail/teaparty/3 >/dev/null || echo "Message 3 differs" | 62 | cmp Mail/inbox/6 Mail/teaparty/3 >/dev/null || echo "Message 3 differs" |
63 | cmp Mail/inbox/7 Mail/teaparty/4 >/dev/null || echo "Message 4 differs" | 63 | cmp Mail/inbox/7 Mail/teaparty/4 >/dev/null || echo "Message 4 differs" | ... | ... |
... | @@ -19,88 +19,45 @@ | ... | @@ -19,88 +19,45 @@ |
19 | 19 | ||
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | 21 | ||
22 | static char doc[] = "GNU MH whatnow"; | 22 | static char prog_doc[] = "GNU MH whatnow"; |
23 | static char args_doc[] = N_("[FILE]"); | 23 | static char args_doc[] = N_("[FILE]"); |
24 | 24 | ||
25 | /* GNU options */ | ||
26 | static struct argp_option options[] = { | ||
27 | {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0, | ||
28 | N_("specify the folder for message drafts")}, | ||
29 | {"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0, | ||
30 | N_("undo the effect of the last --draftfolder option")}, | ||
31 | {"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0, | ||
32 | N_("invoke the draftmessage facility")}, | ||
33 | {"editor", ARG_EDITOR, N_("PROG"), 0, N_("set the editor program to use")}, | ||
34 | {"noedit", ARG_NOEDIT, 0, 0, N_("suppress the initial edit")}, | ||
35 | {"prompt", ARG_PROMPT, N_("STRING"), 0, N_("set the prompt")}, | ||
36 | |||
37 | { NULL } | ||
38 | }; | ||
39 | |||
40 | /* Traditional MH options */ | ||
41 | struct mh_option mh_option[] = { | ||
42 | { "draftfolder", MH_OPT_ARG, "folder" }, | ||
43 | { "nodraftfolder" }, | ||
44 | { "draftmessage" }, | ||
45 | { "editor", MH_OPT_ARG, "program" }, | ||
46 | { "noedit" }, | ||
47 | { "prompt" }, | ||
48 | { NULL } | ||
49 | }; | ||
50 | |||
51 | struct mh_whatnow_env wh_env = { 0 }; | 25 | struct mh_whatnow_env wh_env = { 0 }; |
52 | static int initial_edit = 1; | 26 | static int initial_edit = 1; |
53 | static char *draftmessage = "cur"; | 27 | static char *draftmessage = "cur"; |
54 | static const char *draftfolder = NULL; | 28 | static const char *draftfolder = NULL; |
55 | 29 | ||
56 | static error_t | 30 | static struct mu_option options[] = { |
57 | opt_handler (int key, char *arg, struct argp_state *state) | 31 | { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, |
58 | { | 32 | N_("specify the folder for message drafts"), |
59 | switch (key) | 33 | mu_c_string, &draftfolder }, |
60 | { | 34 | { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT, |
61 | case ARG_DRAFTFOLDER: | 35 | N_("undo the effect of the last -draftfolder option"), |
62 | draftfolder = arg; | 36 | mu_c_string, &draftfolder, mh_opt_clear_string }, |
63 | break; | 37 | { "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT, |
64 | 38 | N_("invoke the draftmessage facility"), | |
65 | case ARG_EDITOR: | 39 | mu_c_string, &draftmessage }, |
66 | wh_env.editor = arg; | 40 | { "editor", 0, N_("PROG"), MU_OPTION_DEFAULT, |
67 | break; | 41 | N_("set the editor program to use"), |
68 | 42 | mu_c_string, &wh_env.editor }, | |
69 | case ARG_NODRAFTFOLDER: | 43 | { "noedit", 0, NULL, MU_OPTION_DEFAULT, |
70 | draftfolder = NULL; | 44 | N_("suppress the initial edit"), |
71 | break; | 45 | mu_c_int, &initial_edit, NULL, "0" }, |
72 | 46 | { "prompt", 0, N_("STRING"), MU_OPTION_DEFAULT, | |
73 | case ARG_NOEDIT: | 47 | N_("set the prompt"), |
74 | initial_edit = 0; | 48 | mu_c_string, &wh_env.prompt }, |
75 | break; | 49 | MU_OPTION_END |
76 | 50 | }; | |
77 | case ARG_DRAFTMESSAGE: | 51 | |
78 | draftmessage = arg; | ||
79 | break; | ||
80 | |||
81 | case ARG_PROMPT: | ||
82 | wh_env.prompt = arg; | ||
83 | break; | ||
84 | |||
85 | default: | ||
86 | return ARGP_ERR_UNKNOWN; | ||
87 | } | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | int | 52 | int |
92 | main (int argc, char **argv) | 53 | main (int argc, char **argv) |
93 | { | 54 | { |
94 | int index; | ||
95 | |||
96 | MU_APP_INIT_NLS (); | 55 | MU_APP_INIT_NLS (); |
97 | 56 | ||
98 | mh_argp_init (); | ||
99 | mh_whatnow_env_from_environ (&wh_env); | 57 | mh_whatnow_env_from_environ (&wh_env); |
100 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 58 | |
101 | opt_handler, NULL, &index); | 59 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
102 | argc -= index; | 60 | |
103 | argv += index; | ||
104 | if (argc) | 61 | if (argc) |
105 | wh_env.draftfile = argv[0]; | 62 | wh_env.draftfile = argv[0]; |
106 | else if (draftfolder) | 63 | else if (draftfolder) | ... | ... |
... | @@ -17,99 +17,58 @@ | ... | @@ -17,99 +17,58 @@ |
17 | 17 | ||
18 | #include <mh.h> | 18 | #include <mh.h> |
19 | 19 | ||
20 | static char doc[] = N_("GNU MH whom")"\v" | 20 | static char prog_doc[] = N_("GNU MH whom"); |
21 | N_("Use -help to obtain the list of traditional MH options."); | ||
22 | static char args_doc[] = "[FILE]"; | 21 | static char args_doc[] = "[FILE]"; |
23 | 22 | ||
24 | /* GNU options */ | ||
25 | static struct argp_option options[] = { | ||
26 | {"alias", ARG_ALIAS, N_("FILE"), 0, | ||
27 | N_("specify additional alias file") }, | ||
28 | {"draft", ARG_DRAFT, NULL, 0, | ||
29 | N_("use prepared draft") }, | ||
30 | {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0, | ||
31 | N_("specify the folder for message drafts") }, | ||
32 | {"draftmessage", ARG_DRAFTMESSAGE, NULL, 0, | ||
33 | N_("treat the arguments as a list of messages from the draftfolder") }, | ||
34 | {"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0, | ||
35 | N_("undo the effect of the last --draftfolder option") }, | ||
36 | {"check", ARG_CHECK, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
37 | N_("check if addresses are deliverable") }, | ||
38 | {"nocheck", ARG_NOCHECK, NULL, OPTION_HIDDEN, "" }, | ||
39 | |||
40 | {NULL} | ||
41 | }; | ||
42 | |||
43 | /* Traditional MH options */ | ||
44 | struct mh_option mh_option[] = { | ||
45 | { "alias", MH_OPT_ARG, "aliasfile" }, | ||
46 | { "draft" }, | ||
47 | { "draftfolder", MH_OPT_ARG, "folder" }, | ||
48 | { "draftmessage", MH_OPT_ARG, "message" }, | ||
49 | { "nodraftfolder" }, | ||
50 | { "check", MH_OPT_BOOL }, | ||
51 | {NULL} | ||
52 | }; | ||
53 | |||
54 | static int check_recipients; | 23 | static int check_recipients; |
55 | static int use_draft; /* Use the prepared draft */ | 24 | static int use_draft; /* Use the prepared draft */ |
56 | static const char *draft_folder; /* Use this draft folder */ | 25 | static const char *draft_folder; /* Use this draft folder */ |
57 | 26 | ||
58 | static error_t | 27 | static void |
59 | opt_handler (int key, char *arg, struct argp_state *state) | 28 | add_alias (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
60 | { | 29 | { |
61 | switch (key) | 30 | mh_alias_read (arg, 1); |
62 | { | 31 | } |
63 | case ARG_ALIAS: | ||
64 | mh_alias_read (arg, 1); | ||
65 | break; | ||
66 | |||
67 | case ARG_DRAFT: | ||
68 | use_draft = 1; | ||
69 | break; | ||
70 | |||
71 | case ARG_DRAFTFOLDER: | ||
72 | draft_folder = arg; | ||
73 | break; | ||
74 | |||
75 | case ARG_NODRAFTFOLDER: | ||
76 | draft_folder = NULL; | ||
77 | break; | ||
78 | |||
79 | case ARG_DRAFTMESSAGE: | ||
80 | if (!draft_folder) | ||
81 | draft_folder = mh_global_profile_get ("Draft-Folder", | ||
82 | mu_folder_directory ()); | ||
83 | break; | ||
84 | |||
85 | case ARG_CHECK: | ||
86 | check_recipients = is_true (arg); | ||
87 | break; | ||
88 | |||
89 | case ARG_NOCHECK: | ||
90 | check_recipients = 0; | ||
91 | break; | ||
92 | 32 | ||
93 | default: | 33 | static void |
94 | return ARGP_ERR_UNKNOWN; | 34 | set_draftmessage (struct mu_parseopt *po, struct mu_option *opt, |
95 | } | 35 | char const *arg) |
96 | return 0; | 36 | { |
37 | if (!draft_folder) | ||
38 | draft_folder = mh_global_profile_get ("Draft-Folder", | ||
39 | mu_folder_directory ()); | ||
97 | } | 40 | } |
98 | 41 | ||
42 | static struct mu_option options[] = { | ||
43 | { "alias", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
44 | N_("specify additional alias file"), | ||
45 | mu_c_string, NULL, add_alias }, | ||
46 | { "draft", 0, NULL, MU_OPTION_DEFAULT, | ||
47 | N_("use prepared draft"), | ||
48 | mu_c_bool, &use_draft }, | ||
49 | { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
50 | N_("specify the folder for message drafts"), | ||
51 | mu_c_string, &draft_folder }, | ||
52 | { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT, | ||
53 | N_("undo the effect of the last -draftfolder option"), | ||
54 | mu_c_string, &draft_folder, mh_opt_clear_string }, | ||
55 | { "draftmessage", 0, NULL, MU_OPTION_DEFAULT, | ||
56 | N_("treat the arguments as a list of messages from the draftfolder"), | ||
57 | mu_c_string, NULL, set_draftmessage }, | ||
58 | { "check", 0, NULL, MU_OPTION_DEFAULT, | ||
59 | N_("check if addresses are deliverable"), | ||
60 | mu_c_bool, &check_recipients }, | ||
61 | MU_OPTION_END | ||
62 | }; | ||
63 | |||
99 | int | 64 | int |
100 | main (int argc, char **argv) | 65 | main (int argc, char **argv) |
101 | { | 66 | { |
102 | int index; | ||
103 | char *name = "draft"; | 67 | char *name = "draft"; |
104 | 68 | ||
105 | MU_APP_INIT_NLS (); | 69 | MU_APP_INIT_NLS (); |
106 | 70 | ||
107 | mh_argp_init (); | 71 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
108 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
109 | opt_handler, NULL, &index); | ||
110 | |||
111 | argc -= index; | ||
112 | argv += index; | ||
113 | 72 | ||
114 | if (!use_draft && argc > 0) | 73 | if (!use_draft && argc > 0) |
115 | name = argv[0]; | 74 | name = argv[0]; | ... | ... |
... | @@ -144,7 +144,6 @@ mh/inc.c | ... | @@ -144,7 +144,6 @@ mh/inc.c |
144 | mh/install-mh.c | 144 | mh/install-mh.c |
145 | mh/mark.c | 145 | mh/mark.c |
146 | mh/mboxprop.c | 146 | mh/mboxprop.c |
147 | mh/mh_argp.c | ||
148 | mh/mh_fmtgram.y | 147 | mh/mh_fmtgram.y |
149 | mh/mh_format.c | 148 | mh/mh_format.c |
150 | mh/mh_getopt.c | 149 | mh/mh_getopt.c | ... | ... |
-
Please register or sign in to post a comment