示例#1
0
VALUE
rb_ca_is_not_masked (VALUE self)
{
  volatile VALUE mask;
  CArray *ca, *cm, *co;
  boolean8_t one = 1;
  boolean8_t *m, *p;
  ca_size_t i;

  Data_Get_Struct(self, CArray, ca);

  co = carray_new(CA_BOOLEAN, ca->rank, ca->dim, ca->bytes, NULL);

  ca_update_mask(ca);
  if ( ! ca->mask ) {
    ca_fill(co, &one);
  }
  else {
    mask = rb_ca_mask_array(self);
    Data_Get_Struct(mask, CArray, cm);
    ca_attach(cm);
    m = (boolean8_t *) cm->ptr;
    p = (boolean8_t *) co->ptr;
    for (i=0; i<ca->elements; i++) {
      *p = ( *m ) ? 0 : 1;
      m++; p++;
    }
    ca_detach(cm);
  }

  return ca_wrap_struct(co);
}
示例#2
0
struct mail_flags_store * mail_flags_store_new(void)
{
  struct mail_flags_store * flags_store;

  flags_store = malloc(sizeof(struct mail_flags_store));
  if (flags_store == NULL)
    goto err;

  flags_store->fls_tab = carray_new(128);
  if (flags_store->fls_tab == NULL)
    goto free;

  flags_store->fls_hash = chash_new(128, CHASH_COPYALL);
  if (flags_store->fls_hash == NULL)
    goto free_tab;
  
  return flags_store;

 free_tab:
  carray_free(flags_store->fls_tab);
 free:
  free(flags_store);
 err:
  return NULL;
}
示例#3
0
static int feeddriver_get_messages_list(mailsession * session,
    struct mailmessage_list ** result)
{
  unsigned int i;
  struct feed_session_state_data * data;
  unsigned int count;
  struct mailmessage_list * msg_list;
  carray * tab;
  int res;
  int r;
  
  update(session);
  data = get_data(session);
  if (data->feed_error != MAIL_NO_ERROR) {
    res = data->feed_error;
    goto err;
  }
  
  count = newsfeed_item_list_get_count(data->feed_session);
  
  tab = carray_new(count);
  if (tab == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }
  fprintf(stderr, "count: %i\n", count);
  
  for(i = 0 ; i < count ; i ++) {
    struct newsfeed_item * item;
    mailmessage * msg;
    
    item = newsfeed_get_item(data->feed_session, i);
    msg = feed_item_to_message(session, i, item);
    r = carray_add(tab, msg, NULL);
    if (r < 0) {
      res = MAIL_ERROR_MEMORY;
      goto free_tab;
    }
  }
  
  msg_list = mailmessage_list_new(tab);
  if (msg_list == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_tab;
  }
  
  * result = msg_list;
  
  return MAIL_NO_ERROR;
  
 free_tab:
  for(i = 0 ; i < carray_count(tab) ; i ++) {
    mailmessage * msg;
    
    msg = carray_get(tab, i);
    mailmessage_free(msg);
  }
 err:
  return res;
}
示例#4
0
static VALUE
rb_ca_arg (VALUE self)
{
  volatile VALUE obj;
  CArray *ca, *co;

  Data_Get_Struct(self, CArray, ca);

  co = carray_new(CA_FLOAT64, ca->rank, ca->dim, 0, NULL);
  obj = ca_wrap_struct(co);

  if ( ca_has_mask(ca) ) {
    ca_copy_mask_overlay(co, co->elements, 1, ca);
  }

  ca_attach(ca);

  switch ( ca->data_type ) {
  case CA_FLOAT32:  proc_arg_cmplx(float32_t);  break;
  case CA_FLOAT64:  proc_arg_cmplx(float64_t);  break;
  case CA_FLOAT128: proc_arg_cmplx(float128_t);  break;
  case CA_CMPLX64:  proc_arg_cmplx(cmplx64_t);   break;
  case CA_CMPLX128: proc_arg_cmplx(cmplx128_t);  break;
  case CA_CMPLX256: proc_arg_cmplx(cmplx256_t);  break;
  default: rb_raise(rb_eRuntimeError, "invalid data type");
  }

  ca_detach(ca);

  return obj;
}
示例#5
0
int mailmbox_copy_msg(struct mailmbox_folder * dest_folder,
		      struct mailmbox_folder * src_folder,
		      uint32_t uid)
{
  carray * tab;
  int res;
  uint32_t * puid;
  int r;

  tab = carray_new(1);
  if (tab == NULL) {
    res = MAILMBOX_ERROR_MEMORY;
    goto err;
  }

  puid = malloc(sizeof(* puid));
  if (puid == NULL) {
    res = MAILMBOX_ERROR_MEMORY;
    goto free_array;
  }
  * puid = uid;
  
  r = mailmbox_copy_msg_list(dest_folder, src_folder, tab);
  res = r;

  free(puid);
 free_array:
  carray_free(tab);
 err:
  return res;
}
static carray * mailstream_low_cfstream_get_certificate_chain(mailstream_low * s)
{
#if HAVE_CFNETWORK
  struct mailstream_cfstream_data * cfstream_data;
  unsigned int i;
  carray * result;
  
  cfstream_data = (struct mailstream_cfstream_data *) s->data;
  SecTrustRef secTrust = (SecTrustRef)CFReadStreamCopyProperty(cfstream_data->readStream, kCFStreamPropertySSLPeerTrust);
  if (secTrust == NULL)
    return NULL;
  
  CFIndex count = SecTrustGetCertificateCount(secTrust);
  
  result = carray_new(4);
  for(i = 0 ; i < count ; i ++) {
    SecCertificateRef cert = (SecCertificateRef) SecTrustGetCertificateAtIndex(secTrust, i);
    CFDataRef data = SecCertificateCopyData(cert);
    CFIndex length = CFDataGetLength(data);
    const UInt8 * bytes = CFDataGetBytePtr(data);
    MMAPString * str = mmap_string_sized_new(length);
    mmap_string_append_len(str, (char*) bytes, length);
    carray_add(result, str, NULL);
    CFRelease(data);
  }
  
  CFRelease(secTrust);
  
  return result;
#else
  return NULL;
#endif
}
示例#7
0
/* feed_new()
 * Initializes new Feed struct, setting its url and a default timeout. */
struct newsfeed * newsfeed_new(void)
{
  struct newsfeed * feed;

  feed = malloc(sizeof(* feed));
  if (feed == NULL)
    goto err;

  feed->feed_url = NULL;
  feed->feed_title = NULL;
  feed->feed_description = NULL;
  feed->feed_language = NULL;
  feed->feed_author = NULL;
  feed->feed_generator = NULL;
  feed->feed_item_list = carray_new(16);
  if (feed->feed_item_list == NULL)
    goto free;
  feed->feed_response_code = 0;
  feed->feed_timeout = 0;

