Exemple #1
0
static int
pop3driver_cached_get_envelopes_list(mailsession * session,
    struct mailmessage_list * env_list)
{
  int r;
  unsigned int i;
  struct pop3_cached_session_state_data * cached_data;
  char filename_env[PATH_MAX];
  char filename_flags[PATH_MAX];
  struct mail_cache_db * cache_db_env;
  struct mail_cache_db * cache_db_flags;
  MMAPString * mmapstr;
  int res;

  cached_data = get_cached_data(session);

  pop3_flags_store_process(cached_data->pop3_flags_directory,
      cached_data->pop3_flags_store);

  snprintf(filename_env, PATH_MAX, "%s/%s",
      cached_data->pop3_cache_directory, ENV_NAME);

  mmapstr = mmap_string_new("");
  if (mmapstr == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }

  r = mail_cache_db_open_lock(filename_env, &cache_db_env);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto free_mmapstr;
  }

  snprintf(filename_flags, PATH_MAX, "%s/%s",
      cached_data->pop3_flags_directory, FLAGS_NAME);

  r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto close_db_env;
  }

  /* fill with cached */

  for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {   
    mailmessage * msg;
    struct mailimf_fields * fields;
    struct mail_flags * flags;

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

    if (msg->msg_fields == NULL) {
      r = get_cached_envelope(cache_db_env, mmapstr,
          session, msg->msg_index, &fields);
      if (r == MAIL_NO_ERROR) {
	msg->msg_cached = TRUE;
	msg->msg_fields = fields;
      }
    }

    if (msg->msg_flags == NULL) {
      r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
          session, msg->msg_index, &flags);
      if (r == MAIL_NO_ERROR) {
	msg->msg_flags = flags;
      }
    }
  }
  
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);
  mail_cache_db_close_unlock(filename_env, cache_db_env);

  r = maildriver_generic_get_envelopes_list(session, env_list);

  if (r != MAIL_NO_ERROR) {
    res = r;
    goto free_mmapstr;
  }

  /* add flags */
  
  for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
    mailmessage * msg;

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

    if (msg->msg_flags == NULL)
      msg->msg_flags = mail_flags_new_empty();
  }
  
  r = mail_cache_db_open_lock(filename_env, &cache_db_env);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto free_mmapstr;
  }
  
  r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto close_db_env;
  }

  /* must write cache */

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

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

    if (msg->msg_fields != NULL) {
      if (!msg->msg_cached) {
	r = write_cached_envelope(cache_db_env, mmapstr,
            session, msg->msg_index, msg->msg_fields);
      }
    }
    
    if (msg->msg_flags != NULL) {
      r = pop3driver_write_cached_flags(cache_db_flags, mmapstr,
          msg->msg_uid, msg->msg_flags);
    }
  }

  /* flush cache */
  
  maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
  
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);
  mail_cache_db_close_unlock(filename_env, cache_db_env);
  mmap_string_free(mmapstr);

  /* remove cache files */
  
  maildriver_message_cache_clean_up(cached_data->pop3_cache_directory,
      env_list, get_uid_from_filename);
  
  return MAIL_NO_ERROR;

 close_db_env:
  mail_cache_db_close_unlock(filename_env, cache_db_env);
 free_mmapstr:
  mmap_string_free(mmapstr);
 err:
  return res;
}
Exemple #2
0
static int newsnntp_get_content(newsnntp * f, char ** result,
				size_t * result_len)
{
  int r;
  char * response;
  MMAPString * buffer;
  char * result_multiline;

  response = read_line(f);
  if (response == NULL)
    return NEWSNNTP_ERROR_STREAM;

  r = parse_response(f, response);

  switch (r) {
  case 480:
    return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_USERNAME;
    
  case 381:
    return NEWSNNTP_WARNING_REQUEST_AUTHORIZATION_PASSWORD;
    
  case 220:
  case 221:
  case 222:
  case 223:
    buffer = mmap_string_new("");
    if (buffer == NULL)
      return NEWSNNTP_ERROR_MEMORY;

    result_multiline = read_multiline(f, 0, buffer);
    if (result_multiline == NULL) {
      mmap_string_free(buffer);
      return NEWSNNTP_ERROR_MEMORY;
    }
    else {
      r = mmap_string_ref(buffer);
      if (r < 0) {
        mmap_string_free(buffer);
        return NEWSNNTP_ERROR_MEMORY;
      }
      
      * result = result_multiline;
      * result_len = buffer->len;
      return NEWSNNTP_NO_ERROR;
    }

  case 412:
    return NEWSNNTP_ERROR_NO_NEWSGROUP_SELECTED;

  case 420:
    return NEWSNNTP_ERROR_NO_ARTICLE_SELECTED;

  case 423:
    return NEWSNNTP_ERROR_INVALID_ARTICLE_NUMBER;

  case 430:
    return NEWSNNTP_ERROR_ARTICLE_NOT_FOUND;

  default:
    return NEWSNNTP_ERROR_UNEXPECTED_RESPONSE;
  }
}
Exemple #3
0
static int pop3driver_cached_status_folder(mailsession * session,
    const char * mb, uint32_t * result_messages, uint32_t * result_recent,
    uint32_t * result_unseen)
{
  int res;
  struct pop3_cached_session_state_data * cached_data;
  char filename_flags[PATH_MAX];
  struct mail_cache_db * cache_db_flags;
  MMAPString * mmapstr;
  unsigned int i;
  int r;
  carray * msg_tab;
  mailpop3 * pop3;
  uint32_t recent;
  uint32_t unseen;
  
  recent = 0;
  unseen = 0;
  
  pop3 = get_pop3_session(session);

  cached_data = get_cached_data(session);

  pop3_flags_store_process(cached_data->pop3_flags_directory,
      cached_data->pop3_flags_store);

  snprintf(filename_flags, PATH_MAX, "%s/%s",
      cached_data->pop3_flags_directory, FLAGS_NAME);

  r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto err;
  }

  mmapstr = mmap_string_new("");
  if (mmapstr == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto close_db_flags;
  }

  r = mailpop3_list(pop3, &msg_tab);
  if (r != MAILPOP3_NO_ERROR) {
    res = pop3driver_pop3_error_to_mail_error(r);
    goto free_mmapstr;
  }

  for(i = 0 ; i < carray_count(msg_tab) ; i++) {
    struct mailpop3_msg_info * pop3_info;
    struct mail_flags * flags;
    
    pop3_info = carray_get(msg_tab, i);
    if (pop3_info == NULL)
      continue;

    if (pop3_info->msg_deleted)
      continue;

    r = pop3driver_get_cached_flags(cache_db_flags, mmapstr,
        session, pop3_info->msg_index, &flags);
    if (r != MAIL_NO_ERROR) {
      recent ++;
      unseen ++;
      continue;
    }

    if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
      recent ++;
    }
    if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
      unseen ++;
    }
    mail_flags_free(flags);

  }
  
  mmap_string_free(mmapstr);
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);

  * result_messages = carray_count(msg_tab) - pop3->pop3_deleted_count;
  * result_recent = recent;
  * result_unseen = unseen;
  
  return MAIL_NO_ERROR;

 free_mmapstr:
  mmap_string_free(mmapstr);
 close_db_flags:
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);
 err:
  return res;
}
static int get_flags(mailmessage * msg_info,
    struct mail_flags ** result)
{
  struct mail_cache_db * cache_db_flags;
  chashdatum key;
  chashdatum value;
  struct maildir * md;
  struct mail_flags * flags;
  struct maildir_cached_session_state_data * data;
  struct maildir_msg * md_msg;
  int r;
  uint32_t driver_flags;
  char filename_flags[PATH_MAX];
  char keyname[PATH_MAX];
  MMAPString * mmapstr;
  
