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