  return feed;

 free:
  free(feed);
 err:
  return NULL;
}
示例#8
0
LIBETPAN_EXPORT
struct mailfolder * mailfolder_new(struct mailstorage * storage,
    const char * pathname, const char * virtual_name)
{
  struct mailfolder * folder;
  
  folder = malloc(sizeof(struct mailfolder));
  if (folder == NULL)
    goto err;

  if (pathname != NULL) {
    folder->fld_pathname = strdup(pathname);
    if (folder->fld_pathname == NULL)
      goto free;
  }
  else
    folder->fld_pathname = NULL;
  
  if (virtual_name != NULL) {
    folder->fld_virtual_name = strdup(virtual_name);
    if (folder->fld_virtual_name == NULL)
      goto free_pathname;
  }
  else
    folder->fld_virtual_name = NULL;

  folder->fld_storage = storage;

  folder->fld_session = NULL;
  folder->fld_shared_session = 0;
  folder->fld_pos = NULL;

  folder->fld_parent = NULL;
  folder->fld_sibling_index = 0;
  folder->fld_children = carray_new(128);
  if (folder->fld_children == NULL)
    goto free_virtualname;

  return folder;

free_virtualname:
  if (folder->fld_virtual_name != NULL)
    free(folder->fld_virtual_name);
free_pathname:
  if (folder->fld_pathname != NULL)
    free(folder->fld_pathname);
free:
  free(folder);
err:
  return NULL;
}
示例#9
0
static int read_list(mailpop3 * f, carray ** result)
{
  unsigned int indx;
  uint32_t size;
  carray * msg_tab;
  struct mailpop3_msg_info * msg;
  char * line;

  msg_tab = carray_new(128);
  if (msg_tab == NULL)
    goto err;

  while (1) {
    line = read_line(f);
    if (line == NULL)
      goto free_list;

    if (mailstream_is_end_multiline(line))
      break;

    indx = strtol(line, &line, 10);

    if (!parse_space(&line))
      continue;

    size = strtol(line, &line, 10);
    
    msg = mailpop3_msg_info_new(indx, size, NULL);
    if (msg == NULL)
      goto free_list;

    if (carray_count(msg_tab) < indx) {
      int r;

      r = carray_set_size(msg_tab, indx);
      if (r == -1)
	goto free_list;
    }

    carray_set(msg_tab, indx - 1, msg);
  }

  * result = msg_tab;
  
  return MAILPOP3_NO_ERROR;

 free_list:
  mailpop3_msg_info_tab_free(msg_tab);
 err:
  return MAILPOP3_ERROR_STREAM;
}
示例#10
0
static void
carray_grow(struct carray* a)
{
	int i;
	struct carray* tmp = carray_new(a->size * 2);
	for (i = 0; i < a->count; i++)
		carray_push_back(tmp, carray_at(a, i));
	free(a->array);
	a->head = 0;
	a->tail = tmp->tail;
	a->size = tmp->size;
	a->array = tmp->array;
	free(tmp);
}
示例#11
0
struct mailprivacy * mailprivacy_new(char * tmp_dir, int make_alternative)
{
  struct mailprivacy * privacy;
  
  privacy = malloc(sizeof(* privacy));
  if (privacy == NULL)
    goto err;
  
  privacy->tmp_dir = strdup(tmp_dir); 
  if (privacy->tmp_dir == NULL)
    goto free;
  
  privacy->msg_ref = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
  if (privacy->msg_ref == NULL)
    goto free_tmp_dir;
  
  privacy->mmapstr = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
  if (privacy->mmapstr == NULL)
    goto free_msg_ref;
  
  privacy->mime_ref = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
  if (privacy->mime_ref == NULL)
    goto free_mmapstr;
  
  privacy->protocols = carray_new(16);
  if (privacy->protocols == NULL)
    goto free_mime_ref;

  privacy->make_alternative = make_alternative;
  
  return privacy;
  
 free_mime_ref:
  chash_free(privacy->mime_ref);
 free_mmapstr:
  chash_free(privacy->mmapstr);
 free_msg_ref:
  chash_free(privacy->msg_ref);
 free_tmp_dir:
  free(privacy->tmp_dir);
 free:
  free(privacy);
 err:
  return NULL;
}
示例#12
0
int
mailmbox_append_message_uid(struct mailmbox_folder * folder,
    const char * data, size_t len, unsigned int * puid)
{
  carray * tab;
  struct mailmbox_append_info * append_info;
  int res;
  int r;

  tab = carray_new(1);
  if (tab == NULL) {
    res = MAILMBOX_ERROR_MEMORY;
    goto err;
  }

  append_info = mailmbox_append_info_new(data, len);
  if (append_info == NULL) {
    res = MAILMBOX_ERROR_MEMORY;
    goto free_list;
  }

  r = carray_add(tab, append_info, NULL);
  if (r < 0) {
    res = MAILMBOX_ERROR_MEMORY;
    goto free_append_info;
  }

  r = mailmbox_append_message_list(folder, tab);
  
  if (puid != NULL)
    * puid = append_info->ai_uid;
  
  mailmbox_append_info_free(append_info);
  carray_free(tab);

  return r;

 free_append_info:
  mailmbox_append_info_free(append_info);
 free_list:
  carray_free(tab);
 err:
  return res;
}
示例#13
0
struct claws_mailmbox_folder * claws_mailmbox_folder_new(const char * mb_filename)
{
  struct claws_mailmbox_folder * folder;

  folder = malloc(sizeof(* folder));
  if (folder == NULL)
    goto err;

  strncpy(folder->mb_filename, mb_filename, PATH_MAX);

  folder->mb_mtime = (time_t) -1;

  folder->mb_fd = -1;
  folder->mb_read_only = TRUE;
  folder->mb_no_uid = TRUE;

  folder->mb_changed = FALSE;
  folder->mb_deleted_count = 0;
  
  folder->mb_mapping = NULL;
  folder->mb_mapping_size = 0;

  folder->mb_written_uid = 0;
  folder->mb_max_uid = 0;

  folder->mb_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
  if (folder->mb_hash == NULL)
    goto free;
  
  folder->mb_tab = carray_new(128);
  if (folder->mb_tab == NULL)
    goto free_hash;

  return folder;

