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; }
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; } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/* 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 }
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 }