static int expunge_folder(mailsession * session)
{
  unsigned int i;
  int r;
  int res;
  struct maildir * md;

  check_folder(session);

  md = get_maildir_session(session);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;

  r = maildir_update(md);
  if (r != MAILDIR_NO_ERROR) {
    res = maildirdriver_maildir_error_to_mail_error(r);
    goto err;
  }

  for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i++) {
    struct maildir_msg * md_msg;

    md_msg = carray_get(md->mdir_msg_list, i);

    if ((md_msg->msg_flags & MAILDIR_FLAG_TRASHED) != 0)
      maildir_message_remove(md, md_msg->msg_uid);
  }

  return MAIL_NO_ERROR;

 err:
  return res;
}
static int get_messages_list(mailsession * session,
    struct mailmessage_list ** result)
{
  struct maildir * md;
  int r;
  struct mailmessage_list * env_list;
  int res;

  md = get_maildir_session(session);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;

  r = maildir_update(md);
  if (r != MAILDIR_NO_ERROR) {
    res = maildirdriver_maildir_error_to_mail_error(r);
    goto err;
  }

  r = maildir_get_messages_list(session, md,
      maildir_message_driver, &env_list);
  if (r != MAILDIR_NO_ERROR) {
    res = r;
    goto free_list;
  }

  * result = env_list;

  return MAIL_NO_ERROR;

 free_list:
  mailmessage_list_free(env_list);
 err:
  return res;
}
static int connect_path(mailsession * session, const char * path)
{
  struct maildir * md;
  int res;
  int r;

  if (get_maildir_session(session) != NULL) {
    res = MAIL_ERROR_BAD_STATE;
    goto err;
  }

  md = maildir_new(path);
  if (md == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }

  r = maildir_update(md);
  if (r != MAILDIR_NO_ERROR) {
    res = maildirdriver_maildir_error_to_mail_error(r);
    goto free;
  }

  get_data(session)->md_session = md;

  return MAIL_NO_ERROR;

 free:
  maildir_free(md);
 err:
  return res;
}
static int prefetch(mailmessage * msg_info)
{
  struct generic_message_t * msg;
  int res;
  struct maildir_msg_data * data;
  char * filename;
  int fd;
  char * mapping;
  struct maildir * md;
  
  md = get_maildir_session(msg_info);
  
  if (msg_info->msg_uid == NULL) {
    res = MAIL_ERROR_INVAL;
    goto err;
  }
  
  filename = maildir_message_get(md, msg_info->msg_uid);
  if (filename == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }
  
  fd = open(filename, O_RDONLY);
  free(filename);
  if (fd == -1) {
    res = MAIL_ERROR_FILE;
    goto err;
  }
  
  mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (mapping == (char *)MAP_FAILED) {
    res = MAIL_ERROR_FILE;
    goto close;
  }
  
  data = malloc(sizeof(* data));
  if (data == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto unmap;
  }
  
  data->fd = fd;
  
  msg = msg_info->msg_data;
  
  msg->msg_data = data;
  msg->msg_message = mapping;
  msg->msg_length = msg_info->msg_size;
  
  return MAIL_NO_ERROR;
  
 unmap:
  munmap(mapping, msg_info->msg_size);
 close:
  close(fd);
 err:
  return res;
}
static int get_flags(mailmessage * msg_info,
    struct mail_flags ** result)
{
  chashdatum key;
  chashdatum value;
  struct maildir * md;
  struct mail_flags * flags;
  struct maildir_session_state_data * data;
  struct maildir_msg * md_msg;
  int r;
  uint32_t driver_flags;
  clist * ext;
  
  if (msg_info->msg_flags != NULL) {
    * result = msg_info->msg_flags;
    return MAIL_NO_ERROR;
  }
  