 free_hash:
  chash_free(folder->mb_hash);
 free:
  free(folder);
 err:
  return NULL;
}
示例#14
0
struct mailmessage_tree *
mailmessage_tree_new(char * node_msgid, time_t node_date,
                     mailmessage * node_msg)
{
    struct mailmessage_tree * tree;
    carray * array;

    array = carray_new(16);
    if (array == NULL)
        return NULL;

    tree = malloc(sizeof(* tree));
    tree->node_parent = NULL;
    tree->node_date = node_date;
    tree->node_msgid = node_msgid;
    tree->node_msg = node_msg;
    tree->node_children = array;
    tree->node_base_subject = NULL;
    tree->node_is_reply = FALSE;

    return tree;
}
示例#15
0
struct tcp_receiver* tcp_receiver_new(struct event_base* b, int port, bufferevent_data_cb cb, void* arg)
{
	struct tcp_receiver* r;
	struct sockaddr_in sin;
	unsigned flags = LEV_OPT_CLOSE_ON_EXEC | LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE;

	r = malloc(sizeof(struct tcp_receiver));
	set_sockaddr_in(&sin, port);
	r->callback = cb;
	r->arg = arg;
	/*libevent listener和bind端口*/
	r->listener = evconnlistener_new_bind(b, on_accept, r, flags,	-1, (struct sockaddr*)&sin, sizeof(sin));
	assert(r->listener != NULL);
	/*设置listen error 回调处理*/
	evconnlistener_set_error_cb(r->listener, on_listener_error);

	r->bevs = carray_new(10);

	paxos_log_info("Listening on port %d", port);

	return r;
}
示例#16
0
carray * mailstream_low_ssl_get_certificate_chain(mailstream_low * s)
{
#ifdef USE_SSL
#ifndef USE_GNUTLS
  STACK_OF(X509) * skx;
  struct mailstream_ssl_data * ssl_data;
  carray * result;
  int skpos;
  
  ssl_data = (struct mailstream_ssl_data *) s->data;
  if (!(skx = SSL_get_peer_cert_chain(ssl_data->ssl_conn))) {
    return NULL;
  }
  
  result = carray_new(4);
  for(skpos = 0 ; skpos < sk_num(skx) ; skpos ++) {
    X509 * x = (X509 *) sk_value(skx, skpos);
    unsigned char * p;
    MMAPString * str;
    int length = i2d_X509(x, NULL);
    str = mmap_string_sized_new(length);
    p = (unsigned char *) str->str;
    str->len = length;
    i2d_X509(x, &p);
    carray_add(result, str, NULL);
  }
  
  return result;
#else
  /* TODO: GnuTLS implementation */
  return NULL;
#endif
#else
  return NULL;
#endif
}
示例#17
0
static int
mail_build_thread_references(char * default_from,
    struct mailmessage_list * env_list,
    struct mailmessage_tree ** result,
    int use_subject, 
    int (* comp_func)(struct mailmessage_tree **,
        struct mailmessage_tree **))
{
  int r;
  int res;
  chash * msg_id_hash;
  unsigned int cur;
  struct mailmessage_tree * root;
  carray * rootlist;
  carray * msg_list;
  unsigned int i;
  chash * subject_hash;

  msg_id_hash = chash_new(128, CHASH_COPYNONE);
  if (msg_id_hash == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }

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

  msg_list = carray_new(128);
  if (msg_list == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_root;
  }

  /* collect message-ID */
  for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
    mailmessage * msg;
    char * msgid;
    struct mailmessage_tree * env_tree;
    chashdatum hashkey;
    chashdatum hashdata;
    chashdatum hashold;
    time_t date;

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

    if (msg == NULL)
      continue;

