Exemplo n.º 1
0
int
mail_tmp_finish (struct mail_tmp *mtmp, mu_mailbox_t *mbox)
{
  int status;
  static char *newline = "\n";
  size_t n;
  
  if (!mtmp->had_nl)
    status = mu_stream_sequential_write (mtmp->stream, newline, 1);

  status = mu_stream_sequential_write (mtmp->stream, newline, 1);
  unlink (mtmp->tempfile);
  free (mtmp->tempfile);
  mtmp->tempfile = NULL;
  
  if (status)
    {
      errno = status;
      maidag_error (_("error writing temporary file: %s"), 
                    mu_strerror (status));
      mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream));
      return status;
    }

  mu_stream_flush (mtmp->stream);
  if ((status = mu_mailbox_create (mbox, "mbox:/dev/null")) 
      || (status = mu_mailbox_open (*mbox, MU_STREAM_READ))
      || (status = mu_mailbox_set_stream (*mbox, mtmp->stream)))
    {
      maidag_error (_("error opening temporary file: %s"), 
                    mu_strerror (status));
      mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream));
      return status;
    }

  status = mu_mailbox_messages_count (*mbox, &n);
  if (status)
    {
      errno = status;
      maidag_error (_("error creating temporary message: %s"),
		    mu_strerror (status));
      mu_stream_destroy (&mtmp->stream, mu_stream_get_owner (mtmp->stream));
      return status;
    }

  mtmp->stream = NULL;
  mtmp->line = 0;
  
  return status;
  
}
Exemplo n.º 2
0
int
mta_stdin (int argc, char **argv)
{
  int c;
  char *tempfile;
  mu_mailbox_t mbox;
  mu_message_t msg = NULL;
  
  for (c = 0; c < argc; c++)
    {
      if (add_recipient (argv[c]))
	{
	  mu_error ("%s: bad address %s", progname, argv[c]);
	  return 1;
	}
    }

  make_tmp (stdin, from_person, &tempfile);
  if ((c = mu_mailbox_create_default (&mbox, tempfile)) != 0)
    {
      mu_error ("%s: can't create mailbox %s: %s",
		progname, tempfile, mu_strerror (c));
      unlink (tempfile);
      return 1;
    }

  if ((c = mu_mailbox_open (mbox, MU_STREAM_RDWR)) != 0)
    {
      mu_error ("%s: can't open mailbox %s: %s",
		progname, tempfile, mu_strerror (c));
      unlink (tempfile);
      return 1;
    }

  mu_mailbox_get_message (mbox, 1, &msg);
  if (message_finalize (msg, 1))
    return 1;

  if (!recipients)
    {
      mu_error ("%s: Recipient names must be specified", progname);
      return 1;
    }

  mta_send (msg);
  
  unlink (tempfile);
  free (tempfile);
  return 0;
}
Exemplo n.º 3
0
int
mail_file (int argc, char **argv)
{
  if (argc == 1)
    {
      mail_summary (0, NULL);
    }
  else if (argc == 2)
    {
      /* switch folders */
      char *pname;
      mu_url_t url;
      mu_mailbox_t newbox = NULL;
      char *name = mail_expand_name (argv[1]);
      int status;

      if (!name)
	return 1;
      
      if ((status = mu_mailbox_create_default (&newbox, name)) != 0 
	  || (status = mu_mailbox_open (newbox, MU_STREAM_RDWR)) != 0)
	{
	  mu_mailbox_destroy (&newbox);
	  util_error(_("Cannot open mailbox %s: %s"), name, mu_strerror (status));
	  free (name);
	  return 1;
	}

      free (name); /* won't need it any more */
      page_invalidate (1); /* Invalidate current page map */
      
      mu_mailbox_get_url (mbox, &url);
      pname = strdup (mu_url_to_string (url));
      if (mail_mbox_close ())
	{
	  if (pname)
	    free (pname);
	  mu_mailbox_close (newbox);
	  mu_mailbox_destroy (&newbox);
	  return 1;
	}
      
      if (prev_name)
	free (prev_name);
      prev_name = pname;
      
      mbox = newbox;
      mu_mailbox_messages_count (mbox, &total);
      set_cursor (1);
      if (mailvar_get (NULL, "header", mailvar_type_boolean, 0) == 0)
	{
	  util_do_command ("summary");
	  util_do_command ("headers");
	}
      return 0;
    }
  else
    {
      util_error(_("%s takes only one argument"), argv[0]);
    }
  return 1;
}
Exemplo n.º 4
0
int
main (int argc, char **argv)
{
  mu_mailbox_t mbox = NULL;
  size_t i;
  size_t count = 0;
  char *mailbox_name;
  int debug = 0;

  for (i = 1; i < argc; i++)
    {
      if (strcmp (argv[i], "-d") == 0)
        debug = 1;
      else if (strcmp (argv[i], "-p") == 0)
        print_attachments = 1;
      else if (strcmp (argv[i], "-i") == 0)
	{
	  if (++i == argc)
	    {
	      mu_error ("-i requires argument");
	      exit (1);
	    }
	  indent_level = strtoul (argv[i], NULL, 0);
	}
      else if (strcmp (argv[i], "-c") == 0)
	{
	  if (++i == argc)
	    {
	      mu_error ("-c requires argument");
	      exit (1);
	    }
	  charset = argv[i];
	}
      else
        break;
    }

  mailbox_name = argv[i];

  /* Registration.  */
  mu_registrar_record (mu_imap_record);
  mu_registrar_record (mu_pop_record);
  mu_registrar_record (mu_mbox_record);
  mu_registrar_set_default_record (mu_mbox_record);

  MU_ASSERT (mu_mailbox_create_default (&mbox, mailbox_name));
  
  /* Debugging trace. */
  if (debug)
    {
      mu_debug_set_category_level (MU_DEBCAT_MAILBOX, 
                                   MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT));
    }

  /* Open the mailbox for reading only.  */
  MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_READ));

  /* Iterate through the entire message set.  */
  MU_ASSERT (mu_mailbox_messages_count (mbox, &count));

  for (i = 1; i <= count; ++i)
    {
      mu_message_t msg;
      mu_header_t hdr;
      size_t nparts;
      size_t msize, nlines;

      MU_ASSERT (mu_mailbox_get_message (mbox, i, &msg));
      MU_ASSERT (mu_message_size (msg, &msize));
      MU_ASSERT (mu_message_lines (msg, &nlines));
      MU_ASSERT (mu_message_get_header (msg, &hdr));
      if (mu_header_sget_value (hdr, MU_HEADER_FROM, &from))
	from = "";
      if (mu_header_sget_value (hdr, MU_HEADER_SUBJECT, &subject))
	subject = "";
      printf ("Message: %lu\n", (unsigned long) i);
      printf ("From: %s\n", from);
      printf ("Subject: %s\n", subject);

      MU_ASSERT (mu_message_get_num_parts (msg, &nparts));
      printf ("Number of parts in message - %lu\n",
	      (unsigned long) nparts);
      printf ("Total message size - %lu/%lu\n",
	      (unsigned long) msize, (unsigned long) nlines);
      message_display_parts (msg, 0);
    }
  mu_mailbox_close (mbox);
  mu_mailbox_destroy (&mbox);
  return 0;
}
Exemplo n.º 5
0
/* For the expunge bits  we took a very cautionnary approach, meaning
   we create a temporary mailbox in the tmpdir copy all the message not mark
   deleted(Actually we copy all the message that may have been modified
   i.e new header values set; UIDL or UID or etc ....
   and skip the deleted ones, truncate the real mailbox to the desired size
   and overwrite with the tmp mailbox.  The approach to do everyting
   in core is tempting but require
   - to much memory, it is not rare nowadays to have 30 Megs mailbox,
   - also there is danger for filesystems with quotas,
   - if we run out of disk space everything is lost.
   - or some program may not respect the advisory lock and decide to append
   a new message while your expunging etc ...
   The real downside to the approach is that when things go wrong
   the temporary file may be left in /tmp, which is not all that bad
   because at least, we have something to recuperate when failure.  */
