Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-storage/index/maildir/maildir-list.c @ 10:82b7de533f98 HEAD
s/user_data/context/ and some s/Data/Context/
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 22 Aug 2002 15:48:38 +0300 |
parents | 3b1985cbc908 |
children | edc37d046b08 |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "unlink-directory.h" #include "imap-match.h" #include "subscription-file/subscription-file.h" #include "maildir-index.h" #include "maildir-storage.h" #include <dirent.h> #include <sys/stat.h> typedef struct { MailboxFunc func; void *context; } FindSubscribedContext; static MailboxFlags maildir_get_marked_flags(const char *dir) { struct stat st; char path[1024]; time_t index_stamp, cur_stamp; i_snprintf(path, sizeof(path), "%s/" INDEX_FILE_PREFIX, dir); if (stat(path, &st) == -1) { /* index file wasn't found. it might be with another name, but finding it would be too slow. */ return 0; } index_stamp = st.st_mtime; i_snprintf(path, sizeof(path), "%s/cur", dir); if (stat(path, &st) == -1) { /* no cur/ directory - broken */ return 0; } cur_stamp = st.st_mtime; if (cur_stamp != index_stamp) { /* changes in cur directory */ return MAILBOX_MARKED; } i_snprintf(path, sizeof(path), "%s/new", dir); if (stat(path, &st) == -1) { /* no new/ directory - broken */ return 0; } return st.st_mtime <= cur_stamp ? MAILBOX_UNMARKED : MAILBOX_MARKED; } int maildir_find_mailboxes(MailStorage *storage, const char *mask, MailboxFunc func, void *context) { const ImapMatchGlob *glob; DIR *dirp; struct dirent *d; struct stat st; MailboxFlags flags; char path[1024]; int failed, found_inbox; mail_storage_clear_error(storage); dirp = opendir(storage->dir); if (dirp == NULL) { mail_storage_set_critical(storage, "opendir(%s) failed: %m", storage->dir); return FALSE; } glob = imap_match_init(mask, TRUE, '.'); failed = found_inbox = FALSE; while ((d = readdir(dirp)) != NULL) { const char *fname = d->d_name; if (fname[0] != '.') continue; /* skip . and .. */ if (fname[1] == '\0' || (fname[1] == '.' && fname[2] == '\0')) continue; /* make sure the mask matches - dirs beginning with ".." should be deleted and we always want to check those. */ if (fname[1] == '.' || imap_match(glob, fname+1, 0, NULL) < 0) continue; /* make sure it's a directory */ i_snprintf(path, sizeof(path), "%s/%s", storage->dir, fname); if (stat(path, &st) != 0) { if (errno == ENOENT) continue; /* just deleted, ignore */ mail_storage_set_critical(storage, "stat(%s) failed: %m", path); failed = TRUE; break; } if (!S_ISDIR(st.st_mode)) continue; if (fname[1] == '.') { /* this mailbox is in the middle of being deleted, or the process trying to delete it had died. delete it ourself if it's been there longer than one hour */ if (st.st_mtime < 3600) (void)unlink_directory(path); continue; } flags = maildir_get_marked_flags(path); func(storage, fname+1, flags, context); } if (!failed && !found_inbox && imap_match(glob, "INBOX", 0, NULL) >= 0) { /* .INBOX directory doesn't exist yet, but INBOX still exists */ func(storage, "INBOX", 0, context); } (void)closedir(dirp); return !failed; } static int maildir_subs_func(MailStorage *storage, const char *name, void *context) { FindSubscribedContext *ctx = context; MailboxFlags flags; struct stat st; char path[1024]; i_snprintf(path, sizeof(path), "%s/.%s", storage->dir, name); if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) flags = maildir_get_marked_flags(path); else flags = MAILBOX_NOSELECT; ctx->func(storage, name, flags, ctx->context); return TRUE; } int maildir_find_subscribed(MailStorage *storage, const char *mask, MailboxFunc func, void *context) { FindSubscribedContext ctx; ctx.func = func; ctx.context = context; if (subsfile_foreach(storage, mask, maildir_subs_func, &ctx) <= 0) return FALSE; return TRUE; }