    if (msg->msg_fields != NULL) {
      msgid = get_msg_id(msg);

      if (msgid == NULL) {
	msgid = mailimf_get_message_id();
      }
      else {
	hashkey.data = msgid;
	hashkey.len = strlen(msgid);
	
	if (chash_get(msg_id_hash, &hashkey, &hashdata) == 0)
	  msgid = mailimf_get_message_id();
	else
	  msgid = strdup(msgid);
      }
      
      if (msgid == NULL) {
	res = MAIL_ERROR_MEMORY;
	goto free_list;
      }
      
      date = get_date(msg);
      
      env_tree = mailmessage_tree_new(msgid, date, msg);
      if (env_tree == NULL) {
	res = MAIL_ERROR_MEMORY;
	goto free_list;
      }
      
      r = carray_add(msg_list, env_tree, NULL);
      if (r < 0) {
	mailmessage_tree_free(env_tree);
	res = MAIL_ERROR_MEMORY;
	goto free_list;
      }
      
      hashkey.data = msgid;
      hashkey.len = strlen(msgid);
      
      hashdata.data = env_tree;
      hashdata.len = 0;
      
      r = chash_set(msg_id_hash, &hashkey, &hashdata, &hashold);
      if (r < 0) {
	res = MAIL_ERROR_MEMORY;
	goto free_list;
      }
    }
  }

  /* (1) for all messages */

  for(cur = 0 ; cur < carray_count(msg_list) ; cur ++) {
    struct mailmessage_tree * env_tree;
    mailmessage * msg;
    clist * ref;

    env_tree = carray_get(msg_list, cur);

    msg = env_tree->node_msg;

    ref = NULL;
    if (msg != NULL) {
      ref = get_ref(msg);
      if (ref == NULL)
	ref = get_in_reply_to(msg);
    }      

    /* (A) Using the Message IDs in the message's references, link
       the corresponding messages (those whose Message-ID header
       line contains the given reference Message ID) together as
       parent/child.
    */

    if (ref != NULL) {
      /* try to start a tree */

      clistiter * cur_ref;
      chashdatum hashkey;
      chashdatum hashdata;
      chashdatum hashold;
      struct mailmessage_tree * env_cur_tree;
      struct mailmessage_tree * last_env_cur_tree;

      env_cur_tree = NULL;
      for(cur_ref = clist_begin(ref) ; cur_ref != NULL ;
	  cur_ref = clist_next(cur_ref)) {
	char * msgid;

	last_env_cur_tree = env_cur_tree;

	msgid = clist_content(cur_ref);

	hashkey.data = msgid;
	hashkey.len = strlen(msgid);
	
	r = chash_get(msg_id_hash, &hashkey, &hashdata);
	if (r < 0) {
	  /* not found, create a dummy message */
	  msgid = strdup(msgid);
	  if (msgid == NULL) {
	    res = MAIL_ERROR_MEMORY;
	    goto free_list;
	  }

	  env_cur_tree = mailmessage_tree_new(msgid, (time_t) -1, NULL);
	  if (env_cur_tree == NULL) {
	    free(msgid);
	    res = MAIL_ERROR_MEMORY;
	    goto free_list;
	  }

	  r = carray_add(msg_list, env_cur_tree, NULL);
	  if (r < 0) {
	    mailmessage_tree_free(env_cur_tree);
	    res = MAIL_ERROR_MEMORY;
	    goto free_list;
	  }

	  hashkey.data = msgid;
	  hashkey.len = strlen(msgid);
	    
	  hashdata.data = env_cur_tree;
	  hashdata.len = 0;
	  
	  r = chash_set(msg_id_hash, &hashkey, &hashdata, &hashold);
	  if (r < 0) {
	    res = MAIL_ERROR_MEMORY;
	    goto free_list;
	  }
	}
	else {
	  env_cur_tree = hashdata.data;
	}

	if (last_env_cur_tree != NULL) {
	  if (env_cur_tree->node_parent == NULL) {
	    /* make it one child */
	    if (env_cur_tree != last_env_cur_tree) {
	      if (!is_descendant(env_cur_tree, last_env_cur_tree)) {
                /* set parent */
		env_cur_tree->node_parent = last_env_cur_tree;
		r = carray_add(last_env_cur_tree->node_children,
                    env_cur_tree, NULL);
		if (r < 0) {
		  res = MAIL_ERROR_MEMORY;
		  goto free_list;
		}
	      }
	    }
	  }
	}
      }

      /* (B) Create a parent/child link between the last reference
	 (or NIL if there are no references) and the current message.
	 If the current message already has a parent, it is probably
	 the result of a truncated References header line, so break
	 the current parent/child link before creating the new
	 correct one.
      */
      
      last_env_cur_tree = env_cur_tree;
      
      if (last_env_cur_tree != NULL) {
	if (env_tree->node_parent == NULL) {
	  if (last_env_cur_tree != env_tree) {
	    if (!is_descendant(env_tree, last_env_cur_tree)) {
              /* set parent */
	      env_tree->node_parent = last_env_cur_tree;
	      r = carray_add(last_env_cur_tree->node_children, env_tree, NULL);
	      if (r < 0) {
		res = MAIL_ERROR_MEMORY;
		goto free_list;
	      }
	    }
	  }
	}
      }
    }
  }

  chash_free(msg_id_hash);
  msg_id_hash = NULL;

  /* (2) Gather together all of the messages that have no parents
     and make them all children (siblings of one another) of a dummy
     parent (the "root").
  */

  for(cur = 0 ; cur < carray_count(msg_list) ; cur ++) {
    struct mailmessage_tree * env_tree;

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

  carray_free(msg_list);
  msg_list = NULL;

  /* (3) Prune dummy messages from the thread tree.
   */

  cur = 0;
  while (cur < carray_count(rootlist)) {
    r = delete_dummy(rootlist, rootlist, cur, &cur);
    if (r != MAIL_NO_ERROR) {
      res = r;
      goto free_list;
    }
  }

  /* (4) Sort the messages under the root (top-level siblings only)
     by sent date.
  */

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

  if (use_subject) {

    /* (5) Gather together messages under the root that have the same
       extracted subject text.

       (A) Create a table for associating extracted subjects with
       messages.
    */

    subject_hash = chash_new(128, CHASH_COPYVALUE);
    if (subject_hash == NULL) {
      res = MAIL_ERROR_MEMORY;
      goto free_list;
    }

    /*
      (B) Populate the subject table with one message per
      extracted subject.  For each child of the root:
    */

    for(cur = 0 ; cur < carray_count(rootlist) ; cur ++) {
      struct mailmessage_tree * env_tree;
      chashdatum key;
      chashdatum data;
      char * base_subject;

      env_tree = carray_get(rootlist, cur);

      /*
	(i) Find the subject of this thread by extracting the
	base subject from the current message, or its first child
	if the current message is a dummy.
      */

      r = get_thread_subject(default_from, env_tree, &base_subject);

      /*
	(ii) If the extracted subject is empty, skip this
	message.
      */

      if (r == MAIL_ERROR_SUBJECT_NOT_FOUND) {
	/* no subject found */
	continue;
      }
      else if (r == MAIL_NO_ERROR) {
	if (* base_subject == '\0') {
	  /* subject empty */
	  free(base_subject);
	  continue;
	}
	else {
	  /* do nothing */
	}
      }
      else {
	res = r;
	goto free_subject_hash;
      }

      env_tree->node_base_subject = base_subject;

      /*
	(iii) Lookup the message associated with this extracted
	subject in the table.
      */

      key.data = base_subject;
      key.len = strlen(base_subject);

      r = chash_get(subject_hash, &key, &data);

      if (r < 0) {
	/*
	  (iv) If there is no message in the table with this
	  subject, add the current message and the extracted
	  subject to the subject table.
	*/

	data.data = &cur;
	data.len = sizeof(cur);

	r = chash_set(subject_hash, &key, &data, NULL);
	if (r < 0) {
	  res = MAIL_ERROR_MEMORY;
	  goto free_subject_hash;
	}
      }
      else {
	/*
	  Otherwise, replace the message in the table with the
	  current message if the message in the table is not a
	  dummy AND either of the following criteria are true:
	  The current message is a dummy, OR                  
	  The message in the table is a reply or forward (its
	  original subject contains a subj-refwd part and/or a
	  "(fwd)" subj-trailer) and the current message is not.
	*/
	struct mailmessage_tree * msg_in_table;
	unsigned int * iter_in_table;
	int replace;

	iter_in_table = data.data;
	msg_in_table = carray_get(rootlist, cur);

	replace = FALSE;
	/* message is dummy if info is NULL */
	if (msg_in_table->node_msg != NULL) {

	  if (env_tree->node_msg == NULL)
	    replace = TRUE;
	  else {
	    if (env_tree->node_is_reply && !env_tree->node_is_reply)
	      replace = TRUE;
	  }
	}
 
	if (replace) {
	  data.data = &cur;
	  data.len = sizeof(cur);
	
	  r = chash_set(subject_hash, &key, &data, NULL);
	  if (r < 0) {
	    res = MAIL_ERROR_MEMORY;
	    goto free_subject_hash;
	  }
	}
      }
    }

    /*
      (C) Merge threads with the same subject.  For each child of
      the root:
    */

    cur = 0;
    while (cur < carray_count(rootlist)) {
      struct mailmessage_tree * env_tree;
      chashdatum key;
      chashdatum data;
      struct mailmessage_tree * main_tree;
      unsigned int * main_cur;

      env_tree = carray_get(rootlist, cur);

      if (env_tree == NULL)
        goto next_msg;

      /*
	(i) Find the subject of this thread as in step 4.B.i
	above.
      */
    
      /* already done in tree->node_base_subject */
    
      /*
	(ii) If the extracted subject is empty, skip this
	message.
      */
    
      if (env_tree->node_base_subject == NULL)
	goto next_msg;

      if (* env_tree->node_base_subject == '\0')
	goto next_msg;

      /*
	(iii) Lookup the message associated with this extracted
	subject in the table.
      */

      key.data = env_tree->node_base_subject;
      key.len = strlen(env_tree->node_base_subject);

      r = chash_get(subject_hash, &key, &data);
      if (r < 0)
	goto next_msg;

      /*
	(iv) If the message in the table is the current message,
	skip this message. 
      */
    
      main_cur = data.data;
      if (* main_cur == cur)
	goto next_msg;

      /*
	Otherwise, merge the current message with the one in the
	table using the following rules:
      */

      main_tree = carray_get(rootlist, * main_cur);

      /*
	If both messages are dummies, append the current
	message's children to the children of the message in
	the table (the children of both messages become
	siblings), and then delete the current message.
      */

      if ((env_tree->node_msg == NULL) && (main_tree->node_msg == NULL)) {
        unsigned int old_size;

        old_size = carray_count(main_tree->node_children);

        r = carray_set_size(main_tree->node_children, old_size +
            carray_count(env_tree->node_children));
        if (r < 0) {
          res = MAIL_ERROR_MEMORY;
          goto free_subject_hash;
        }

        for(i = 0 ; i < carray_count(env_tree->node_children) ; i ++) {
          struct mailmessage_tree * child;

          child = carray_get(env_tree->node_children, i);
          carray_set(main_tree->node_children, old_size + i, child);
          /* set parent */
          child->node_parent = main_tree;
        }
        carray_set_size(env_tree->node_children, 0);
	/* this is the only case where children can be NULL,
	   this is before freeing it */
	mailmessage_tree_free(env_tree);
        carray_delete_fast(rootlist, cur);
      }

      /*
	If the message in the table is a dummy and the current
	message is not, make the current message a child of
	the message in the table (a sibling of it's children).
      */

      else if (main_tree->node_msg == NULL) {
	r = carray_add(main_tree->node_children, env_tree, NULL);
	if (r < 0) {
	  res = MAIL_ERROR_MEMORY;
	  goto free_subject_hash;
	}
        /* set parent */
        env_tree->node_parent = main_tree;

	carray_delete_fast(rootlist, cur);
      }

      /*
	If the current message is a reply or forward and the
	message in the table is not, make the current message
	a child of the message in the table (a sibling of it's
	children).
      */

      else if (env_tree->node_is_reply && !main_tree->node_is_reply) {
	r = carray_add(main_tree->node_children, env_tree, NULL);
	if (r < 0) {
	  res = MAIL_ERROR_MEMORY;
	  goto free_subject_hash;
	}
        /* set parent */
        env_tree->node_parent = main_tree;

	carray_delete_fast(rootlist, cur);
      }

      /*
	Otherwise, create a new dummy message and make both
	the current message and the message in the table
	children of the dummy.  Then replace the message in
	the table with the dummy message.
	Note: Subject comparisons are case-insensitive, as
	described under "Internationalization
	Considerations."
      */

      else {
	struct mailmessage_tree * new_main_tree;
	char * base_subject;
        unsigned int last;

	new_main_tree = mailmessage_tree_new(NULL, (time_t) -1, NULL);
	if (new_main_tree == NULL) {
	  res = MAIL_ERROR_MEMORY;
	  goto free_subject_hash;
	}

	/* main_tree->node_base_subject is never NULL */

	base_subject = strdup(main_tree->node_base_subject);
	if (base_subject == NULL) {
	  mailmessage_tree_free(new_main_tree);
	  res = MAIL_ERROR_MEMORY;
	  goto free_subject_hash;
	}

	new_main_tree->node_base_subject = base_subject;

	r = carray_add(rootlist, new_main_tree, &last);
	if (r < 0) {
	  mailmessage_tree_free(new_main_tree);
	  res = MAIL_ERROR_MEMORY;
	  goto free_subject_hash;
	}

	r = carray_add(new_main_tree->node_children, main_tree, NULL);
	if (r < 0) {
	  res = MAIL_ERROR_MEMORY;
	  goto free_subject_hash;
	}
        /* set parent */
        main_tree->node_parent = new_main_tree;

	carray_delete_fast(rootlist, * main_cur);

	r = carray_add(new_main_tree->node_children, env_tree, NULL);
	if (r < 0) {
	  res = MAIL_ERROR_MEMORY;
	  goto free_subject_hash;
	}
        /* set parent */
        env_tree->node_parent = new_main_tree;

	carray_delete_fast(rootlist, cur);

	data.data = &last;
	data.len = sizeof(last);
      
	r = chash_set(subject_hash, &key, &data, NULL);

	if (r < 0) {
	  res = MAIL_ERROR_MEMORY;
	  goto free_subject_hash;
	}
      }

      continue;

    next_msg:
      cur ++;
      continue;
    }
    
    i = 0;
    for(cur = 0 ; cur < carray_count(rootlist) ; cur ++) {
      struct mailmessage_tree * env_tree;

      env_tree = carray_get(rootlist, cur);
      if (env_tree == NULL)
        continue;
      
      carray_set(rootlist, i, env_tree);
      i ++;
    }
    carray_set_size(rootlist, i);
    
    chash_free(subject_hash);
  }

  /*
    (6) Traverse the messages under the root and sort each set of
    siblings by sent date.  Traverse the messages in such a way
    that the "youngest" set of siblings are sorted first, and the
    "oldest" set of siblings are sorted last (grandchildren are
    sorted before children, etc).

    In the case of an exact match on
    sent date or if either of the Date: headers used in a
    comparison can not be parsed, use the order in which the
    messages appear in the mailbox (that is, by sequence number) to
    determine the order.  In the case of a dummy message (which can
    only occur with top-level siblings), use its first child for
    sorting.
  */

#if 0
  if (comp_func != NULL) {
    r = mail_thread_sort(root, comp_func, TRUE);
    if (r != MAIL_NO_ERROR) {
      res = r;
      goto free_list;
    }
  }
#endif
  if (comp_func == NULL)
    comp_func = mailthread_tree_timecomp;
  
  r = mail_thread_sort(root, comp_func, TRUE);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto free_list;
  }
  
  * result = root;

  return MAIL_NO_ERROR;

 free_subject_hash:
  chash_free(subject_hash);
 free_list:
  if (msg_list != NULL) {
    for(i = 0 ; i < carray_count(msg_list) ; i ++)
      mailmessage_tree_free(carray_get(msg_list, i));
    carray_free(msg_list);
  }
 free_root:
  mailmessage_tree_free_recursive(root);
 free_hash:
  if (msg_id_hash != NULL)
    chash_free(msg_id_hash);
 err:
  return res;
}
示例#18
0
static carray * mailstream_low_cfstream_get_certificate_chain(mailstream_low * s)
{
#if HAVE_CFNETWORK
  struct mailstream_cfstream_data * cfstream_data;
  unsigned int i;
  carray * result;
  CFArrayRef certs;
  CFIndex count;
  
  cfstream_data = (struct mailstream_cfstream_data *) s->data;
    
  SecTrustRef secTrust = (SecTrustRef)CFReadStreamCopyProperty(cfstream_data->readStream, kCFStreamPropertySSLPeerTrust);
  if (secTrust) {
      // SecTrustEvaluate() needs to be called before SecTrustGetCertificateCount() in Mac OS X <= 10.8
      SecTrustEvaluate(secTrust, NULL);
      count = SecTrustGetCertificateCount(secTrust);
      result = carray_new(4);
      for(i = 0 ; i < count ; i ++) {
          SecCertificateRef cert = (SecCertificateRef) SecTrustGetCertificateAtIndex(secTrust, i);
          CFDataRef data = SecCertificateCopyData(cert);
          if (data == NULL) {
            carray_free(result);
            CFRelease(secTrust);
            return NULL;
          }
          CFIndex length = CFDataGetLength(data);
          const UInt8 * bytes = CFDataGetBytePtr(data);
          MMAPString * str = mmap_string_sized_new(length);
          mmap_string_append_len(str, (char*) bytes, length);
          carray_add(result, str, NULL);
          CFRelease(data);
      }
      CFRelease(secTrust);
  }
  else {
      certs = CFReadStreamCopyProperty(cfstream_data->readStream, kCFStreamPropertySSLPeerCertificates);
      if (certs) {
          count = CFArrayGetCount(certs);
          result = carray_new(4);
          for(i = 0 ; i < count ; i ++) {
              SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(certs, i);
              CFDataRef data = SecCertificateCopyData(cert);
              if (data == NULL) {
                carray_free(result);
                CFRelease(certs);
                return NULL;
              }
              CFIndex length = CFDataGetLength(data);
              const UInt8 * bytes = CFDataGetBytePtr(data);
              MMAPString * str = mmap_string_sized_new(length);
              mmap_string_append_len(str, (char*) bytes, length);
              carray_add(result, str, NULL);
              CFRelease(data);
          }
          CFRelease(certs);
      }
      else {
          return NULL;
      }
  }
    
  return result;
#else
  return NULL;
#endif
}
示例#19
0
carray * mailstream_low_ssl_get_certificate_chain(mailstream_low * s)
{
#ifdef USE_SSL
  struct mailstream_ssl_data * ssl_data;
  carray * result;
  int skpos;
#ifndef USE_GNUTLS
  STACK_OF(X509) * skx;
  
  ssl_data = (struct mailstream_ssl_data *) s->data;
  if (!(skx = SSL_get_peer_cert_chain(ssl_data->ssl_conn))) {
    return NULL;
  }
  
  result = carray_new(4);
  for(skpos = 0 ; skpos < sk_num((_STACK *) skx) ; skpos ++) {
    X509 * x = (X509 *) sk_value((_STACK *) skx, skpos);
    unsigned char * p;
    MMAPString * str;
    int length = i2d_X509(x, NULL);
    str = mmap_string_sized_new(length);
    p = (unsigned char *) str->str;
    str->len = length;
    i2d_X509(x, &p);
    carray_add(result, str, NULL);
  }
  
  return result;
#else
  gnutls_session session = NULL;
  const gnutls_datum *raw_cert_list;
  unsigned int raw_cert_list_length;

  ssl_data = (struct mailstream_ssl_data *) s->data;

  session = ssl_data->session;
  raw_cert_list = gnutls_certificate_get_peers(session, &raw_cert_list_length);

  if (raw_cert_list && gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
    result = carray_new(4);
    for(skpos = 0 ; skpos < raw_cert_list_length ; skpos ++) {
      gnutls_x509_crt cert = NULL;
      if (gnutls_x509_crt_init(&cert) >= 0
       && gnutls_x509_crt_import(cert, &raw_cert_list[skpos], GNUTLS_X509_FMT_DER) >= 0) {
         size_t cert_size = 0;
         MMAPString * str = NULL;
         unsigned char * p;

         if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, NULL, &cert_size)
	     == GNUTLS_E_SHORT_MEMORY_BUFFER) {
           str = mmap_string_sized_new(cert_size);
           p = (unsigned char *) str->str;
           str->len = cert_size;
	 }
	 if (str != NULL &&
             gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, p, &cert_size) >= 0) {
           carray_add(result, str, NULL);
	 } else {
	   return NULL;
	 }
         gnutls_x509_crt_deinit(cert);
       }
    }
  }

  return result;

  return NULL;
