Example #1
0
/* FIXME is message is set deleted should we sent a notif ?  */
static int
nntp_mailbox_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount)
{
  int status;
  size_t i;
  size_t count = 0;

  /* Select first.  */
  status = nntp_mailbox_messages_count (mbox, &count);
  if (pcount)
    *pcount = count;
  if (status != 0)
    return status;
  if (mbox->observable == NULL)
    return 0;
  for (i = msgno; i <= count; i++)
    {
      size_t tmp = i;
      if (mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD,
				&tmp) != 0)
	break;
      if ((i +1) % 10 == 0)
	mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_PROGRESS, NULL);
    }
  return 0;
}
Example #2
0
/* Cover function that call the real thing, mbox_scan(), with
   notification set.  */
static int
mbox_scan (mu_mailbox_t mailbox, size_t msgno, size_t *pcount)
{
  size_t i;
  mbox_data_t mud = mailbox->data;
  MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1, "mbox_scan (%s)\n", mud->name);
  if (! mbox_is_updated (mailbox))
    return mbox_scan0 (mailbox, msgno, pcount, 1);
  /* Since the mailbox is already updated fake the scan. */
  if (msgno > 0)
    msgno--; /* The fist message is number "1", decrement for the C array.  */
  for (i = msgno; i < mud->messages_count; i++)
    {
      size_t tmp = i;
      if (mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD,
				&tmp) != 0)
	break;
      if (((i +1) % 50) == 0)
	{
	  mu_observable_notify (mailbox->observable, MU_EVT_MAILBOX_PROGRESS,
				NULL);
	}
    }
  *pcount = mud->messages_count;
  return 0;
}
Example #3
0
static int
pop_expunge (mu_mailbox_t mbox)
{
  struct _pop3_mailbox *mpd = mbox->data;
  int status = 0;
  size_t i;
  size_t expcount = 0;
  
  if (mpd == NULL)
    return EINVAL;

  if (!mpd->msg)
    return 0;
  
  for (i = 0; i < mpd->msg_count; i++)
    {
      struct _pop3_message *mpm = mpd->msg[i];

      if (mpm &&
	  (mpm->flags & _POP3_MSG_ATTRSET) &&
	  (mpm->attr_flags & MU_ATTRIBUTE_DELETED))
	{
	  size_t expevt[2] = { i + 1, expcount };
	  status = mu_pop3_dele (mpd->pop3, mpm->num);
	  if (status)
	    break;
	  mu_observable_notify (mbox->observable,
				MU_EVT_MAILBOX_MESSAGE_EXPUNGE,
				&expevt);
	  ++expcount;
	}
    }
  return 0;
}
Example #4
0
/* The folder is destroy if it is the last reference.  */
void
mu_folder_destroy (mu_folder_t *pfolder)
{
  if (pfolder && *pfolder)
    {
      mu_folder_t folder = *pfolder;
      int destroy_lock = 0;
      mu_monitor_t monitor = folder->monitor;

      mu_monitor_wrlock (monitor);

      /* Check if this the last reference for this folder.  If yes removed
         it from the list.  */
      mu_monitor_wrlock (&folder_lock);
      folder->ref--;
      /* Remove the folder from the list of known folder.  */
      if (folder->ref <= 0)
	mu_list_remove (known_folder_list, folder);
      /* If the list is empty we can safely remove it.  */
      if (mu_list_is_empty (known_folder_list))
	mu_list_destroy (&known_folder_list);

      mu_monitor_unlock (&folder_lock);

      if (folder->ref <= 0)
	{
	  mu_monitor_unlock (monitor);
	  destroy_lock = 1;
	  /* Notify the observers.  */
	  if (folder->observable)
	    {
	      mu_observable_notify (folder->observable, MU_EVT_FOLDER_DESTROY,
				    folder);
	      mu_observable_destroy (&folder->observable, folder);
	    }
	  if (folder->_destroy)
	    folder->_destroy (folder);
	  mu_monitor_wrlock (monitor);
	  if (folder->authority)
	    mu_authority_destroy (&folder->authority, folder);
	  if (folder->url)
	    mu_url_destroy (&folder->url);
	  if (folder->property)
	    mu_property_destroy (&folder->property);
	  free (folder);
	}
      mu_monitor_unlock (monitor);
      if (destroy_lock)
	mu_monitor_destroy (&monitor, folder);
      *pfolder = NULL;
    }
}
Example #5
0
static int
mbox_append_message (mu_mailbox_t mailbox, mu_message_t msg)
{
  int status = 0;
  mbox_data_t mud = mailbox->data;
  mu_off_t qid;
  
  if (msg == NULL || mud == NULL)
    return EINVAL;

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

  switch (mud->state)
    {
    case MBOX_NO_STATE:
      if ((status = mu_locker_lock (mailbox->locker)) != 0)
	{
	  MU_DEBUG1 (mailbox->debug, MU_DEBUG_TRACE1,
			  "mbox_append_message: %s\n",
			  mu_strerror(status));
	  return status;
	}

    default:
      {
	mu_off_t size;
	/* Move to the end of the file, not necesary if _APPEND mode.  */
	if ((status = mu_stream_size (mailbox->stream, &size)) != 0
	    || (qid = size,
	        status = mbox_append_message0 (mailbox, msg,
					       &size, 0, 0)) != 0)
	  {
	    if (status != EAGAIN)
	      mu_locker_unlock (mailbox->locker);
	    return status;
	  }
      }
    }
  mu_locker_unlock (mailbox->locker);

  if (mailbox->observable)
    {
      char *buf = NULL;
      mu_asprintf (&buf, "%lu", (unsigned long) qid);
      mu_observable_notify (mailbox->observable, MU_EVT_MESSAGE_APPEND, buf);
      free (buf);
    }
  
  return 0;
}
Example #6
0
static int
mbox_is_updated (mu_mailbox_t mailbox)
{
  mu_off_t size = 0;
  mbox_data_t mud = mailbox->data;
  if (mu_stream_size (mailbox->stream, &size) != 0)
    return 1;
  if (size < mud->size)
    {
      mu_observable_notify (mailbox->observable, MU_EVT_MAILBOX_CORRUPT,
			    mailbox);
      /* And be verbose.  ? */
      mu_diag_output (MU_DIAG_EMERG, _("mailbox corrupted, shrank in size"));
      /* FIXME: should I crash.  */
      return 0;
    }
  return (mud->size == size);
}
Example #7
0
static int
pop_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount)
{
  int status;
  size_t i;
  size_t count = 0;
  struct _pop3_mailbox *mpd = mbox->data;
  int flags;
  mu_iterator_t itr;
  
  status = pop_messages_count (mbox, &count);
  if (status != 0)
    return status;
  if (pcount)
    *pcount = count;

  flags = _POP3_MSG_SIZE;
  if (!mu_pop3_capa_test (mpd->pop3, "XLINES", NULL))
    flags |= _POP3_MSG_LINES;

  status = mu_pop3_list_all (mpd->pop3, &itr);
  if (status)
    return status;
  
  for (i = 0, mu_iterator_first (itr);
       i <= count && !mu_iterator_is_done (itr);
       i++, mu_iterator_next (itr))
    {
      const char *str;
      char *p;
      size_t num;
      
      mu_iterator_current (itr, (void**) &str);
      num = strtoul (str, &p, 10);

      if (*p != ' ')
	{
	  mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
		    ("invalid reply to LIST command: %s", str));
	  status = MU_ERR_BADREPLY;
	  break;
	}
      if (num >= msgno)
	{
	  size_t size, lines;
	  struct _pop3_message *mpm;

	  size = strtoul (p + 1, &p, 10);
	  if (flags & _POP3_MSG_LINES)
	    {
	      if (*p != ' ')
		{
		  mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
			    ("invalid reply to LIST command: %s", str));
		  status = MU_ERR_BADREPLY;
		  break;
		}
	      lines = strtoul (p + 1, &p, 10);
	    }

	  status = pop_create_pop3_message (mpd, num, &mpm);
	  if (status)
	    break;
	  mpm->message_size = size;
	  if (flags & _POP3_MSG_LINES)
	    mpm->message_lines = lines;
	  mpm->flags |= flags;

	  if (mbox->observable)
	    {
	      if (((i + 1) % 10) == 0)
		mu_observable_notify (mbox->observable,
				      MU_EVT_MAILBOX_PROGRESS,
				      NULL);
	    }
	}
    }
  
  mu_iterator_destroy (&itr);

  if (mbox->observable)
    {
      /* MU_EVT_MESSAGE_ADD must be delivered only when it is already possible
         to retrieve the message in question.  It could not be done in the
         main loop because no other pop3d function can be called while LIST
         is being handled.  Hence the extra loop. */
      for (i = 0; i <= count; i++)
	{
	  if (mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD,
				    &i) != 0)
	    break;
	}
    }
  
  return status;
}