X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-mx%2Fmh.c;h=23d21fe7a0f9ff06c00be111fd95c14393912db9;hp=7325b0ca11867c02d4bcfe5b00db69c7dc58f125;hb=19806c1ee3019ddf9facf23eb19a13c128abfba9;hpb=928ca0d87eb15bfa4c150abdadadaf3b177f95bd diff --git a/lib-mx/mh.c b/lib-mx/mh.c index 7325b0c..23d21fe 100644 --- a/lib-mx/mh.c +++ b/lib-mx/mh.c @@ -16,7 +16,7 @@ #include #include -#include +#include #include "mutt.h" #include "mx.h" @@ -35,13 +35,12 @@ struct maildir { struct maildir *next; }; -struct mh_sequences { - int max; - short *flags; -}; +typedef struct mh_sequences { + int size; + char flags[]; +} mh_sequences; /* mh_sequences support */ - #define MH_SEQ_UNSEEN (1 << 0) #define MH_SEQ_REPLIED (1 << 1) #define MH_SEQ_FLAGGED (1 << 2) @@ -51,39 +50,37 @@ static int maildir_check_empty (const char*); static int maildir_check_mailbox (CONTEXT*, int*, int); static int mh_check_mailbox (CONTEXT*, int*, int); -static void mhs_alloc (struct mh_sequences *mhs, int i) +static mh_sequences *mhs_new(void) { - int j; - int newmax; - - if (i > mhs->max || !mhs->flags) { - newmax = i + 128; - p_realloc(&mhs->flags, newmax + 1); - for (j = mhs->max + 1; j <= newmax; j++) - mhs->flags[j] = 0; + mh_sequences *res = xmalloc(sizeof(mh_sequences) + 128); + res->size = 128; + return res; +} - mhs->max = newmax; - } +static void mhs_ensure(mh_sequences *mhs, int i) +{ + if (i > mhs->size) { + xrealloc((void *)&mhs, sizeof(mh_sequences) + mhs->size + 128); + p_clear(mhs->flags + mhs->size, 128); + mhs->size += 128; + } } -static void mhs_free_sequences (struct mh_sequences *mhs) +static void mhs_delete(mh_sequences **mhs) { - p_delete(&mhs->flags); + p_delete(mhs); } static short mhs_check (struct mh_sequences *mhs, int i) { - if (!mhs->flags || i > mhs->max) - return 0; - else - return mhs->flags[i]; + return i > mhs->size ? 0 : mhs->flags[i]; } static short mhs_set (struct mh_sequences *mhs, int i, short f) { - mhs_alloc (mhs, i); - mhs->flags[i] |= f; - return mhs->flags[i]; + mhs_ensure(mhs, i); + mhs->flags[i] |= f; + return mhs->flags[i]; } static void mh_read_token (char *t, int *first, int *last) @@ -143,17 +140,19 @@ static void mh_read_sequences (struct mh_sequences *mhs, const char *path) int mh_buffy (const char *path) { - int i, r = 0; - struct mh_sequences mhs; - - p_clear(&mhs, 1); + mh_sequences *mhs = mhs_new(); + int i; + + mh_read_sequences(mhs, path); + for (i = 0; i <= mhs->size; i++) { + if (mhs_check(mhs, i) & MH_SEQ_UNSEEN) { + mhs_delete(&mhs); + return 1; + } + } - mh_read_sequences (&mhs, path); - for (i = 0; !r && i <= mhs.max; i++) - if (mhs_check (&mhs, i) & MH_SEQ_UNSEEN) - r = 1; - mhs_free_sequences (&mhs); - return r; + mhs_delete(&mhs); + return 0; } static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt) @@ -164,7 +163,7 @@ static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt) for (;;) { snprintf (path, _POSIX_PATH_MAX, "%s/.mutt-%s-%d-%d", - dest->path, NONULL (Hostname), (int) getpid (), Counter++); + dest->path, NONULL(mod_core.shorthost), (int) getpid (), Counter++); umask (Umask); if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1) { if (errno != EEXIST) { @@ -182,14 +181,14 @@ static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt) p_delete(tgt); close (fd); unlink (path); - return (-1); + return -1; } return 0; } -static void mhs_write_one_sequence (FILE * fp, struct mh_sequences *mhs, - short f, const char *tag) +static void mhs_write_one_sequence(FILE * fp, struct mh_sequences *mhs, + short f, const char *tag) { int i; int first, last; @@ -199,7 +198,7 @@ static void mhs_write_one_sequence (FILE * fp, struct mh_sequences *mhs, first = -1; last = -1; - for (i = 0; i <= mhs->max; i++) { + for (i = 0; i <= mhs->size; i++) { if ((mhs_check (mhs, i) & f)) { if (first < 0) first = i; @@ -248,15 +247,11 @@ static void mh_update_sequences (CONTEXT * ctx) char seq_unseen[STRING]; char seq_replied[STRING]; char seq_flagged[STRING]; + mh_sequences *mhs = mhs_new(); - - struct mh_sequences mhs; - - p_clear(&mhs, 1); - - snprintf (seq_unseen, sizeof (seq_unseen), "%s:", NONULL (MhUnseen)); - snprintf (seq_replied, sizeof (seq_replied), "%s:", NONULL (MhReplied)); - snprintf (seq_flagged, sizeof (seq_flagged), "%s:", NONULL (MhFlagged)); + snprintf(seq_unseen, sizeof(seq_unseen), "%s:", NONULL(MhUnseen)); + snprintf(seq_replied, sizeof(seq_replied), "%s:", NONULL(MhReplied)); + snprintf(seq_flagged, sizeof(seq_flagged), "%s:", NONULL(MhFlagged)); if (mh_mkstemp (ctx, &nfp, &tmpfname) != 0) { /* error message? */ @@ -294,29 +289,28 @@ static void mh_update_sequences (CONTEXT * ctx) i = atoi (p); if (!ctx->hdrs[l]->read) { - mhs_set (&mhs, i, MH_SEQ_UNSEEN); + mhs_set(mhs, i, MH_SEQ_UNSEEN); unseen++; } if (ctx->hdrs[l]->flagged) { - mhs_set (&mhs, i, MH_SEQ_FLAGGED); + mhs_set(mhs, i, MH_SEQ_FLAGGED); flagged++; } if (ctx->hdrs[l]->replied) { - mhs_set (&mhs, i, MH_SEQ_REPLIED); + mhs_set(mhs, i, MH_SEQ_REPLIED); replied++; } } /* write out the new sequences */ if (unseen) - mhs_write_one_sequence (nfp, &mhs, MH_SEQ_UNSEEN, NONULL (MhUnseen)); + mhs_write_one_sequence(nfp, mhs, MH_SEQ_UNSEEN, NONULL (MhUnseen)); if (flagged) - mhs_write_one_sequence (nfp, &mhs, MH_SEQ_FLAGGED, NONULL (MhFlagged)); + mhs_write_one_sequence(nfp, mhs, MH_SEQ_FLAGGED, NONULL (MhFlagged)); if (replied) - mhs_write_one_sequence (nfp, &mhs, MH_SEQ_REPLIED, NONULL (MhReplied)); - - mhs_free_sequences (&mhs); + mhs_write_one_sequence(nfp, mhs, MH_SEQ_REPLIED, NONULL (MhReplied)); + mhs_delete(&mhs); /* try to commit the changes - no guarantee here */ m_fclose(&nfp); @@ -662,7 +656,7 @@ static int maildir_parse_dir (CONTEXT * ctx, struct maildir ***last, /* FOO - really ignore the return value? */ maildir_parse_entry (ctx, last, subdir, de->d_name, count, is_old, -#if HAVE_DIRENT_D_INO +#ifdef HAVE_DIRENT_D_INO de->d_ino #else 0 @@ -730,13 +724,13 @@ static void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md) int count; #ifdef USE_HCACHE - void *hc = NULL; + hcache_t *hc = NULL; void *data; struct timeval *when = NULL; struct stat lastchanged; int ret; - hc = mutt_hcache_open (HeaderCache, ctx->path); + hc = mutt_hcache_open(ctx->path); #endif for (p = md, count = 0; p; p = p->next, count++) { @@ -753,19 +747,11 @@ static void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md) snprintf (fn, sizeof (fn), "%s/%s", ctx->path, p->h->path); #ifdef USE_HCACHE - if (option (OPTHCACHEVERIFY)) { - ret = stat (fn, &lastchanged); - } - else { - lastchanged.st_mtime = 0; - ret = 0; - } - - if (data != NULL && !ret && lastchanged.st_mtime <= when->tv_sec) { - p->h = mutt_hcache_restore ((unsigned char *) data, &p->h); + ret = stat(fn, &lastchanged); + if (data && !ret && lastchanged.st_mtime <= when->tv_sec) { + p->h = mutt_hcache_restore(data, &p->h); maildir_parse_flags (p->h, fn); - } - else + } else #endif if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h)) { p->header_parsed = 1; @@ -773,15 +759,15 @@ static void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md) #ifdef USE_HCACHE mutt_hcache_store (hc, p->h->path + 3, p->h, 0, &maildir_hcache_keylen); #endif - } - else + } else { header_delete(&p->h); + } #ifdef USE_HCACHE p_delete(&data); #endif } #ifdef USE_HCACHE - mutt_hcache_close (hc); + mutt_hcache_close (&hc); #endif } @@ -794,26 +780,19 @@ static void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md) */ static int _mh_read_dir (CONTEXT * ctx, const char *subdir) { - struct maildir *md; - struct mh_sequences mhs; - struct maildir **last; - int count; - - - p_clear(&mhs, 1); + struct maildir *md = NULL, **last = &md; + int count = 0; maildir_update_mtime (ctx); - md = NULL; - last = &md; - count = 0; if (maildir_parse_dir (ctx, &last, subdir, &count) == -1) return -1; if (ctx->magic == M_MH) { - mh_read_sequences (&mhs, ctx->path); - mh_update_maildir (md, &mhs); - mhs_free_sequences (&mhs); + mh_sequences *mhs = mhs_new(); + mh_read_sequences(mhs, ctx->path); + mh_update_maildir(md, mhs); + mhs_delete(&mhs); } if (ctx->magic == M_MAILDIR) @@ -824,7 +803,7 @@ static int _mh_read_dir (CONTEXT * ctx, const char *subdir) } static int mh_read_dir (CONTEXT* ctx) { - return (_mh_read_dir (ctx, NULL)); + return _mh_read_dir (ctx, NULL); } /* read a maildir style mailbox */ @@ -834,7 +813,7 @@ static int maildir_read_dir (CONTEXT * ctx) * of the main folder path from which to read messages */ if (_mh_read_dir (ctx, "new") == -1 || _mh_read_dir (ctx, "cur") == -1) - return (-1); + return -1; return 0; } @@ -919,7 +898,7 @@ static int maildir_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr for (;;) { snprintf (path, _POSIX_PATH_MAX, "%s/tmp/%s.%ld.%u_%d.%s%s", dest->path, subdir, (long) time (NULL), - (unsigned int) getpid (), Counter++, NONULL (Hostname), suffix); + (unsigned int) getpid (), Counter++, NONULL (mod_core.shorthost), suffix); umask (Umask); if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1) { @@ -937,7 +916,7 @@ static int maildir_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr p_delete(&msg->path); close (fd); unlink (path); - return (-1); + return -1; } return 0; @@ -992,7 +971,7 @@ static int maildir_commit_message (MESSAGE * msg, CONTEXT * ctx, HEADER * hdr) for (;;) { snprintf (path, _POSIX_PATH_MAX, "%s/%ld.%u_%d.%s%s", subdir, (long) time (NULL), (unsigned int) getpid (), Counter++, - NONULL (Hostname), suffix); + NONULL (mod_core.shorthost), suffix); snprintf (full, _POSIX_PATH_MAX, "%s/%s", ctx->path, path); if (safe_rename (msg->path, full) == 0) { @@ -1048,7 +1027,7 @@ static int _mh_commit_message (MESSAGE * msg, CONTEXT * ctx, HEADER * hdr, if ((dirp = opendir (ctx->path)) == NULL) { mutt_perror (ctx->path); - return (-1); + return -1; } /* figure out what the next message number is */ @@ -1198,7 +1177,7 @@ static int maildir_sync_message (CONTEXT * ctx, int msgno) (h->env && (h->env->refs_changed || h->env->irt_changed))) { /* when doing attachment deletion/rethreading, fall back to the MH case. */ if (mh_rewrite_message (ctx, msgno) != 0) - return (-1); + return -1; } else { /* we just have to rename the file. */ @@ -1211,7 +1190,7 @@ static int maildir_sync_message (CONTEXT * ctx, int msgno) char *p; if ((p = strrchr (h->path, '/')) == NULL) { - return (-1); + return -1; } p++; m_strcpy(newpath, sizeof(newpath), p); @@ -1237,11 +1216,11 @@ static int maildir_sync_message (CONTEXT * ctx, int msgno) if (rename (oldpath, fullpath) != 0) { mutt_perror ("rename"); - return (-1); + return -1; } m_strreplace(&h->path, partpath); } - return (0); + return 0; } static int mh_sync_mailbox (CONTEXT * ctx, int unused __attribute__ ((unused)), int *index_hint) @@ -1250,7 +1229,7 @@ static int mh_sync_mailbox (CONTEXT * ctx, int unused __attribute__ ((unused)), int i, j; #ifdef USE_HCACHE - void *hc = NULL; + hcache_t *hc = NULL; #endif /* USE_HCACHE */ if (ctx->magic == M_MH) @@ -1263,7 +1242,7 @@ static int mh_sync_mailbox (CONTEXT * ctx, int unused __attribute__ ((unused)), #ifdef USE_HCACHE if (ctx->magic == M_MAILDIR) - hc = mutt_hcache_open (HeaderCache, ctx->path); + hc = mutt_hcache_open(ctx->path); #endif /* USE_HCACHE */ for (i = 0; i < ctx->msgcount; i++) { @@ -1307,7 +1286,7 @@ static int mh_sync_mailbox (CONTEXT * ctx, int unused __attribute__ ((unused)), #ifdef USE_HCACHE if (ctx->magic == M_MAILDIR) - mutt_hcache_close (hc); + mutt_hcache_close (&hc); #endif /* USE_HCACHE */ if (ctx->magic == M_MH) @@ -1332,7 +1311,7 @@ static int mh_sync_mailbox (CONTEXT * ctx, int unused __attribute__ ((unused)), err: #ifdef USE_HCACHE if (ctx->magic == M_MAILDIR) - mutt_hcache_close (hc); + mutt_hcache_close (&hc); #endif /* USE_HCACHE */ return -1; } @@ -1431,7 +1410,7 @@ static int maildir_check_mailbox (CONTEXT * ctx, int *index_hint, int unused __a struct maildir *md; /* list of messages in the mailbox */ struct maildir **last, *p; int i; - HASH *fnames; /* hash table for quickly looking up the base filename + hash_t *fnames; /* hash table for quickly looking up the base filename for a maildir message */ if (!option (OPTCHECKNEW)) @@ -1472,12 +1451,12 @@ static int maildir_check_mailbox (CONTEXT * ctx, int *index_hint, int unused __a * of each message we scanned. This is used in the loop over the * existing messages below to do some correlation. */ - fnames = hash_create (1031); + fnames = hash_new (1031, 0); for (p = md; p; p = p->next) { maildir_canon_filename (buf, p->h->path, sizeof (buf)); p->canon_fname = m_strdup(buf); - hash_insert (fnames, p->canon_fname, p, 0); + hash_insert (fnames, p->canon_fname, p); } /* check for modifications and adjust flags */ @@ -1530,7 +1509,7 @@ static int maildir_check_mailbox (CONTEXT * ctx, int *index_hint, int unused __a } /* destroy the file name hash */ - hash_destroy (&fnames, NULL); + hash_delete (&fnames, NULL); /* If we didn't just get new mail, update the tables. */ if (occult) @@ -1561,10 +1540,9 @@ static int mh_check_mailbox (CONTEXT * ctx, int *index_hint, int unused __attrib char buf[_POSIX_PATH_MAX]; struct stat st, st_cur; short modified = 0, have_new = 0, occult = 0; - struct maildir *md, *p; - struct maildir **last = NULL; - struct mh_sequences mhs; - HASH *fnames; + struct maildir *md = NULL, **last = &md, *p; + mh_sequences *mhs; + hash_t *fnames; int i; if (!option (OPTCHECKNEW)) @@ -1600,20 +1578,17 @@ static int mh_check_mailbox (CONTEXT * ctx, int *index_hint, int unused __attrib ctx->mtime_cur = st_cur.st_mtime; ctx->mtime = st.st_mtime; - p_clear(&mhs, 1); - - md = NULL; - last = &md; maildir_parse_dir (ctx, &last, NULL, NULL); - mh_read_sequences (&mhs, ctx->path); - mh_update_maildir (md, &mhs); - mhs_free_sequences (&mhs); + mhs = mhs_new(); + mh_read_sequences(mhs, ctx->path); + mh_update_maildir(md, mhs); + mhs_delete(&mhs); /* check for modifications and adjust flags */ - fnames = hash_create (1031); + fnames = hash_new (1031, 0); for (p = md; p; p = p->next) - hash_insert (fnames, p->h->path, p, 0); + hash_insert (fnames, p->h->path, p); for (i = 0; i < ctx->msgcount; i++) { ctx->hdrs[i]->active = 0; @@ -1633,7 +1608,7 @@ static int mh_check_mailbox (CONTEXT * ctx, int *index_hint, int unused __attrib /* destroy the file name hash */ - hash_destroy (&fnames, NULL); + hash_delete (&fnames, NULL); /* If we didn't just get new mail, update the tables. */ if (occult) @@ -1646,16 +1621,13 @@ static int mh_check_mailbox (CONTEXT * ctx, int *index_hint, int unused __attrib } - - /* * These functions try to find a message in a maildir folder when it * has moved under our feet. Note that this code is rather expensive, but * then again, it's called rarely. */ - -static FILE *_maildir_open_find_message (const char *folder, const char *unique, - const char *subfolder) +static FILE *_maildir_open_find_message(const char *folder, const char *unique, + const char *subfolder) { char dir[_POSIX_PATH_MAX]; char tunique[_POSIX_PATH_MAX]; @@ -1680,7 +1652,7 @@ static FILE *_maildir_open_find_message (const char *folder, const char *unique, if (!m_strcmp(tunique, unique)) { snprintf (fname, sizeof (fname), "%s/%s/%s", folder, subfolder, de->d_name); - fp = fopen (fname, "r"); /* __FOPEN_CHECKED__ */ + fp = fopen(fname, "r"); oe = errno; break; } @@ -1790,52 +1762,38 @@ static int mh_check_empty (const char *path) return r; } -static int mh_is_magic (const char* path, struct stat* st) { - char tmp[_POSIX_PATH_MAX]; - - if (S_ISDIR (st->st_mode)) { - snprintf (tmp, sizeof (tmp), "%s/.mh_sequences", path); - if (access (tmp, F_OK) == 0) - return (M_MH); - - snprintf (tmp, sizeof (tmp), "%s/.xmhcache", path); - if (access (tmp, F_OK) == 0) - return (M_MH); - - snprintf (tmp, sizeof (tmp), "%s/.mew_cache", path); - if (access (tmp, F_OK) == 0) - return (M_MH); - - snprintf (tmp, sizeof (tmp), "%s/.mew-cache", path); - if (access (tmp, F_OK) == 0) - return (M_MH); - - snprintf (tmp, sizeof (tmp), "%s/.sylpheed_cache", path); - if (access (tmp, F_OK) == 0) - return (M_MH); - - /* - * ok, this isn't an mh folder, but mh mode can be used to read - * Usenet news from the spool. ;-) - */ +static int mh_is_magic(const char *path, struct stat *st) +{ + static char const * const files[] = { + ".mh_sequences", ".xmhcache", ".mew_cache", + ".mew-cache", ".sylpheed_cache", + }; + + if (S_ISDIR(st->st_mode)) { + for (int i = 0; i < countof(files); i++) { + char tmp[_POSIX_PATH_MAX]; + + snprintf(tmp, sizeof(tmp), "%s/%s", path, files[i]); + if (access(tmp, F_OK) == 0) + return M_MH; + } + } - snprintf (tmp, sizeof (tmp), "%s/.overview", path); - if (access (tmp, F_OK) == 0) - return (M_MH); - } - return (-1); + return -1; } -static int maildir_is_magic (const char* path, struct stat* st) { - struct stat sb; - char tmp[_POSIX_PATH_MAX]; +static int maildir_is_magic (const char *path, struct stat *st) +{ + if (S_ISDIR(st->st_mode)) { + char tmp[_POSIX_PATH_MAX]; + struct stat sb; + + snprintf(tmp, sizeof(tmp), "%s/cur", path); + if (stat(tmp, &sb) == 0 && S_ISDIR(sb.st_mode)) + return M_MAILDIR; + } - if (S_ISDIR (st->st_mode)) { - snprintf (tmp, sizeof (tmp), "%s/cur", path); - if (stat (tmp, &sb) == 0 && S_ISDIR (sb.st_mode)) - return (M_MAILDIR); - } - return (-1); + return -1; } static int mh_commit (MESSAGE* msg, CONTEXT* ctx) {