  if (msg_info->msg_flags != NULL) {
    * result = msg_info->msg_flags;
    return MAIL_NO_ERROR;
  }
  
  data = get_cached_session_data(msg_info);
  flags = mail_flags_store_get(data->md_flags_store,
      msg_info->msg_index);
  if (flags != NULL) {
    msg_info->msg_flags = flags;
    * result = msg_info->msg_flags;
    return MAIL_NO_ERROR;
  }
  
  snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
      data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
      MAIL_DIR_SEPARATOR, FLAGS_NAME);
  
  r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
  if (r < 0)
    return MAIL_ERROR_FILE;
  
  snprintf(keyname, PATH_MAX, "%s-flags", msg_info->msg_uid);
  
  mmapstr = mmap_string_new("");
  if (mmapstr == NULL) {
    mail_cache_db_close_unlock(filename_flags, cache_db_flags);
    return MAIL_ERROR_MEMORY;
  }
  
  r = generic_cache_flags_read(cache_db_flags, mmapstr, keyname, &flags);
  mmap_string_free(mmapstr);
  
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);
  
  if (r != MAIL_NO_ERROR) {
    flags = mail_flags_new_empty();
    if (flags == NULL)
      return MAIL_ERROR_MEMORY;
  }
  
  md = get_maildir_session(msg_info);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;
  
  key.data = msg_info->msg_uid;
  key.len = (unsigned int) strlen(msg_info->msg_uid);
  r = chash_get(md->mdir_msg_hash, &key, &value);
  if (r < 0)
    return MAIL_ERROR_MSG_NOT_FOUND;
  
  md_msg = value.data;
  
  driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags);
  
  flags->fl_flags = driver_flags;
  msg_info->msg_flags = flags;
  
  * result = msg_info->msg_flags;
  
  return MAIL_NO_ERROR;
}
static int mh_get_flags(mailmessage * msg_info,
    struct mail_flags ** result)
{
  int r;
  struct mail_flags * flags;
  struct mail_cache_db * cache_db_flags;
  char filename_flags[PATH_MAX];
  int res;
  struct mh_cached_session_state_data * cached_data;
  MMAPString * mmapstr;