static int
mbox_expunge0 (mu_mailbox_t mailbox, int remove_deleted)
{
  mbox_data_t mud = mailbox->data;
  mbox_message_t mum;
  int status = 0;
  sigset_t signalset;
  int tempfile;
  size_t i, j, dirty;  /* dirty will indicate the first modified message.  */
  mu_off_t marker = 0;    /* marker will be the position to truncate.  */
  mu_off_t total = 0;
  char *tmpmboxname = NULL;
  mu_mailbox_t tmpmailbox = NULL;
  size_t save_imapbase = 0;  /* uidvalidity is save in the first message.  */
#ifdef WITH_PTHREAD
  int state;
#endif

  if (mud == NULL)
    return EINVAL;

  MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1, "mbox_expunge (%s)\n", mud->name);

  /* Noop.  */
  if (mud->messages_count == 0)
    return 0;

  /* Find the first dirty(modified) message.  */
  for (dirty = 0; dirty < mud->messages_count; dirty++)
    {
      mum = mud->umessages[dirty];
      /* Message may have been tampered, break here.  */
      if ((mum->attr_flags & MU_ATTRIBUTE_MODIFIED) ||
	  (mum->attr_flags & MU_ATTRIBUTE_DELETED) ||
	  (mum->message && mu_message_is_modified (mum->message)))
	break;
    }

  /* Did something change ?  */
  if (dirty == mud->messages_count)
    return 0; /* Nothing change, bail out.  */

  /* Create a temporary file.  */
  tempfile = mbox_tmpfile (mailbox, &tmpmboxname);
  if (tempfile == -1)
    {
      if (tmpmboxname)
	free (tmpmboxname);
      mu_error (_("failed to create temporary file when expunging"));
      return errno;
    }

  /* This is redundant, we go to the loop again.  But it's more secure here
     since we don't want to be disturb when expunging.  Destroy all the
     messages mark for deletion.  */
  if (remove_deleted)
    {
      for (j = 0; j < mud->messages_count; j++)
	{
	  mum = mud->umessages[j];
	  if (mum && mum->message && ATTRIBUTE_IS_DELETED (mum->attr_flags))
	    mu_message_destroy (&(mum->message), mum);
	}
    }

  /* Create temporary mu_mailbox_t.  */
  {
    mbox_data_t tmp_mud;
    char *m = malloc (5 + strlen (tmpmboxname) + 1);
    if (!m)
      return ENOMEM;
    /* Try via the mbox: protocol.  */
    sprintf (m, "mbox:%s", tmpmboxname);
    status = mu_mailbox_create (&tmpmailbox, m);
    if (status != 0)
      {
	/* Do not give up just yet, maybe they register the mu_path_record.  */
	sprintf (m, "%s", tmpmboxname);
	status = mu_mailbox_create (&tmpmailbox, m);
	if (status != 0)
	  {
	    /* Ok give up.  */
	    close (tempfile);
	    remove (tmpmboxname);
            free (m);
	    free (tmpmboxname);
	    return status;
	  }
      }
    free (m);
    /* Must be flag CREATE if not the mu_mailbox_open will try to mmap()
       the file.  */
    status = mu_mailbox_open (tmpmailbox, MU_STREAM_CREAT | MU_STREAM_RDWR);
    if (status != 0)
      {
	close (tempfile);
	remove (tmpmboxname);
	free (tmpmboxname);
	return status;
      }
    close (tempfile); /* This one is useless the mailbox have its own.  */
    tmp_mud = tmpmailbox->data;
    /* May need when appending.  */
    tmp_mud->uidvalidity = mud->uidvalidity;
    tmp_mud->uidnext = mud->uidnext;
  }

  /* Get the File lock.  */
  if ((status = mu_locker_lock (mailbox->locker)) != 0)
    {
      mu_mailbox_close (tmpmailbox);
      mu_mailbox_destroy (&tmpmailbox);
      remove (tmpmboxname);
      free (tmpmboxname);
      mu_error (_("failed to grab the lock: %s"), mu_strerror (status));
      return status;
    }

  /* Critical section, we can not allowed signal here.  */