#endif
#else
  return NULL;
#endif
}
示例#20
0
static int db_get_message_list(struct mail_cache_db * maildb,
    carray ** p_msglist)
{
  carray * msglist;
  void * serialized;
  size_t serialized_len;
  int r;
  char key_value[PATH_MAX];
  int res;
  unsigned int i;

  msglist = carray_new(16);
  if (msglist == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }
  
  snprintf(key_value, sizeof(key_value), "message-list");
  r = mail_cache_db_get(maildb, key_value, strlen(key_value),
      &serialized, &serialized_len);
  if (r >= 0) {
    MMAPString * mmapstr;
    size_t cur_token;
    
    /* collect message list */
    
    mmapstr = mmap_string_new_len(serialized, serialized_len);
    if (mmapstr == NULL) {
      res = MAIL_ERROR_MEMORY;
      goto free_msglist;
    }
    
    cur_token = 0;
    do {
      uint32_t num;
      uint32_t * msg;
      
      r = mailimf_cache_int_read(mmapstr, &cur_token, &num);
      if (r != MAIL_NO_ERROR)
        break;
      
      msg = malloc(sizeof(* msg));
      if (msg == NULL) {
        res = MAIL_ERROR_MEMORY;
        mmap_string_free(mmapstr);
        goto free_msglist;
      }
      * msg = num;
      
      r = carray_add(msglist, msg, NULL);
      if (r < 0) {
        res = MAIL_ERROR_MEMORY;
        free(msg);
        mmap_string_free(mmapstr);
        goto free_msglist;
      }
    } while (1);
    
    mmap_string_free(mmapstr);
  }
  
  * p_msglist = msglist;
  
  return MAIL_NO_ERROR;
  
 free_msglist:
  for(i = 0 ; i < carray_count(msglist) ; i ++) {
    uint32_t * msg;
    
    msg = carray_get(msglist, i);
    free(msg);
  }
  carray_free(msglist);
 err:
  return res;
}
示例#21
0
struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent,
					 const char * name)
{
  char * filename;
  char * parent_filename;

  struct mailmh_folder * folder;

  folder = malloc(sizeof(* folder));
  if (folder == NULL)
    goto err;

  if (parent == NULL) {
    filename = strdup(name);
    if (filename == NULL)
      goto free_folder;
  }
  else {
    parent_filename = parent->fl_filename;
    filename = malloc(strlen(parent_filename) + strlen(name) + 2);
    if (filename == NULL)
      goto free_folder;

    strcpy(filename, parent_filename);
    strcat(filename, MAIL_DIR_SEPARATOR_S);
    strcat(filename, name);
  }

  folder->fl_filename = filename;

  folder->fl_name = strdup(name);
  if (folder->fl_name == NULL)
    goto free_filename;

  folder->fl_msgs_tab = carray_new(128);
  if (folder->fl_msgs_tab == NULL)
    goto free_name;

  folder->fl_msgs_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
  if (folder->fl_msgs_hash == NULL)
    goto free_msgs_tab;

  folder->fl_subfolders_tab = carray_new(128);
  if (folder->fl_subfolders_tab == NULL)
    goto free_msgs_hash;

  folder->fl_subfolders_hash = chash_new(128, CHASH_COPYNONE);
  if (folder->fl_subfolders_hash == NULL)
    goto free_subfolders_tab;

  folder->fl_mtime = 0;
  folder->fl_parent = parent;
  folder->fl_max_index = 0;

  return folder;

 free_subfolders_tab:
  carray_free(folder->fl_subfolders_tab);
 free_msgs_hash:
  chash_free(folder->fl_msgs_hash);
 free_msgs_tab:
  carray_free(folder->fl_msgs_tab);
 free_name:
  free(folder->fl_name);
 free_filename:
  free(folder->fl_filename);
 free_folder:
  free(folder);
 err:
  return NULL;
}
示例#22
0
static int get_messages_list(mailsession * session,
    struct mailmessage_list ** result)
{
  int r;
  char key[PATH_MAX];
  struct mail_cache_db * maildb;
  struct db_session_state_data * data;
  int res;
  carray * msglist;
  unsigned int i;
  carray * msgtab;
  struct mailmessage_list * driver_msglist;
  