  if (msg_info->msg_flags != NULL) {
    * result = msg_info->msg_flags;
    
    return MAIL_NO_ERROR;
  }

  cached_data = get_cached_session_data(msg_info);
  
  flags = mail_flags_store_get(cached_data->mh_flags_store,
      msg_info->msg_index);

  if (flags == NULL) {
    if (cached_data->mh_quoted_mb == NULL) {
      res = MAIL_ERROR_BAD_STATE;
      goto err;
    }
    
    snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
        cached_data->mh_flags_directory,
        cached_data->mh_quoted_mb, FLAGS_NAME);
    
    r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
    if (r < 0) {
      res = MAIL_ERROR_FILE;
      goto err;
    }
    
    mmapstr = mmap_string_new("");
    if (mmapstr == NULL) {
      res = MAIL_ERROR_MEMORY;
      goto close_db_flags;
    }
    
    r = mhdriver_get_cached_flags(cache_db_flags, mmapstr,
        msg_info->msg_session, msg_info->msg_index, &flags);
    if (r != MAIL_NO_ERROR) {
      flags = mail_flags_new_empty();
      if (flags == NULL) {
	res = MAIL_ERROR_MEMORY;
	goto free_mmapstr;
      }
    }

    mmap_string_free(mmapstr);
    mail_cache_db_close_unlock(filename_flags, cache_db_flags);
  }
    
  msg_info->msg_flags = flags;

  * result = flags;

  return MAIL_NO_ERROR;

 free_mmapstr:
  mmap_string_free(mmapstr);
 close_db_flags:
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);
 err:
  return res;
}
Exemple #6
0
static int
nntpdriver_cached_get_envelopes_list(mailsession * session,
				     struct mailmessage_list * env_list)
{
  int r;
  unsigned int i;
  struct nntp_cached_session_state_data * cached_data;
  uint32_t first;
  uint32_t last;
  struct nntp_session_state_data * ancestor_data;
  char filename_env[PATH_MAX];
  char filename_flags[PATH_MAX];
  struct mail_cache_db * cache_db_env;
  struct mail_cache_db * cache_db_flags;
  MMAPString * mmapstr;
  int res;
  char cache_dir[PATH_MAX];

  cached_data = get_cached_data(session);
  ancestor_data = get_ancestor_data(session);

  nntp_flags_store_process(cached_data->nntp_flags_directory,
      ancestor_data->nntp_group_name,
      cached_data->nntp_flags_store);

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

  /* read articles sequence */

  read_article_seq(session, &first, &last);

  mmapstr = mmap_string_new("");
  if (mmapstr == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }

  snprintf(filename_env, PATH_MAX, "%s/%s/%s",
      cached_data->nntp_cache_directory,
      ancestor_data->nntp_group_name, ENV_NAME);

