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