  data = get_data(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;
  }
  
  msgtab = carray_new(16);
  if (msgtab == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto close_db;
  }
  
  for(i = 0 ; i < carray_count(msglist) ; i ++) {
    uint32_t msg_num;
    uint32_t * pmsg_num;
    mailmessage * msg;
    size_t size;
    
    pmsg_num = carray_get(msglist, i);
    msg_num = * pmsg_num;
    free(pmsg_num);
    carray_set(msglist, i, NULL);
    
    snprintf(key, sizeof(key), "%lu", (unsigned long) msg_num);
    r = mail_cache_db_get_size(maildb, key, strlen(key), &size);
    if (r < 0) {
      continue;
    }
    
    msg = mailmessage_new();
    if (msg == NULL) {
      res = MAIL_ERROR_MEMORY;
      goto free_list;
    }
    
    r = mailmessage_init(msg, session, db_message_driver,
        msg_num, size);
    if (r != MAIL_NO_ERROR) {
      mailmessage_free(msg);
      res = r;
      goto free_list;
    }
    
    r = carray_add(msgtab, msg, NULL);
    if (r < 0) {
      mailmessage_free(msg);
      res = MAIL_ERROR_MEMORY;
      goto free_list;
    }
  }
  carray_free(msglist);
  
  driver_msglist = mailmessage_list_new(msgtab);
  if (driver_msglist == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_list;
  }
  