  r = mail_cache_db_open_lock(filename_env, &cache_db_env);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto free_mmapstr;
  }

  snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
      cached_data->nntp_flags_directory,
      ancestor_data->nntp_group_name, FLAGS_NAME);

  /* fill with cached */
  
  for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {   
    mailmessage * msg;
    struct mailimf_fields * fields;

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

    if ((msg->msg_index < first) || (msg->msg_index > last))
      continue;

    if (msg->msg_fields == NULL) {
      r = get_cached_envelope(cache_db_env, mmapstr,
          session, msg->msg_index, &fields);
      if (r == MAIL_NO_ERROR) {
        msg->msg_fields = fields;
        msg->msg_cached = TRUE;
      }
    }
  }
  
  mail_cache_db_close_unlock(filename_env, cache_db_env);

  r = mailsession_get_envelopes_list(get_ancestor(session), env_list);

  if (r != MAIL_NO_ERROR) {
    res = r;
    goto free_mmapstr;
  }

  r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto free_mmapstr;
  }
  
  /* add flags */
  
  for(i = 0 ; i < carray_count(env_list->msg_tab) ; i ++) {
    mailmessage * msg;

    msg = carray_get(env_list->msg_tab, i);
    
    if (msg->msg_flags == NULL) {
      struct mail_flags * flags;
      
      r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr,
          msg->msg_index, &flags);
      if (r == MAIL_NO_ERROR) {
	msg->msg_flags = flags;
      }
      else {
        msg->msg_flags = mail_flags_new_empty();
        if (msg->msg_fields == NULL) {
          msg->msg_flags->fl_flags |= MAIL_FLAG_CANCELLED;
          mailmessage_check(msg);
        }
      }
    }
  }
  
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);
  
  r = mail_cache_db_open_lock(filename_env, &cache_db_env);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto free_mmapstr;
  }
  
  r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto close_db_env;
  }

  /* must write cache */

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

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

    if (msg->msg_fields != NULL) {
      if (!msg->msg_cached) {
	r = write_cached_envelope(cache_db_env, mmapstr,
            session, msg->msg_index, msg->msg_fields);
      }
    }

    if (msg->msg_flags != NULL) {
      r = nntpdriver_write_cached_flags(cache_db_flags, mmapstr,
          msg->msg_index, msg->msg_flags);
    }
  }

  first = 0;
  last = 0;
  if (carray_count(env_list->msg_tab) > 0) {
    mailmessage * msg;

    msg = carray_get(env_list->msg_tab, 0);
    first = msg->msg_index;

    msg = carray_get(env_list->msg_tab, carray_count(env_list->msg_tab) - 1);
    last = msg->msg_index;
  }

  /* write articles sequence */

  write_article_seq(session, first, last);

  /* flush cache */
  
  maildriver_cache_clean_up(cache_db_env, cache_db_flags, env_list);
  
  /* remove cache files */
  
  snprintf(cache_dir, PATH_MAX, "%s/%s",
      cached_data->nntp_cache_directory, ancestor_data->nntp_group_name);
  
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);
  mail_cache_db_close_unlock(filename_env, cache_db_env);
  mmap_string_free(mmapstr);

  maildriver_message_cache_clean_up(cache_dir, env_list,
      get_uid_from_filename);

  return MAIL_NO_ERROR;

 close_db_env:
  mail_cache_db_close_unlock(filename_env, cache_db_env);
 free_mmapstr:
  mmap_string_free(mmapstr);
 err:
  return res;
}
LIBETPAN_EXPORT
int mailmime_encoded_phrase_parse(const char * default_fromcode,
    const char * message, size_t length,
    size_t * indx, const char * tocode,
    char ** result)
{
  MMAPString * gphrase;
  struct mailmime_encoded_word * word;
  int first;
  size_t cur_token;
  int r;
  int res;
  char * str;
  char * wordutf8;
  int type;
  
  cur_token = * indx;
  
  gphrase = mmap_string_new("");
  if (gphrase == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }
  
  first = TRUE;
  
  type = TYPE_ERROR; /* XXX - removes a gcc warning */
  
  while (1) {
    int has_fwd;
    
    word = NULL;
    r = mailmime_encoded_word_parse(message, length, &cur_token, &word, &has_fwd);
    if (r == MAILIMF_NO_ERROR) {
      if ((!first) && has_fwd) {
        if (type != TYPE_ENCODED_WORD) {
          if (mmap_string_append_c(gphrase, ' ') == NULL) {
            mailmime_encoded_word_free(word);
            res = MAILIMF_ERROR_MEMORY;
            goto free;
          }
        }
      }
      type = TYPE_ENCODED_WORD;
      wordutf8 = NULL;
      r = charconv(tocode, word->wd_charset, word->wd_text,
                   strlen(word->wd_text), &wordutf8);
      switch (r) {
        case MAIL_CHARCONV_ERROR_MEMORY:
          mailmime_encoded_word_free(word);
          res = MAILIMF_ERROR_MEMORY;
          goto free;
          
        case MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET:
          r = charconv(tocode, "iso-8859-1", word->wd_text,
                       strlen(word->wd_text), &wordutf8);
          break;
        case MAIL_CHARCONV_ERROR_CONV:
          mailmime_encoded_word_free(word);
          res = MAILIMF_ERROR_PARSE;
          goto free;
      }
      
      switch (r) {
        case MAIL_CHARCONV_ERROR_MEMORY:
          mailmime_encoded_word_free(word);
          res = MAILIMF_ERROR_MEMORY;
          goto free;
        case MAIL_CHARCONV_ERROR_CONV:
          mailmime_encoded_word_free(word);
          res = MAILIMF_ERROR_PARSE;
          goto free;
      }
      
      if (wordutf8 != NULL) {
        if (mmap_string_append(gphrase, wordutf8) == NULL) {
          mailmime_encoded_word_free(word);
          free(wordutf8);
          res = MAILIMF_ERROR_MEMORY;
          goto free;
        }
        free(wordutf8);
      }
      mailmime_encoded_word_free(word);
      first = FALSE;
    }
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto free;
    }
    
    if (r == MAILIMF_ERROR_PARSE) {
      char * raw_word;
      
      raw_word = NULL;
      r = mailmime_non_encoded_word_parse(message, length,
                                          &cur_token, &raw_word, &has_fwd);
      if (r == MAILIMF_NO_ERROR) {
        if ((!first) && has_fwd) {
          if (mmap_string_append_c(gphrase, ' ') == NULL) {
            free(raw_word);
            res = MAILIMF_ERROR_MEMORY;
            goto free;
          }
        }
        type = TYPE_WORD;
        
        wordutf8 = NULL;
        r = charconv(tocode, default_fromcode, raw_word,
                     strlen(raw_word), &wordutf8);
        
        switch (r) {
          case MAIL_CHARCONV_ERROR_MEMORY:
            free(raw_word);
            res = MAILIMF_ERROR_MEMORY;
            goto free;
            
          case MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET:
          case MAIL_CHARCONV_ERROR_CONV:
            free(raw_word);
            res = MAILIMF_ERROR_PARSE;
            goto free;
        }
        
        if (mmap_string_append(gphrase, wordutf8) == NULL) {
          free(wordutf8);
          free(raw_word);
          res = MAILIMF_ERROR_MEMORY;
          goto free;
        }
        
        free(wordutf8);
        free(raw_word);
        first = FALSE;
      }
      else if (r == MAILIMF_ERROR_PARSE) {
        r = mailimf_fws_parse(message, length, &cur_token);
        if (r != MAILIMF_NO_ERROR) {
          break;
        }
        
        if (mmap_string_append_c(gphrase, ' ') == NULL) {
          res = MAILIMF_ERROR_MEMORY;
          goto free;
        }
        first = FALSE;
        break;
      }
      else {
        res = r;
        goto free;
      }
    }
  }
  
  if (first) {
    if (cur_token != length) {
      res = MAILIMF_ERROR_PARSE;
      goto free;
    }
  }
  
  str = strdup(gphrase->str);
  if (str == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }
  mmap_string_free(gphrase);
  
  * result = str;
  * indx = cur_token;
  
  return MAILIMF_NO_ERROR;
  
