Nico Golde:
[apps/madmutt.git] / main.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>
4  * Copyright (C) 1999-2002 Thomas Roessler <roessler@does-not-exist.org>
5  * Copyright (C) 2004 g10 Code GmbH
6  *
7  * This file is part of mutt-ng, see http://www.muttng.org/.
8  * It's licensed under the GNU General Public License,
9  * please see the file GPL in the top level source directory.
10  */
11
12 #define MAIN_C 1
13
14 #if HAVE_CONFIG_H
15 # include "config.h"
16 #endif
17
18 #include "mutt.h"
19 #include "mutt_curses.h"
20 #include "keymap.h"
21 #include "mailbox.h"
22 #include "url.h"
23 #include "mutt_crypt.h"
24 #include "mutt_idna.h"
25
26 #include <string.h>
27 #include <stdlib.h>
28 #include <locale.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <sys/stat.h>
32 #include <sys/utsname.h>
33
34 #ifdef HAVE_GETOPT_H
35 #include <getopt.h>
36 #endif
37
38 #ifdef HAVE_LIBIDN
39 #include <stringprep.h>
40 #endif
41
42 #ifdef USE_NNTP
43 #include <nntp.h>
44 #endif
45
46 static const char *ReachingUs = N_("\
47 To contact the developers, please mail to <mutt-ng-devel@lists.berlios.de>.\n\
48 To visit the Mutt-ng homepage go to http://www.muttng.org.\n\
49 To report a bug, please use the fleang(1) utility.\n");
50
51 static const char *Notice = N_("\
52 Copyright (C) 1996-2002 Michael R. Elkins and others.\n\
53 Mutt-ng comes with ABSOLUTELY NO WARRANTY; for details type `muttng -vv'.\n\
54 Mutt is free software, and you are welcome to redistribute it\n\
55 under certain conditions; type `muttng -vv' for details.\n");
56
57 static const char *Copyright = N_("\
58 Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>\n\
59 Copyright (C) 1996-2002 Brandon Long <blong@fiction.net>\n\
60 Copyright (C) 1997-2002 Thomas Roessler <roessler@does-not-exist.org>\n\
61 Copyright (C) 1998-2002 Werner Koch <wk@isil.d.shuttle.de>\n\
62 Copyright (C) 1999-2002 Brendan Cully <brendan@kublai.com>\n\
63 Copyright (C) 1999-2002 Tommi Komulainen <Tommi.Komulainen@iki.fi>\n\
64 Copyright (C) 2000-2002 Edmund Grimley Evans <edmundo@rano.org>\n\
65 Copyright (C) 2004-2005 Andreas Krennmair <ak@synflood.at>\n\
66 \n\
67 Lots of others not mentioned here contributed lots of code,\n\
68 fixes, and suggestions.\n\
69 \n\
70     This program is free software; you can redistribute it and/or modify\n\
71     it under the terms of the GNU General Public License as published by\n\
72     the Free Software Foundation; either version 2 of the License, or\n\
73     (at your option) any later version.\n\
74 \n\
75     This program is distributed in the hope that it will be useful,\n\
76     but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
77     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
78     GNU General Public License for more details.\n\
79 \n\
80     You should have received a copy of the GNU General Public License\n\
81     along with this program; if not, write to the Free Software\n\
82     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.\n\
83 ");
84
85 void mutt_exit (int code)
86 {
87   mutt_endwin (NULL);
88   exit (code);
89 }
90
91 static void mutt_usage (void)
92 {
93   puts (mutt_make_version ());
94
95   puts
96     _
97     ("usage: muttng [ -nRyzZ ] [ -e <cmd> ] [ -F <file> ] [ -m <type> ] [ -f <file> ]\n\
98        muttng [ -nR ] [ -e <cmd> ] [ -F <file> ] -Q <query> [ -Q <query> ] [...]\n\
99        muttng [ -nR ] [ -e <cmd> ] [ -F <file> ] -A <alias> [ -A <alias> ] [...]\n\
100        muttng [ -nx ] [ -e <cmd> ] [ -a <file> ] [ -F <file> ] [ -H <file> ] [ -i <file> ] [ -s <subj> ] [ -b <addr> ] [ -c <addr> ] <addr> [ ... ]\n\
101        muttng [ -n ] [ -e <cmd> ] [ -F <file> ] -p\n\
102        muttng -v[v]\n\
103 \n\
104 options:\n\
105   -A <alias>\texpand the given alias\n\
106   -a <file>\tattach a file to the message\n\
107   -b <address>\tspecify a blind carbon-copy (BCC) address\n\
108   -c <address>\tspecify a carbon-copy (CC) address\n\
109   -e <command>\tspecify a command to be executed after initialization\n\
110   -f <file>\tspecify which mailbox to read\n\
111   -F <file>\tspecify an alternate muttrc file\n\
112   -g <server>\tspecify a newsserver (if compiled with NNTP)\n\
113   -G\t\tselect a newsgroup (if compiled with NNTP)\n\
114   -H <file>\tspecify a draft file to read header and body from\n\
115   -i <file>\tspecify a file which Mutt-ng should include in the body\n\
116   -m <type>\tspecify a default mailbox type\n\
117   -n\t\tcauses Mutt-ng not to read the system Muttngrc\n\
118   -p\t\trecall a postponed message\n\
119   -Q <variable>\tquery a configuration variable\n\
120   -R\t\topen mailbox in read-only mode\n\
121   -s <subj>\tspecify a subject (must be in quotes if it has spaces)\n\
122   -v\t\tshow version and compile-time definitions\n\
123   -x\t\tsimulate the mailx send mode\n\
124   -y\t\tselect a mailbox specified in your `mailboxes' list\n\
125   -z\t\texit immediately if there are no messages in the mailbox\n\
126   -Z\t\topen the first folder with new message, exit immediately if none\n\
127   -h\t\tthis help message");
128
129   exit (0);
130 }
131
132 static void show_version (void)
133 {
134   struct utsname uts;
135
136   puts (mutt_make_version ());
137   puts (_(Notice));
138
139   uname (&uts);
140
141 #ifdef _AIX
142   printf ("System: %s %s.%s", uts.sysname, uts.version, uts.release);
143 #elif defined (SCO)
144   printf ("System: SCO %s", uts.release);
145 #else
146   printf ("System: %s %s", uts.sysname, uts.release);
147 #endif
148
149   printf (" (%s)", uts.machine);
150
151 #ifdef NCURSES_VERSION
152   printf (" [using ncurses %s]", NCURSES_VERSION);
153 #elif defined(USE_SLANG_CURSES)
154   printf (" [using slang %d]", SLANG_VERSION);
155 #endif
156
157 #ifdef _LIBICONV_VERSION
158   printf (" [using libiconv %d.%d]", _LIBICONV_VERSION >> 8,
159           _LIBICONV_VERSION & 0xff);
160 #endif
161
162 #ifdef HAVE_LIBIDN
163   printf (" [using libidn %s (compiled with %s)]",
164           stringprep_check_version (NULL), STRINGPREP_VERSION);
165 #endif
166
167   puts (_("\nCompile options:"));
168
169 #ifdef DOMAIN
170   printf ("DOMAIN=\"%s\"\n", DOMAIN);
171 #else
172   puts ("-DOMAIN");
173 #endif
174
175 #ifdef DEBUG
176   puts ("+DEBUG");
177 #else
178   puts ("-DEBUG");
179 #endif
180
181
182
183   puts (
184 #ifdef HOMESPOOL
185          "+HOMESPOOL  "
186 #else
187          "-HOMESPOOL  "
188 #endif
189 #ifdef USE_SETGID
190          "+USE_SETGID  "
191 #else
192          "-USE_SETGID  "
193 #endif
194 #ifdef USE_DOTLOCK
195          "+USE_DOTLOCK  "
196 #else
197          "-USE_DOTLOCK  "
198 #endif
199 #ifdef DL_STANDALONE
200          "+DL_STANDALONE  "
201 #else
202          "-DL_STANDALONE  "
203 #endif
204          "\n"
205 #ifdef USE_FCNTL
206          "+USE_FCNTL  "
207 #else
208          "-USE_FCNTL  "
209 #endif
210 #ifdef USE_FLOCK
211          "+USE_FLOCK   "
212 #else
213          "-USE_FLOCK   "
214 #endif
215 #ifdef USE_INODESORT
216          "+USE_INODESORT   "
217 #else
218          "-USE_INODESORT   "
219 #endif
220     );
221   puts (
222 #ifdef USE_POP
223          "+USE_POP  "
224 #else
225          "-USE_POP  "
226 #endif
227 #ifdef USE_NNTP
228          "+USE_NNTP  "
229 #else
230          "-USE_NNTP  "
231 #endif
232 #ifdef USE_IMAP
233          "+USE_IMAP  "
234 #else
235          "-USE_IMAP  "
236 #endif
237 #ifdef IMAP_EDIT_THREADS
238          "+IMAP_EDIT_THREADS  "
239 #else
240          "-IMAP_EDIT_THREADS  "
241 #endif
242 #ifdef USE_GSS
243          "+USE_GSS  "
244 #else
245          "-USE_GSS  "
246 #endif
247 #ifdef USE_SSL
248          "+USE_SSL  "
249 #else
250          "-USE_SSL  "
251 #endif
252 #ifdef USE_GNUTLS
253          "+USE_GNUTLS  "
254 #else
255          "-USE_GNUTLS  "
256 #endif
257 #ifdef USE_GNUTLS
258          "+USE_GNUTLS  "
259 #else
260          "-USE_GNUTLS  "
261 #endif
262 #ifdef USE_SASL
263          "+USE_SASL  "
264 #else
265          "-USE_SASL  "
266 #endif
267 #ifdef USE_SASL2
268          "+USE_SASL2  "
269 #else
270          "-USE_SASL2  "
271 #endif
272 #ifdef USE_LIBESMTP
273          "+USE_LIBESMTP  "
274 #else
275          "-USE_LIBESMTP  "
276 #endif
277          "\n"
278 #ifdef HAVE_REGCOMP
279          "+HAVE_REGCOMP  "
280 #else
281          "-HAVE_REGCOMP  "
282 #endif
283 #ifdef USE_GNU_REGEX
284          "+USE_GNU_REGEX  "
285 #else
286          "-USE_GNU_REGEX  "
287 #endif
288 #ifdef USE_COMPRESSED
289          "+COMPRESSED  "
290 #else
291          "-COMPRESSED  "
292 #endif
293          "\n"
294 #ifdef HAVE_COLOR
295          "+HAVE_COLOR  "
296 #else
297          "-HAVE_COLOR  "
298 #endif
299 #ifdef HAVE_START_COLOR
300          "+HAVE_START_COLOR  "
301 #else
302          "-HAVE_START_COLOR  "
303 #endif
304 #ifdef HAVE_TYPEAHEAD
305          "+HAVE_TYPEAHEAD  "
306 #else
307          "-HAVE_TYPEAHEAD  "
308 #endif
309 #ifdef HAVE_BKGDSET
310          "+HAVE_BKGDSET  "
311 #else
312          "-HAVE_BKGDSET  "
313 #endif
314          "\n"
315 #ifdef HAVE_CURS_SET
316          "+HAVE_CURS_SET  "
317 #else
318          "-HAVE_CURS_SET  "
319 #endif
320 #ifdef HAVE_META
321          "+HAVE_META  "
322 #else
323          "-HAVE_META  "
324 #endif
325 #ifdef HAVE_RESIZETERM
326          "+HAVE_RESIZETERM  "
327 #else
328          "-HAVE_RESIZETERM  "
329 #endif
330     );
331
332   puts (
333 #ifdef CRYPT_BACKEND_CLASSIC_PGP
334          "+CRYPT_BACKEND_CLASSIC_PGP  "
335 #else
336          "-CRYPT_BACKEND_CLASSIC_PGP  "
337 #endif
338 #ifdef CRYPT_BACKEND_CLASSIC_SMIME
339          "+CRYPT_BACKEND_CLASSIC_SMIME  "
340 #else
341          "-CRYPT_BACKEND_CLASSIC_SMIME  "
342 #endif
343 #ifdef CRYPT_BACKEND_GPGME
344          "+CRYPT_BACKEND_GPGME  "
345 #else
346          "-CRYPT_BACKEND_GPGME  "
347 #endif
348 #ifdef BUFFY_SIZE
349          "+BUFFY_SIZE "
350 #else
351          "-BUFFY_SIZE "
352 #endif
353 #ifdef EXACT_ADDRESS
354          "+EXACT_ADDRESS  "
355 #else
356          "-EXACT_ADDRESS  "
357 #endif
358 #ifdef SUN_ATTACHMENT
359          "+SUN_ATTACHMENT  "
360 #else
361          "-SUN_ATTACHMENT  "
362 #endif
363          "\n"
364 #ifdef ENABLE_NLS
365          "+ENABLE_NLS  "
366 #else
367          "-ENABLE_NLS  "
368 #endif
369 #ifdef LOCALES_HACK
370          "+LOCALES_HACK  "
371 #else
372          "-LOCALES_HACK  "
373 #endif
374 #ifdef HAVE_WC_FUNCS
375          "+HAVE_WC_FUNCS  "
376 #else
377          "-HAVE_WC_FUNCS  "
378 #endif
379 #ifdef HAVE_LANGINFO_CODESET
380          "+HAVE_LANGINFO_CODESET  "
381 #else
382          "-HAVE_LANGINFO_CODESET  "
383 #endif
384 #ifdef HAVE_LANGINFO_YESEXPR
385          "+HAVE_LANGINFO_YESEXPR  "
386 #else
387          "-HAVE_LANGINFO_YESEXPR  "
388 #endif
389          "\n"
390 #if HAVE_ICONV
391          "+HAVE_ICONV  "
392 #else
393          "-HAVE_ICONV  "
394 #endif
395 #if ICONV_NONTRANS
396          "+ICONV_NONTRANS  "
397 #else
398          "-ICONV_NONTRANS  "
399 #endif
400 #if HAVE_LIBIDN
401          "+HAVE_LIBIDN  "
402 #else
403          "-HAVE_LIBIDN  "
404 #endif
405 #if HAVE_GETSID
406          "+HAVE_GETSID  "
407 #else
408          "-HAVE_GETSID  "
409 #endif
410 #if HAVE_GETADDRINFO
411          "+HAVE_GETADDRINFO  "
412 #else
413          "-HAVE_GETADDRINFO  "
414 #endif
415 #if USE_HCACHE
416          "+USE_HCACHE  "
417 #else
418          "-USE_HCACHE  "
419 #endif
420 #if USE_HCACHE
421          "+USE_HCACHE  "
422 #else
423          "-USE_HCACHE  "
424 #endif
425     );
426
427 #ifdef ISPELL
428   printf ("ISPELL=\"%s\"\n", ISPELL);
429 #else
430   puts ("-ISPELL");
431 #endif
432
433   printf ("SENDMAIL=\"%s\"\n", SENDMAIL);
434   printf ("MAILPATH=\"%s\"\n", MAILPATH);
435   printf ("PKGDATADIR=\"%s\"\n", PKGDATADIR);
436   printf ("SYSCONFDIR=\"%s\"\n", SYSCONFDIR);
437   printf ("EXECSHELL=\"%s\"\n", EXECSHELL);
438 #ifdef MIXMASTER
439   printf ("MIXMASTER=\"%s\"\n", MIXMASTER);
440 #else
441   puts ("-MIXMASTER");
442 #endif
443
444   puts (_(ReachingUs));
445
446   mutt_print_patchlist ();
447
448   exit (0);
449 }
450
451 static void start_curses (void)
452 {
453   km_init ();                   /* must come before mutt_init */
454
455 #ifdef USE_SLANG_CURSES
456   SLtt_Ignore_Beep = 1;         /* don't do that #*$@^! annoying visual beep! */
457   SLsmg_Display_Eight_Bit = 128;        /* characters above this are printable */
458   SLtt_set_color (0, NULL, "default", "default");
459 #else
460   /* should come before initscr() so that ncurses 4.2 doesn't try to install
461      its own SIGWINCH handler */
462   mutt_signal_init ();
463 #endif
464   if (initscr () == NULL) {
465     puts _("Error initializing terminal.");
466
467     exit (1);
468   }
469 #if 1                           /* USE_SLANG_CURSES  - commenting out suggested in #455. */
470   /* slang requires the signal handlers to be set after initializing */
471   mutt_signal_init ();
472 #endif
473   ci_start_color ();
474   keypad (stdscr, TRUE);
475   cbreak ();
476   noecho ();
477 #if HAVE_TYPEAHEAD
478   typeahead (-1);               /* simulate smooth scrolling */
479 #endif
480 #if HAVE_META
481   meta (stdscr, TRUE);
482 #endif
483 }
484
485 #define M_IGNORE  (1<<0)        /* -z */
486 #define M_BUFFY   (1<<1)        /* -Z */
487 #define M_NOSYSRC (1<<2)        /* -n */
488 #define M_RO      (1<<3)        /* -R */
489 #define M_SELECT  (1<<4)        /* -y */
490 #ifdef USE_NNTP
491 #define M_NEWS    (1<<5)        /* -g and -G */
492 #endif
493
494 int main (int argc, char **argv)
495 {
496   char folder[_POSIX_PATH_MAX] = "";
497   char *subject = NULL;
498   char *includeFile = NULL;
499   char *draftFile = NULL;
500   char *newMagic = NULL;
501   HEADER *msg = NULL;
502   LIST *attach = NULL;
503   LIST *commands = NULL;
504   LIST *queries = NULL;
505   LIST *alias_queries = NULL;
506   int sendflags = 0;
507   int flags = 0;
508   int version = 0;
509   int i;
510   int explicit_folder = 0;
511   extern char *optarg;
512   extern int optind;
513
514   /* sanity check against stupid administrators */
515
516   if (getegid () != getgid ()) {
517     fprintf (stderr, "%s: I don't want to run with privileges!\n", argv[0]);
518     exit (1);
519   }
520
521 #ifdef ENABLE_NLS
522   /* FIXME what about init.c:1439 ? */
523   setlocale (LC_ALL, "");
524   bindtextdomain (PACKAGE, MUTTLOCALEDIR);
525   textdomain (PACKAGE);
526 #endif
527
528   setlocale (LC_CTYPE, "");
529
530   mutt_error = mutt_nocurses_error;
531   mutt_message = mutt_nocurses_error;
532   SRAND (time (NULL));
533   umask (077);
534
535   memset (Options, 0, sizeof (Options));
536   memset (QuadOptions, 0, sizeof (QuadOptions));
537
538 #ifdef USE_NNTP
539   while ((i =
540           getopt (argc, argv,
541                   "A:a:b:F:f:c:d:e:g:GH:s:i:hm:npQ:RvxyzZ")) != EOF)
542 #else
543   while ((i =
544           getopt (argc, argv, "A:a:b:F:f:c:d:e:H:s:i:hm:npQ:RvxyzZ")) != EOF)
545 #endif
546     switch (i) {
547     case 'A':
548       alias_queries = mutt_add_list (alias_queries, optarg);
549       break;
550     case 'a':
551       attach = mutt_add_list (attach, optarg);
552       break;
553
554     case 'F':
555       mutt_str_replace (&Muttrc, optarg);
556       break;
557
558     case 'f':
559       strfcpy (folder, optarg, sizeof (folder));
560       explicit_folder = 1;
561       break;
562
563     case 'b':
564     case 'c':
565       if (!msg)
566         msg = mutt_new_header ();
567       if (!msg->env)
568         msg->env = mutt_new_envelope ();
569       if (i == 'b')
570         msg->env->bcc = rfc822_parse_adrlist (msg->env->bcc, optarg);
571       else
572         msg->env->cc = rfc822_parse_adrlist (msg->env->cc, optarg);
573       break;
574
575     case 'd':
576 #ifdef DEBUG
577       debuglevel = atoi (optarg);
578       printf (_("Debugging at level %d.\n"), debuglevel);
579 #else
580       printf _("DEBUG was not defined during compilation.  Ignored.\n");
581 #endif
582       break;
583
584     case 'e':
585       commands = mutt_add_list (commands, optarg);
586       break;
587
588     case 'H':
589       draftFile = optarg;
590       break;
591
592     case 'i':
593       includeFile = optarg;
594       break;
595
596     case 'm':
597       /* should take precedence over .muttrc setting, so save it for later */
598       newMagic = optarg;
599       break;
600
601     case 'n':
602       flags |= M_NOSYSRC;
603       break;
604
605     case 'p':
606       sendflags |= SENDPOSTPONED;
607       break;
608
609     case 'Q':
610       queries = mutt_add_list (queries, optarg);
611       break;
612
613     case 'R':
614       flags |= M_RO;            /* read-only mode */
615       break;
616
617     case 's':
618       subject = optarg;
619       break;
620
621     case 'v':
622       version++;
623       break;
624
625     case 'x':                  /* mailx compatible send mode */
626       sendflags |= SENDMAILX;
627       break;
628
629     case 'y':                  /* My special hack mode */
630       flags |= M_SELECT;
631       break;
632
633 #ifdef USE_NNTP
634     case 'g':                  /* Specify a newsserver */
635       {
636         char buf[LONG_STRING];
637
638         snprintf (buf, sizeof (buf), "set news_server=%s", optarg);
639         commands = mutt_add_list (commands, buf);
640       }
641
642     case 'G':                  /* List of newsgroups */
643       flags |= M_SELECT | M_NEWS;
644       break;
645 #endif
646
647     case 'z':
648       flags |= M_IGNORE;
649       break;
650
651     case 'Z':
652       flags |= M_BUFFY | M_IGNORE;
653       break;
654
655     default:
656       mutt_usage ();
657     }
658
659   switch (version) {
660   case 0:
661     break;
662   case 1:
663     show_version ();
664     break;
665   default:
666     puts (mutt_make_version ());
667     puts (_(Copyright));
668     puts (_(ReachingUs));
669     exit (0);
670   }
671
672   /* Check for a batch send. */
673   if (!isatty (0) || queries || alias_queries) {
674     set_option (OPTNOCURSES);
675     sendflags = SENDBATCH;
676   }
677
678   /* This must come before mutt_init() because curses needs to be started
679      before calling the init_pair() function to set the color scheme.  */
680   if (!option (OPTNOCURSES))
681     start_curses ();
682
683   /* set defaults and read init files */
684   mutt_init (flags & M_NOSYSRC, commands);
685   mutt_free_list (&commands);
686
687   /* Initialize crypto backends.  */
688   crypt_init ();
689
690   if (queries)
691     return mutt_query_variables (queries);
692
693   if (alias_queries) {
694     int rv = 0;
695     ADDRESS *a;
696
697     for (; alias_queries; alias_queries = alias_queries->next) {
698       if ((a = mutt_lookup_alias (alias_queries->data))) {
699         /* output in machine-readable form */
700         mutt_addrlist_to_idna (a, NULL);
701         mutt_write_address_list (a, stdout, 0, 0);
702       }
703       else {
704         rv = 1;
705         printf ("%s\n", alias_queries->data);
706       }
707     }
708     return rv;
709   }
710
711   if (newMagic)
712     mx_set_magic (newMagic);
713
714   if (!option (OPTNOCURSES)) {
715     SETCOLOR (MT_COLOR_NORMAL);
716     clear ();
717     mutt_error = mutt_curses_error;
718     mutt_message = mutt_curses_message;
719   }
720
721   /* Create the Maildir directory if it doesn't exist. */
722   if (!option (OPTNOCURSES) && Maildir) {
723     struct stat sb;
724     char fpath[_POSIX_PATH_MAX];
725     char msg[STRING];
726
727     strfcpy (fpath, Maildir, sizeof (fpath));
728     mutt_expand_path (fpath, sizeof (fpath));
729 #ifdef USE_IMAP
730     /* we're not connected yet - skip mail folder creation */
731     if (!mx_is_imap (fpath))
732 #endif
733       if (stat (fpath, &sb) == -1 && errno == ENOENT) {
734         snprintf (msg, sizeof (msg), _("%s does not exist. Create it?"),
735                   Maildir);
736         if (mutt_yesorno (msg, M_YES) == M_YES) {
737           if (mkdir (fpath, 0700) == -1 && errno != EEXIST)
738             mutt_error (_("Can't create %s: %s."), Maildir, strerror (errno));
739         }
740       }
741   }
742
743   if (sendflags & SENDPOSTPONED) {
744     if (!option (OPTNOCURSES))
745       mutt_flushinp ();
746     ci_send_message (SENDPOSTPONED, NULL, NULL, NULL, NULL);
747     mutt_endwin (NULL);
748   }
749   else if (subject || msg || sendflags || draftFile || includeFile || attach
750            || optind < argc) {
751     FILE *fin = NULL;
752     char buf[LONG_STRING];
753     char *tempfile = NULL, *infile = NULL;
754     char *bodytext = NULL;
755
756     if (!option (OPTNOCURSES))
757       mutt_flushinp ();
758
759     if (!msg)
760       msg = mutt_new_header ();
761
762     if (draftFile)
763       infile = draftFile;
764     else {
765       if (!msg->env)
766         msg->env = mutt_new_envelope ();
767
768       for (i = optind; i < argc; i++) {
769         if (url_check_scheme (argv[i]) == U_MAILTO)
770           url_parse_mailto (msg->env, &bodytext, argv[i]);
771         else
772           msg->env->to = rfc822_parse_adrlist (msg->env->to, argv[i]);
773       }
774
775       if (option (OPTAUTOEDIT) && !msg->env->to && !msg->env->cc) {
776         if (!option (OPTNOCURSES))
777           mutt_endwin (NULL);
778         fputs (_("No recipients specified.\n"), stderr);
779         exit (1);
780       }
781
782       if (subject)
783         msg->env->subject = safe_strdup (subject);
784
785       if (includeFile)
786         infile = includeFile;
787     }
788
789     if (infile || bodytext) {
790       if (infile) {
791         if (mutt_strcmp ("-", infile) == 0)
792           fin = stdin;
793         else {
794           char path[_POSIX_PATH_MAX];
795
796           strfcpy (path, infile, sizeof (path));
797           mutt_expand_path (path, sizeof (path));
798           if ((fin = fopen (path, "r")) == NULL) {
799             if (!option (OPTNOCURSES))
800               mutt_endwin (NULL);
801             perror (path);
802             exit (1);
803           }
804         }
805       }
806       else
807         fin = NULL;
808
809       mutt_mktemp (buf);
810       tempfile = safe_strdup (buf);
811
812       if (draftFile)
813         msg->env = mutt_read_rfc822_header (fin, NULL, 1, 0);
814
815       /* is the following if still needed? */
816
817       if (tempfile) {
818         FILE *fout;
819
820         if ((fout = safe_fopen (tempfile, "w")) == NULL) {
821           if (!option (OPTNOCURSES))
822             mutt_endwin (NULL);
823           perror (tempfile);
824           fclose (fin);
825           FREE (&tempfile);
826           exit (1);
827         }
828         if (fin)
829           mutt_copy_stream (fin, fout);
830         else if (bodytext)
831           fputs (bodytext, fout);
832         fclose (fout);
833         if (fin && fin != stdin)
834           fclose (fin);
835       }
836     }
837
838     FREE (&bodytext);
839
840     if (attach) {
841       LIST *t = attach;
842       BODY *a = NULL;
843
844       while (t) {
845         if (a) {
846           a->next = mutt_make_file_attach (t->data);
847           a = a->next;
848         }
849         else
850           msg->content = a = mutt_make_file_attach (t->data);
851         if (!a) {
852           if (!option (OPTNOCURSES))
853             mutt_endwin (NULL);
854           fprintf (stderr, _("%s: unable to attach file.\n"), t->data);
855           mutt_free_list (&attach);
856           exit (1);
857         }
858         t = t->next;
859       }
860       mutt_free_list (&attach);
861     }
862
863     ci_send_message (sendflags, msg, tempfile, NULL, NULL);
864
865     if (!option (OPTNOCURSES))
866       mutt_endwin (NULL);
867   }
868   else {
869     if (flags & M_BUFFY) {
870       if (!mutt_buffy_check (0)) {
871         mutt_endwin _("No mailbox with new mail.");
872
873         exit (1);
874       }
875       folder[0] = 0;
876       mutt_buffy (folder, sizeof (folder));
877     }
878     else if (flags & M_SELECT) {
879 #ifdef USE_NNTP
880       if (flags & M_NEWS) {
881         set_option (OPTNEWS);
882         if (!(CurrentNewsSrv = mutt_select_newsserver (NewsServer))) {
883           mutt_endwin (Errorbuf);
884           exit (1);
885         }
886       }
887       else
888 #endif
889       if (!Incoming) {
890         mutt_endwin _("No incoming mailboxes defined.");
891
892         exit (1);
893       }
894       folder[0] = 0;
895       mutt_select_file (folder, sizeof (folder), M_SEL_FOLDER | M_SEL_BUFFY);
896       if (!folder[0]) {
897         mutt_endwin (NULL);
898         exit (0);
899       }
900     }
901
902     if (!folder[0])
903       strfcpy (folder, NONULL (Spoolfile), sizeof (folder));
904
905 #ifdef USE_NNTP
906     if (option (OPTNEWS)) {
907       unset_option (OPTNEWS);
908       nntp_expand_path (folder, sizeof (folder),
909                         &CurrentNewsSrv->conn->account);
910     }
911     else
912 #endif
913       mutt_expand_path (folder, sizeof (folder));
914
915     mutt_str_replace (&CurrentFolder, folder);
916     mutt_str_replace (&LastFolder, folder);
917
918     if (flags & M_IGNORE) {
919       /* check to see if there are any messages in the folder */
920       switch (mx_check_empty (folder)) {
921       case -1:
922         mutt_endwin (strerror (errno));
923         exit (1);
924       case 1:
925         mutt_endwin _("Mailbox is empty.");
926         exit (1);
927       }
928     }
929
930     mutt_folder_hook (folder);
931
932     if ((Context = mx_open_mailbox (folder, ((flags & M_RO)
933                                              || option (OPTREADONLY)) ?
934                                     M_READONLY : 0, NULL))
935         || !explicit_folder) {
936       mutt_index_menu ();
937       if (Context)
938         FREE (&Context);
939     }
940     mutt_endwin (Errorbuf);
941   }
942
943   exit (0);
944 }