mbox-list.c revision defb12ecd360df672ffb2f4dbf4d1218a0a9549c
/* Copyright (C) 2002-2003 Timo Sirainen */
#include "lib.h"
#include "unlink-directory.h"
#include "imap-match.h"
#include "subscription-file/subscription-file.h"
#include "mbox-storage.h"
#include "home-expand.h"
#include <dirent.h>
/* Assume that if atime < mtime, there are new mails. If it's good enough for
UW-IMAP, it's good enough for us. */
#define STAT_GET_MARKED(st) \
struct list_dir_context {
struct list_dir_context *prev;
char *real_path, *virtual_path;
};
struct mbox_list_context {
struct mailbox_list_context mailbox_ctx;
struct index_storage *istorage;
enum mailbox_list_flags flags;
struct imap_match_glob *glob;
struct subsfile_list_context *subsfile_ctx;
bool inbox_found;
struct mailbox_list list;
struct list_dir_context *dir;
};
static const char *mask_get_dir(const char *mask)
{
const char *p, *last_dir;
if (*p == '/')
last_dir = p;
}
}
static const char *
{
else
return home_expand(name);
}
{
return 1;
/* root) user gave invalid hiearchy, ignore
sub) probably just race condition with other client
deleting the mailbox. */
return 0;
}
if (!root) {
/* subfolder, ignore */
return 0;
}
return -1;
}
return -1;
}
struct mailbox_list_context *
enum mailbox_list_flags flags)
{
struct mbox_list_context *ctx;
const char *path, *virtual_path;
/* check that we're not trying to do any "../../" lists */
return &ctx->mailbox_ctx;
}
/* mask overrides reference */
} else if (*ref != '\0') {
/* merge reference and mask */
else
}
if ((flags & MAILBOX_LIST_SUBSCRIBED) != 0) {
ctx->subsfile_ctx =
return &ctx->mailbox_ctx;
}
return &ctx->mailbox_ctx;
}
/* if we're matching only subdirectories, don't bother scanning the
parent directories */
return &ctx->mailbox_ctx;
/* if user gave invalid directory, we just don't show any results. */
}
return &ctx->mailbox_ctx;
}
{
}
{
ret = -1;
}
}
return ret;
}
{
}
{
struct list_dir_context *dir;
int ret;
bool noselect;
/* skip all hidden files */
if (fname[0] == '.')
return 0;
/* skip all .lock files */
return 0;
/* check the mask */
else {
}
return 0;
/* see if it's a directory */
else {
return 0;
"stat(%s) failed: %m", real_path);
return -1;
}
/* make sure we give only one correct INBOX */
if (ctx->inbox_found ||
return 0;
}
/* subdirectory. scan inside it. */
if (match > 0)
else if (match2 > 0)
else
if (ret > 0) {
} else if (ret < 0)
return -1;
} else if (match > 0) {
return 1;
}
return 0;
}
{
break;
}
return NULL;
if (match == IMAP_MATCH_PARENT) {
/* placeholder */
}
}
i_unreached();
}
t_push();
else {
}
} else {
}
t_pop();
}
{
else
}
{
else {
return NULL;
}
}
{
struct list_dir_context *dir;
struct dirent *d;
int ret;
/* NOTE: list_file() may change ctx->dir */
t_push();
t_pop();
if (ret > 0)
if (ret < 0) {
return NULL;
}
}
}
/* show inbox */
return mbox_list_inbox(ctx);
}
/* finished */
return NULL;
}