  data = get_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;
  }
  
  md = get_maildir_session(msg_info);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;
  
  key.data = msg_info->msg_uid;
  key.len = 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);
  
  ext = clist_new();
  if (ext == NULL)
    return MAIL_ERROR_MEMORY;
  
  msg_info->msg_flags = mail_flags_new(driver_flags, ext);
  
  * result = msg_info->msg_flags;
  
  return MAIL_NO_ERROR;
}
static int check_folder(mailsession * session)
{
  struct mail_flags_store * flags_store;
  struct maildir_session_state_data * data;
  struct maildir * md;

  md = get_maildir_session(session);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;

  data = get_data(session);
  flags_store = data->md_flags_store;

  return flags_store_process(md, flags_store);
}
static int logout(mailsession * session)
{
  struct maildir * md;

  check_folder(session);

  md = get_maildir_session(session);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;

  maildir_free(md);
  get_data(session)->md_session = NULL;

  return MAIL_NO_ERROR;
}
Exemple #8
0
static int messages_number(mailsession * session, const char * mb,
    uint32_t * result)
{
  struct maildir * md;
  int r;

  md = get_maildir_session(session);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;
  
  r = maildir_update(md);
  if (r != MAILDIR_NO_ERROR)
    return maildirdriver_maildir_error_to_mail_error(r);
  
  * result = carray_count(md->mdir_msg_list);
  
  return MAIL_NO_ERROR;
}
static int status_folder(mailsession * session, const char * mb,
    uint32_t * result_messages, uint32_t * result_recent,
    uint32_t * result_unseen)
{
  int r;
  struct maildir * md;
  unsigned int i;
  uint32_t messages;
  uint32_t recent;
  uint32_t unseen;
  UNUSED(mb);

  check_folder(session);

  md = get_maildir_session(session);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;

  r = maildir_update(md);
  if (r != MAILDIR_NO_ERROR)
    return maildirdriver_maildir_error_to_mail_error(r);

  messages = 0;
  recent = 0;
  unseen = 0;
  for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i ++) {
    struct maildir_msg * msg;

    msg = carray_get(md->mdir_msg_list, i);
    if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
      recent ++;
    if ((msg->msg_flags & MAILDIR_FLAG_SEEN) == 0)
      unseen ++;
    messages ++;
  }

  * result_messages = messages;
  * result_recent = recent;
  * result_unseen = unseen;

  return MAIL_NO_ERROR;
}
Exemple #10
0
static int append_message_flags(mailsession * session,
    const char * message, size_t size, struct mail_flags * flags)
{
  struct maildir * md;
  int r;
  char uid[PATH_MAX];
  struct maildir_msg * md_msg;
  chashdatum key;
  chashdatum value;
  uint32_t md_flags;
  
  md = get_maildir_session(session);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;
  
  r = maildir_message_add_uid(md, message, size,
      uid, sizeof(uid));
  if (r != MAILDIR_NO_ERROR)
    return maildirdriver_maildir_error_to_mail_error(r);
  
  if (flags == NULL)
    goto exit;
  
  key.data = uid;
  key.len = strlen(uid);
  r = chash_get(md->mdir_msg_hash, &key, &value);
  if (r < 0)
    goto exit;
  
  md_msg = value.data;
  
  md_flags = maildirdriver_flags_to_maildir_flags(flags->fl_flags);
  
  r = maildir_message_change_flags(md, uid, md_flags);
  if (r != MAILDIR_NO_ERROR)
    goto exit;
  
  return MAIL_NO_ERROR;
  
 exit:
  return MAIL_NO_ERROR;
}
static int append_message(mailsession * session,
    const char * message, size_t size)
{
#if 0
  struct maildir * md;
  int r;

  md = get_maildir_session(session);
  if (md == NULL)
    return MAIL_ERROR_BAD_STATE;

  r = maildir_message_add(md, message, size);
  if (r != MAILDIR_NO_ERROR)
    return maildirdriver_maildir_error_to_mail_error(r);

  return MAIL_NO_ERROR;
#endif

  return append_message_flags(session, message, size, NULL);
}
static int get_message_by_uid(mailsession * session,
    const char * uid, mailmessage ** result)
{
  int r;
  struct maildir * md;
  int res;
  mailmessage * msg;
  char * msg_filename;
  struct stat stat_info;

  md = get_maildir_session(session);

  /* update maildir data */

  r = maildir_update(md);
  if (r != MAILDIR_NO_ERROR) {
    res = maildirdriver_maildir_error_to_mail_error(r);
    goto err;
  }

  msg_filename = maildir_message_get(md, uid);
  if (msg_filename == NULL) {
    res = MAIL_ERROR_INVAL;
    goto err;
  }

  r = stat(msg_filename, &stat_info);
  free(msg_filename);
  if (r < 0) {
    res = MAIL_ERROR_INVAL;
    goto err;
  }

  /* create message */

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

  r = mailmessage_init(msg, session, maildir_message_driver,
      0, stat_info.st_size);
  if (r != MAIL_NO_ERROR) {
    mailmessage_free(msg);
    res = r;
    goto err;
  }

  msg->msg_uid = strdup(uid);
  if (msg->msg_uid == NULL) {
    mailmessage_free(msg);
    res = r;
    goto err;
  }

  * result = msg;

  return MAIL_NO_ERROR;

 err:
  return res;
}
static int get_envelopes_list(mailsession * session,
    struct mailmessage_list * env_list)
{
  int r;
  struct maildir * md;
  unsigned int i;
  int res;

  check_folder(session);

  md = get_maildir_session(session);
  if (md == NULL) {
    res = MAIL_ERROR_BAD_STATE;
    goto err;
  }

  r = maildir_update(md);
  if (r != MAILDIR_NO_ERROR) {
    res = maildirdriver_maildir_error_to_mail_error(r);
    goto err;
  }

  r = maildriver_generic_get_envelopes_list(session, env_list);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto err;
  }

  for(i = 0 ; i < carray_count(env_list->msg_tab) ; i++) {
    struct maildir_msg * md_msg;
    mailmessage * msg;
    uint32_t driver_flags;
    clist * ext;
    chashdatum key;
    chashdatum value;

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

    key.data = msg->msg_uid;
    key.len = strlen(msg->msg_uid);
    r = chash_get(md->mdir_msg_hash, &key, &value);
    if (r < 0)
      continue;

    md_msg = value.data;

    driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags);

    if (msg->msg_flags == NULL) {
      ext = clist_new();
      if (ext == NULL) {
        res = MAIL_ERROR_MEMORY;
        continue;
      }

      msg->msg_flags = mail_flags_new(driver_flags, ext);
      if (msg->msg_flags == NULL) {
        clist_free(ext);
        res = MAIL_ERROR_MEMORY;
        continue;
      }

      if ((md_msg->msg_flags & MAILDIR_FLAG_NEW) != 0) {
        mail_flags_store_set(get_data(session)->md_flags_store, msg);
      }
    }
    else {
      msg->msg_flags->fl_flags &= MAIL_FLAG_FORWARDED;
      msg->msg_flags->fl_flags |= driver_flags;
    }
  }

  return MAIL_NO_ERROR;

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