  mail_cache_db_close_unlock(data->db_filename, maildb);
  
  * result = driver_msglist;
  
  return MAIL_NO_ERROR;
  
 free_list:
  for(i = 0 ; i < carray_count(msgtab) ; i ++) {
    mailmessage * msg;
    
    msg = carray_get(msgtab, i);
    mailmessage_free(msg);
  }
  carray_free(msgtab);
  
  for(i = 0 ; i < carray_count(msglist) ; i ++) {
    uint32_t * msg;
    
    msg = carray_get(msglist, i);
    if (msg != NULL)
      free(msg);
  }
  carray_free(msglist);
 close_db:
  mail_cache_db_close_unlock(data->db_filename, maildb);
 err:
  return res;
}
示例#23
0
文件: cbc.c 项目: okayman/ebgn
EC_BOOL cbc_new(const UINT32 size)
{
    g_cbc = carray_new(size, NULL_PTR, LOC_CBC_0002);

    return (EC_TRUE);
}
示例#24
0
int mailmbox_copy_msg_list(struct mailmbox_folder * dest_folder,
			   struct mailmbox_folder * src_folder,
			   carray * tab)
{
  int r;
  int res;
  carray * append_tab;
  unsigned int i;

  r = mailmbox_validate_read_lock(src_folder);
  if (r != MAILMBOX_NO_ERROR) {
    res = r;
    goto err;
  }

  append_tab = carray_new(carray_count(tab));
  if (append_tab == NULL) {
    res = MAILMBOX_ERROR_MEMORY;
    goto src_unlock;
  }

  for(i = 0 ; i < carray_count(tab) ; i ++) {
    struct mailmbox_append_info * append_info;
    char * data;
    size_t len;
    uint32_t uid;

    uid = * ((uint32_t *) carray_get(tab, i));

    r = mailmbox_fetch_msg_no_lock(src_folder, uid, &data, &len);
    if (r != MAILMBOX_NO_ERROR) {
      res = r;
      goto free_list;
    }
    
    append_info = mailmbox_append_info_new(data, len);
    if (append_info == NULL) {
      res = MAILMBOX_ERROR_MEMORY;
      goto free_list;
    }
    
    r = carray_add(append_tab, append_info, NULL);
    if (r < 0) {
      mailmbox_append_info_free(append_info);
      res = MAILMBOX_ERROR_MEMORY;
      goto free_list;
    }
  }    

  r = mailmbox_append_message_list(dest_folder, append_tab);
  if (r != MAILMBOX_NO_ERROR) {
    res = r;
    goto src_unlock;
  }

  for(i = 0 ; i < carray_count(append_tab) ; i ++) {
    struct mailmbox_append_info * append_info;

    append_info = carray_get(append_tab, i);
    mailmbox_append_info_free(append_info);
  }
  carray_free(append_tab);

  mailmbox_read_unlock(src_folder);

  return MAILMBOX_NO_ERROR;

 free_list:
  for(i = 0 ; i < carray_count(append_tab) ; i ++) {
    struct mailmbox_append_info * append_info;

    append_info = carray_get(append_tab, i);
    mailmbox_append_info_free(append_info);
  }
  carray_free(append_tab);
 src_unlock:
  mailmbox_read_unlock(src_folder);
 err:
  return res;
}
示例#25
0
static int folder_update_msg_list(struct folder_ref_info * ref_info,
                                  struct mailmessage_list ** p_new_msg_list,
                                  struct mailmessage_list ** p_lost_msg_list)
{
    int r;
    int res;
    struct mailmessage_list * new_env_list;
    unsigned int i;
    carray * lost_msg_tab;
    struct mailmessage_list * lost_msg_list;
    unsigned int free_start_index;
    chashiter * iter;
    unsigned int lost_count;