free:
  mmap_string_free(gphrase);
err:
  return res;
}
Exemple #8
0
static int append_message_flags(mailsession * session,
    const char * message, size_t size, struct mail_flags * flags)
{
  carray * msglist;
  unsigned int i;
  uint32_t * msg;
  uint32_t num;
  char key_value[PATH_MAX];
  MMAPString * mmapstr;
  struct mail_cache_db * maildb;
  struct db_session_state_data * data;
  size_t cur_token;
  struct mailimf_fields * fields;
  int r;
  int res;
  
  data = get_data(session);
  
  r = mail_cache_db_open_lock(data->db_filename, &maildb);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto err;
  }
  
  num = 0;
  r = db_get_next_msg_number(maildb, &num);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto err;
  }
  
  r = db_get_message_list(maildb, &msglist);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto close_db;
  }
  
  msg = malloc(sizeof(* msg));
  if (msg == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_msglist;
  }
  
  * msg = num;
  
  r = carray_add(msglist, msg, NULL);
  if (r < 0) {
    res = MAIL_ERROR_MEMORY;
    free(msg);
    goto free_msglist;
  }
  
  r = db_set_message_list(maildb, msglist);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto free_msglist;
  }
  
  /* free msglist */
  
  for(i = 0 ; i < carray_count(msglist) ; i ++) {
    msg = carray_get(msglist, i);
    free(msg);
  }
  carray_free(msglist);
  
  snprintf(key_value, sizeof(key_value), "%lu", (unsigned long) num);
  
  r = mail_cache_db_put(maildb, key_value, strlen(key_value),
      message, size);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto close_db;
  }
  
  /* write envelope */
  
  cur_token = 0;
  r = mailimf_envelope_fields_parse(message, size, &cur_token, &fields);
  if (r != MAILIMF_NO_ERROR) {
    res = MAIL_ERROR_PARSE;
    goto close_db;
  }
  
  mmapstr = mmap_string_new("");
  if (mmapstr == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto close_db;
  }
  
  cur_token = 0;
  r = mailimf_cache_fields_write(mmapstr, &cur_token, fields);
  if (r != MAIL_NO_ERROR) {
    res = r;
    mmap_string_free(mmapstr);
    goto close_db;
  }
  
  snprintf(key_value, sizeof(key_value), "%lu-envelope", (unsigned long) num);
  
  r = mail_cache_db_put(maildb, key_value, strlen(key_value),
      mmapstr->str, mmapstr->len);
  
  mmap_string_free(mmapstr);
  
  mailimf_fields_free(fields);
  
  /* write flags */
  
  if (flags != NULL) {
    snprintf(key_value, sizeof(key_value), "%lu-flags", (unsigned long) num);
    
    mmapstr = mmap_string_new("");
    if (mmapstr == NULL) {
      res = MAIL_ERROR_MEMORY;
      goto close_db;
    }
    
    r = generic_cache_flags_write(maildb, mmapstr,
        key_value, flags);
    
    mmap_string_free(mmapstr);
    
    if (r != MAIL_NO_ERROR) {
      res = MAIL_ERROR_FILE;
      goto close_db;
    }
  }
  
  mail_cache_db_close_unlock(data->db_filename, maildb);
  
  return MAIL_NO_ERROR;
  
 free_msglist:
  for(i = 0 ; i < carray_count(msglist) ; i ++) {
    msg = carray_get(msglist, i);
    free(msg);
  }
  carray_free(msglist);
 close_db:
  mail_cache_db_close_unlock(data->db_filename, maildb);
 err:
  return res;
}
Exemple #9
0
static int nntpdriver_cached_status_folder(mailsession * session,
    const char * mb, uint32_t * result_messages, uint32_t * result_recent,
    uint32_t * result_unseen)
{
  int res;
  struct nntp_cached_session_state_data * cached_data;
  struct nntp_session_state_data * ancestor_data;
  char filename_flags[PATH_MAX];
  struct mail_cache_db * cache_db_flags;
  MMAPString * mmapstr;
  uint32_t i;
  int r;
  uint32_t recent;
  uint32_t unseen;
  uint32_t first;
  uint32_t last;
  uint32_t count;
  uint32_t additionnal;

  r = nntpdriver_cached_select_folder(session, mb);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto err;
  }

  read_article_seq(session, &first, &last);

  count = 0;
  recent = 0;
  unseen = 0;
  
  ancestor_data = get_ancestor_data(session);
  cached_data = get_cached_data(session);
  if (ancestor_data->nntp_group_name == NULL) {
    res = MAIL_ERROR_BAD_STATE;
    goto err;
  }

  if (ancestor_data->nntp_group_info->grp_first > first)
    first = ancestor_data->nntp_group_info->grp_first;
  if (last < first)
    last = ancestor_data->nntp_group_info->grp_last;

  snprintf(filename_flags, PATH_MAX, "%s/%s/%s",
      cached_data->nntp_flags_directory,
      ancestor_data->nntp_group_name, FLAGS_NAME);

  r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto err;
  }

  mmapstr = mmap_string_new("");
  if (mmapstr == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto close_db_flags;
  }

  for(i = first ; i <= last ; i++) {
    struct mail_flags * flags;
    
    r = nntpdriver_get_cached_flags(cache_db_flags, mmapstr,
        i, &flags);
    if (r == MAIL_NO_ERROR) {
      if ((flags->fl_flags & MAIL_FLAG_CANCELLED) != 0) {
        mail_flags_free(flags);
        continue;
      }
      
      count ++;
      if ((flags->fl_flags & MAIL_FLAG_NEW) != 0) {
	recent ++;
      }
      if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
	unseen ++;
      }
      mail_flags_free(flags);
    }
  }

  if ((count == 0) && (first != last)) {
    count = last - first + 1;
    recent = count;
    unseen = count;
  }
  
  additionnal = ancestor_data->nntp_group_info->grp_last - last;
  recent += additionnal;
  unseen += additionnal;
  
  mmap_string_free(mmapstr);
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);

  * result_messages = count;
  * result_recent = recent;
  * result_unseen = unseen;
  
  return MAIL_NO_ERROR;

 close_db_flags:
  mail_cache_db_close_unlock(filename_flags, cache_db_flags);
 err:
  return res;
}
Exemple #10
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;
}
Exemple #11
0
static int status_folder(mailsession * session, const char * mb,
    uint32_t * result_messages, uint32_t * result_recent,
    uint32_t * result_unseen)
{
  struct mail_cache_db * maildb;
  char key_value[PATH_MAX];
  MMAPString * mmapstr;
  uint32_t messages;
  uint32_t recent;
  uint32_t unseen;
  struct db_session_state_data * data;
  int r;
  int res;
  carray * msglist;
  unsigned int i;
  
  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;
  }

  mmapstr = mmap_string_new("");
  if (mmapstr == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_list;
  }
  
  messages = 0;
  recent = 0;
  unseen = 0;
  for(i = 0 ; i < carray_count(msglist) ; i ++) {
    uint32_t num;
    uint32_t * msg;
    struct mail_flags * flags;
    
    msg = carray_get(msglist, i);
    num = * msg;
    free(msg);
    carray_set(msglist, i, NULL);
    
    messages ++;
    
    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_NEW) != 0) {
        recent ++;
      }
      if ((flags->fl_flags & MAIL_FLAG_SEEN) == 0) {
        unseen ++;
      }
      mail_flags_free(flags);
    }
  }

  mmap_string_free(mmapstr);
  
  carray_free(msglist);
  
  mail_cache_db_close_unlock(data->db_filename, maildb);

  * result_messages = messages;
  * result_unseen = unseen;
  * result_recent = recent;
  
  return MAIL_NO_ERROR;
  
 free_list:
  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;
}
Exemple #12
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;
}
Exemple #13
0
static int db_get_next_msg_number(struct mail_cache_db * maildb,
    uint32_t * p_num)
{
  int r;
  char key_value[PATH_MAX];
  uint32_t num;
  void * serialized;
  size_t serialized_len;
  int res;
  MMAPString * mmapstr;
  size_t cur_token;
  
  mmapstr = mmap_string_new("");
  if (mmapstr == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }
  
  snprintf(key_value, sizeof(key_value), "next-msg");
  
  r = mail_cache_db_get(maildb, key_value, strlen(key_value),
      &serialized, &serialized_len);
  
  if (r >= 0) {
    if (mmap_string_append_len(mmapstr, serialized, serialized_len) == NULL) {
      res = MAIL_ERROR_MEMORY;
      goto err;
    }
    
    cur_token = 0;
    r = mailimf_cache_int_read(mmapstr, &cur_token, &num);
    if (r < 0)
      num = 1;
  }
  else {
    num = 1;
  }
  
  mmap_string_set_size(mmapstr, 0);
  cur_token = 0;
  r = mailimf_cache_int_write(mmapstr, &cur_token, num + 1);
  if (r < 0) {
    res = MAIL_ERROR_MEMORY;
    goto free_mmapstr;
  }
  
  r = mail_cache_db_put(maildb, key_value, strlen(key_value),
      mmapstr->str, mmapstr->len);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto free_mmapstr;
  }
  
  mmap_string_free(mmapstr);
  
  * p_num = num;
  
  return MAIL_NO_ERROR;
  
 free_mmapstr:
  mmap_string_free(mmapstr);
 err:
  return res;
}
Exemple #14
0
int mailmbox_fetch_msg_headers(struct mailmbox_folder * folder,
			       uint32_t num, char ** result,
			       size_t * result_len)
{
  MMAPString * mmapstr;
  int res;
  char * data;
  size_t len;
  int r;
  size_t fixed_size;
  char * end;

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

  r = mailmbox_fetch_msg_headers_no_lock(folder, num, &data, &len);
  if (r != MAILMBOX_NO_ERROR) {
    res = r;
    goto unlock;
  }

#if 0
  mmapstr = mmap_string_new_len(data, len);
  if (mmapstr == NULL) {
    res = MAILMBOX_ERROR_MEMORY;
    goto unlock;
  }
#endif
  /* size with no uid */
  fixed_size = get_fixed_message_size(data, len, 0, 1 /* force no uid */);
  
  mmapstr = mmap_string_sized_new(fixed_size);
  if (mmapstr == NULL) {
    res = MAILMBOX_ERROR_MEMORY;
    goto unlock;
  }
  
  end = write_fixed_message(mmapstr->str, data, len, 0, 1 /* force no uid */);
  * end = '\0';
  mmapstr->len = fixed_size;

  r = mmap_string_ref(mmapstr);
  if (r < 0) {
    mmap_string_free(mmapstr);
    res = MAILMBOX_ERROR_MEMORY;
    goto unlock;
  }

  * result = mmapstr->str;
  * result_len = mmapstr->len;

  mailmbox_read_unlock(folder);

  return MAILMBOX_NO_ERROR;

 unlock:
  mailmbox_read_unlock(folder);
 err:
  return res;
}
Exemple #15
0
/* feed_update()
 * Takes initialized feed with url set, fetches the feed from this url,
 * updates rest of Feed struct members and returns HTTP response code
 * we got from url's server. */
