main.c 16.9 KB
Newer Older
Thomas Roessler's avatar
Thomas Roessler committed
1
/*
2 3
 * Copyright (C) 1996-2000 Michael R. Elkins <me@cs.hmc.edu>
 * Copyright (C) 1999-2000 Thomas Roessler <roessler@guug.de>
Thomas Roessler's avatar
Thomas Roessler committed
4 5 6 7 8 9 10 11 12 13 14 15 16
 * 
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with this program; if not, write to the Free Software
17
 *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
Thomas Roessler's avatar
Thomas Roessler committed
18 19 20 21 22 23 24 25
 */ 

#define MAIN_C 1

#include "mutt.h"
#include "mutt_curses.h"
#include "keymap.h"
#include "mailbox.h"
26
#include "url.h"
Thomas Roessler's avatar
Thomas Roessler committed
27 28 29 30 31 32 33 34 35 36
#include "reldate.h"

#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/utsname.h>

Thomas Roessler's avatar
Thomas Roessler committed
37 38 39 40
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif

41
static const char *ReachingUs = N_("\
42
To contact the developers, please mail to <mutt-dev@mutt.org>.\n\
43
To report a bug, please use the flea(1) utility.\n");
44

45
static const char *Notice = N_("\
46
Copyright (C) 1996-2000 Michael R. Elkins and others.\n\
Thomas Roessler's avatar
Thomas Roessler committed
47 48
Mutt comes with ABSOLUTELY NO WARRANTY; for details type `mutt -vv'.\n\
Mutt is free software, and you are welcome to redistribute it\n\
Thomas Roessler's avatar
Thomas Roessler committed
49
under certain conditions; type `mutt -vv' for details.\n");
Thomas Roessler's avatar
Thomas Roessler committed
50

51
static const char *Copyright = N_("\
52 53 54 55 56 57
Copyright (C) 1996-2000 Michael R. Elkins <me@cs.hmc.edu>\n\
Copyright (C) 1996-2000 Brandon Long <blong@fiction.net>\n\
Copyright (C) 1997-2000 Thomas Roessler <roessler@guug.de>\n\
Copyright (C) 1998-2000 Werner Koch <wk@isil.d.shuttle.de>\n\
Copyright (C) 1999-2000 Brendan Cully <brendan@kublai.com>\n\
Copyright (C) 1999-2000 Tommi Komulainen <Tommi.Komulainen@iki.fi>\n\
Thomas Roessler's avatar
Thomas Roessler committed
58
Copyright (C) 2000      Edmund Grimley Evans <edmundo@rano.org>\n\
59 60 61
\n\
Lots of others not mentioned here contributed lots of code,\n\
fixes, and suggestions.\n\
Thomas Roessler's avatar
Thomas Roessler committed
62 63 64 65 66 67 68 69 70 71 72 73 74
\n\
    This program is free software; you can redistribute it and/or modify\n\
    it under the terms of the GNU General Public License as published by\n\
    the Free Software Foundation; either version 2 of the License, or\n\
    (at your option) any later version.\n\
\n\
    This program is distributed in the hope that it will be useful,\n\
    but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
    GNU General Public License for more details.\n\
\n\
    You should have received a copy of the GNU General Public License\n\
    along with this program; if not, write to the Free Software\n\
75
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.\n\
Thomas Roessler's avatar
Thomas Roessler committed
76
");
Thomas Roessler's avatar
Thomas Roessler committed
77 78 79 80 81 82 83 84 85

void mutt_exit (int code)
{
  mutt_endwin (NULL);
  exit (code);
}

static void mutt_usage (void)
{
86 87
  printf ("Mutt %s (%s)\n", MUTT_VERSION, ReleaseDate);
  puts _(
88
"usage: mutt [ -nRyzZ ] [ -e <cmd> ] [ -F <file> ] [ -m <type> ] [ -f <file> ]\n\
Thomas Roessler's avatar
Thomas Roessler committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
       mutt [ -nx ] [ -e <cmd> ] [ -a <file> ] [ -F <file> ] [ -H <file> ] [ -i <file> ] [ -s <subj> ] [ -b <addr> ] [ -c <addr> ] <addr> [ ... ]\n\
       mutt [ -n ] [ -e <cmd> ] [ -F <file> ] -p\n\
       mutt -v[v]\n\
\n\
options:\n\
  -a <file>\tattach a file to the message\n\
  -b <address>\tspecify a blind carbon-copy (BCC) address\n\
  -c <address>\tspecify a carbon-copy (CC) address\n\
  -e <command>\tspecify a command to be executed after initialization\n\
  -f <file>\tspecify which mailbox to read\n\
  -F <file>\tspecify an alternate muttrc file\n\
  -H <file>\tspecify a draft file to read header from\n\
  -i <file>\tspecify a file which Mutt should include in the reply\n\
  -m <type>\tspecify a default mailbox type\n\
  -n\t\tcauses Mutt not to read the system Muttrc\n\
  -p\t\trecall a postponed message\n\
  -R\t\topen mailbox in read-only mode\n\
  -s <subj>\tspecify a subject (must be in quotes if it has spaces)\n\
  -v\t\tshow version and compile-time definitions\n\
  -x\t\tsimulate the mailx send mode\n\
  -y\t\tselect a mailbox specified in your `mailboxes' list\n\
  -z\t\texit immediately if there are no messages in the mailbox\n\
  -Z\t\topen the first folder with new message, exit immediately if none\n\
  -h\t\tthis help message");

  exit (0);
}

static void show_version (void)
{
  struct utsname uts;

121
  printf ("Mutt %s (%s)\n", MUTT_VERSION, ReleaseDate);
122
  puts (_(Notice));
Thomas Roessler's avatar
Thomas Roessler committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

  uname (&uts);

#ifdef _AIX
  printf ("System: %s %s.%s", uts.sysname, uts.version, uts.release);
#elif defined (SCO)
  printf ("System: SCO %s", uts.release);
#else
  printf ("System: %s %s", uts.sysname, uts.release);
#endif

#ifdef NCURSES_VERSION
  printf (" [using ncurses %s]", NCURSES_VERSION);
#elif defined(USE_SLANG_CURSES)
  printf (" [using slang %d]", SLANG_VERSION);
#endif

140
  puts (_("\nCompile options:"));
Thomas Roessler's avatar
Thomas Roessler committed
141 142 143 144 145 146 147

#ifdef DOMAIN
  printf ("DOMAIN=\"%s\"\n", DOMAIN);
#else
  puts ("-DOMAIN");
#endif

148 149 150 151 152 153 154 155
#ifdef DEBUG
  puts ("+DEBUG");
#else
  puts ("-DEBUG");
#endif
  

  
Thomas Roessler's avatar
Thomas Roessler committed
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
  puts (

#ifdef HOMESPOOL
	"+HOMESPOOL  "
#else
	"-HOMESPOOL  "
#endif

#ifdef USE_SETGID
	"+USE_SETGID  "
#else
	"-USE_SETGID  "
#endif

#ifdef USE_DOTLOCK
	"+USE_DOTLOCK  "
#else
	"-USE_DOTLOCK  "
#endif

176 177 178 179 180 181 182 183
#ifdef DL_STANDALONE
	"+DL_STANDALONE  "
#else
	"-DL_STANDALONE  "
#endif

	"\n"
	
Thomas Roessler's avatar
Thomas Roessler committed
184 185 186 187 188 189 190 191 192 193 194 195 196
#ifdef USE_FCNTL
	"+USE_FCNTL  "
#else
	"-USE_FCNTL  "
#endif

#ifdef USE_FLOCK
	"+USE_FLOCK"
#else
	"-USE_FLOCK"
#endif
	);
  puts (
197 198 199 200 201 202
#ifdef USE_POP
	"+USE_POP  "
#else
	"-USE_POP  "
#endif

Thomas Roessler's avatar
Thomas Roessler committed
203 204 205 206 207 208
#ifdef USE_IMAP
        "+USE_IMAP  "
#else
        "-USE_IMAP  "
#endif

209 210 211 212 213 214
#ifdef USE_GSS
	"+USE_GSS  "
#else
	"-USE_GSS  "
#endif

215
	
216 217 218 219 220 221
#ifdef USE_SSL
	"+USE_SSL  "
#else
	"-USE_SSL  "
#endif

222 223
#ifdef USE_SASL
	"+USE_SASL  "
Thomas Roessler's avatar
Thomas Roessler committed
224
#else
225
	"-USE_SASL  "
Thomas Roessler's avatar
Thomas Roessler committed
226
#endif
227 228
	"\n"
	
Thomas Roessler's avatar
Thomas Roessler committed
229 230 231 232 233 234
#ifdef HAVE_REGCOMP
	"+HAVE_REGCOMP  "
#else
	"-HAVE_REGCOMP  "
#endif

235 236
#ifdef USE_GNU_REGEX
	"+USE_GNU_REGEX  "
Thomas Roessler's avatar
Thomas Roessler committed
237
#else
238
	"-USE_GNU_REGEX  "
Thomas Roessler's avatar
Thomas Roessler committed
239 240
#endif

Thomas Roessler's avatar
Thomas Roessler committed
241 242
	"\n"
	
Thomas Roessler's avatar
Thomas Roessler committed
243 244 245 246 247
#ifdef HAVE_COLOR
	"+HAVE_COLOR  "
#else
	"-HAVE_COLOR  "
#endif
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
	
#ifdef HAVE_START_COLOR
	"+HAVE_START_COLOR  "
#else
	"-HAVE_START_COLOR  "
#endif
	
#ifdef HAVE_TYPEAHEAD
	"+HAVE_TYPEAHEAD  "
#else
	"-HAVE_TYPEAHEAD  "
#endif
	
#ifdef HAVE_BKGDSET
	"+HAVE_BKGDSET  "
#else
	"-HAVE_BKGDSET  "
#endif
Thomas Roessler's avatar
Thomas Roessler committed
266

267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
	"\n"
	
#ifdef HAVE_CURS_SET
	"+HAVE_CURS_SET  "
#else
	"-HAVE_CURS_SET  "
#endif
	
#ifdef HAVE_META
	"+HAVE_META  "
#else
	"-HAVE_META  "
#endif
	
#ifdef HAVE_RESIZETERM
	"+HAVE_RESIZETERM  "
#else
	"-HAVE_RESIZETERM  "
#endif
	
	
	);
  
  
  puts (
	
293 294 295 296
#ifdef HAVE_PGP
	"+HAVE_PGP  "
#else
	"-HAVE_PGP  "
Thomas Roessler's avatar
Thomas Roessler committed
297 298 299
#endif

#ifdef BUFFY_SIZE
Thomas Roessler's avatar
Thomas Roessler committed
300
	"+BUFFY_SIZE "
Thomas Roessler's avatar
Thomas Roessler committed
301
#else
Thomas Roessler's avatar
Thomas Roessler committed
302
	"-BUFFY_SIZE "
Thomas Roessler's avatar
Thomas Roessler committed
303 304
#endif
#ifdef EXACT_ADDRESS
305
	"+EXACT_ADDRESS  "
Thomas Roessler's avatar
Thomas Roessler committed
306
#else
307
	"-EXACT_ADDRESS  "
Thomas Roessler's avatar
Thomas Roessler committed
308
#endif
309 310 311 312 313 314 315 316 317

#ifdef SUN_ATTACHMENT
	"+SUN_ATTACHMENT  "
#else
	"-SUN_ATTACHMENT  "
#endif

	"\n"
	
318
#ifdef ENABLE_NLS
319
	"+ENABLE_NLS  "
320
#else
321
	"-ENABLE_NLS  "
322
#endif
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340

#ifdef LOCALES_HACK
	"+LOCALES_HACK  "
#else
	"-LOCALES_HACK  "
#endif
	      
#ifdef HAVE_WC_FUNCS
	"+HAVE_WC_FUNCS  "
#else
	"-HAVE_WC_FUNCS  "
#endif
	
#ifdef HAVE_LANGINFO_CODESET
	"+HAVE_LANGINFO_CODESET  "
#else
	"-HAVE_LANGINFO_CODESET  "
#endif
341

342 343 344 345 346 347 348
	
#ifdef HAVE_LANGINFO_YESEXPR
 	"+HAVE_LANGINFO_YESEXPR  "
#else
 	"-HAVE_LANGINFO_YESEXPR  "
#endif
	
349 350
	"\n"

Thomas Roessler's avatar
Thomas Roessler committed
351 352 353 354 355 356
#if HAVE_ICONV
	"+HAVE_ICONV  "
#else
	"-HAVE_ICONV  "
#endif

357 358 359 360 361 362
#if ICONV_NONTRANS
	"+ICONV_NONTRANS  "
#else
	"-ICONV_NONTRANS  "
#endif

363
#if HAVE_GETSID
364
	"+HAVE_GETSID  "
365
#else
366
	"-HAVE_GETSID  "
367
#endif
368 369 370 371 372 373 374

#if HAVE_GETADDRINFO
	"+HAVE_GETADDRINFO  "
#else
	"-HAVE_GETADDRINFO  "
#endif

Thomas Roessler's avatar
Thomas Roessler committed
375 376 377 378 379 380 381 382
	);

#ifdef ISPELL
  printf ("ISPELL=\"%s\"\n", ISPELL);
#else
  puts ("-ISPELL");
#endif

383 384 385 386
  printf ("SENDMAIL=\"%s\"\n", SENDMAIL);
  printf ("MAILPATH=\"%s\"\n", MAILPATH);
  printf ("SHAREDIR=\"%s\"\n", SHAREDIR);
  printf ("SYSCONFDIR=\"%s\"\n", SYSCONFDIR);
387 388 389 390 391 392 393
  printf ("EXECSHELL=\"%s\"\n", EXECSHELL);
#ifdef MIXMASTER
  printf ("MIXMASTER=\"%s\"\n", MIXMASTER);
#else
  puts ("-MIXMASTER");
#endif
  
394
  puts(_(ReachingUs));
Thomas Roessler's avatar
Thomas Roessler committed
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412

  exit (0);
}

static void start_curses (void)
{
  km_init (); /* must come before mutt_init */

#ifdef USE_SLANG_CURSES
  SLtt_Ignore_Beep = 1; /* don't do that #*$@^! annoying visual beep! */
  SLsmg_Display_Eight_Bit = 128; /* characters above this are printable */
#else
  /* should come before initscr() so that ncurses 4.2 doesn't try to install
     its own SIGWINCH handler */
  mutt_signal_init ();
#endif
  if (initscr () == NULL)
  {
413
    puts _("Error initializing terminal.");
Thomas Roessler's avatar
Thomas Roessler committed
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
    exit (1);
  }
#ifdef USE_SLANG_CURSES
  /* slang requires the signal handlers to be set after initializing */
  mutt_signal_init ();
#endif
  ci_start_color ();
  keypad (stdscr, TRUE);
  cbreak ();
  noecho ();
#if HAVE_TYPEAHEAD
  typeahead (-1);       /* simulate smooth scrolling */
#endif
#if HAVE_META
  meta (stdscr, TRUE);
#endif
}

#define M_IGNORE  (1<<0)	/* -z */
#define M_BUFFY   (1<<1)	/* -Z */
#define M_NOSYSRC (1<<2)	/* -n */
#define M_RO      (1<<3)	/* -R */
#define M_SELECT  (1<<4)	/* -y */

int main (int argc, char **argv)
{
  char folder[_POSIX_PATH_MAX] = "";
  char *subject = NULL;
  char *includeFile = NULL;
  char *draftFile = NULL;
  char *newMagic = NULL;
  HEADER *msg = NULL;
  LIST *attach = NULL;
  LIST *commands = NULL;
  int sendflags = 0;
  int flags = 0;
  int version = 0;
  int i;
452
  int explicit_folder = 0;
Thomas Roessler's avatar
Thomas Roessler committed
453 454 455
  extern char *optarg;
  extern int optind;

Thomas Roessler's avatar
Thomas Roessler committed
456 457 458 459 460 461 462 463
  /* sanity check against stupid administrators */
  
  if(getegid() != getgid())
  {
    fprintf(stderr, "%s: I don't want to run with privileges!\n",
	    argv[0]);
    exit(1);
  }
Thomas Roessler's avatar
Thomas Roessler committed
464

465 466 467 468 469 470
#ifdef ENABLE_NLS
  /* FIXME what about init.c:1439 ? */
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, MUTTLOCALEDIR);
  textdomain (PACKAGE);
#endif
Thomas Roessler's avatar
Thomas Roessler committed
471

472 473
  setlocale (LC_CTYPE, "");

Thomas Roessler's avatar
Thomas Roessler committed
474
  mutt_error = mutt_nocurses_error;
Thomas Roessler's avatar
Thomas Roessler committed
475 476 477 478
  SRAND (time (NULL));
  umask (077);

  memset (Options, 0, sizeof (Options));
479 480
  memset (QuadOptions, 0, sizeof (QuadOptions));
  
Thomas Roessler's avatar
Thomas Roessler committed
481 482 483 484 485 486 487 488
  while ((i = getopt (argc, argv, "a:b:F:f:c:d:e:H:s:i:hm:npRvxyzZ")) != EOF)
    switch (i)
    {
      case 'a':
	attach = mutt_add_list (attach, optarg);
	break;

      case 'F':
489
	mutt_str_replace (&Muttrc, optarg);
Thomas Roessler's avatar
Thomas Roessler committed
490 491 492 493
	break;

      case 'f':
	strfcpy (folder, optarg, sizeof (folder));
494
        explicit_folder = 1;
Thomas Roessler's avatar
Thomas Roessler committed
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
	break;

      case 'b':
      case 'c':
	if (!msg)
	  msg = mutt_new_header ();
	if (!msg->env)
	  msg->env = mutt_new_envelope ();
	if (i == 'b')
	  msg->env->bcc = rfc822_parse_adrlist (msg->env->bcc, optarg);
	else
	  msg->env->cc = rfc822_parse_adrlist (msg->env->cc, optarg);
	break;

      case 'd':
#ifdef DEBUG
	debuglevel = atoi (optarg);
512
	printf (_("Debugging at level %d.\n"), debuglevel);
Thomas Roessler's avatar
Thomas Roessler committed
513
#else
514
	printf _("DEBUG was not defined during compilation.  Ignored.\n");
Thomas Roessler's avatar
Thomas Roessler committed
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
#endif
	break;

      case 'e':
	commands = mutt_add_list (commands, optarg);
	break;

      case 'H':
	draftFile = optarg;
	break;

      case 'i':
	includeFile = optarg;
	break;

      case 'm':
	/* should take precedence over .muttrc setting, so save it for later */
	newMagic = optarg; 
	break;

      case 'n':
	flags |= M_NOSYSRC;
	break;

      case 'p':
	sendflags |= SENDPOSTPONED;
	break;

      case 'R':
	flags |= M_RO; /* read-only mode */
	break;

      case 's':
	subject = optarg;
	break;

      case 'v':
	version++;
	break;

      case 'x': /* mailx compatible send mode */
	sendflags |= SENDMAILX;
	break;

      case 'y': /* My special hack mode */
	flags |= M_SELECT;
	break;

      case 'z':
	flags |= M_IGNORE;
	break;

      case 'Z':
	flags |= M_BUFFY | M_IGNORE;
	break;

      default:
	mutt_usage ();
    }

  switch (version)
  {
    case 0:
      break;
    case 1:
      show_version ();
      break;
    default:
583
      printf ("Mutt %s (%s)\n", MUTT_VERSION, ReleaseDate);
584 585
      puts (_(Copyright));
      puts (_(ReachingUs));
Thomas Roessler's avatar
Thomas Roessler committed
586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
      exit (0);
  }

  /* Check for a batch send. */
  if (!isatty (0))
  {
    set_option (OPTNOCURSES);
    sendflags = SENDBATCH;
  }

  /* This must come before mutt_init() because curses needs to be started
     before calling the init_pair() function to set the color scheme.  */
  if (!option (OPTNOCURSES))
    start_curses ();

  /* set defaults and read init files */
  mutt_init (flags & M_NOSYSRC, commands);
  mutt_free_list (&commands);

  if (newMagic)
    mx_set_magic (newMagic);

  if (!option (OPTNOCURSES))
  {
    SETCOLOR (MT_COLOR_NORMAL);
    clear ();
    mutt_error = mutt_curses_error;
  }

615
  /* Create the Maildir directory if it doesn't exist. */
616 617 618 619 620 621 622 623
  if (!option (OPTNOCURSES) && Maildir)
  {
    struct stat sb;
    char fpath[_POSIX_PATH_MAX];
    char msg[STRING];

    strfcpy (fpath, Maildir, sizeof (fpath));
    mutt_expand_path (fpath, sizeof (fpath));
624 625 626 627
#ifdef USE_IMAP
    /* we're not connected yet - skip mail folder creation */
    if (!mx_is_imap (fpath))
#endif
628 629 630 631 632 633 634 635 636 637 638
    if (stat (fpath, &sb) == -1 && errno == ENOENT)
    {
      snprintf (msg, sizeof (msg), _("%s does not exist. Create it?"), Maildir);
      if (mutt_yesorno (msg, 1) == 1)
      {
	if (mkdir (fpath, 0700) == -1 && errno != EEXIST)
	  mutt_error ( _("Can't create %s: %s."), Maildir, strerror (errno));
      }
    }
  }

Thomas Roessler's avatar
Thomas Roessler committed
639 640 641 642 643 644 645 646 647 648 649 650 651
  if (sendflags & SENDPOSTPONED)
  {
    if (!option (OPTNOCURSES))
      mutt_flushinp ();
    ci_send_message (SENDPOSTPONED, NULL, NULL, NULL, NULL);
    mutt_endwin (NULL);
  }
  else if (subject || msg || sendflags || draftFile || includeFile || attach ||
	   optind < argc)
  {
    FILE *fin = NULL;
    char buf[LONG_STRING];
    char *tempfile = NULL, *infile = NULL;
652 653
    char *bodytext = NULL;
    
Thomas Roessler's avatar
Thomas Roessler committed
654 655 656 657 658 659 660 661 662 663 664 665 666 667
    if (!option (OPTNOCURSES))
      mutt_flushinp ();

    if (!msg)
      msg = mutt_new_header ();

    if (draftFile)
      infile = draftFile;
    else
    {
      if (!msg->env)
	msg->env = mutt_new_envelope ();

      for (i = optind; i < argc; i++)
668 669 670 671 672 673
      {
	if (url_check_scheme (argv[i]) == U_MAILTO)
	  url_parse_mailto (msg->env, &bodytext, argv[i]);
	else
	  msg->env->to = rfc822_parse_adrlist (msg->env->to, argv[i]);
      }
Thomas Roessler's avatar
Thomas Roessler committed
674

675
      if (option (OPTAUTOEDIT) && !msg->env->to && !msg->env->cc)
Thomas Roessler's avatar
Thomas Roessler committed
676 677 678
      {
	if (!option (OPTNOCURSES))
	  mutt_endwin (NULL);
679
	fputs (_("No recipients specified.\n"), stderr);
Thomas Roessler's avatar
Thomas Roessler committed
680 681 682
	exit (1);
      }

683 684 685
      if (subject)
	msg->env->subject = safe_strdup (subject);

Thomas Roessler's avatar
Thomas Roessler committed
686 687 688 689
      if (includeFile)
	infile = includeFile;
    }

690
    if (infile || bodytext)
Thomas Roessler's avatar
Thomas Roessler committed
691
    {
692
      if (infile)
Thomas Roessler's avatar
Thomas Roessler committed
693
      {
694 695 696
	if (mutt_strcmp ("-", infile) == 0)
	  fin = stdin;
	else 
Thomas Roessler's avatar
Thomas Roessler committed
697
	{
698 699 700 701 702 703 704 705 706 707 708
	  char path[_POSIX_PATH_MAX];
	  
	  strfcpy (path, infile, sizeof (path));
	  mutt_expand_path (path, sizeof (path));
	  if ((fin = fopen (path, "r")) == NULL)
	  {
	    if (!option (OPTNOCURSES))
	      mutt_endwin (NULL);
	    perror (path);
	    exit (1);
	  }
Thomas Roessler's avatar
Thomas Roessler committed
709 710
	}
      }
711 712 713
      else
	fin = NULL;

Thomas Roessler's avatar
Thomas Roessler committed
714 715 716 717
      mutt_mktemp (buf);
      tempfile = safe_strdup (buf);

      if (draftFile)
718
	msg->env = mutt_read_rfc822_header (fin, NULL, 1, 0);
Thomas Roessler's avatar
Thomas Roessler committed
719

720 721
      /* is the following if still needed? */
      
Thomas Roessler's avatar
Thomas Roessler committed
722 723 724 725 726 727 728 729 730 731
      if (tempfile)
      {
	FILE *fout;

	if ((fout = safe_fopen (tempfile, "w")) == NULL)
	{
	  if (!option (OPTNOCURSES))
	    mutt_endwin (NULL);
	  perror (tempfile);
	  fclose (fin);
Thomas Roessler's avatar
Thomas Roessler committed
732
	  FREE (&tempfile);
Thomas Roessler's avatar
Thomas Roessler committed
733 734
	  exit (1);
	}
735 736 737 738
	if (fin)
	  mutt_copy_stream (fin, fout);
	else if (bodytext)
	  fputs (bodytext, fout);
Thomas Roessler's avatar
Thomas Roessler committed
739
	fclose (fout);
740
	if (fin && fin != stdin)
Thomas Roessler's avatar
Thomas Roessler committed
741 742 743 744
	  fclose (fin);
      }
    }

745 746
    safe_free ((void **) &bodytext);
    
Thomas Roessler's avatar
Thomas Roessler committed
747 748 749 750 751 752 753 754 755
    if (attach)
    {
      LIST *t = attach;
      BODY *a = NULL;

      while (t)
      {
	if (a)
	{
Thomas Roessler's avatar
Thomas Roessler committed
756
	  a->next = mutt_make_file_attach (t->data);
Thomas Roessler's avatar
Thomas Roessler committed
757 758 759
	  a = a->next;
	}
	else
Thomas Roessler's avatar
Thomas Roessler committed
760
	  msg->content = a = mutt_make_file_attach (t->data);
Thomas Roessler's avatar
Thomas Roessler committed
761 762 763 764
	if (!a)
	{
	  if (!option (OPTNOCURSES))
	    mutt_endwin (NULL);
765
	  fprintf (stderr, _("%s: unable to attach file.\n"), t->data);
Thomas Roessler's avatar
Thomas Roessler committed
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
	  mutt_free_list (&attach);
	  exit (1);
	}
	t = t->next;
      }
      mutt_free_list (&attach);
    }

    ci_send_message (sendflags, msg, tempfile, NULL, NULL);

    if (!option (OPTNOCURSES))
      mutt_endwin (NULL);
  }
  else
  {
    if (flags & M_BUFFY)
    {
      if (!mutt_buffy_check (0))
      {
785
	mutt_endwin _("No mailbox with new mail.");
Thomas Roessler's avatar
Thomas Roessler committed
786 787 788 789 790 791 792
	exit (1);
      }
      folder[0] = 0;
      mutt_buffy (folder);
    }
    else if (flags & M_SELECT)
    {
793 794 795 796
      if (!Incoming) {
	mutt_endwin _("No incoming mailboxes defined.");
	exit (1);
      }
Thomas Roessler's avatar
Thomas Roessler committed
797 798 799 800 801 802 803 804 805 806
      folder[0] = 0;
      mutt_select_file (folder, sizeof (folder), 1);
      if (!folder[0])
      {
	mutt_endwin (NULL);
	exit (0);
      }
    }

    if (!folder[0])
Thomas Roessler's avatar
Thomas Roessler committed
807
      strfcpy (folder, NONULL(Spoolfile), sizeof (folder));
Thomas Roessler's avatar
Thomas Roessler committed
808 809
    mutt_expand_path (folder, sizeof (folder));

810 811
    mutt_str_replace (&LastFolder, folder);

Thomas Roessler's avatar
Thomas Roessler committed
812 813 814 815 816 817 818 819 820 821 822 823 824
    if (flags & M_IGNORE)
    {
      struct stat st;

      /* check to see if there are any messages in the folder */
      if (stat (folder, &st) != 0)
      {
	mutt_endwin (strerror (errno));
	exit (1);
      }

      if (st.st_size == 0)
      {
825
	mutt_endwin _("Mailbox is empty.");
Thomas Roessler's avatar
Thomas Roessler committed
826 827 828 829 830 831
	exit (1);
      }
    }

    mutt_folder_hook (folder);

832 833 834 835 836 837 838
    if((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL))
       || !explicit_folder)
    {
      mutt_index_menu ();
      if (Context)
	safe_free ((void **)&Context);
    }
839
    mutt_endwin (Errorbuf);
Thomas Roessler's avatar
Thomas Roessler committed
840 841 842 843
  }

  exit (0);
}