#include "browser.h"
#ifdef USE_IMAP
#include "imap.h"
+#include "imap/mx_imap.h"
#endif
#ifdef USE_NNTP
#include "nntp.h"
case 'N':
#ifdef USE_IMAP
- if (mx_get_magic (folder->ff->desc) == M_IMAP) {
+ if (imap_is_magic (folder->ff->desc, NULL) == M_IMAP) {
if (!optional) {
snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
snprintf (dest, destlen, tmp, folder->ff->new);
for (i = 0; i < Incoming->length; i++) {
tmp = (BUFFY*) Incoming->data[i];
+ tmp->magic = mx_get_magic (tmp->path);
#ifdef USE_IMAP
- if (mx_get_magic (tmp->path) == M_IMAP) {
+ if (tmp->magic == M_IMAP) {
add_folder (menu, state, tmp->path, NULL, NULL, tmp->new);
continue;
}
#endif
#ifdef USE_POP
- if (mx_get_magic (tmp->path) == M_POP) {
+ if (tmp->magic == M_POP) {
add_folder (menu, state, tmp->path, NULL, NULL, tmp->new);
continue;
}
#endif
#ifdef USE_NNTP
- if (mx_get_magic (tmp->path) == M_NNTP) {
+ if (tmp->magic == M_NNTP) {
add_folder (menu, state, tmp->path, NULL, NULL, tmp->new);
continue;
}
if (*f) {
mutt_expand_path (f, flen);
#ifdef USE_IMAP
- if (mx_get_magic (f) == M_IMAP) {
+ if (imap_is_magic (f, NULL) == M_IMAP) {
init_state (&state, NULL);
state.imap_browse = 1;
imap_browse (f, &state);
strfcpy (LastDir, NONULL (Maildir), sizeof (LastDir));
#ifdef USE_IMAP
- if (!buffy && mx_get_magic (LastDir) == M_IMAP) {
+ if (!buffy && imap_is_magic (LastDir, NULL) == M_IMAP) {
init_state (&state, NULL);
state.imap_browse = 1;
imap_browse (LastDir, &state);
buffy = 0;
mutt_expand_path (buf, sizeof (buf));
#ifdef USE_IMAP
- if (mx_get_magic (buf) == M_IMAP) {
+ if (imap_is_magic (buf, NULL) == M_IMAP) {
strfcpy (LastDir, buf, sizeof (LastDir));
destroy_state (&state);
init_state (&state, NULL);
goto bail;
}
#ifdef USE_IMAP
- else if (mx_get_magic (LastDir) == M_IMAP) {
+ else if (imap_is_magic (LastDir, NULL) == M_IMAP) {
init_state (&state, NULL);
state.imap_browse = 1;
imap_browse (LastDir, &state);
struct stat contex_sb;
time_t now, last1;
CONTEXT *ctx;
- int i = 0;
+ int i = 0, local = 0;
#ifdef USE_IMAP
time_t last2;
BuffyCount = 0;
BuffyNotify = 0;
-#ifdef USE_IMAP
- if (!Context || Context->magic != M_IMAP)
-#endif
-#ifdef USE_POP
- if (!Context || Context->magic != M_POP)
-#endif
-#ifdef USE_NNTP
- if (!Context || Context->magic != M_NNTP)
-#endif
- /* check device ID and serial number instead of comparing paths */
- if (!Context || !Context->path
- || stat (Context->path, &contex_sb) != 0) {
- contex_sb.st_dev = 0;
- contex_sb.st_ino = 0;
- }
+ if ((!Context || mx_is_local (Context->magic-1)) && stat (Context->path, &contex_sb) != 0) {
+ /* check device ID and serial number instead of comparing paths */
+ contex_sb.st_dev = 0;
+ contex_sb.st_ino = 0;
+ }
for (i = 0; i < Incoming->length; i++) {
tmp = (BUFFY*) Incoming->data[i];
-#ifdef USE_IMAP
- if (mx_get_magic (tmp->path) == M_IMAP)
- tmp->magic = M_IMAP;
- else
-#endif
-#ifdef USE_POP
- if (mx_get_magic (tmp->path) == M_IMAP)
- tmp->magic = M_POP;
- else
-#endif
-#ifdef USE_NNTP
- if (mx_get_magic (tmp->path) == M_NNTP)
- tmp->magic = M_NNTP;
- else
-#endif
- if (stat (tmp->path, &sb) != 0 || sb.st_size == 0 ||
- (!tmp->magic && (tmp->magic = mx_get_magic (tmp->path)) <= 0)) {
+ tmp->magic = mx_get_magic (tmp->path);
+ local = mx_is_local (tmp->magic-1);
+ if ((tmp->magic <= 0 || local) && (stat (tmp->path, &sb) != 0 || sb.st_size == 0)) {
/* if the mailbox still doesn't exist, set the newly created flag to
* be ready for when it does. */
tmp->newly_created = 1;
- tmp->magic = 0;
+ tmp->magic = -1;
#ifdef BUFFY_SIZE
tmp->size = 0;
#endif
/* check to see if the folder is the currently selected folder
* before polling */
- if (!Context || !Context->path || ((0
-#ifdef USE_IMAP
- || tmp->magic == M_IMAP
-#endif
-#ifdef USE_POP
- || tmp->magic == M_POP
-#endif
-#ifdef USE_NNTP
- || tmp->magic == M_NNTP
-#endif
- )? safe_strcmp (tmp->path,
- Context->path) : (sb.
- st_dev
- !=
- contex_sb.
- st_dev
- ||
- sb.
- st_ino
- !=
- contex_sb.
- st_ino)
- )
- ) {
+ if (!Context || !Context->path || (local ? (sb.st_dev != contex_sb.st_dev ||
+ sb.st_ino != contex_sb.st_ino) :
+ safe_strcmp (tmp->path, Context->path))) {
switch (tmp->magic) {
case M_MBOX:
case M_MMDF:
break;
#endif
-#ifdef USE_POP
- case M_POP:
- break;
-#endif
-
-#ifdef USE_NNTP
- case M_NNTP:
- break;
-#endif
}
}
#ifdef BUFFY_SIZE
#include "config.h"
#endif
+#include <sys/stat.h>
+
#include "mutt.h"
#include "imap_private.h"
#include "url.h"
-static int imap_is_magic (const char* path) {
+int imap_is_magic (const char* path, struct stat* st) {
url_scheme_t s;
if (!path || !*path)
return (-1);
#ifndef _IMAP_MX_H
#define _IMAP_MX_H
+#include <sys/stat.h>
+
#include "mx.h"
+int imap_is_magic (const char*, struct stat*);
mx_t* imap_reg_mx (void);
#endif /* !_IMAP_MX_H */
return ((st.st_size == 0));
}
-int mbox_is_magic (const char* path) {
- struct stat st;
- int magic = 0;
+int mbox_is_magic (const char* path, struct stat* st) {
+ int magic = -1;
FILE* f;
char tmp[_POSIX_PATH_MAX];
- if (stat (path, &st) == -1 || S_ISDIR(st.st_mode))
+ if (S_ISDIR(st->st_mode))
return (-1);
- if (st.st_size == 0) {
+ if (st->st_size == 0) {
/* hard to tell what zero-length files are, so assume the default magic */
if (DefaultMagic == M_MBOX || DefaultMagic == M_MMDF)
return (DefaultMagic);
* only the type was accessed. This is important, because detection
* of "new mail" depends on those times set correctly.
*/
- times.actime = st.st_atime;
- times.modtime = st.st_mtime;
+ times.actime = st->st_atime;
+ times.modtime = st->st_mtime;
utime (path, ×);
#endif
} else {
}
#ifdef USE_COMPRESSED
- if (magic == 0 && mutt_can_read_compressed (path))
+ if (magic == -1 && mutt_can_read_compressed (path))
return (M_COMPRESSED);
#endif
return (magic);
#ifndef _MBOX_H
#define _MBOX_H
+#include <sys/stat.h>
+
#include "mx.h"
#define MMDF_SEP "\001\001\001\001\n"
int mmdf_parse_mailbox (CONTEXT *);
void mbox_unlock_mailbox (CONTEXT *);
int mbox_check_empty (const char *);
-int mbox_is_magic (const char*);
+/* this is still here for compressed folders support... */
+int mbox_is_magic (const char*, struct stat*);
int mbox_strict_cmp_headers (const HEADER *, const HEADER *);
int mbox_reopen_mailbox (CONTEXT *, int *);
return r;
}
-int mh_is_magic (const char* path) {
- struct stat st;
+static int mh_is_magic (const char* path, struct stat* st) {
char tmp[_POSIX_PATH_MAX];
- if (stat (path, &st) == -1)
- return (-1);
-
- if (S_ISDIR (st.st_mode)) {
+ if (S_ISDIR (st->st_mode)) {
snprintf (tmp, sizeof (tmp), "%s/.mh_sequences", path);
if (access (tmp, F_OK) == 0)
return (M_MH);
return (-1);
}
-int maildir_is_magic (const char* path) {
- struct stat st;
+static int maildir_is_magic (const char* path, struct stat* st) {
+ struct stat sb;
char tmp[_POSIX_PATH_MAX];
- if (stat (path, &st) == -1)
- return (-1);
- if (S_ISDIR (st.st_mode)) {
+ if (S_ISDIR (st->st_mode)) {
snprintf (tmp, sizeof (tmp), "%s/cur", path);
- if (stat (tmp, &st) == 0 && S_ISDIR (st.st_mode))
+ if (stat (tmp, &sb) == 0 && S_ISDIR (sb.st_mode))
return (M_MAILDIR);
}
return (-1);
#ifndef _MH_H
#define _MH_H
+#include <sys/stat.h>
+
#include "mx.h"
int mh_read_dir (CONTEXT *);
int mh_check_empty (const char *);
int mh_commit_message (CONTEXT *, MESSAGE *, HEADER *);
int mh_open_new_message (MESSAGE *, CONTEXT *, HEADER *);
-int mh_is_magic (const char*);
int maildir_read_dir (CONTEXT *);
int maildir_check_mailbox (CONTEXT *, int *);
int maildir_commit_message (CONTEXT *, MESSAGE *, HEADER *);
int maildir_open_new_message (MESSAGE *, CONTEXT *, HEADER *);
FILE *maildir_open_find_message (const char *, const char *);
-int maildir_is_magic (const char*);
mx_t* maildir_reg_mx (void);
mx_t* mh_reg_mx (void);
#ifdef USE_IMAP
#include "imap.h"
+#include "imap/mx_imap.h"
#endif
#include "mutt_crypt.h"
{
#ifdef USE_IMAP
/* if folder = {host} or imap[s]://host/: don't append slash */
- if (mx_get_magic (NONULL (Maildir)) == M_IMAP &&
+ if (imap_is_magic (NONULL (Maildir), NULL) == M_IMAP &&
(Maildir[safe_strlen (Maildir) - 1] == '}' ||
Maildir[safe_strlen (Maildir) - 1] == '/'))
strfcpy (p, NONULL (Maildir), sizeof (p));
#ifdef USE_IMAP
/* Rewrite IMAP path in canonical form - aids in string comparisons of
* folders. May possibly fail, in which case s should be the same. */
- if (mx_get_magic (s) == M_IMAP)
+ if (imap_is_magic (s, NULL) == M_IMAP)
imap_expand_path (s, slen);
#endif
static list2_t* MailboxFormats = NULL;
#define MX_COMMAND(idx,cmd) ((mx_t*) MailboxFormats->data[idx])->cmd
+#define MX_IDX(idx) (idx >= 0 && idx < MailboxFormats->length)
#define mutt_is_spool(s) (safe_strcmp (Spoolfile, s) == 0)
/* looks up index of type for path in MailboxFormats */
static int mx_get_idx (const char* path) {
int i = 0, t = 0;
+ struct stat st;
+ /* first, test all non-local folders to avoid stat() call */
for (i = 0; i < MailboxFormats->length; i++) {
- t = MX_COMMAND(i,mx_is_magic)(path);
+ if (!MX_COMMAND(i,local))
+ t = MX_COMMAND(i,mx_is_magic)(path, NULL);
if (t >= 1)
- return (t-1); /* use type as index for array */
+ return (t-1);
+ }
+ if (stat (path, &st) == 0) {
+ /* if stat() succeeded, keep testing until success and
+ * pass stat() info so that we only need to do it once */
+ for (i = 0; i < MailboxFormats->length; i++) {
+ if (MX_COMMAND(i,local))
+ t = MX_COMMAND(i,mx_is_magic)(path, &st);
+ if (t >= 1)
+ return (t-1);
+ }
}
return (-1);
}
return (-1);
}
+int mx_is_local (int m) {
+ if (!MX_IDX(m))
+ return (0);
+ return (MX_COMMAND(m,local));
+}
+
/*
* set DefaultMagic to the given value
*/
return ctx;
}
- ctx->magic = mx_get_magic (path);
+ if (!MX_IDX(ctx->magic-1))
+ ctx->magic = mx_get_magic (path);
#ifdef USE_COMPRESSED
if (ctx->magic == M_COMPRESSED)
/* try to use server-side copy first */
i = 1;
- if (ctx->magic == M_IMAP && mx_get_magic (mbox) == M_IMAP) {
+ if (ctx->magic == M_IMAP && imap_is_magic (mbox, NULL) == M_IMAP) {
/* tag messages for moving, and clear old tags, if any */
for (i = 0; i < ctx->msgcount; i++)
if (ctx->hdrs[i]->read && !ctx->hdrs[i]->deleted
}
int mx_acl_check (CONTEXT* ctx, int flag) {
- if (!ctx || ctx->magic <= 0 || ctx->magic > MailboxFormats->length)
+ if (!ctx || !MX_IDX(ctx->magic-1))
return (0);
/* if no acl_check defined for module, assume permission is granted */
if (!MX_COMMAND(ctx->magic-1,mx_acl_check))
#ifndef _MX_H
#define _MX_H
+#include <sys/stat.h>
+
/*
* supported mailbox formats
* in mx_init() the registration order must be exactly as given here!!!1!
/* may we stat() it? */
unsigned int local : 1;
/* tests if given path is of its magic */
- int (*mx_is_magic) (const char*);
+ int (*mx_is_magic) (const char*, struct stat*);
/* tests if folder is empty */
int (*mx_check_empty) (const char*);
/* test for access */
int mx_sync_mailbox (CONTEXT *, int *);
int mx_commit_message (MESSAGE *, CONTEXT *);
int mx_close_message (MESSAGE **);
-int mx_get_magic (const char *);
+
+/* determines magic for given folder */
+int mx_get_magic (const char*);
+/* sets/parses DefaultMagic */
int mx_set_magic (const char *);
+/* tests whether given folder magic is (valid and) local */
+int mx_is_local (int);
+
int mx_check_mailbox (CONTEXT *, int *, int);
int mx_access (const char *, int);
#include "config.h"
#endif
+#include <sys/stat.h>
+
#include "mutt.h"
#include "nntp.h"
#include "url.h"
-static int nntp_is_magic (const char* path) {
+static int nntp_is_magic (const char* path, struct stat* st) {
url_scheme_t s = url_check_scheme (NONULL (path));
return ((s == U_NNTP || s == U_NNTPS) ? M_NNTP : -1);
}
#include "config.h"
#endif
+#include <sys/stat.h>
+
#include "mutt.h"
#include "pop.h"
#include "url.h"
-static int pop_is_magic (const char* path) {
+static int pop_is_magic (const char* path, struct stat* st) {
url_scheme_t s = url_check_scheme (NONULL (path));
return ((s == U_POP || s == U_POPS) ? M_POP : -1);
}
#include "mx.h"
#ifdef USE_IMAP
#include "imap.h"
+#include "imap/mx_imap.h"
#endif
#include "mutt_crypt.h"
#ifdef USE_IMAP
/* LastModify is useless for IMAP */
- if (mx_get_magic (Postponed) == M_IMAP) {
+ if (imap_is_magic (Postponed, NULL) == M_IMAP) {
if (force) {
short newpc;