int newsfeed_update(struct newsfeed * feed, time_t last_update)
{
#if (defined(HAVE_LIBCURL) && defined(HAVE_EXPAT))
  CURL * eh;
  CURLcode curl_res;
  struct newsfeed_parser_context * feed_ctx;
  unsigned int res;
  unsigned int timeout_value;
  long response_code;
  
  if (feed->feed_url == NULL) {
    res = NEWSFEED_ERROR_BADURL;
    goto err;
  }
  
  /* Init curl before anything else. */
  eh = curl_easy_init();
  if (eh == NULL) {
    res = NEWSFEED_ERROR_MEMORY;
    goto err;
  }
  
  /* Curl initialized, create parser context now. */
  feed_ctx = malloc(sizeof(* feed_ctx));
  if (feed_ctx == NULL) {
    res = NEWSFEED_ERROR_MEMORY;
    goto free_eh;
  }
  
  feed_ctx->parser = XML_ParserCreate(NULL);
  if (feed_ctx->parser == NULL) {
    res = NEWSFEED_ERROR_MEMORY;
    goto free_ctx;
  }
  feed_ctx->depth = 0;
  feed_ctx->str = mmap_string_sized_new(256);
  if (feed_ctx->str == NULL) {
    res = NEWSFEED_ERROR_MEMORY;
    goto free_praser;
  }
  feed_ctx->feed = feed;
  feed_ctx->location = 0;
  feed_ctx->curitem = NULL;
  feed_ctx->error = NEWSFEED_NO_ERROR;
  
  /* Set initial expat handlers, which will take care of choosing
   * correct parser later. */
  newsfeed_parser_set_expat_handlers(feed_ctx);
  
  if (feed->feed_timeout != 0)
    timeout_value = feed->feed_timeout;
  else
    timeout_value = mailstream_network_delay.tv_sec;
  
  curl_easy_setopt(eh, CURLOPT_URL, feed->feed_url);
  curl_easy_setopt(eh, CURLOPT_NOPROGRESS, 1);
#ifdef CURLOPT_MUTE
  curl_easy_setopt(eh, CURLOPT_MUTE, 1);
#endif
  curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, newsfeed_writefunc);
  curl_easy_setopt(eh, CURLOPT_WRITEDATA, feed_ctx);
  curl_easy_setopt(eh, CURLOPT_FOLLOWLOCATION, 1);
  curl_easy_setopt(eh, CURLOPT_MAXREDIRS, 3);
  curl_easy_setopt(eh, CURLOPT_TIMEOUT, timeout_value);
  curl_easy_setopt(eh, CURLOPT_NOSIGNAL, 1);
  curl_easy_setopt(eh, CURLOPT_USERAGENT, "libEtPan!");
  
  /* Use HTTP's If-Modified-Since feature, if application provided
   * the timestamp of last update. */
  if (last_update != -1) {
    curl_easy_setopt(eh, CURLOPT_TIMECONDITION,
        CURL_TIMECOND_IFMODSINCE);
    curl_easy_setopt(eh, CURLOPT_TIMEVALUE, last_update);
  }
        