    r = mailfolder_get_messages_list(ref_info->folder, &new_env_list);
    if (r != MAIL_NO_ERROR) {
        res = r;
        goto err;
    }

    for(iter = chash_begin(ref_info->msg_hash) ; iter != NULL ;
            iter = chash_next(ref_info->msg_hash, iter)) {
        struct message_ref_elt * msg_ref;
        chashdatum data;

        chash_value(iter, &data);
        msg_ref = data.data;
        msg_ref->lost = 1;
    }

    lost_count = chash_count(ref_info->msg_hash);

    for(i = 0 ; i < carray_count(new_env_list->msg_tab) ; i ++) {
        mailmessage * msg;
        mailmessage * old_msg;

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

        if (msg->msg_uid == NULL)
            continue;

        old_msg = folder_info_get_msg_by_uid(ref_info, msg->msg_uid);
        if (old_msg != NULL) {
            struct message_ref_elt * msg_ref;

            /* replace old message */
            old_msg->msg_index = msg->msg_index;
            carray_set(new_env_list->msg_tab, i, old_msg);
            mailmessage_free(msg);

            msg_ref = folder_info_get_msg_ref(ref_info, old_msg);
            msg_ref->lost = 0;
            lost_count --;
        }
        else {
            /* set new message */
            r = folder_message_add(ref_info, msg);
            if (r != MAIL_NO_ERROR) {
                free_start_index = i;
                res = r;
                goto free_remaining;
            }
        }
    }

    /* build the table of lost messages */
    lost_msg_tab = carray_new(lost_count);
    if (lost_msg_tab == NULL) {
        res = MAIL_ERROR_MEMORY;
        goto free_env_list;
    }

    carray_set_size(lost_msg_tab, lost_count);

    i = 0;
    for(iter = chash_begin(ref_info->msg_hash) ; iter != NULL ;
            iter = chash_next(ref_info->msg_hash, iter)) {
        struct message_ref_elt * msg_ref;
        chashdatum key;
        chashdatum value;
        mailmessage * msg;

        chash_key(iter, &key);
        memcpy(&msg, key.data, sizeof(msg));

        chash_value(iter, &value);
        msg_ref = value.data;
        if (msg_ref->lost) {
            carray_set(lost_msg_tab, i, msg);
            i ++;
        }
    }

    lost_msg_list = mailmessage_list_new(lost_msg_tab);
    if (lost_msg_list == NULL) {
        res = MAIL_ERROR_MEMORY;
        goto free_lost_msg_tab;
    }

    /* reference messages */
    for(i = 0 ; i < carray_count(new_env_list->msg_tab) ; i ++) {
        mailmessage * msg;

        msg = carray_get(new_env_list->msg_tab, i);
        folder_message_ref(ref_info, msg);
    }

    * p_new_msg_list = new_env_list;
    * p_lost_msg_list = lost_msg_list;

    return MAIL_NO_ERROR;

free_lost_msg_tab:
    carray_free(lost_msg_tab);
free_env_list:
    for(i = 0 ; i < carray_count(new_env_list->msg_tab) ; i ++) {
        mailmessage * msg;
        struct message_ref_elt * msg_ref;

        msg = carray_get(new_env_list->msg_tab, i);
        msg_ref = folder_info_get_msg_ref(ref_info, msg);
        if (msg_ref != NULL) {
            if (msg_ref->ref_count == 0)
                folder_message_remove(ref_info, msg);
        }
    }
    carray_set_size(new_env_list->msg_tab, 0);
    mailmessage_list_free(new_env_list);
    goto err;
free_remaining:
    for(i = 0 ; i < carray_count(new_env_list->msg_tab) ; i ++) {
        mailmessage * msg;
        struct message_ref_elt * msg_ref;

        msg = carray_get(new_env_list->msg_tab, i);
        msg_ref = folder_info_get_msg_ref(ref_info, msg);
        if (msg_ref != NULL) {
            if (msg_ref->ref_count == 0)
                folder_message_remove(ref_info, msg);
        }
    }
    for(i = free_start_index ; i < carray_count(new_env_list->msg_tab) ; i ++) {
        mailmessage * msg;

        msg = carray_get(new_env_list->msg_tab, i);
        mailmessage_free(msg);
    }
    carray_set_size(new_env_list->msg_tab, 0);
    mailmessage_list_free(new_env_list);
err:
    return res;
}
示例#26
0
int nntp_get_messages_list(mailsession * nntp_session,
                           mailsession * session,
                           mailmessage_driver * driver,
                           struct mailmessage_list ** result)
{
    carray * tab;
    struct mailmessage_list * env_list;
    uint32_t i;
    int res;
    int r;
    struct nntp_session_state_data * data;
    struct newsnntp_group_info * group_info;
    uint32_t max;
    unsigned int cur;

    data = session_get_data(nntp_session);

    if (data->nntp_group_name == NULL) {
        res = MAIL_ERROR_BAD_STATE;
        goto err;
    }

    r = nntpdriver_select_folder(nntp_session, data->nntp_group_name);
    if (r != MAIL_NO_ERROR) {
        res = r;
        goto err;
    }

    group_info = data->nntp_group_info;

    if (group_info == NULL) {
        res = MAIL_ERROR_BAD_STATE;
        goto err;
    }

    max = group_info->grp_first;
    if (data->nntp_max_articles != 0) {
        if (group_info->grp_last - data->nntp_max_articles + 1 > max)
            max = group_info->grp_last - data->nntp_max_articles + 1;
    }

    tab = carray_new(128);
    if (tab == NULL) {
        res = MAIL_ERROR_MEMORY;
        goto err;
    }

    for(i = max ; i <= group_info->grp_last ; i++) {
        mailmessage * msg;

        msg = mailmessage_new();
        if (msg == NULL) {
            res = MAIL_ERROR_MEMORY;
            goto free_list;
        }

        r = mailmessage_init(msg, session, driver, i, 0);
        if (r != MAIL_NO_ERROR) {
            mailmessage_free(msg);
            res = r;
            goto free_list;
        }

        r = carray_add(tab, msg, NULL);
        if (r < 0) {
            mailmessage_free(msg);
            res = MAIL_ERROR_MEMORY;
            goto free_list;
        }
    }

    env_list = mailmessage_list_new(tab);
    if (env_list == NULL) {
        res = MAIL_ERROR_MEMORY;
        goto free_list;
    }

    * result = env_list;

    return MAIL_NO_ERROR;

free_list:
    for(cur = 0 ; cur < carray_count(tab) ; cur ++)
        mailmessage_free(carray_get(tab, cur));
    carray_free(tab);
err:
    return res;
}