X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=mh.c;h=5ca542f1b640c4024f74323f16346892ef98c723;hp=56ff8b4b3b541fd28d0ccd96cd84d0ee38ec677c;hb=40fc05e11b8f95a9661e6e410a9e7b7da7824891;hpb=3d937534e7b1ee723f86594b5e4c64c95158a933 diff --git a/mh.c b/mh.c index 56ff8b4..5ca542f 100644 --- a/mh.c +++ b/mh.c @@ -1,20 +1,11 @@ /* + * Copyright notice from original mutt: * Copyright (C) 1996-2002 Michael R. Elkins * Copyright (C) 1999-2002 Thomas Roessler - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * + * This file is part of mutt-ng, see http://www.muttng.org/. + * It's licensed under the GNU General Public License, + * please see the file GPL in the top level source directory. */ /* @@ -22,12 +13,9 @@ * mailboxes. */ -#include "mutt.h" -#include "mailbox.h" -#include "mx.h" -#include "copy.h" -#include "buffy.h" -#include "sort.h" +#if HAVE_CONFIG_H +# include "config.h" +#endif #include #include @@ -43,17 +31,34 @@ #include #include -struct maildir -{ +#if HAVE_SYS_TIME_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "mutt.h" +#include "mx.h" +#include "mh.h" +#include "mbox.h" +#include "copy.h" +#include "buffy.h" +#include "sort.h" +#include "thread.h" +#include "hcache.h" + +struct maildir { HEADER *h; char *canon_fname; unsigned header_parsed:1; - ino_t inode; struct maildir *next; }; -struct mh_sequences -{ +struct mh_sequences { int max; short *flags; }; @@ -64,15 +69,19 @@ struct mh_sequences #define MH_SEQ_REPLIED (1 << 1) #define MH_SEQ_FLAGGED (1 << 2) +/* prototypes */ +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) { int j; int newmax; - if (i > mhs->max || !mhs->flags) - { + if (i > mhs->max || !mhs->flags) { newmax = i + 128; - safe_realloc (&mhs->flags, sizeof (mhs->flags[0]) * (newmax + 1)); + p_realloc(&mhs->flags, newmax + 1); for (j = mhs->max + 1; j <= newmax; j++) mhs->flags[j] = 0; @@ -82,7 +91,7 @@ static void mhs_alloc (struct mh_sequences *mhs, int i) static void mhs_free_sequences (struct mh_sequences *mhs) { - FREE (&mhs->flags); + p_delete(&mhs->flags); } static short mhs_check (struct mh_sequences *mhs, int i) @@ -116,8 +125,8 @@ static short mhs_unset (struct mh_sequences *mhs, int i, short f) static void mh_read_token (char *t, int *first, int *last) { char *p; - if ((p = strchr (t, '-'))) - { + + if ((p = strchr (t, '-'))) { *p++ = '\0'; *first = atoi (t); *last = atoi (p); @@ -132,40 +141,39 @@ static void mh_read_sequences (struct mh_sequences *mhs, const char *path) int line = 1; char *buff = NULL; char *t; - size_t sz = 0; + ssize_t sz = 0; short f; int first, last; char pathname[_POSIX_PATH_MAX]; + snprintf (pathname, sizeof (pathname), "%s/.mh_sequences", path); if (!(fp = fopen (pathname, "r"))) return; - while ((buff = mutt_read_line (buff, &sz, fp, &line))) - { + while ((buff = mutt_read_line (buff, &sz, fp, &line))) { if (!(t = strtok (buff, " \t:"))) continue; - if (!mutt_strcmp (t, MhUnseen)) + if (!m_strcmp(t, MhUnseen)) f = MH_SEQ_UNSEEN; - else if (!mutt_strcmp (t, MhFlagged)) + else if (!m_strcmp(t, MhFlagged)) f = MH_SEQ_FLAGGED; - else if (!mutt_strcmp (t, MhReplied)) + else if (!m_strcmp(t, MhReplied)) f = MH_SEQ_REPLIED; - else /* unknown sequence */ + else /* unknown sequence */ continue; - while ((t = strtok (NULL, " \t:"))) - { + while ((t = strtok (NULL, " \t:"))) { mh_read_token (t, &first, &last); for (; first <= last; first++) - mhs_set (mhs, first, f); + mhs_set (mhs, first, f); } } - FREE (&buff); + p_delete(&buff); safe_fclose (&fp); } @@ -173,7 +181,8 @@ int mh_buffy (const char *path) { int i, r = 0; struct mh_sequences mhs; - memset (&mhs, 0, sizeof (mhs)); + + p_clear(&mhs, 1); mh_read_sequences (&mhs, path); for (i = 0; !r && i <= mhs.max; i++) @@ -188,29 +197,24 @@ static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt) int fd; char path[_POSIX_PATH_MAX]; - FOREVER - { + for (;;) { snprintf (path, _POSIX_PATH_MAX, "%s/.mutt-%s-%d-%d", - dest->path, NONULL (Hostname), (int) getpid (), Counter++); - umask(Umask); - if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1) - { - if (errno != EEXIST) - { - mutt_perror (path); - return -1; + dest->path, NONULL (Hostname), (int) getpid (), Counter++); + umask (Umask); + if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1) { + if (errno != EEXIST) { + mutt_perror (path); + return -1; } } - else - { - *tgt = safe_strdup (path); + else { + *tgt = m_strdup(path); break; } } - if ((*fp = fdopen (fd, "w")) == NULL) - { - FREE (tgt); + if ((*fp = fdopen (fd, "w")) == NULL) { + p_delete(tgt); close (fd); unlink (path); return (-1); @@ -220,38 +224,35 @@ static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt) } static void mhs_write_one_sequence (FILE * fp, struct mh_sequences *mhs, - short f, const char *tag) + short f, const char *tag) { int i; int first, last; + fprintf (fp, "%s:", tag); first = -1; last = -1; - for (i = 0; i <= mhs->max; i++) - { - if ((mhs_check (mhs, i) & f)) - { + for (i = 0; i <= mhs->max; i++) { + if ((mhs_check (mhs, i) & f)) { if (first < 0) - first = i; + first = i; else - last = i; + last = i; } - else if (first >= 0) - { + else if (first >= 0) { if (last < 0) - fprintf (fp, " %d", first); + fprintf (fp, " %d", first); else - fprintf (fp, " %d-%d", first, last); + fprintf (fp, " %d-%d", first, last); first = -1; last = -1; } } - if (first >= 0) - { + if (first >= 0) { if (last < 0) fprintf (fp, " %d", first); else @@ -271,7 +272,7 @@ void mh_update_sequences (CONTEXT * ctx) char *tmpfname; char *buff = NULL; char *p; - size_t s; + ssize_t s; int l = 0; int i; @@ -285,14 +286,14 @@ void mh_update_sequences (CONTEXT * ctx) struct mh_sequences mhs; - memset (&mhs, 0, sizeof (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)); - if (mh_mkstemp (ctx, &nfp, &tmpfname) != 0) - { + if (mh_mkstemp (ctx, &nfp, &tmpfname) != 0) { /* error message? */ return; } @@ -301,16 +302,14 @@ void mh_update_sequences (CONTEXT * ctx) /* first, copy unknown sequences */ - if ((ofp = fopen (sequences, "r"))) - { - while ((buff = mutt_read_line (buff, &s, ofp, &l))) - { - if (!mutt_strncmp (buff, seq_unseen, mutt_strlen (seq_unseen))) - continue; - if (!mutt_strncmp (buff, seq_flagged, mutt_strlen (seq_flagged))) - continue; - if (!mutt_strncmp (buff, seq_replied, mutt_strlen (seq_replied))) - continue; + if ((ofp = fopen (sequences, "r"))) { + while ((buff = mutt_read_line (buff, &s, ofp, &l))) { + if (!m_strncmp(buff, seq_unseen, m_strlen(seq_unseen))) + continue; + if (!m_strncmp(buff, seq_flagged, m_strlen(seq_flagged))) + continue; + if (!m_strncmp(buff, seq_replied, m_strlen(seq_replied))) + continue; fprintf (nfp, "%s\n", buff); } @@ -318,8 +317,7 @@ void mh_update_sequences (CONTEXT * ctx) safe_fclose (&ofp); /* now, update our unseen, flagged, and replied sequences */ - for (l = 0; l < ctx->msgcount; l++) - { + for (l = 0; l < ctx->msgcount; l++) { if (ctx->hdrs[l]->deleted) continue; @@ -330,18 +328,15 @@ void mh_update_sequences (CONTEXT * ctx) i = atoi (p); - if (!ctx->hdrs[l]->read) - { + if (!ctx->hdrs[l]->read) { mhs_set (&mhs, i, MH_SEQ_UNSEEN); unseen++; } - if (ctx->hdrs[l]->flagged) - { + if (ctx->hdrs[l]->flagged) { mhs_set (&mhs, i, MH_SEQ_FLAGGED); flagged++; } - if (ctx->hdrs[l]->replied) - { + if (ctx->hdrs[l]->replied) { mhs_set (&mhs, i, MH_SEQ_REPLIED); replied++; } @@ -362,17 +357,16 @@ void mh_update_sequences (CONTEXT * ctx) safe_fclose (&nfp); unlink (sequences); - if (safe_rename (tmpfname, sequences) != 0) - { + if (safe_rename (tmpfname, sequences) != 0) { /* report an error? */ unlink (tmpfname); } - FREE (&tmpfname); + p_delete(&tmpfname); } static void mh_sequences_add_one (CONTEXT * ctx, int n, short unseen, - short flagged, short replied) + short flagged, short replied) { short unseen_done = 0; short flagged_done = 0; @@ -389,7 +383,7 @@ static void mh_sequences_add_one (CONTEXT * ctx, int n, short unseen, char *buff = NULL; int line; - size_t sz; + ssize_t sz; if (mh_mkstemp (ctx, &nfp, &tmpfname) == -1) return; @@ -399,33 +393,28 @@ static void mh_sequences_add_one (CONTEXT * ctx, int n, short unseen, snprintf (seq_flagged, sizeof (seq_flagged), "%s:", NONULL (MhFlagged)); snprintf (sequences, sizeof (sequences), "%s/.mh_sequences", ctx->path); - if ((ofp = fopen (sequences, "r"))) - { - while ((buff = mutt_read_line (buff, &sz, ofp, &line))) - { - if (unseen && !strncmp (buff, seq_unseen, mutt_strlen (seq_unseen))) - { - fprintf (nfp, "%s %d\n", buff, n); - unseen_done = 1; + if ((ofp = fopen (sequences, "r"))) { + while ((buff = mutt_read_line (buff, &sz, ofp, &line))) { + if (unseen && !strncmp (buff, seq_unseen, m_strlen(seq_unseen))) { + fprintf (nfp, "%s %d\n", buff, n); + unseen_done = 1; } else if (flagged - && !strncmp (buff, seq_flagged, mutt_strlen (seq_flagged))) - { - fprintf (nfp, "%s %d\n", buff, n); - flagged_done = 1; + && !strncmp (buff, seq_flagged, m_strlen(seq_flagged))) { + fprintf (nfp, "%s %d\n", buff, n); + flagged_done = 1; } else if (replied - && !strncmp (buff, seq_replied, mutt_strlen (seq_replied))) - { - fprintf (nfp, "%s %d\n", buff, n); - replied_done = 1; + && !strncmp (buff, seq_replied, m_strlen(seq_replied))) { + fprintf (nfp, "%s %d\n", buff, n); + replied_done = 1; } else - fprintf (nfp, "%s\n", buff); + fprintf (nfp, "%s\n", buff); } } safe_fclose (&ofp); - FREE (&buff); + p_delete(&buff); if (!unseen_done && unseen) fprintf (nfp, "%s: %d\n", NONULL (MhUnseen), n); @@ -440,7 +429,7 @@ static void mh_sequences_add_one (CONTEXT * ctx, int n, short unseen, if (safe_rename (tmpfname, sequences) != 0) unlink (tmpfname); - FREE (&tmpfname); + p_delete(&tmpfname); } static void mh_update_maildir (struct maildir *md, struct mh_sequences *mhs) @@ -449,8 +438,7 @@ static void mh_update_maildir (struct maildir *md, struct mh_sequences *mhs) short f; char *p; - for (; md; md = md->next) - { + for (; md; md = md->next) { if ((p = strrchr (md->h->path, '/'))) p++; else @@ -472,11 +460,11 @@ static void maildir_free_entry (struct maildir **md) if (!md || !*md) return; - FREE (&(*md)->canon_fname); + p_delete(&(*md)->canon_fname); if ((*md)->h) - mutt_free_header (&(*md)->h); + header_delete(&(*md)->h); - FREE (md); + p_delete(md); } static void maildir_free_maildir (struct maildir **md) @@ -486,8 +474,7 @@ static void maildir_free_maildir (struct maildir **md) if (!md || !*md) return; - for (p = *md; p; p = q) - { + for (p = *md; p; p = q) { q = p->next; maildir_free_entry (&p); } @@ -501,47 +488,44 @@ static void maildir_parse_flags (HEADER * h, const char *path) h->read = 0; h->replied = 0; - if ((p = strrchr (path, ':')) != NULL && mutt_strncmp (p + 1, "2,", 2) == 0) - { + if ((p = strrchr (path, ':')) != NULL && m_strncmp(p + 1, "2,", 2) == 0) { p += 3; - - mutt_str_replace (&h->maildir_flags, p); + + m_strreplace(&h->maildir_flags, p); q = h->maildir_flags; - while (*p) - { - switch (*p) - { + while (*p) { + switch (*p) { case 'F': - h->flagged = 1; - break; + h->flagged = 1; + break; - case 'S': /* seen */ + case 'S': /* seen */ - h->read = 1; - break; + h->read = 1; + break; - case 'R': /* replied */ + case 'R': /* replied */ - h->replied = 1; - break; + h->replied = 1; + break; + + case 'T': /* trashed */ + h->trash = 1; + h->deleted = 1; + break; - case 'T': /* trashed */ - h->trash = 1; - h->deleted = 1; - break; - default: - *q++ = *p; - break; + *q++ = *p; + break; } p++; } } - + if (q == h->maildir_flags) - FREE (&h->maildir_flags); + p_delete(&h->maildir_flags); else if (q) *q = '\0'; } @@ -551,20 +535,18 @@ static void maildir_update_mtime (CONTEXT * ctx) char buf[_POSIX_PATH_MAX]; struct stat st; - if (ctx->magic == M_MAILDIR) - { + if (ctx->magic == M_MAILDIR) { snprintf (buf, sizeof (buf), "%s/%s", ctx->path, "cur"); if (stat (buf, &st) == 0) ctx->mtime_cur = st.st_mtime; snprintf (buf, sizeof (buf), "%s/%s", ctx->path, "new"); } - else - { + else { snprintf (buf, sizeof (buf), "%s/.mh_sequences", ctx->path); if (stat (buf, &st) == 0) ctx->mtime_cur = st.st_mtime; - strfcpy (buf, ctx->path, sizeof (buf)); + m_strcpy(buf, sizeof(buf), ctx->path); } if (stat (buf, &st) == 0) @@ -576,16 +558,15 @@ static void maildir_update_mtime (CONTEXT * ctx) * out a fake header structure generated by lazy maildir parsing. */ static HEADER *maildir_parse_message (int magic, const char *fname, - int is_old, HEADER * _h) + int is_old, HEADER * _h) { FILE *f; HEADER *h = _h; struct stat st; - if ((f = fopen (fname, "r")) != NULL) - { + if ((f = fopen (fname, "r")) != NULL) { if (!h) - h = mutt_new_header (); + h = header_new(); h->env = mutt_read_rfc822_header (f, h, 0, 0); fstat (fileno (f), &st); @@ -599,8 +580,7 @@ static HEADER *maildir_parse_message (int magic, const char *fname, h->index = -1; - if (magic == M_MAILDIR) - { + if (magic == M_MAILDIR) { /* * maildir stores its flags in the filename, so ignore the * flags in the header of the message @@ -628,8 +608,8 @@ static HEADER *maildir_parse_message (int magic, const char *fname, */ static int maildir_parse_entry (CONTEXT * ctx, struct maildir ***last, - const char *subdir, const char *fname, - int *count, int is_old, ino_t inode) + const char *subdir, const char *fname, + int *count, int is_old, ino_t inode __attribute__ ((unused))) { struct maildir *entry; HEADER *h = NULL; @@ -642,34 +622,29 @@ static int maildir_parse_entry (CONTEXT * ctx, struct maildir ***last, if (ctx->magic == M_MH) h = maildir_parse_message (ctx->magic, buf, is_old, NULL); - else - { - h = mutt_new_header (); + else { + h = header_new(); h->old = is_old; maildir_parse_flags (h, buf); } - if (h != NULL) - { - if (count) - { + if (h != NULL) { + if (count) { (*count)++; if (!ctx->quiet && ReadInc && ((*count % ReadInc) == 0 || *count == 1)) - mutt_message (_("Reading %s... %d"), ctx->path, *count); + mutt_message (_("Reading %s... %d"), ctx->path, *count); } - if (subdir) - { + if (subdir) { snprintf (buf, sizeof (buf), "%s/%s", subdir, fname); - h->path = safe_strdup (buf); + h->path = m_strdup(buf); } else - h->path = safe_strdup (fname); + h->path = m_strdup(fname); - entry = safe_calloc (sizeof (struct maildir), 1); + entry = p_new(struct maildir, 1); entry->h = h; entry->header_parsed = (ctx->magic == M_MH); - entry->inode = inode; **last = entry; *last = &entry->next; @@ -688,8 +663,7 @@ static int maildir_parse_entry (CONTEXT * ctx, struct maildir ***last, int mh_valid_message (const char *s) { - for (; *s; s++) - { + for (; *s; s++) { if (!isdigit ((unsigned char) *s)) return 0; } @@ -697,38 +671,39 @@ int mh_valid_message (const char *s) } static int maildir_parse_dir (CONTEXT * ctx, struct maildir ***last, - const char *subdir, int *count) + const char *subdir, int *count) { DIR *dirp; struct dirent *de; char buf[_POSIX_PATH_MAX]; int is_old = 0; - if (subdir) - { + if (subdir) { snprintf (buf, sizeof (buf), "%s/%s", ctx->path, subdir); - is_old = (mutt_strcmp ("cur", subdir) == 0); + is_old = (m_strcmp("cur", subdir) == 0); } else - strfcpy (buf, ctx->path, sizeof (buf)); + m_strcpy(buf, sizeof(buf), ctx->path); if ((dirp = opendir (buf)) == NULL) return -1; - while ((de = readdir (dirp)) != NULL) - { + while ((de = readdir (dirp)) != NULL) { if ((ctx->magic == M_MH && !mh_valid_message (de->d_name)) - || (ctx->magic == M_MAILDIR && *de->d_name == '.')) + || (ctx->magic == M_MAILDIR && *de->d_name == '.')) continue; /* FOO - really ignore the return value? */ - dprint (2, - (debugfile, "%s:%d: parsing %s\n", __FILE__, __LINE__, - de->d_name)); - maildir_parse_entry (ctx, last, subdir, de->d_name, count, is_old, - de->d_ino); + debug_print (2, ("parsing %s\n", de->d_name)); + maildir_parse_entry (ctx, last, subdir, de->d_name, count, is_old, +#if HAVE_DIRENT_D_INO + de->d_ino +#else + 0 +#endif + ); } closedir (dirp); @@ -739,28 +714,22 @@ static int maildir_add_to_context (CONTEXT * ctx, struct maildir *md) { int oldmsgcount = ctx->msgcount; - while (md) - { + while (md) { + + debug_print (2, ("considering %s\n", NONULL (md->canon_fname))); - dprint (2, (debugfile, "%s:%d maildir_add_to_context(): Considering %s\n", - __FILE__, __LINE__, NONULL (md->canon_fname))); - - if (md->h) - { - dprint (2, - (debugfile, - "%s:%d Adding header structure. Flags: %s%s%s%s%s\n", __FILE__, - __LINE__, md->h->flagged ? "f" : "", md->h->deleted ? "D" : "", - md->h->replied ? "r" : "", md->h->old ? "O" : "", - md->h->read ? "R" : "")); + if (md->h) { + debug_print (2, ("flags: %s%s%s%s%s\n", md->h->flagged ? "f" : "", + md->h->deleted ? "D" : "", md->h->replied ? "r" : "", + md->h->old ? "O" : "", md->h->read ? "R" : "")); if (ctx->msgcount == ctx->hdrmax) - mx_alloc_memory (ctx); + mx_alloc_memory (ctx); ctx->hdrs[ctx->msgcount] = md->h; ctx->hdrs[ctx->msgcount]->index = ctx->msgcount; ctx->size += - md->h->content->length + md->h->content->offset - - md->h->content->hdr_offset; + md->h->content->length + md->h->content->offset - + md->h->content->hdr_offset; md->h = NULL; ctx->msgcount++; @@ -768,8 +737,7 @@ static int maildir_add_to_context (CONTEXT * ctx, struct maildir *md) md = md->next; } - if (ctx->msgcount > oldmsgcount) - { + if (ctx->msgcount > oldmsgcount) { mx_update_context (ctx, ctx->msgcount - oldmsgcount); return 1; } @@ -779,104 +747,16 @@ static int maildir_add_to_context (CONTEXT * ctx, struct maildir *md) static int maildir_move_to_context (CONTEXT * ctx, struct maildir **md) { int r; + r = maildir_add_to_context (ctx, *md); maildir_free_maildir (md); return r; } -/* - * Merge two maildir lists according to the inode numbers. - */ -static struct maildir* maildir_merge_inode (struct maildir *left, - struct maildir *right) +#ifdef USE_HCACHE +static ssize_t maildir_hcache_keylen (const char *fn) { - struct maildir* head; - struct maildir* tail; - - if (left && right) - { - if (left->inode < right->inode) - { - head = left; - left = left->next; - } - else - { - head = right; - right = right->next; - } - } - else - { - if (left) - return left; - else - return right; - } - - tail = head; - - while (left && right) - { - if (left->inode < right->inode) - { - tail->next = left; - left = left->next; - } - else - { - tail->next = right; - right = right->next; - } - tail = tail->next; - } - - if (left) - { - tail->next = left; - } - else - { - tail->next = right; - } - - return head; -} - -/* - * Sort maildir list according to inode. - */ -static struct maildir* maildir_sort_inode(struct maildir* list) -{ - struct maildir* left = list; - struct maildir* right = list; - - if (!list || !list->next) - { - return list; - } - - list = list->next; - while (list && list->next) - { - right = right->next; - list = list->next->next; - } - - list = right; - right = right->next; - list->next = 0; - - left = maildir_sort_inode(left); - right = maildir_sort_inode(right); - return maildir_merge_inode(left, right); -} - -#if USE_HCACHE -static size_t maildir_hcache_keylen (const char *fn) -{ - const char * p = strchr (fn, ':'); - return p ? (size_t) (p - fn) : mutt_strlen(fn); + return m_strchrnul(fn, ':') - fn; } #endif @@ -890,10 +770,9 @@ void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md) char fn[_POSIX_PATH_MAX]; int count; -#if USE_HCACHE +#ifdef USE_HCACHE void *hc = NULL; void *data; - unsigned int size; struct timeval *when = NULL; struct stat lastchanged; int ret; @@ -901,48 +780,48 @@ void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md) hc = mutt_hcache_open (HeaderCache, ctx->path); #endif - for (p = md, count = 0; p; p = p->next, count++) - { - if (! (p && p->h && !p->header_parsed)) - continue; + for (p = md, count = 0; p; p = p->next, count++) { + if (!(p && p->h && !p->header_parsed)) + continue; -#if USE_HCACHE - data = mutt_hcache_fetch (hc, p->h->path + 3, &maildir_hcache_keylen); - when = (struct timeval *) data; +#ifdef USE_HCACHE + data = mutt_hcache_fetch (hc, p->h->path + 3, &maildir_hcache_keylen); + when = (struct timeval *) data; #endif if (!ctx->quiet && ReadInc && ((count % ReadInc) == 0 || count == 1)) mutt_message (_("Reading %s... %d"), ctx->path, count); snprintf (fn, sizeof (fn), "%s/%s", ctx->path, p->h->path); -#if USE_HCACHE - if (option(OPTHCACHEVERIFY)) { - ret = stat(fn, &lastchanged); - } else { +#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); + if (data != NULL && !ret && lastchanged.st_mtime <= when->tv_sec) { + p->h = mutt_hcache_restore ((unsigned char *) data, &p->h); maildir_parse_flags (p->h, fn); - } else + } + else #endif - if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h)) - { + if (maildir_parse_message (ctx->magic, fn, p->h->old, p->h)) { p->header_parsed = 1; maildir_parse_flags (p->h, fn); -#if USE_HCACHE +#ifdef USE_HCACHE mutt_hcache_store (hc, p->h->path + 3, p->h, 0, &maildir_hcache_keylen); #endif - } else - mutt_free_header (&p->h); -#if USE_HCACHE - FREE(&data); + } + else + header_delete(&p->h); +#ifdef USE_HCACHE + p_delete(&data); #endif } -#if USE_HCACHE +#ifdef USE_HCACHE mutt_hcache_close (hc); #endif } @@ -954,7 +833,7 @@ void maildir_delayed_parsing (CONTEXT * ctx, struct maildir *md) * subdir [IN] NULL for MH mailboxes, otherwise the subdir of the * maildir mailbox to read from */ -int mh_read_dir (CONTEXT * ctx, const char *subdir) +static int _mh_read_dir (CONTEXT * ctx, const char *subdir) { struct maildir *md; struct mh_sequences mhs; @@ -962,7 +841,7 @@ int mh_read_dir (CONTEXT * ctx, const char *subdir) int count; - memset (&mhs, 0, sizeof (mhs)); + p_clear(&mhs, 1); maildir_update_mtime (ctx); @@ -972,15 +851,12 @@ int mh_read_dir (CONTEXT * ctx, const char *subdir) if (maildir_parse_dir (ctx, &last, subdir, &count) == -1) return -1; - if (ctx->magic == M_MH) - { + if (ctx->magic == M_MH) { mh_read_sequences (&mhs, ctx->path); mh_update_maildir (md, &mhs); mhs_free_sequences (&mhs); } - md = maildir_sort_inode(md); - if (ctx->magic == M_MAILDIR) maildir_delayed_parsing (ctx, md); @@ -988,13 +864,17 @@ int mh_read_dir (CONTEXT * ctx, const char *subdir) return 0; } +static int mh_read_dir (CONTEXT* ctx) { + return (_mh_read_dir (ctx, NULL)); +} + /* read a maildir style mailbox */ -int maildir_read_dir (CONTEXT * ctx) +static int maildir_read_dir (CONTEXT * ctx) { /* maildir looks sort of like MH, except that there are two subdirectories * of the main folder path from which to read messages */ - if (mh_read_dir (ctx, "new") == -1 || mh_read_dir (ctx, "cur") == -1) + if (_mh_read_dir (ctx, "new") == -1 || _mh_read_dir (ctx, "cur") == -1) return (-1); return 0; @@ -1004,17 +884,17 @@ int maildir_read_dir (CONTEXT * ctx) * Open a new (temporary) message in an MH folder. */ -int mh_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) +static int mh_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr __attribute__ ((unused))) { return mh_mkstemp (dest, &msg->fp, &msg->path); } int ch_compar (const void *a, const void *b) { - return (int)( *((const char *) a) - *((const char *) b)); + return (int) (*((const char *) a) - *((const char *) b)); } -static void maildir_flags (char *dest, size_t destlen, HEADER * hdr) +static void maildir_flags (char *dest, ssize_t destlen, HEADER * hdr) { *dest = '\0'; @@ -1025,18 +905,20 @@ static void maildir_flags (char *dest, size_t destlen, HEADER * hdr) * will end up in the cur directory, so we include it in the following * test even though there is no associated flag. */ - - if (hdr && (hdr->flagged || hdr->replied || hdr->read || hdr->deleted || hdr->old || hdr->maildir_flags)) - { + + if (hdr + && (hdr->flagged || hdr->replied || hdr->read || hdr->deleted + || hdr->old || hdr->maildir_flags)) { char tmp[LONG_STRING]; + snprintf (tmp, sizeof (tmp), - "%s%s%s%s%s", - hdr->flagged ? "F" : "", - hdr->replied ? "R" : "", - hdr->read ? "S" : "", hdr->deleted ? "T" : "", - NONULL(hdr->maildir_flags)); + "%s%s%s%s%s", + hdr->flagged ? "F" : "", + hdr->replied ? "R" : "", + hdr->read ? "S" : "", hdr->deleted ? "T" : "", + NONULL (hdr->maildir_flags)); if (hdr->maildir_flags) - qsort (tmp, strlen (tmp), 1, ch_compar); + qsort (tmp, m_strlen(tmp), 1, ch_compar); snprintf (dest, destlen, ":2,%s", tmp); } } @@ -1050,16 +932,16 @@ static void maildir_flags (char *dest, size_t destlen, HEADER * hdr) * */ -int maildir_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) +static int maildir_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) { int fd; char path[_POSIX_PATH_MAX]; char suffix[16]; char subdir[16]; - if (hdr) - { + if (hdr) { short deleted = hdr->deleted; + hdr->deleted = 0; maildir_flags (suffix, sizeof (suffix), hdr); @@ -1070,39 +952,33 @@ int maildir_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) *suffix = '\0'; if (hdr && (hdr->read || hdr->old)) - strfcpy (subdir, "cur", sizeof (subdir)); + m_strcpy(subdir, sizeof(subdir), "cur"); else - strfcpy (subdir, "new", sizeof (subdir)); + m_strcpy(subdir, sizeof(subdir), "new"); - FOREVER - { + for (;;) { snprintf (path, _POSIX_PATH_MAX, "%s/tmp/%s.%ld.%u_%d.%s%s", - dest->path, subdir, time (NULL), (unsigned int)getpid (), - Counter++, NONULL (Hostname), suffix); - - dprint (2, (debugfile, "maildir_open_new_message (): Trying %s.\n", - path)); - - umask(Umask); - if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1) - { - if (errno != EEXIST) - { - mutt_perror (path); - return -1; + dest->path, subdir, (long) time (NULL), + (unsigned int) getpid (), Counter++, NONULL (Hostname), suffix); + + debug_print (2, ("trying %s.\n", path)); + + umask (Umask); + if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1) { + if (errno != EEXIST) { + mutt_perror (path); + return -1; } } - else - { - dprint (2, (debugfile, "maildir_open_new_message (): Success.\n")); - msg->path = safe_strdup (path); + else { + debug_print (2, ("success.\n")); + msg->path = m_strdup(path); break; } } - if ((msg->fp = fdopen (fd, "w")) == NULL) - { - FREE (&msg->path); + if ((msg->fp = fdopen (fd, "w")) == NULL) { + p_delete(&msg->path); close (fd); unlink (path); return (-1); @@ -1134,7 +1010,7 @@ int maildir_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) * */ -int maildir_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr) +static int maildir_commit_message (MESSAGE * msg, CONTEXT * ctx, HEADER * hdr) { char subdir[4]; char suffix[16]; @@ -1147,30 +1023,27 @@ int maildir_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr) /* extract the subdir */ s = strrchr (msg->path, '/') + 1; - strfcpy (subdir, s, 4); + m_strcpy(subdir, sizeof(subdir), s); /* extract the flags */ if ((s = strchr (s, ':'))) - strfcpy (suffix, s, sizeof (suffix)); + m_strcpy(suffix, sizeof(suffix), s); else suffix[0] = '\0'; /* construct a new file name. */ - FOREVER - { + for (;;) { snprintf (path, _POSIX_PATH_MAX, "%s/%ld.%u_%d.%s%s", subdir, - time (NULL), (unsigned int)getpid (), Counter++, - NONULL (Hostname), suffix); + (long) time (NULL), (unsigned int) getpid (), Counter++, + NONULL (Hostname), suffix); snprintf (full, _POSIX_PATH_MAX, "%s/%s", ctx->path, path); - dprint (2, (debugfile, "maildir_commit_message (): renaming %s to %s.\n", - msg->path, full)); + debug_print (2, ("renaming %s to %s.\n", msg->path, full)); - if (safe_rename (msg->path, full) == 0) - { + if (safe_rename (msg->path, full) == 0) { if (hdr) - mutt_str_replace (&hdr->path, path); - FREE (&msg->path); + m_strreplace(&hdr->path, path); + p_delete(&msg->path); /* * Adjust the mtime on the file to match the time at which this @@ -1178,23 +1051,21 @@ int maildir_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr) * messages between mailboxes, so we test to ensure that it is * actually set. */ - if (msg->received) - { - struct utimbuf ut; - - ut.actime = msg->received; - ut.modtime = msg->received; - if (utime (full, &ut)) - { - mutt_perror (_("maildir_commit_message(): unable to set time on file")); - return -1; - } + if (msg->received) { + struct utimbuf ut; + + ut.actime = msg->received; + ut.modtime = msg->received; + if (utime (full, &ut)) { + mutt_perror (_ + ("maildir_commit_message(): unable to set time on file")); + return -1; + } } return 0; } - else if (errno != EEXIST) - { + else if (errno != EEXIST) { mutt_perror (ctx->path); return -1; } @@ -1207,8 +1078,8 @@ int maildir_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr) */ -static int _mh_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr, - short updseq) +static int _mh_commit_message (MESSAGE * msg, CONTEXT * ctx, HEADER * hdr, + short updseq) { DIR *dirp; struct dirent *de; @@ -1220,30 +1091,26 @@ static int _mh_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr, if (safe_fclose (&msg->fp) != 0) return -1; - if ((dirp = opendir (ctx->path)) == NULL) - { + if ((dirp = opendir (ctx->path)) == NULL) { mutt_perror (ctx->path); return (-1); } /* figure out what the next message number is */ - while ((de = readdir (dirp)) != NULL) - { + while ((de = readdir (dirp)) != NULL) { dep = de->d_name; if (*dep == ',') dep++; cp = dep; - while (*cp) - { + while (*cp) { if (!isdigit ((unsigned char) *cp)) - break; + break; cp++; } - if (!*cp) - { + if (!*cp) { n = atoi (dep); if (n > hi) - hi = n; + hi = n; } } closedir (dirp); @@ -1255,36 +1122,31 @@ static int _mh_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr, * slot. */ - FOREVER - { + for (;;) { hi++; snprintf (tmp, sizeof (tmp), "%d", hi); snprintf (path, sizeof (path), "%s/%s", ctx->path, tmp); - if (safe_rename (msg->path, path) == 0) - { + if (safe_rename (msg->path, path) == 0) { if (hdr) - mutt_str_replace (&hdr->path, tmp); - FREE (&msg->path); + m_strreplace(&hdr->path, tmp); + p_delete(&msg->path); break; } - else if (errno != EEXIST) - { + else if (errno != EEXIST) { mutt_perror (ctx->path); return -1; } } if (updseq) mh_sequences_add_one (ctx, hi, !msg->flags.read, msg->flags.flagged, - msg->flags.replied); + msg->flags.replied); return 0; } -int mh_commit_message (CONTEXT * ctx, MESSAGE * msg, HEADER * hdr) -{ - return _mh_commit_message (ctx, msg, hdr, 1); +static int mh_commit_message (MESSAGE * msg, CONTEXT * ctx, HEADER * hdr) { + return _mh_commit_message (msg, ctx, hdr, 1); } - /* Sync a message in an MH folder. * * This code is also used for attachment deletion in maildir @@ -1310,20 +1172,19 @@ static int mh_rewrite_message (CONTEXT * ctx, int msgno) return -1; if ((rc = mutt_copy_message (dest->fp, ctx, h, - M_CM_UPDATE, CH_UPDATE | CH_UPDATE_LEN)) == 0) + M_CM_UPDATE, CH_UPDATE | CH_UPDATE_LEN)) == 0) { - snprintf (oldpath, _POSIX_PATH_MAX, "%s/%s", ctx->path, h->path); - strfcpy (partpath, h->path, _POSIX_PATH_MAX); + snprintf (oldpath, sizeof(oldpath), "%s/%s", ctx->path, h->path); + m_strcpy(partpath, sizeof(partpath), h->path); if (ctx->magic == M_MAILDIR) - rc = maildir_commit_message (ctx, dest, h); + rc = maildir_commit_message (dest, ctx, h); else - rc = _mh_commit_message (ctx, dest, h, 0); + rc = _mh_commit_message (dest, ctx, h, 0); mx_close_message (&dest); - if (rc == 0) - { + if (rc == 0) { unlink (oldpath); restore = 0; } @@ -1343,18 +1204,16 @@ static int mh_rewrite_message (CONTEXT * ctx, int msgno) * lose flag modifications. */ - if (ctx->magic == M_MH && rc == 0) - { + if (ctx->magic == M_MH && rc == 0) { snprintf (newpath, _POSIX_PATH_MAX, "%s/%s", ctx->path, h->path); if ((rc = safe_rename (newpath, oldpath)) == 0) - mutt_str_replace (&h->path, partpath); + m_strreplace(&h->path, partpath); } } else mx_close_message (&dest); - if (rc == -1 && restore) - { + if (rc == -1 && restore) { h->content->offset = old_body_offset; h->content->length = old_body_length; h->lines = old_hdr_lines; @@ -1368,7 +1227,8 @@ static int mh_sync_message (CONTEXT * ctx, int msgno) { HEADER *h = ctx->hdrs[msgno]; - if (h->attach_del || h->refs_changed || h->irt_changed) + if (h->attach_del || + (h->env && (h->env->refs_changed || h->env->irt_changed))) if (mh_rewrite_message (ctx, msgno) != 0) return -1; @@ -1379,14 +1239,13 @@ static int maildir_sync_message (CONTEXT * ctx, int msgno) { HEADER *h = ctx->hdrs[msgno]; - if (h->attach_del || h->refs_changed || h->irt_changed) - { + if (h->attach_del || + (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); } - else - { + else { /* we just have to rename the file. */ char newpath[_POSIX_PATH_MAX]; @@ -1396,16 +1255,12 @@ static int maildir_sync_message (CONTEXT * ctx, int msgno) char suffix[16]; char *p; - if ((p = strrchr (h->path, '/')) == NULL) - { - dprint (1, - (debugfile, - "maildir_sync_message: %s: unable to find subdir!\n", - h->path)); + if ((p = strrchr (h->path, '/')) == NULL) { + debug_print (1, ("%s: unable to find subdir!\n", h->path)); return (-1); } p++; - strfcpy (newpath, p, sizeof (newpath)); + m_strcpy(newpath, sizeof(newpath), p); /* kill the previous flags */ if ((p = strchr (newpath, ':')) != NULL) @@ -1414,12 +1269,11 @@ static int maildir_sync_message (CONTEXT * ctx, int msgno) maildir_flags (suffix, sizeof (suffix), h); snprintf (partpath, sizeof (partpath), "%s/%s%s", - (h->read || h->old) ? "cur" : "new", newpath, suffix); + (h->read || h->old) ? "cur" : "new", newpath, suffix); snprintf (fullpath, sizeof (fullpath), "%s/%s", ctx->path, partpath); snprintf (oldpath, sizeof (oldpath), "%s/%s", ctx->path, h->path); - if (mutt_strcmp (fullpath, oldpath) == 0) - { + if (m_strcmp(fullpath, oldpath) == 0) { /* message hasn't really changed */ return 0; } @@ -1427,84 +1281,77 @@ static int maildir_sync_message (CONTEXT * ctx, int msgno) /* record that the message is possibly marked as trashed on disk */ h->trash = h->deleted; - if (rename (oldpath, fullpath) != 0) - { + if (rename (oldpath, fullpath) != 0) { mutt_perror ("rename"); return (-1); } - mutt_str_replace (&h->path, partpath); + m_strreplace(&h->path, partpath); } return (0); } -int mh_sync_mailbox (CONTEXT * ctx, int *index_hint) +static int mh_sync_mailbox (CONTEXT * ctx, int unused __attribute__ ((unused)), int *index_hint) { char path[_POSIX_PATH_MAX], tmp[_POSIX_PATH_MAX]; int i, j; -#if USE_HCACHE + +#ifdef USE_HCACHE void *hc = NULL; #endif /* USE_HCACHE */ if (ctx->magic == M_MH) - i = mh_check_mailbox (ctx, index_hint); - else - i = maildir_check_mailbox (ctx, index_hint); - + i = mh_check_mailbox (ctx, index_hint, 0); + else + i = maildir_check_mailbox (ctx, index_hint, 0); + if (i != 0) return i; -#if USE_HCACHE +#ifdef USE_HCACHE if (ctx->magic == M_MAILDIR) - hc = mutt_hcache_open(HeaderCache, ctx->path); + hc = mutt_hcache_open (HeaderCache, ctx->path); #endif /* USE_HCACHE */ - for (i = 0; i < ctx->msgcount; i++) - { + for (i = 0; i < ctx->msgcount; i++) { if (ctx->hdrs[i]->deleted - && (ctx->magic != M_MAILDIR || !option (OPTMAILDIRTRASH))) - { + && (ctx->magic != M_MAILDIR || !option (OPTMAILDIRTRASH))) { snprintf (path, sizeof (path), "%s/%s", ctx->path, ctx->hdrs[i]->path); if (ctx->magic == M_MAILDIR - || (option (OPTMHPURGE) && ctx->magic == M_MH)) - { -#if USE_HCACHE + || (option (OPTMHPURGE) && ctx->magic == M_MH)) { +#ifdef USE_HCACHE if (ctx->magic == M_MAILDIR) - mutt_hcache_delete (hc, ctx->hdrs[i]->path + 3, &maildir_hcache_keylen); + mutt_hcache_delete (hc, ctx->hdrs[i]->path + 3, + &maildir_hcache_keylen); #endif /* USE_HCACHE */ - unlink (path); + unlink (path); } - else if (ctx->magic == M_MH) - { - /* MH just moves files out of the way when you delete them */ - if (*ctx->hdrs[i]->path != ',') - { - snprintf (tmp, sizeof (tmp), "%s/,%s", ctx->path, - ctx->hdrs[i]->path); - unlink (tmp); - rename (path, tmp); - } + else if (ctx->magic == M_MH) { + /* MH just moves files out of the way when you delete them */ + if (*ctx->hdrs[i]->path != ',') { + snprintf (tmp, sizeof (tmp), "%s/,%s", ctx->path, + ctx->hdrs[i]->path); + unlink (tmp); + rename (path, tmp); + } } } else if (ctx->hdrs[i]->changed || ctx->hdrs[i]->attach_del || - (ctx->magic == M_MAILDIR - && (option (OPTMAILDIRTRASH) || ctx->hdrs[i]->trash) - && (ctx->hdrs[i]->deleted != ctx->hdrs[i]->trash))) - { - if (ctx->magic == M_MAILDIR) - { - if (maildir_sync_message (ctx, i) == -1) - goto err; + (ctx->magic == M_MAILDIR + && (option (OPTMAILDIRTRASH) || ctx->hdrs[i]->trash) + && (ctx->hdrs[i]->deleted != ctx->hdrs[i]->trash))) { + if (ctx->magic == M_MAILDIR) { + if (maildir_sync_message (ctx, i) == -1) + goto err; } - else - { - if (mh_sync_message (ctx, i) == -1) - goto err; + else { + if (mh_sync_message (ctx, i) == -1) + goto err; } } } -#if USE_HCACHE +#ifdef USE_HCACHE if (ctx->magic == M_MAILDIR) mutt_hcache_close (hc); #endif /* USE_HCACHE */ @@ -1518,60 +1365,56 @@ int mh_sync_mailbox (CONTEXT * ctx, int *index_hint) /* adjust indices */ - if (ctx->deleted) - { - for (i = 0, j = 0; i < ctx->msgcount; i++) - { + if (ctx->deleted) { + for (i = 0, j = 0; i < ctx->msgcount; i++) { if (!ctx->hdrs[i]->deleted - || (ctx->magic == M_MAILDIR && option (OPTMAILDIRTRASH))) - ctx->hdrs[i]->index = j++; + || (ctx->magic == M_MAILDIR && option (OPTMAILDIRTRASH))) + ctx->hdrs[i]->index = j++; } } return 0; err: -#if USE_HCACHE +#ifdef USE_HCACHE if (ctx->magic == M_MAILDIR) mutt_hcache_close (hc); #endif /* USE_HCACHE */ return -1; } -static char *maildir_canon_filename (char *dest, const char *src, size_t l) +static char *maildir_canon_filename (char *dest, const char *src, ssize_t l) { char *t, *u; if ((t = strrchr (src, '/'))) src = t + 1; - strfcpy (dest, src, l); + m_strcpy(dest, l, src); if ((u = strrchr (dest, ':'))) *u = '\0'; return dest; } -static void maildir_update_tables (CONTEXT *ctx, int *index_hint) +static void maildir_update_tables (CONTEXT * ctx, int *index_hint) { short old_sort; int old_count; int i, j; - - if (Sort != SORT_ORDER) - { + + if (Sort != SORT_ORDER) { old_sort = Sort; Sort = SORT_ORDER; mutt_sort_headers (ctx, 1); Sort = old_sort; } - + old_count = ctx->msgcount; - for (i = 0, j = 0; i < old_count; i++) - { + for (i = 0, j = 0; i < old_count; i++) { if (ctx->hdrs[i]->active && index_hint && *index_hint == i) *index_hint = j; - + if (ctx->hdrs[i]->active) ctx->hdrs[i]->index = j++; } @@ -1580,13 +1423,13 @@ static void maildir_update_tables (CONTEXT *ctx, int *index_hint) mutt_clear_threads (ctx); } -static void maildir_update_flags (CONTEXT *ctx, HEADER *o, HEADER *n) +static void maildir_update_flags (CONTEXT * ctx, HEADER * o, HEADER * n) { /* save the global state here so we can reset it at the * end of list block if required. */ int context_changed = ctx->changed; - + /* user didn't modify this message. alter the flags to * match the current state on disk. This may not actually * do anything, but we can't tell right now. mutt_set_flag() @@ -1604,7 +1447,7 @@ static void maildir_update_flags (CONTEXT *ctx, HEADER *o, HEADER *n) * message. */ o->changed = 0; - + /* if the mailbox was not modified before we made these * changes, unset the changed flag since nothing needs to * be synchronized. @@ -1622,24 +1465,21 @@ static void maildir_update_flags (CONTEXT *ctx, HEADER *o, HEADER *n) * either subdirectory differently, as mail could be copied directly into * the cur directory from another agent. */ -int maildir_check_mailbox (CONTEXT * ctx, int *index_hint) +static int maildir_check_mailbox (CONTEXT * ctx, int *index_hint, int unused __attribute__ ((unused))) { - struct stat st_new; /* status of the "new" subdirectory */ - struct stat st_cur; /* status of the "cur" subdirectory */ + struct stat st_new; /* status of the "new" subdirectory */ + struct stat st_cur; /* status of the "cur" subdirectory */ char buf[_POSIX_PATH_MAX]; - int changed = 0; /* bitmask representing which subdirectories - have changed. 0x1 = new, 0x2 = cur */ - int occult = 0; /* messages were removed from the mailbox */ - int have_new = 0; /* messages were added to the mailbox */ - struct maildir *md; /* list of messages in the mailbox */ + int changed = 0; /* bitmask representing which subdirectories + have changed. 0x1 = new, 0x2 = cur */ + int occult = 0; /* messages were removed from the mailbox */ + int have_new = 0; /* messages were added to the mailbox */ + 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 - for a maildir message */ + HASH *fnames; /* hash table for quickly looking up the base filename + for a maildir message */ - /* XXX seems like this check belongs in mx_check_mailbox() - * rather than here. - */ if (!option (OPTCHECKNEW)) return 0; @@ -1658,7 +1498,7 @@ int maildir_check_mailbox (CONTEXT * ctx, int *index_hint) changed |= 2; if (!changed) - return 0; /* nothing to do */ + return 0; /* nothing to do */ /* update the modification times on the mailbox */ ctx->mtime_cur = st_cur.st_mtime; @@ -1680,58 +1520,53 @@ int maildir_check_mailbox (CONTEXT * ctx, int *index_hint) */ fnames = hash_create (1031); - for (p = md; p; p = p->next) - { + for (p = md; p; p = p->next) { maildir_canon_filename (buf, p->h->path, sizeof (buf)); - p->canon_fname = safe_strdup (buf); + p->canon_fname = m_strdup(buf); hash_insert (fnames, p->canon_fname, p, 0); } /* check for modifications and adjust flags */ - for (i = 0; i < ctx->msgcount; i++) - { + for (i = 0; i < ctx->msgcount; i++) { ctx->hdrs[i]->active = 0; maildir_canon_filename (buf, ctx->hdrs[i]->path, sizeof (buf)); p = hash_find (fnames, buf); - if (p && p->h) - { + if (p && p->h) { /* message already exists, merge flags */ ctx->hdrs[i]->active = 1; /* check to see if the message has moved to a different * subdirectory. If so, update the associated filename. */ - if (mutt_strcmp (ctx->hdrs[i]->path, p->h->path)) - mutt_str_replace (&ctx->hdrs[i]->path, p->h->path); + if (m_strcmp(ctx->hdrs[i]->path, p->h->path)) + m_strreplace(&ctx->hdrs[i]->path, p->h->path); /* if the user hasn't modified the flags on this message, update * the flags we just detected. */ if (!ctx->hdrs[i]->changed) - maildir_update_flags (ctx, ctx->hdrs[i], p->h); + maildir_update_flags (ctx, ctx->hdrs[i], p->h); if (ctx->hdrs[i]->deleted == ctx->hdrs[i]->trash) - ctx->hdrs[i]->deleted = p->h->deleted; + ctx->hdrs[i]->deleted = p->h->deleted; ctx->hdrs[i]->trash = p->h->trash; /* this is a duplicate of an existing header, so remove it */ - mutt_free_header (&p->h); + header_delete(&p->h); } /* This message was not in the list of messages we just scanned. * Check to see if we have enough information to know if the * message has disappeared out from underneath us. */ else if (((changed & 1) && (!strncmp (ctx->hdrs[i]->path, "new/", 4))) || - ((changed & 2) && (!strncmp (ctx->hdrs[i]->path, "cur/", 4)))) - { + ((changed & 2) && (!strncmp (ctx->hdrs[i]->path, "cur/", 4)))) { /* This message disappeared, so we need to simulate a "reopen" * event. We know it disappeared because we just scanned the * subdirectory it used to reside in. */ occult = 1; } - else - { + else { /* This message resides in a subdirectory which was not * modified, so we assume that it is still present and * unchanged. @@ -1746,7 +1581,7 @@ int maildir_check_mailbox (CONTEXT * ctx, int *index_hint) /* If we didn't just get new mail, update the tables. */ if (occult) maildir_update_tables (ctx, index_hint); - + /* do any delayed parsing we need to do. */ maildir_delayed_parsing (ctx, md); @@ -1767,7 +1602,7 @@ int maildir_check_mailbox (CONTEXT * ctx, int *index_hint) * */ -int mh_check_mailbox (CONTEXT * ctx, int *index_hint) +static int mh_check_mailbox (CONTEXT * ctx, int *index_hint, int unused __attribute__ ((unused))) { char buf[_POSIX_PATH_MAX]; struct stat st, st_cur; @@ -1781,23 +1616,21 @@ int mh_check_mailbox (CONTEXT * ctx, int *index_hint) if (!option (OPTCHECKNEW)) return 0; - strfcpy (buf, ctx->path, sizeof (buf)); + m_strcpy(buf, sizeof(buf), ctx->path); if (stat (buf, &st) == -1) return -1; - + /* create .mh_sequences when there isn't one. */ snprintf (buf, sizeof (buf), "%s/.mh_sequences", ctx->path); - if ((i = stat (buf, &st_cur) == -1) && errno == ENOENT) - { + if ((i = stat (buf, &st_cur) == -1) && errno == ENOENT) { char *tmp; FILE *fp = NULL; - - if (mh_mkstemp (ctx, &fp, &tmp) == 0) - { + + if (mh_mkstemp (ctx, &fp, &tmp) == 0) { safe_fclose (&fp); if (safe_rename (tmp, buf) == -1) - unlink (tmp); - FREE (&tmp); + unlink (tmp); + p_delete(&tmp); } } @@ -1813,9 +1646,9 @@ int mh_check_mailbox (CONTEXT * ctx, int *index_hint) ctx->mtime_cur = st_cur.st_mtime; ctx->mtime = st.st_mtime; - memset (&mhs, 0, sizeof (mhs)); - - md = NULL; + p_clear(&mhs, 1); + + md = NULL; last = &md; maildir_parse_dir (ctx, &last, NULL, NULL); mh_read_sequences (&mhs, ctx->path); @@ -1828,21 +1661,19 @@ int mh_check_mailbox (CONTEXT * ctx, int *index_hint) for (p = md; p; p = p->next) hash_insert (fnames, p->h->path, p, 0); - for (i = 0; i < ctx->msgcount; i++) - { + for (i = 0; i < ctx->msgcount; i++) { ctx->hdrs[i]->active = 0; if ((p = hash_find (fnames, ctx->hdrs[i]->path)) && p->h && - (mbox_strict_cmp_headers (ctx->hdrs[i], p->h))) - { + (mutt_cmp_header (ctx->hdrs[i], p->h))) { ctx->hdrs[i]->active = 1; /* found the right message */ if (!ctx->hdrs[i]->changed) - maildir_update_flags (ctx, ctx->hdrs[i], p->h); + maildir_update_flags (ctx, ctx->hdrs[i], p->h); - mutt_free_header (&p->h); + header_delete(&p->h); } - else /* message has disappeared */ + else /* message has disappeared */ occult = 1; } @@ -1870,7 +1701,7 @@ int mh_check_mailbox (CONTEXT * ctx, int *index_hint) */ FILE *_maildir_open_find_message (const char *folder, const char *unique, - const char *subfolder) + const char *subfolder) { char dir[_POSIX_PATH_MAX]; char tunique[_POSIX_PATH_MAX]; @@ -1884,21 +1715,18 @@ FILE *_maildir_open_find_message (const char *folder, const char *unique, snprintf (dir, sizeof (dir), "%s/%s", folder, subfolder); - if ((dp = opendir (dir)) == NULL) - { + if ((dp = opendir (dir)) == NULL) { errno = ENOENT; return NULL; } - while ((de = readdir (dp))) - { + while ((de = readdir (dp))) { maildir_canon_filename (tunique, de->d_name, sizeof (tunique)); - if (!mutt_strcmp (tunique, unique)) - { + if (!m_strcmp(tunique, unique)) { snprintf (fname, sizeof (fname), "%s/%s/%s", folder, subfolder, - de->d_name); - fp = fopen (fname, "r"); /* __FOPEN_CHECKED__ */ + de->d_name); + fp = fopen (fname, "r"); /* __FOPEN_CHECKED__ */ oe = errno; break; } @@ -1915,32 +1743,26 @@ FILE *maildir_open_find_message (const char *folder, const char *msg) char unique[_POSIX_PATH_MAX]; FILE *fp; - static unsigned int new_hits = 0, cur_hits = 0; /* simple dynamic optimization */ + static unsigned int new_hits = 0, cur_hits = 0; /* simple dynamic optimization */ maildir_canon_filename (unique, msg, sizeof (unique)); - if ( - (fp = + if ((fp = _maildir_open_find_message (folder, unique, - new_hits > cur_hits ? "new" : "cur")) - || errno != ENOENT) - { - if (new_hits < UINT_MAX && cur_hits < UINT_MAX) - { + new_hits > cur_hits ? "new" : "cur")) + || errno != ENOENT) { + if (new_hits < UINT_MAX && cur_hits < UINT_MAX) { new_hits += (new_hits > cur_hits ? 1 : 0); cur_hits += (new_hits > cur_hits ? 0 : 1); } return fp; } - if ( - (fp = + if ((fp = _maildir_open_find_message (folder, unique, - new_hits > cur_hits ? "cur" : "new")) - || errno != ENOENT) - { - if (new_hits < UINT_MAX && cur_hits < UINT_MAX) - { + new_hits > cur_hits ? "cur" : "new")) + || errno != ENOENT) { + if (new_hits < UINT_MAX && cur_hits < UINT_MAX) { new_hits += (new_hits > cur_hits ? 0 : 1); cur_hits += (new_hits > cur_hits ? 1 : 0); } @@ -1958,12 +1780,12 @@ FILE *maildir_open_find_message (const char *folder, const char *msg) * 0 if there are messages in the mailbox * -1 on error */ -int maildir_check_empty (const char *path) +static int maildir_check_empty (const char *path) { DIR *dp; struct dirent *de; - int r = 1; /* assume empty until we find a message */ - char realpath[_POSIX_PATH_MAX]; + int r = 1; /* assume empty until we find a message */ + char frealpath[_POSIX_PATH_MAX]; int iter = 0; /* Strategy here is to look for any file not beginning with a period */ @@ -1972,16 +1794,14 @@ int maildir_check_empty (const char *path) /* we do "cur" on the first iteration since its more likely that we'll * find old messages without having to scan both subdirs */ - snprintf (realpath, sizeof (realpath), "%s/%s", path, - iter == 0 ? "cur" : "new"); - if ((dp = opendir (realpath)) == NULL) + snprintf (frealpath, sizeof (frealpath), "%s/%s", path, + iter == 0 ? "cur" : "new"); + if ((dp = opendir (frealpath)) == NULL) return -1; - while ((de = readdir (dp))) - { - if (*de->d_name != '.') - { - r = 0; - break; + while ((de = readdir (dp))) { + if (*de->d_name != '.') { + r = 0; + break; } } closedir (dp); @@ -2001,19 +1821,106 @@ int mh_check_empty (const char *path) { DIR *dp; struct dirent *de; - int r = 1; /* assume empty until we find a message */ - + int r = 1; /* assume empty until we find a message */ + if ((dp = opendir (path)) == NULL) return -1; - while ((de = readdir (dp))) - { - if (mh_valid_message (de->d_name)) - { + while ((de = readdir (dp))) { + if (mh_valid_message (de->d_name)) { r = 0; break; } } closedir (dp); - + 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. ;-) + */ + + snprintf (tmp, sizeof (tmp), "%s/.overview", path); + if (access (tmp, F_OK) == 0) + return (M_MH); + } + return (-1); +} + +static int maildir_is_magic (const char* path, struct stat* st) { + struct stat sb; + char tmp[_POSIX_PATH_MAX]; + + 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); +} + +/* routines common to maildir and mh */ +static mx_t* reg_mx (void) { + mx_t* fmt = p_new(mx_t, 1); + fmt->local = 1; + fmt->mx_access = access; + fmt->mx_sync_mailbox = mh_sync_mailbox; + return (fmt); +} + +static int mh_commit (MESSAGE* msg, CONTEXT* ctx) { + return (mh_commit_message (msg, ctx, NULL)); +} + +static int maildir_commit (MESSAGE* msg, CONTEXT* ctx) { + return (maildir_commit_message (msg, ctx, NULL)); +} + +mx_t* mh_reg_mx (void) { + mx_t* fmt = reg_mx (); + fmt->type = M_MH; + fmt->mx_check_empty = mh_check_empty; + fmt->mx_is_magic = mh_is_magic; + fmt->mx_open_mailbox = mh_read_dir; + fmt->mx_open_new_message = mh_open_new_message; + fmt->mx_check_mailbox = mh_check_mailbox; + fmt->mx_commit_message = mh_commit; + return (fmt); +} + +mx_t* maildir_reg_mx (void) { + mx_t* fmt = reg_mx (); + fmt->type = M_MAILDIR; + fmt->mx_check_empty = maildir_check_empty; + fmt->mx_is_magic = maildir_is_magic; + fmt->mx_open_mailbox = maildir_read_dir; + fmt->mx_open_new_message = maildir_open_new_message; + fmt->mx_check_mailbox = maildir_check_mailbox; + fmt->mx_commit_message = maildir_commit; + return (fmt); +}