#if LIBCURL_VERSION_NUM >= 0x070a00
  curl_easy_setopt(eh, CURLOPT_SSL_VERIFYPEER, 0);
  curl_easy_setopt(eh, CURLOPT_SSL_VERIFYHOST, 0);
#endif

  curl_res = curl_easy_perform(eh);
  if (curl_res != 0) {
    res = curl_error_convert(curl_res);
    goto free_str;
  }
  
  curl_easy_getinfo(eh, CURLINFO_RESPONSE_CODE, &response_code);
  
  curl_easy_cleanup(eh);
  
  if (feed_ctx->error != NEWSFEED_NO_ERROR) {
    res = feed_ctx->error;
    goto free_str;
  }
  
  /* Cleanup, we should be done. */
  mmap_string_free(feed_ctx->str);
  XML_ParserFree(feed_ctx->parser);
  free(feed_ctx);
  
  feed->feed_response_code = (int) response_code;
  
  return NEWSFEED_NO_ERROR;;
  
 free_str:
  mmap_string_free(feed_ctx->str);
 free_praser:
  XML_ParserFree(feed_ctx->parser);
 free_ctx:
  free(feed_ctx);
 free_eh:
  curl_easy_cleanup(eh);
 err:
  return res;
#else
  return NEWSFEED_ERROR_INTERNAL;