#ifdef WITH_PTHREAD
  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
#endif
  sigemptyset (&signalset);
  sigaddset (&signalset, SIGTERM);
  sigaddset (&signalset, SIGHUP);
  sigaddset (&signalset, SIGTSTP);
  sigaddset (&signalset, SIGINT);
  sigaddset (&signalset, SIGWINCH);
  sigprocmask (SIG_BLOCK, &signalset, 0);

  /* Set the marker position.  */
  marker = mud->umessages[dirty]->header_from;
  total = 0;

  /* Copy to the temporary mailbox emails not mark deleted.  */
  for (i = dirty; i < mud->messages_count; i++)
    {
      mum = mud->umessages[i];

      /* Skip it, if mark for deletion.  */
      if (remove_deleted && ATTRIBUTE_IS_DELETED (mum->attr_flags))
	{
	  /* We save the uidvalidity in the first message, if it is being
	     deleted we need to move the uidvalidity to the first available
	     (non-deleted) message.  */
	  if (i == save_imapbase)
	    {
	      save_imapbase = i + 1;
	      if (save_imapbase < mud->messages_count)
		(mud->umessages[save_imapbase])->attr_flags |= MU_ATTRIBUTE_MODIFIED;
	    }
	  continue;
	}

      /* Do the expensive mbox_append_message0() only if mark dirty.  */
      if ((mum->attr_flags & MU_ATTRIBUTE_MODIFIED) ||
	  (mum->message && mu_message_is_modified (mum->message)))
	{
	  /* The message was not instantiated, probably the dirty flag was
	     set by mbox_scan(), create one here.  */
	  if (mum->message == 0)
	    {
	      mu_message_t msg;
	      status = mbox_get_message (mailbox, i + 1, &msg);
	      if (status != 0)
		{
		  mu_error (_("error expunging:%d: %s"), __LINE__,
			    mu_strerror (status));
		  goto bailout0;
		}
	    }
	  status = mbox_append_message0 (tmpmailbox, mum->message,
					 &total, 1, (i == save_imapbase));
	  if (status != 0)
	    {
	      mu_error (_("error expunging:%d: %s"), __LINE__,
		        mu_strerror (status));
	      goto bailout0;
	    }
	  /* Clear the dirty bits.  */
	  mum->attr_flags &= ~MU_ATTRIBUTE_MODIFIED;
	  mu_message_clear_modified (mum->message);
	}
      else
	{
	  /* Nothing changed copy the message straight.  */
	  char buffer [1024];
	  size_t n;
	  mu_off_t offset = mum->header_from;
	  size_t len = mum->body_end - mum->header_from;
	  while (len > 0)
	    {
	      n = (len < sizeof (buffer)) ? len : sizeof (buffer);
	      if ((status = mu_stream_read (mailbox->stream, buffer, n, offset,
					 &n) != 0)
		  || (status = mu_stream_write (tmpmailbox->stream, buffer, n,
					     total, &n) != 0))
		{
		  mu_error (_("error expunging:%d: %s"), __LINE__,
			    mu_strerror (status));
		  goto bailout0;
		}
	      len -= n;
	      total += n;
	      offset += n;
	    }
	  /* Add the newline separator.  */
	  status = mu_stream_write (tmpmailbox->stream, "\n", 1, total, &n);
	  if (status != 0)
	    {
	      mu_error (_("error expunging:%d: %s"), __LINE__,
		        mu_strerror (status));
	      goto bailout0;
	    }
	  total++;
	}
    } /* for (;;) */

  /* Caution: before ftruncate()ing the file see
     - if we've receive new mails.  Some programs may not respect the lock,
     - or the lock was held for too long.
     - The mailbox may not have been properly updated before expunging.  */
  {
    mu_off_t size = 0;
    if (mu_stream_size (mailbox->stream, &size) == 0)
      {
	mu_off_t len = size - mud->size;
	mu_off_t offset = mud->size;
	char buffer [1024];
	size_t n = 0;
	if (len > 0 )
	  {
	    while ((status = mu_stream_read (mailbox->stream, buffer,
					  sizeof (buffer), offset, &n)) == 0
		   && n > 0)
	      {
		status = mu_stream_write (tmpmailbox->stream, buffer, n,
				       total, &n);
		if (status != 0)
		  {
		    mu_error (_("error expunging:%d: %s"), __LINE__,
			      mu_strerror (status));
		    goto bailout0;
		  }
		total += n;
		offset += n;
	      }
	  }
	else if (len < 0)
	  {
	    /* Corrupted mailbox.  */
	    mu_error (_("error expunging:%d: %s"), __LINE__,
		      mu_strerror (status));
	    goto bailout0;
	  }
      }
  } /* End of precaution.  */

  /* Seek and rewrite it.  */
  if (total > 0)
    {
      char buffer [1024];
      size_t n = 0;
      mu_off_t off = 0;
      mu_off_t offset = marker;
      while ((status = mu_stream_read (tmpmailbox->stream, buffer,
				    sizeof (buffer), off, &n)) == 0
	     && n > 0)
	{
	  status = mu_stream_write (mailbox->stream, buffer, n, offset, &n);
	  if (status != 0)
	    {
	      mu_error (_("error expunging:%d: %s"), __LINE__,
		        mu_strerror (status));
	      goto bailout;
	    }
	  off += n;
	  offset += n;
	}
    }

  /* Flush/truncation. Need to flush before truncate.  */
  mu_stream_flush (mailbox->stream);
  status = mu_stream_truncate (mailbox->stream, total + marker);
  if (status != 0)
    {
      mu_error (_("error expunging:%d: %s"), __LINE__,
	        mu_strerror (status));
      goto bailout;
    }

  /* Don't remove the tmp mbox in case of errors, when writing back.  */
 bailout0:
  remove (tmpmboxname);

 bailout:

  free (tmpmboxname);
  /* Release the File lock.  */
  mu_locker_unlock (mailbox->locker);
  mu_mailbox_close (tmpmailbox);
  mu_mailbox_destroy (&tmpmailbox);

  /* Reenable signal.  */
