Example #1
0
void mailprivacy_unregister(struct mailprivacy * privacy,
    struct mailprivacy_protocol * protocol)
{
  unsigned int i;
  
  for(i = 0 ; i < carray_count(privacy->protocols) ; i ++) {
    if (carray_get(privacy->protocols, i) == protocol) {
      carray_delete(privacy->protocols, i);
      return;
    }
  }
}
Example #2
0
int mail_flags_store_set(struct mail_flags_store * flags_store,
			 mailmessage * msg)
{
  chashdatum key;
  chashdatum value;
  unsigned int indx;
  int res;
  int r;
  mailmessage * new_msg;

  if (msg->msg_flags == NULL) {
    res = MAIL_NO_ERROR;
    goto err;
  }

  /* duplicate needed message info */
  new_msg = mailmessage_build(msg);
  if (new_msg == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }

  key.data = &new_msg->msg_index;
  key.len = sizeof(new_msg->msg_index);

  r = chash_get(flags_store->fls_hash, &key, &value);
  if (r == 0) {
    mailmessage * old_msg;

    indx = * (unsigned int *) value.data;
    old_msg = carray_get(flags_store->fls_tab, indx);
    mailmessage_free(old_msg);
  }
  else {
    r = carray_set_size(flags_store->fls_tab,
        carray_count(flags_store->fls_tab) + 1);
    if (r != 0) {
      res = MAIL_ERROR_MEMORY;
      goto err;
    }
    indx = carray_count(flags_store->fls_tab) - 1;
  }

  carray_set(flags_store->fls_tab, indx, new_msg);
  
  value.data = &indx;
  value.len = sizeof(indx);

  r = chash_set(flags_store->fls_hash, &key, &value, NULL);
  if (r < 0) {
    carray_delete(flags_store->fls_tab, indx);
    res = MAIL_ERROR_MEMORY;
    goto free;
  }

  return MAIL_NO_ERROR;

 free:
  mailmessage_free(new_msg);
 err:
  return res;
}
Example #3
0
static int expunge_folder(mailsession * session)
{
  int r;
  char key_value[PATH_MAX];
  struct mail_cache_db * maildb;
  carray * msglist;
  unsigned int i;
  struct db_session_state_data * data;
  int res;
  chash * msg_table;
  MMAPString * mmapstr;
  
  data = get_data(session);
  
  flags_store_process(session);
  
  r = mail_cache_db_open_lock(data->db_filename, &maildb);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto err;
  }
  
  r = db_get_message_list(maildb, &msglist);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto close_db;
  }
  
  msg_table = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
  if (msg_table == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_msglist;
  }
  
  mmapstr = mmap_string_new("");
  if (mmapstr == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_msgtable;
  }
  
  i = 0;
  while (i < carray_count(msglist)) {
    uint32_t num;
    uint32_t * msg;
    chashdatum key;
    chashdatum value;
    struct mail_flags * flags;
    int deleted;
    
    msg = carray_get(msglist, i);
    num = * msg;
    
    deleted = 0;
    snprintf(key_value, sizeof(key_value), "%lu-flags",
        (unsigned long) num);
    r = generic_cache_flags_read(maildb, mmapstr, key_value, &flags);
    if (r == MAIL_NO_ERROR) {
      if ((flags->fl_flags & MAIL_FLAG_DELETED) != 0)
        deleted = 1;
    }
    
    if (!deleted) {
      snprintf(key_value, sizeof(key_value), "%lu", (unsigned long) num);
      key.data = key_value;
      key.len = strlen(key_value);
      chash_set(msg_table, &key, &value, NULL);
      
      snprintf(key_value, sizeof(key_value), "%lu-envelope",
          (unsigned long) num);
      key.data = key_value;
      key.len = strlen(key_value);
      chash_set(msg_table, &key, &value, NULL);
      
      snprintf(key_value, sizeof(key_value), "%lu-flags",
          (unsigned long) num);
      key.data = key_value;
      key.len = strlen(key_value);
      chash_set(msg_table, &key, &value, NULL);
      
      i ++;
    }
    else {
      free(msg);
      carray_delete(msglist, i);
    }
  }
  
  mmap_string_free(mmapstr);
  
  r = mail_cache_db_clean_up(maildb, msg_table);
  
  chash_free(msg_table);
  
  r = db_set_message_list(maildb, msglist);
  
  for(i = 0 ; i < carray_count(msglist) ; i ++) {
    uint32_t * msg;
    
    msg = carray_get(msglist, i);
    free(msg);
  }
  carray_free(msglist);
  
  mail_cache_db_close_unlock(data->db_filename, maildb);
  
  return MAIL_NO_ERROR;

 free_msgtable:
  chash_free(msg_table);
 free_msglist:
  for(i = 0 ; i < carray_count(msglist) ; i ++) {
    uint32_t * msg;
    
    msg = carray_get(msglist, i);
    free(msg);
  }
 close_db:
  mail_cache_db_close_unlock(data->db_filename, maildb);
 err:
  return res;
}
Example #4
0
int claws_mailmbox_msg_info_update(struct claws_mailmbox_folder * folder,
			     size_t msg_start, size_t msg_start_len,
			     size_t msg_headers, size_t msg_headers_len,
			     size_t msg_body, size_t msg_body_len,
			     size_t msg_size, size_t msg_padding,
			     uint32_t msg_uid)
{
  struct claws_mailmbox_msg_info * info;
  int res;
  chashdatum key;
  chashdatum data;
  int r;
  
  key.data = &msg_uid;
  key.len = sizeof(msg_uid);
  r = chash_get(folder->mb_hash, &key, &data);
  if (r < 0) {
    unsigned int index;

    info = claws_mailmbox_msg_info_new(msg_start, msg_start_len,
        msg_headers, msg_headers_len,
        msg_body, msg_body_len, msg_size, msg_padding, msg_uid);
    if (info == NULL) {
      res = MAILMBOX_ERROR_MEMORY;
      goto err;
    }

    r = carray_add(folder->mb_tab, info, &index);
    if (r < 0) {
      claws_mailmbox_msg_info_free(info);
      res = MAILMBOX_ERROR_MEMORY;
      goto err;
    }

    if (msg_uid != 0) {
      chashdatum key;
      chashdatum data;
      
      key.data = &msg_uid;
      key.len = sizeof(msg_uid);
      data.data = info;
      data.len = 0;
      
      r = chash_set(folder->mb_hash, &key, &data, NULL);
      if (r < 0) {
	claws_mailmbox_msg_info_free(info);
	carray_delete(folder->mb_tab, index);
	res = MAILMBOX_ERROR_MEMORY;
	goto err;
      }
    }
    
    info->msg_index = index;
  }
  else {
    info = data.data;
    
    info->msg_start = msg_start;
    info->msg_start_len = msg_start_len;
    info->msg_headers = msg_headers;
    info->msg_headers_len = msg_headers_len;
    info->msg_body = msg_body;
    info->msg_body_len = msg_body_len;
    info->msg_size = msg_size;
    info->msg_padding = msg_padding;
  }

  return MAILMBOX_NO_ERROR;

 err:
  return res;
}
Example #5
0
static int delete_dummy(carray * rootlist, carray * sibling_list,
    unsigned int cur, unsigned int * pnext)
{
  struct mailmessage_tree * env_tree;
  int res;
  int r;
  unsigned int cur_child;
  unsigned int next;

  env_tree = carray_get(sibling_list, cur);

  cur_child = 0;
  while (cur_child < carray_count(env_tree->node_children)) {
    delete_dummy(rootlist, env_tree->node_children, cur_child, &cur_child);
  }

  if (env_tree->node_msg == NULL) {
    if (carray_count(env_tree->node_children) == 0) {

      /* If it is a dummy message with NO children, delete it. */
      mailmessage_tree_free(env_tree);
      carray_delete(sibling_list, cur);
      next = cur;
    }
    else {
      /* If it is a dummy message with children, delete it, but
	 promote its children to the current level. */

      /*
	Do not promote the children if doing so would make them
	children of the root, unless there is only one child.
      */

      cur_child = 0;
      if ((sibling_list != rootlist) ||
          (carray_count(env_tree->node_children) == 1)) {
	while (cur_child < carray_count(env_tree->node_children)) {
	  struct mailmessage_tree * child;
	  
	  child = carray_get(env_tree->node_children, cur_child);
	  r = carray_add(sibling_list, child, NULL);
	  if (r < 0) {
	    res = MAIL_ERROR_MEMORY;
	    goto err;
	  }
          /* set new parent of the children */
          child->node_parent = env_tree->node_parent;

	  carray_delete(env_tree->node_children, cur_child);
	}
        mailmessage_tree_free(env_tree);
	carray_delete(sibling_list, cur);
        next = cur;
      }
      else
	next = cur + 1;
    }
  }
  else
    next = cur + 1;

  * pnext = next;

  return MAIL_NO_ERROR;

 err:
  return res;       
}
Example #6
0
static int
mail_build_thread_orderedsubject(char * default_from,
    struct mailmessage_list * env_list,
    struct mailmessage_tree ** result,
    int (* comp_func)(struct mailmessage_tree **,
        struct mailmessage_tree **))
{
  unsigned int i;
  carray * rootlist;
  unsigned int cur;
  struct mailmessage_tree * root;
  int res;
  int r;
  struct mailmessage_tree * current_thread;

