From b2a6a9673e124c222f921650a6f0025b64ab2145 Mon Sep 17 00:00:00 2001 From: pdmef Date: Thu, 14 Apr 2005 17:08:57 +0000 Subject: [PATCH] Rocco Rutte: - (try to) fix startup speed (report and lots of help by Elimar Riesebieter) - some cleanup git-svn-id: svn://svn.berlios.de/mutt-ng/trunk@264 e385b8ad-14ed-0310-8656-cc95a2468c6d --- browser.c | 18 +++++++----- buffy.c | 80 ++++++++------------------------------------------ imap/mx_imap.c | 4 ++- imap/mx_imap.h | 3 ++ mbox.c | 15 +++++----- mbox.h | 5 +++- mh.c | 18 ++++-------- mh.h | 4 +-- muttlib.c | 5 ++-- mx.c | 31 +++++++++++++++---- mx.h | 12 ++++++-- nntp/mx_nntp.c | 4 ++- pop/mx_pop.c | 4 ++- postpone.c | 3 +- 14 files changed, 95 insertions(+), 111 deletions(-) diff --git a/browser.c b/browser.c index 49c6fab..bb687c6 100644 --- a/browser.c +++ b/browser.c @@ -20,6 +20,7 @@ #include "browser.h" #ifdef USE_IMAP #include "imap.h" +#include "imap/mx_imap.h" #endif #ifdef USE_NNTP #include "nntp.h" @@ -270,7 +271,7 @@ static const char *folder_format_str (char *dest, size_t destlen, char op, 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); @@ -594,20 +595,21 @@ static int examine_mailboxes (MUTTMENU * menu, struct browser_state *state) 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; } @@ -764,7 +766,7 @@ void _mutt_select_file (char *f, size_t flen, int flags, char ***files, 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); @@ -809,7 +811,7 @@ void _mutt_select_file (char *f, size_t flen, int flags, char ***files, 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); @@ -1133,7 +1135,7 @@ void _mutt_select_file (char *f, size_t flen, int flags, char ***files, 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); @@ -1290,7 +1292,7 @@ void _mutt_select_file (char *f, size_t flen, int flags, char ***files, 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); diff --git a/buffy.c b/buffy.c index 4d79995..1f49f91 100644 --- a/buffy.c +++ b/buffy.c @@ -271,7 +271,7 @@ int mutt_buffy_check (int force) struct stat contex_sb; time_t now, last1; CONTEXT *ctx; - int i = 0; + int i = 0, local = 0; #ifdef USE_IMAP time_t last2; @@ -303,45 +303,21 @@ int mutt_buffy_check (int force) 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 @@ -350,30 +326,9 @@ int mutt_buffy_check (int force) /* 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: @@ -520,15 +475,6 @@ int mutt_buffy_check (int force) break; #endif -#ifdef USE_POP - case M_POP: - break; -#endif - -#ifdef USE_NNTP - case M_NNTP: - break; -#endif } } #ifdef BUFFY_SIZE diff --git a/imap/mx_imap.c b/imap/mx_imap.c index eb402db..f0aee59 100644 --- a/imap/mx_imap.c +++ b/imap/mx_imap.c @@ -7,6 +7,8 @@ #include "config.h" #endif +#include + #include "mutt.h" #include "imap_private.h" @@ -18,7 +20,7 @@ #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); diff --git a/imap/mx_imap.h b/imap/mx_imap.h index 3b20c80..526bbf9 100644 --- a/imap/mx_imap.h +++ b/imap/mx_imap.h @@ -11,8 +11,11 @@ #ifndef _IMAP_MX_H #define _IMAP_MX_H +#include + #include "mx.h" +int imap_is_magic (const char*, struct stat*); mx_t* imap_reg_mx (void); #endif /* !_IMAP_MX_H */ diff --git a/mbox.c b/mbox.c index f5342a7..bafb7f3 100644 --- a/mbox.c +++ b/mbox.c @@ -1155,16 +1155,15 @@ int mbox_check_empty (const char *path) 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); @@ -1186,8 +1185,8 @@ int mbox_is_magic (const char* path) { * 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 { @@ -1196,7 +1195,7 @@ int mbox_is_magic (const char* path) { } #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); diff --git a/mbox.h b/mbox.h index 78364b3..22adc66 100644 --- a/mbox.h +++ b/mbox.h @@ -15,6 +15,8 @@ #ifndef _MBOX_H #define _MBOX_H +#include + #include "mx.h" #define MMDF_SEP "\001\001\001\001\n" @@ -28,7 +30,8 @@ int mbox_parse_mailbox (CONTEXT *); 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 *); diff --git a/mh.c b/mh.c index c9f3d47..5f3f369 100644 --- a/mh.c +++ b/mh.c @@ -1927,14 +1927,10 @@ int mh_check_empty (const char *path) 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); @@ -1967,15 +1963,13 @@ int mh_is_magic (const char* path) { 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); diff --git a/mh.h b/mh.h index d8b385b..cdc51d0 100644 --- a/mh.h +++ b/mh.h @@ -15,6 +15,8 @@ #ifndef _MH_H #define _MH_H +#include + #include "mx.h" int mh_read_dir (CONTEXT *); @@ -24,7 +26,6 @@ int mh_buffy (const char *); 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 *); @@ -32,7 +33,6 @@ int maildir_check_empty (const char *); 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); diff --git a/muttlib.c b/muttlib.c index 21ae059..0676729 100644 --- a/muttlib.c +++ b/muttlib.c @@ -22,6 +22,7 @@ #ifdef USE_IMAP #include "imap.h" +#include "imap/mx_imap.h" #endif #include "mutt_crypt.h" @@ -363,7 +364,7 @@ char *_mutt_expand_path (char *s, size_t slen, int rx) { #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)); @@ -460,7 +461,7 @@ char *_mutt_expand_path (char *s, size_t slen, int rx) #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 diff --git a/mx.c b/mx.c index c577356..51fc1b3 100644 --- a/mx.c +++ b/mx.c @@ -71,6 +71,7 @@ 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) @@ -152,11 +153,24 @@ static int undotlock_file (const char *path, int fd) /* 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); } @@ -335,6 +349,12 @@ int mx_get_magic (const char *path) { 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 */ @@ -520,7 +540,8 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT * pctx) 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) @@ -822,7 +843,7 @@ int mx_close_mailbox (CONTEXT * ctx, int *index_hint) /* 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 @@ -1543,7 +1564,7 @@ int mx_check_empty (const char *path) } 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)) diff --git a/mx.h b/mx.h index 828c4b8..f2a4e59 100644 --- a/mx.h +++ b/mx.h @@ -17,6 +17,8 @@ #ifndef _MX_H #define _MX_H +#include + /* * supported mailbox formats * in mx_init() the registration order must be exactly as given here!!!1! @@ -68,7 +70,7 @@ typedef struct { /* 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 */ @@ -136,8 +138,14 @@ int mx_close_mailbox (CONTEXT *, int *); 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); diff --git a/nntp/mx_nntp.c b/nntp/mx_nntp.c index 60e90b5..9de796f 100644 --- a/nntp/mx_nntp.c +++ b/nntp/mx_nntp.c @@ -7,6 +7,8 @@ #include "config.h" #endif +#include + #include "mutt.h" #include "nntp.h" @@ -18,7 +20,7 @@ #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); } diff --git a/pop/mx_pop.c b/pop/mx_pop.c index 17a1ac2..2f51756 100644 --- a/pop/mx_pop.c +++ b/pop/mx_pop.c @@ -7,6 +7,8 @@ #include "config.h" #endif +#include + #include "mutt.h" #include "pop.h" @@ -18,7 +20,7 @@ #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); } diff --git a/postpone.c b/postpone.c index 264e9dc..a2815c9 100644 --- a/postpone.c +++ b/postpone.c @@ -21,6 +21,7 @@ #include "mx.h" #ifdef USE_IMAP #include "imap.h" +#include "imap/mx_imap.h" #endif #include "mutt_crypt.h" @@ -75,7 +76,7 @@ int mutt_num_postponed (int force) #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; -- 2.20.1