#ifdef WITH_PTHREAD
  pthread_setcancelstate (state, &state);
#endif
  sigprocmask (SIG_UNBLOCK, &signalset, 0);

  /* We need to readjust the pointers.
     It is a little hairy because we need to keep the message pointers alive
     So we are going through the array and "defragmentize".  For example
     in (1 2 3 4) if 2 was deleted we need to move 3 4 up by one etc ..
  */
  if (status == 0)
    {
      size_t dlast;
      mu_monitor_wrlock (mailbox->monitor);
      for (j = dirty, dlast = mud->messages_count - 1;
	   j <= dlast; j++)
	{
	  /* Clear all the references, any attach messages been already
	     destroy above.  */
	  mum = mud->umessages[j];
	  if (remove_deleted && ATTRIBUTE_IS_DELETED (mum->attr_flags))
	    {
	      if ((j + 1) <= dlast)
		{
		  /* Move all the pointers up.  So the message pointer
		     part of mum will be at the right position.  */
		  memmove (mud->umessages + j, mud->umessages + j + 1,
			   (dlast - j) * sizeof (mum));
#if 0
		  mum->header_from = mum->header_from_end = 0;
		  mum->body = mum->body_end = 0;
		  mum->header_lines = mum->body_lines = 0;
#endif
		  memset (mum, 0, sizeof (*mum));
		  /* We are not free()ing the useless mum, but instead
		     we put it back in the pool, to be reuse.  */
		  mud->umessages[dlast] = mum;
		  dlast--;
		  /* Set mum to the new value after the memmove so it
		     gets cleared to.  */
		  mum = mud->umessages[j];
		}
	      else
		{
		  memset (mum, 0, sizeof (*mum));
		}
	    }
	  mum->header_from = mum->header_from_end = 0;
	  mum->body = mum->body_end = 0;
	  mum->header_lines = mum->body_lines = 0;
	}
      mu_monitor_unlock (mailbox->monitor);
      /* This is should reset the messages_count, the last argument 0 means
	 not to send event notification.  */
      mbox_scan0 (mailbox, dirty, NULL, 0);
    }
  return status;
}
Exemplo n.º 6
0
static int
folder_pop_open (mu_folder_t folder, int flags)
{
  mu_mailbox_t mbox = folder->data;
  return mu_mailbox_open (mbox, flags);
}
Exemplo n.º 7
0
void
smtp (int fd)
{
  int state, c;
  char *buf = NULL;
  size_t size = 0;
  mu_mailbox_t mbox;
  mu_message_t msg;
  char *tempfile;
  char *rcpt_addr;
  
  in = fdopen (fd, "r");
  out = fdopen (fd, "w");
  SETVBUF (in, NULL, _IOLBF, 0);
  SETVBUF (out, NULL, _IOLBF, 0);

  smtp_reply (220, "Ready");
  for (state = STATE_INIT; state != STATE_QUIT; )
    {
      int argc;
      char **argv;
      int kw, len;
      
      if (getline (&buf, &size, in) == -1)
	exit (1);
      len = strlen (buf);
      while (len > 0 && (buf[len-1] == '\n' || buf[len-1] == '\r'))
	len --;
      buf[len] = 0;
      
      if (mu_argcv_get (buf, "", NULL, &argc, &argv))
	exit (1);

      kw = smtp_kw (argv[0]);
      if (kw == KW_QUIT)
	{
	  smtp_reply (221, "Done");
	  state = STATE_QUIT;
	  mu_argcv_free (argc, argv);
	  continue;
	}
      
      switch (state)
	{
	case STATE_INIT:
	  switch (kw)
	    {
	    case KW_EHLO:
	    case KW_HELO:
	      if (argc == 2)
		{
		  smtp_reply (250, "pleased to meet you");
		  state = STATE_EHLO;
		}
	      else
		smtp_reply (501, "%s requires domain address", argv[0]);
	      break;

	    default:
	      smtp_reply (503, "Polite people say HELO first");
	      break;
	    }
	  break;
	  
	case STATE_EHLO:
	  switch (kw)
	    {
	    case KW_MAIL:
	      if (argc == 2)
		from_person = check_prefix (argv[1], "from:");
	      else if (argc == 3 && mu_c_strcasecmp (argv[1], "from:") == 0)
		from_person = argv[2];
	      else
		from_person = NULL;

	      if (from_person)
		{
		  from_person = strdup (from_person);
		  smtp_reply (250, "Sender OK");
		  state = STATE_MAIL;
		}
	      else
		smtp_reply (501, "Syntax error");
	      break;

	    default:
	      smtp_reply (503, "Need MAIL command");
	    }
	  break;
	  
	case STATE_MAIL:
	  switch (kw)
	    {
	    case KW_RCPT:
	      if (argc == 2)
		rcpt_addr = check_prefix (argv[1], "to:");
	      else if (argc == 3 && mu_c_strcasecmp (argv[1], "to:") == 0)
		rcpt_addr = argv[2];
	      else
		rcpt_addr = NULL;
	      
	      if (rcpt_addr)
		{
		  if (add_recipient (rcpt_addr))
		    smtp_reply (451, "Recipient not accepted");
		  else
		    {
		      smtp_reply (250, "Recipient OK");
		      state = STATE_RCPT;
		    }
		}
	      else
		smtp_reply (501, "Syntax error");
	      break;
	      
	    default:
	      smtp_reply (503, "Need RCPT command");
	    }
	  break;
	  
	case STATE_RCPT:
	  switch (kw)
	    {
	    case KW_RCPT:
	      if (argc == 2)
		rcpt_addr = check_prefix (argv[1], "to:");
	      else if (argc == 3 && mu_c_strcasecmp (argv[1], "to:") == 0)
		rcpt_addr = argv[2];
	      else
		rcpt_addr = NULL;
	      
	      if (rcpt_addr)
		{
		  if (add_recipient (rcpt_addr))
		    smtp_reply (451, "Recipient not accepted");
		  else
		    {
		      smtp_reply (250, "Recipient OK");
		      state = STATE_RCPT;
		    }
		}
	      else
		smtp_reply (501, "Syntax error");
	      break;

	    case KW_DATA:
	      smtp_reply (354,
			  "Enter mail, end with \".\" on a line by itself");
	      make_tmp (in, from_person, &tempfile);
	      if ((c = mu_mailbox_create_default (&mbox, tempfile)) != 0)
		{
		  mu_error ("%s: can't create mailbox %s: %s",
			    progname,
			    tempfile, mu_strerror (c));
		  unlink (tempfile);
		  exit (1);
		}

	      if ((c = mu_mailbox_open (mbox, MU_STREAM_RDWR)) != 0)
		{
		  mu_error ("%s: can't open mailbox %s: %s",
			    progname, 
			    tempfile, mu_strerror (c));
		  unlink (tempfile);
		  exit (1);
		}

	      mu_mailbox_get_message (mbox, 1, &msg);
	      if (message_finalize (msg, 0) == 0)
		mta_send (msg);
	      else
		smtp_reply (501, "can't send message"); /*FIXME: code?*/
	      unlink (tempfile);

	      mu_address_destroy (&recipients);
	      from_person = NULL;
	      
	      smtp_reply (250, "Message accepted for delivery");
	      state = STATE_EHLO;
	      break;

	    default:
	      smtp_reply (503, "Invalid command");
	      break;
	    }
	  break;

	}
      mu_argcv_free (argc, argv);
    }
    
  close (fd);
}
Exemplo n.º 8
0
int
main (int argc, const char **argv)
{
  char *from;
  char *subject;
  mu_mailbox_t mbox;
  size_t msgno, total = 0;
  int status;

  /* Register the formats. */
  mu_register_all_mbox_formats ();

  status = mu_mailbox_create_default (&mbox, argv[1]);
  if (status != 0)
    {
      mu_error ("mu_mailbox_create: %s", mu_strerror (status));
      exit (EXIT_FAILURE);
    }

  status = mu_mailbox_open (mbox, MU_STREAM_READ);
  if (status != 0)
    {
      mu_error ("mu_mailbox_open: %s", mu_strerror (status));
      exit (EXIT_FAILURE);
    }

  mu_mailbox_messages_count (mbox, &total);

  for (msgno = 1; msgno <= total; msgno++)
    {
      mu_message_t msg;
      mu_header_t hdr;

      if ((status = mu_mailbox_get_message (mbox, msgno, &msg)) != 0
          || (status = mu_message_get_header (msg, &hdr)) != 0)
        {
          mu_error ("Error message: %s", mu_strerror (status));
          exit (EXIT_FAILURE);
        }

      if (mu_header_aget_value (hdr, MU_HEADER_FROM, &from))
        from = strdup ("(NO FROM)");

      if (mu_header_aget_value (hdr, MU_HEADER_SUBJECT, &subject))
        subject = strdup ("(NO SUBJECT)");

      printf ("%s\t%s\n", from, subject);
      free (from);
      free (subject);
    }

  status = mu_mailbox_close (mbox);
  if (status != 0)
    {
      mu_error ("mu_mailbox_close: %s", mu_strerror (status));
      exit (EXIT_FAILURE);
    }

  mu_mailbox_destroy (&mbox);
  return 0;
}
Exemplo n.º 9
0
/* FIXME: How do we do this ??????:
   IF a new mailbox is created with the same name as a mailbox which was
   deleted, its unique identifiers MUST be greater than any unique identifiers
   used in the previous incarnation of the mailbox.  */