#endif
}
Exemple #16
0
LIBETPAN_EXPORT
int charconv_buffer(const char * tocode, const char * fromcode,
                    const char * str, size_t length,
                    char ** result, size_t * result_len)
{
#ifdef HAVE_ICONV
    iconv_t conv;
    size_t iconv_r;
    int r;
    char * out;
    char * pout;
    size_t out_size;
    size_t old_out_size;
    size_t count;
#endif
    int res;
    MMAPString * mmapstr;

    if (extended_charconv != NULL) {
        size_t		result_length;
        result_length = length * 6;
        mmapstr = mmap_string_sized_new( result_length + 1);
        *result_len = 0;
        if (mmapstr == NULL) {
            res = MAIL_CHARCONV_ERROR_MEMORY;
        } else {
            res = (*extended_charconv)( tocode, fromcode, str, length, mmapstr->str, &result_length);
            if (res != MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET) {
                if (res == MAIL_CHARCONV_NO_ERROR) {
                    *result = mmapstr->str;
                    res = mmap_string_ref(mmapstr);
                    if (res < 0) {
                        res = MAIL_CHARCONV_ERROR_MEMORY;
                        mmap_string_free(mmapstr);
                    } else {
                        mmap_string_set_size( mmapstr, result_length);	/* can't fail */
                        *result_len = result_length;
                    }
                }
                free( *result);
            }
            return res;
        }
        /* else, let's try with iconv, if available */
    }

#ifndef HAVE_ICONV
    return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
#else

    conv = iconv_open(tocode, fromcode);
    if (conv == (iconv_t) -1) {
        res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
        goto err;
    }

    out_size = 6 * length; /* UTF-8 can be encoded up to 6 bytes */

    mmapstr = mmap_string_sized_new(out_size + 1);
    if (mmapstr == NULL) {
        res = MAIL_CHARCONV_ERROR_MEMORY;
        goto err;
    }

    out = mmapstr->str;

    pout = out;
    old_out_size = out_size;

    iconv_r = mail_iconv(conv, &str, &length, &pout, &out_size, NULL, "?");

    if (iconv_r == (size_t) -1) {
        res = MAIL_CHARCONV_ERROR_CONV;
        goto free;
    }

    iconv_close(conv);

    * pout = '\0';

    count = old_out_size - out_size;

    r = mmap_string_ref(mmapstr);
    if (r < 0) {
        res = MAIL_CHARCONV_ERROR_MEMORY;
        goto free;
    }

    * result = out;
    * result_len = count;

    return MAIL_CHARCONV_NO_ERROR;

free:
    mmap_string_free(mmapstr);
err:
    return res;
#endif
}