  root = mailmessage_tree_new(NULL, (time_t) -1, NULL);
  if (root == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }
  rootlist = root->node_children;

  /*
    The ORDEREDSUBJECT threading algorithm is also referred to as
    "poor man's threading."
  */

  for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
    mailmessage * msg;
    struct mailmessage_tree * env_tree;
    char * base_subject;
    time_t date;

    msg = carray_get(env_list->msg_tab, i);

    if (msg == NULL)
      continue;

    if (msg->msg_fields != NULL) {

      date = get_date(msg);

      env_tree = mailmessage_tree_new(NULL, date, msg);
      if (env_tree == NULL) {
	res = MAIL_ERROR_MEMORY;
	goto free;
      }

      /* set parent */
      env_tree->node_parent = root;
      r = carray_add(rootlist, env_tree, NULL);
      if (r < 0) {
	mailmessage_tree_free(env_tree);
	res = MAIL_ERROR_MEMORY;
	goto free;
      }

      r = get_extracted_subject(default_from, env_tree, &base_subject);
      switch (r) {
      case MAIL_NO_ERROR:
	env_tree->node_base_subject = base_subject;
	break;

      case MAIL_ERROR_SUBJECT_NOT_FOUND:
	break;
	
      default:
	res = r;
	goto free;
      }
    }
  }

  /*
    The searched messages are sorted by
    subject and then by the sent date.
  */

  r = mail_thread_sort(root, tree_subj_time_comp, FALSE);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto free;
  }

  /*
    The messages are then split
    into separate threads, with each thread containing messages
    with the same extracted subject text.
  */

  current_thread = NULL;

  cur = 0;
  while (cur < carray_count(rootlist)) {
    struct mailmessage_tree * cur_env_tree;

    cur_env_tree = carray_get(rootlist, cur);
    if (current_thread == NULL) {
      current_thread = cur_env_tree;
      cur ++;
      continue;
    }

    if ((cur_env_tree->node_base_subject == NULL) ||
	(current_thread->node_base_subject == NULL)) {
      current_thread = cur_env_tree;
      cur ++;
      continue;
    }

    if (strcmp(cur_env_tree->node_base_subject,
            current_thread->node_base_subject) == 0) {

      /* set parent */
      cur_env_tree->node_parent = current_thread;
      r = carray_add(current_thread->node_children, cur_env_tree, NULL);
      if (r < 0) {
	res = MAIL_ERROR_MEMORY;
	goto free;
      }
      
      carray_delete(rootlist, cur);
    }
    else
      cur ++;
    current_thread = cur_env_tree;
  }

  /*
    Finally, the threads are
    sorted by the sent date of the first message in the thread.
    Note that each message in a thread is a child (as opposed to a
    sibling) of the previous message.
  */

#if 0
  if (comp_func != NULL) {
    r = mail_thread_sort(root, comp_func, FALSE);
    if (r != MAIL_NO_ERROR) {
      res = r;
      goto free;
    }
  }
#endif
  
  if (comp_func == NULL)
    comp_func = mailthread_tree_timecomp;
  
  r = mail_thread_sort(root, comp_func, FALSE);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto free;
  }

  * result = root;

  return MAIL_NO_ERROR;

 free:
  mailmessage_tree_free_recursive(root);
 err:
  return res;
}