int
imap4d_create (struct imap4d_session *session,
               struct imap4d_command *command, imap4d_tokbuf_t tok)
{
  char *name;
  int isdir = 0;
  int ns;
  int rc = RESP_OK;
  const char *msg = "Completed";

  if (imap4d_tokbuf_argc (tok) != 3)
    return io_completion_response (command, RESP_BAD, "Invalid arguments");

  name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);

  if (*name == '\0')
    return io_completion_response (command, RESP_BAD, "Too few arguments");

  /* Creating, "Inbox" should always fail.  */
  if (mu_c_strcasecmp (name, "INBOX") == 0)
    return io_completion_response (command, RESP_BAD, "Already exist");

  /* RFC 3501:
         If the mailbox name is suffixed with the server's hierarchy
	 separator character, this is a declaration that the client intends
	 to create mailbox names under this name in the hierarchy.

     The trailing delimiter will be removed by namespace normalizer, so
     test for it now.
  */
  if (name[strlen (name) - 1] == MU_HIERARCHY_DELIMITER)
    isdir = 1;
  
  /* Allocates memory.  */
  name = namespace_getfullpath (name, &ns);

  if (!name)
    return io_completion_response (command, RESP_NO, "Cannot create mailbox");

  /* It will fail if the mailbox already exists.  */
  if (access (name, F_OK) != 0)
    {
      if (make_interdir (name, MU_HIERARCHY_DELIMITER, MKDIR_PERMISSIONS))
	{
	  rc = RESP_NO;
	  msg = "Cannot create mailbox";
	}
      
      if (rc == RESP_OK && !isdir)
	{
	  mu_mailbox_t mbox;
	  
	  rc = mu_mailbox_create_default (&mbox, name);
	  if (rc)
	    {
	      mu_diag_output (MU_DIAG_ERR,
			      _("Cannot create mailbox %s: %s"), name,
			      mu_strerror (rc));
	      rc = RESP_NO;
	      msg = "Cannot create mailbox";
	    }
	  else if ((rc = mu_mailbox_open (mbox,
					  MU_STREAM_RDWR | MU_STREAM_CREAT
					  | mailbox_mode[ns])))
	    {
	      mu_diag_output (MU_DIAG_ERR,
			      _("Cannot open mailbox %s: %s"),
			      name, mu_strerror (rc));
	      rc = RESP_NO;
	      msg = "Cannot create mailbox";
	    }
	  else
	    {
	      mu_mailbox_close (mbox);
	      mu_mailbox_destroy (&mbox);
	      rc = RESP_OK;
	    }
	}
    }
  else
    {
      rc = RESP_NO;
      msg = "already exists";
    }

  return io_completion_response (command, rc, "%s", msg);
}
Exemplo n.º 10
0
/* This code is shared with EXAMINE.  */
int
imap4d_select0 (struct imap4d_command *command, const char *mboxname,
		int flags)
{
  int status;
  char *mailbox_name;
  
  /* FIXME: Check state.  */

  /* Even if a mailbox is selected, a SELECT EXAMINE or LOGOUT
     command MAY be issued without previously issuing a CLOSE command.
     The SELECT, EXAMINE, and LOGUT commands implictly close the
     currently selected mailbox without doing an expunge.  */
  if (mbox)
    {
      imap4d_enter_critical ();
      mu_mailbox_sync (mbox);
      mu_mailbox_close (mbox);
      manlock_unlock (mbox);
      imap4d_leave_critical ();
      mu_mailbox_destroy (&mbox);
      /* Destroy the old uid table.  */
      imap4d_sync ();
    }

  if (strcmp (mboxname, "INBOX") == 0)
    flags |= MU_STREAM_CREAT;
  mailbox_name = namespace_getfullpath (mboxname, NULL);

  if (!mailbox_name)
    return io_completion_response (command, RESP_NO, "Couldn't open mailbox");

  if (flags & MU_STREAM_RDWR)
    {
      status = manlock_open_mailbox (&mbox, mailbox_name, 1, flags);
    }
  else
    {
      status = mu_mailbox_create_default (&mbox, mailbox_name);
      if (status)
	mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_create_default",
			 mailbox_name,
			 status);
      else
	{
	  status = mu_mailbox_open (mbox, flags);
	  if (status)
	    {
	      mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_open",
			       mailbox_name,
			       status);
	      mu_mailbox_destroy (&mbox);
	    }
	}
    }
  
  if (status == 0)
    {
      select_flags = flags;
      state = STATE_SEL;

      imap4d_set_observer (mbox);
      
      if ((status = imap4d_select_status ()) == 0)
	{
	  free (mailbox_name);
	  /* Need to set the state explicitely for select.  */
	  return io_sendf ("%s OK [%s] %s Completed\n", command->tag,
			   ((flags & MU_STREAM_RDWR) == MU_STREAM_RDWR) ?
			   "READ-WRITE" : "READ-ONLY", command->name);
	}
    }
  
  mu_mailbox_destroy (&mbox);
  status = io_completion_response (command, RESP_NO, "Could not open %s: %s",
			mboxname, mu_strerror (status));
  free (mailbox_name);
  return status;
}