bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen/* Assume that if atime < mtime, there are new mails. If it's good enough for
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen UW-IMAP, it's good enough for us. */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen (st).st_atime < (st).st_mtime ? MAILBOX_MARKED : MAILBOX_UNMARKED)
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainenlist_is_maildir_mailbox(struct mailbox_list *list, const char *dir,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen const char *fname, enum mailbox_list_file_type type,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* non-directories aren't valid */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen *flags_r |= MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* non-selectable. probably either access denied, or
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen symlink destination not found. don't bother logging
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* temporary NFS file */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen *flags_r |= MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* ok, we've got a directory. see what we can do about it. */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* 1st link is "."
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen 2nd link is ".."
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen 3rd link is either child mailbox or mailbox dir
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen rest of the links are child mailboxes
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen if mailboxes are files, then 3+ links are all child mailboxes.
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen mailbox_files = (list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* we have at least one directory. see if this mailbox is selectable */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen maildir_path = t_strconcat(path, "/", list->set.maildir_name, NULL);
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen *flags_r |= MAILBOX_NOSELECT | MAILBOX_CHILDREN;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen *flags_r |= MAILBOX_NOSELECT | MAILBOX_CHILDREN;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* now we know what link count 3 means. */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainenis_inbox_file(struct mailbox_list *list, const char *path, const char *fname)
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainenint fs_list_get_mailbox_flags(struct mailbox_list *list,
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen if (*list->set.maildir_name != '\0' && !list->set.iter_from_index_dir) {
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen /* maildir_name is set: This is the simple case that works for
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen all mail storage formats, because the only thing that
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen matters for existence or child checks is whether the
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen maildir_name exists or not. For example with Maildir this
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen doesn't care whether the "cur" directory exists; as long
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen as the parent maildir_name exists, the Maildir is
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen selectable. */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen return list_is_maildir_mailbox(list, dir, fname, type, flags_r);
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen /* maildir_name is not set: Now we (may) need to use storage-specific
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen code to determine whether the mailbox is selectable or if it has
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen We're here also when iterating from index directory, because even
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen though maildir_name is set, it's not used for index directory.
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen /* skip internal dirs. For example Maildir's cur/new/tmp */
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen /* We know that we're looking at a directory. If the storage
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen uses files, it has to be a \NoSelect directory. */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen if ((list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) {
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen /* We know that we're looking at a file. If the storage
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen doesn't use files, it's not a mailbox and we want to skip
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen if ((list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) == 0) {
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen *flags_r |= MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* we've done all filtering we can before stat()ing */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* non-selectable. probably either access denied, or
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen symlink destination not found. don't bother logging
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen mailbox_list_set_critical(list, "stat(%s) failed: %m",
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* temporary NFS file */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen if ((list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) == 0) {
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen *flags_r |= MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* looks like a valid mailbox file */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* it's possible for INBOX to have child
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen mailboxes as long as the inbox file itself
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen isn't in <mail root>/INBOX */
9934242994745cb810b290e3127f6a75d89d2177Timo Sirainen /* Return mailbox files as always existing. The current
9934242994745cb810b290e3127f6a75d89d2177Timo Sirainen mailbox_exists() code would do the same stat() anyway
9934242994745cb810b290e3127f6a75d89d2177Timo Sirainen without further checks, so might as well avoid the second
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen /* This is a directory */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen if ((list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) {
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen /* We should get here only if type is
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen MAILBOX_LIST_FILE_TYPE_UNKNOWN because the filesystem didn't
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen return the type. Normally this should have already been
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen handled by the MAILBOX_LIST_FILE_TYPE_DIR check above. */
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen if (list->v.is_internal_name == NULL || list->set.iter_from_index_dir) {
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen /* This mailbox format doesn't use any special directories
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen (e.g. Maildir's cur/new/tmp). In that case we can look at
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen the directory's link count to determine whether there are
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen children or not. The directory's link count equals the
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen number of subdirectories it has. The first two links are
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen for "." and "..".
cea31bf9e588436588e06625c741c0a87de673f1Timo Sirainen link count < 2 can happen with filesystems that don't
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen support link counts. we'll just ignore them for now.. */