X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=mbox.c;h=5f76334032d67b348f77e01656105518a4a4c76b;hp=3d1a31cc6571a993e351724ab6ee8b0576450660;hb=dbacadf0ce81052365d7a43373ac7d4ac67ff91e;hpb=25bf57d598476b329536fa3f748cc0c529fef6bd diff --git a/mbox.c b/mbox.c index 3d1a31c..5f76334 100644 --- a/mbox.c +++ b/mbox.c @@ -13,20 +13,6 @@ # include "config.h" #endif -#include "mutt.h" -#include "mx.h" -#include "mbox.h" -#include "sort.h" -#include "copy.h" - -#ifdef USE_COMPRESSED -#include "compress.h" -#endif - -#include "lib/mem.h" -#include "lib/intl.h" -#include "lib/str.h" - #include #include #include @@ -36,22 +22,42 @@ #include #include +#include +#include +#include +#include +#include + +#include + +#include "mutt.h" +#include "mx.h" +#include "buffy.h" +#include "mbox.h" +#include "sort.h" +#include "thread.h" +#include "copy.h" +#include "compress.h" + /* struct used by mutt_sync_mailbox() to store new offsets */ struct m_update_t { short valid; - long hdr; - long body; + off_t hdr; + off_t body; long lines; - long length; + off_t length; }; -int mbox_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) +static int mbox_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr __attribute__ ((unused))) { msg->fp = dest->fp; return 0; } +/* prototypes */ +static int mbox_reopen_mailbox (CONTEXT*, int*); + /* parameters: * ctx - context to lock * excl - exclusive lock? @@ -81,21 +87,17 @@ void mbox_unlock_mailbox (CONTEXT * ctx) } } -int mmdf_parse_mailbox (CONTEXT * ctx) +static int mmdf_parse_mailbox (CONTEXT * ctx) { char buf[HUGE_STRING]; char return_path[LONG_STRING]; int count = 0, oldmsgcount = ctx->msgcount; int lines; time_t t, tz; - long loc, tmploc; + off_t loc, tmploc; HEADER *hdr; struct stat sb; -#ifdef NFS_ATTRIBUTE_HACK - struct utimbuf newtime; -#endif - if (stat (ctx->path, &sb) == -1) { mutt_perror (ctx->path); return (-1); @@ -103,26 +105,18 @@ int mmdf_parse_mailbox (CONTEXT * ctx) ctx->mtime = sb.st_mtime; ctx->size = sb.st_size; -#ifdef NFS_ATTRIBUTE_HACK - if (sb.st_mtime > sb.st_atime) { - newtime.modtime = sb.st_mtime; - newtime.actime = time (NULL); - utime (ctx->path, &newtime); - } -#endif - /* precompute the local timezone to speed up calculation of the received time */ tz = mutt_local_tz (0); buf[sizeof (buf) - 1] = 0; - FOREVER { + for (;;) { if (fgets (buf, sizeof (buf) - 1, ctx->fp) == NULL) break; - if (safe_strcmp (buf, MMDF_SEP) == 0) { - loc = ftell (ctx->fp); + if (m_strcmp(buf, MMDF_SEP) == 0) { + loc = ftello (ctx->fp); count++; if (!ctx->quiet && ReadInc && ((count % ReadInc == 0) || count == 1)) @@ -132,21 +126,21 @@ int mmdf_parse_mailbox (CONTEXT * ctx) if (ctx->msgcount == ctx->hdrmax) mx_alloc_memory (ctx); - ctx->hdrs[ctx->msgcount] = hdr = mutt_new_header (); + ctx->hdrs[ctx->msgcount] = hdr = header_new(); hdr->offset = loc; hdr->index = ctx->msgcount; if (fgets (buf, sizeof (buf) - 1, ctx->fp) == NULL) { /* TODO: memory leak??? */ - dprint (1, (debugfile, "mmdf_parse_mailbox: unexpected EOF\n")); + debug_print (1, ("unexpected EOF\n")); break; } return_path[0] = 0; if (!is_from (buf, return_path, sizeof (return_path), &t)) { - if (fseek (ctx->fp, loc, SEEK_SET) != 0) { - dprint (1, (debugfile, "mmdf_parse_mailbox: fseek() failed\n")); + if (fseeko (ctx->fp, loc, SEEK_SET) != 0) { + debug_print (1, ("fseeko() failed\n")); mutt_error _("Mailbox is corrupt!"); return (-1); @@ -157,17 +151,17 @@ int mmdf_parse_mailbox (CONTEXT * ctx) hdr->env = mutt_read_rfc822_header (ctx->fp, hdr, 0, 0); - loc = ftell (ctx->fp); + loc = ftello (ctx->fp); if (hdr->content->length > 0 && hdr->lines > 0) { tmploc = loc + hdr->content->length; if (0 < tmploc && tmploc < ctx->size) { - if (fseek (ctx->fp, tmploc, SEEK_SET) != 0 || + if (fseeko (ctx->fp, tmploc, SEEK_SET) != 0 || fgets (buf, sizeof (buf) - 1, ctx->fp) == NULL || - safe_strcmp (MMDF_SEP, buf) != 0) { - if (fseek (ctx->fp, loc, SEEK_SET) != 0) - dprint (1, (debugfile, "mmdf_parse_mailbox: fseek() failed\n")); + m_strcmp(MMDF_SEP, buf) != 0) { + if (fseeko (ctx->fp, loc, SEEK_SET) != 0) + debug_print (1, ("fseeko() failed\n")); hdr->content->length = -1; } } @@ -180,11 +174,11 @@ int mmdf_parse_mailbox (CONTEXT * ctx) if (hdr->content->length < 0) { lines = -1; do { - loc = ftell (ctx->fp); + loc = ftello (ctx->fp); if (fgets (buf, sizeof (buf) - 1, ctx->fp) == NULL) break; lines++; - } while (safe_strcmp (buf, MMDF_SEP) != 0); + } while (m_strcmp(buf, MMDF_SEP) != 0); hdr->lines = lines; hdr->content->length = loc - hdr->content->offset; @@ -195,12 +189,12 @@ int mmdf_parse_mailbox (CONTEXT * ctx) rfc822_parse_adrlist (hdr->env->return_path, return_path); if (!hdr->env->from) - hdr->env->from = rfc822_cpy_adr (hdr->env->return_path); + hdr->env->from = address_list_dup (hdr->env->return_path); ctx->msgcount++; } else { - dprint (1, (debugfile, "mmdf_parse_mailbox: corrupt mailbox!\n")); + debug_print (1, ("corrupt mailbox!\n")); mutt_error _("Mailbox is corrupt!"); return (-1); @@ -219,18 +213,14 @@ int mmdf_parse_mailbox (CONTEXT * ctx) * NOTE: it is assumed that the mailbox being read has been locked before * this routine gets called. Strange things could happen if it's not! */ -int mbox_parse_mailbox (CONTEXT * ctx) +static int mbox_parse_mailbox (CONTEXT * ctx) { struct stat sb; char buf[HUGE_STRING], return_path[STRING]; HEADER *curhdr; time_t t, tz; int count = 0, lines = 0; - long loc; - -#ifdef NFS_ATTRIBUTE_HACK - struct utimbuf newtime; -#endif + off_t loc; /* Save information about the folder at the time we opened it. */ if (stat (ctx->path, &sb) == -1) { @@ -241,14 +231,6 @@ int mbox_parse_mailbox (CONTEXT * ctx) ctx->size = sb.st_size; ctx->mtime = sb.st_mtime; -#ifdef NFS_ATTRIBUTE_HACK - if (sb.st_mtime > sb.st_atime) { - newtime.modtime = sb.st_mtime; - newtime.actime = time (NULL); - utime (ctx->path, &newtime); - } -#endif - if (!ctx->readonly) ctx->readonly = access (ctx->path, W_OK) ? 1 : 0; @@ -256,7 +238,7 @@ int mbox_parse_mailbox (CONTEXT * ctx) date received */ tz = mutt_local_tz (0); - loc = ftell (ctx->fp); + loc = ftello (ctx->fp); while (fgets (buf, sizeof (buf), ctx->fp) != NULL) { if (is_from (buf, return_path, sizeof (return_path), &t)) { /* Save the Content-Length of the previous message */ @@ -276,12 +258,12 @@ int mbox_parse_mailbox (CONTEXT * ctx) if (!ctx->quiet && ReadInc && ((count % ReadInc == 0) || count == 1)) mutt_message (_("Reading %s... %d (%d%%)"), ctx->path, count, - (int) (ftell (ctx->fp) / (ctx->size / 100 + 1))); + (int) (ftello (ctx->fp) / (ctx->size / 100 + 1))); if (ctx->msgcount == ctx->hdrmax) mx_alloc_memory (ctx); - curhdr = ctx->hdrs[ctx->msgcount] = mutt_new_header (); + curhdr = ctx->hdrs[ctx->msgcount] = header_new(); curhdr->received = t - tz; curhdr->offset = loc; curhdr->index = ctx->msgcount; @@ -293,9 +275,9 @@ int mbox_parse_mailbox (CONTEXT * ctx) * save time by not having to search for the next message marker). */ if (curhdr->content->length > 0) { - long tmploc; + off_t tmploc; - loc = ftell (ctx->fp); + loc = ftello (ctx->fp); tmploc = loc + curhdr->content->length + 1; if (0 < tmploc && tmploc < ctx->size) { @@ -303,16 +285,14 @@ int mbox_parse_mailbox (CONTEXT * ctx) * check to see if the content-length looks valid. we expect to * to see a valid message separator at this point in the stream */ - if (fseek (ctx->fp, tmploc, SEEK_SET) != 0 || + if (fseeko (ctx->fp, tmploc, SEEK_SET) != 0 || fgets (buf, sizeof (buf), ctx->fp) == NULL || - safe_strncmp ("From ", buf, 5) != 0) { - dprint (1, - (debugfile, - "mbox_parse_mailbox: bad content-length in message %d (cl=%ld)\n", - curhdr->index, curhdr->content->length)); - dprint (1, (debugfile, "\tLINE: %s", buf)); - if (fseek (ctx->fp, loc, SEEK_SET) != 0) { /* nope, return the previous position */ - dprint (1, (debugfile, "mbox_parse_mailbox: fseek() failed\n")); + m_strncmp("From ", buf, 5) != 0) { + debug_print (1, ("bad content-length in message %d (cl=%zd)\n", + curhdr->index, curhdr->content->length)); + debug_print (1, ("LINE: %s\n", buf)); + if (fseeko (ctx->fp, loc, SEEK_SET) != 0) { /* nope, return the previous position */ + debug_print (1, ("fseeko() failed\n")); } curhdr->content->length = -1; } @@ -332,8 +312,8 @@ int mbox_parse_mailbox (CONTEXT * ctx) int cl = curhdr->content->length; /* count the number of lines in this message */ - if (fseek (ctx->fp, loc, SEEK_SET) != 0) - dprint (1, (debugfile, "mbox_parse_mailbox: fseek() failed\n")); + if (fseeko (ctx->fp, loc, SEEK_SET) != 0) + debug_print (1, ("fseeko() failed\n")); while (cl-- > 0) { if (fgetc (ctx->fp) == '\n') curhdr->lines++; @@ -341,8 +321,8 @@ int mbox_parse_mailbox (CONTEXT * ctx) } /* return to the offset of the next message separator */ - if (fseek (ctx->fp, tmploc, SEEK_SET) != 0) - dprint (1, (debugfile, "mbox_parse_mailbox: fseek() failed\n")); + if (fseeko (ctx->fp, tmploc, SEEK_SET) != 0) + debug_print (1, ("fseeko() failed\n")); } } @@ -353,14 +333,14 @@ int mbox_parse_mailbox (CONTEXT * ctx) rfc822_parse_adrlist (curhdr->env->return_path, return_path); if (!curhdr->env->from) - curhdr->env->from = rfc822_cpy_adr (curhdr->env->return_path); + curhdr->env->from = address_list_dup (curhdr->env->return_path); lines = 0; } else lines++; - loc = ftell (ctx->fp); + loc = ftello (ctx->fp); } /* @@ -371,7 +351,7 @@ int mbox_parse_mailbox (CONTEXT * ctx) */ if (count > 0) { if (PREV->content->length < 0) { - PREV->content->length = ftell (ctx->fp) - PREV->content->offset - 1; + PREV->content->length = ftello (ctx->fp) - PREV->content->offset - 1; if (PREV->content->length < 0) PREV->content->length = 0; } @@ -388,7 +368,7 @@ int mbox_parse_mailbox (CONTEXT * ctx) #undef PREV /* open a mbox or mmdf style mailbox */ -int mbox_open_mailbox (CONTEXT * ctx) +static int mbox_open_mailbox (CONTEXT * ctx) { int rc; @@ -414,116 +394,6 @@ int mbox_open_mailbox (CONTEXT * ctx) return (rc); } -/* return 1 if address lists are strictly identical */ -static int strict_addrcmp (const ADDRESS * a, const ADDRESS * b) -{ - while (a && b) { - if (safe_strcmp (a->mailbox, b->mailbox) || - safe_strcmp (a->personal, b->personal)) - return (0); - - a = a->next; - b = b->next; - } - if (a || b) - return (0); - - return (1); -} - -static int strict_cmp_lists (const LIST * a, const LIST * b) -{ - while (a && b) { - if (safe_strcmp (a->data, b->data)) - return (0); - - a = a->next; - b = b->next; - } - if (a || b) - return (0); - - return (1); -} - -static int strict_cmp_envelopes (const ENVELOPE * e1, const ENVELOPE * e2) -{ - if (e1 && e2) { - if (safe_strcmp (e1->message_id, e2->message_id) || - safe_strcmp (e1->subject, e2->subject) || - !strict_cmp_lists (e1->references, e2->references) || - !strict_addrcmp (e1->from, e2->from) || - !strict_addrcmp (e1->sender, e2->sender) || - !strict_addrcmp (e1->reply_to, e2->reply_to) || - !strict_addrcmp (e1->to, e2->to) || - !strict_addrcmp (e1->cc, e2->cc) || - !strict_addrcmp (e1->return_path, e2->return_path)) - return (0); - else - return (1); - } - else { - if (e1 == NULL && e2 == NULL) - return (1); - else - return (0); - } -} - -static int strict_cmp_parameters (const PARAMETER * p1, const PARAMETER * p2) -{ - while (p1 && p2) { - if (safe_strcmp (p1->attribute, p2->attribute) || - safe_strcmp (p1->value, p2->value)) - return (0); - - p1 = p1->next; - p2 = p2->next; - } - if (p1 || p2) - return (0); - - return (1); -} - -static int strict_cmp_bodies (const BODY * b1, const BODY * b2) -{ - if (b1->type != b2->type || - b1->encoding != b2->encoding || - safe_strcmp (b1->subtype, b2->subtype) || - safe_strcmp (b1->description, b2->description) || - !strict_cmp_parameters (b1->parameter, b2->parameter) || - b1->length != b2->length) - return (0); - return (1); -} - -/* return 1 if headers are strictly identical */ -int mbox_strict_cmp_headers (const HEADER * h1, const HEADER * h2) -{ - if (h1 && h2) { - if (h1->received != h2->received || - h1->date_sent != h2->date_sent || - h1->content->length != h2->content->length || - h1->lines != h2->lines || - h1->zhours != h2->zhours || - h1->zminutes != h2->zminutes || - h1->zoccident != h2->zoccident || - h1->mime != h2->mime || - !strict_cmp_envelopes (h1->env, h2->env) || - !strict_cmp_bodies (h1->content, h2->content)) - return (0); - else - return (1); - } - else { - if (h1 == NULL && h2 == NULL) - return (1); - else - return (0); - } -} - /* check to see if the mailbox has changed on disk. * * return values: @@ -533,7 +403,7 @@ int mbox_strict_cmp_headers (const HEADER * h1, const HEADER * h2) * 0 no change * -1 error */ -int mbox_check_mailbox (CONTEXT * ctx, int *index_hint) +static int _mbox_check_mailbox (CONTEXT * ctx, int *index_hint) { struct stat st; char buffer[LONG_STRING]; @@ -571,13 +441,13 @@ int mbox_check_mailbox (CONTEXT * ctx, int *index_hint) * see the message separator at *exactly* what used to be the end of the * folder. */ - if (fseek (ctx->fp, ctx->size, SEEK_SET) != 0) - dprint (1, (debugfile, "mbox_check_mailbox: fseek() failed\n")); + if (fseeko (ctx->fp, ctx->size, SEEK_SET) != 0) + debug_print (1, ("fseeko() failed\n")); if (fgets (buffer, sizeof (buffer), ctx->fp) != NULL) { - if ((ctx->magic == M_MBOX && safe_strncmp ("From ", buffer, 5) == 0) - || (ctx->magic == M_MMDF && safe_strcmp (MMDF_SEP, buffer) == 0)) { - if (fseek (ctx->fp, ctx->size, SEEK_SET) != 0) - dprint (1, (debugfile, "mbox_check_mailbox: fseek() failed\n")); + if ((ctx->magic == M_MBOX && m_strncmp("From ", buffer, 5) == 0) + || (ctx->magic == M_MMDF && m_strcmp(MMDF_SEP, buffer) == 0)) { + if (fseeko (ctx->fp, ctx->size, SEEK_SET) != 0) + debug_print (1, ("fseeko() failed\n")); if (ctx->magic == M_MBOX) mbox_parse_mailbox (ctx); else @@ -599,7 +469,7 @@ int mbox_check_mailbox (CONTEXT * ctx, int *index_hint) modified = 1; } else { - dprint (1, (debugfile, "mbox_check_mailbox: fgets returned NULL.\n")); + debug_print (1, ("fgets returned NULL.\n")); modified = 1; } } @@ -627,11 +497,31 @@ int mbox_check_mailbox (CONTEXT * ctx, int *index_hint) return (-1); } +static int mbox_check_mailbox (CONTEXT* ctx, int* index_hint, int lock) { + int rc = 0; + + if (lock) { + mutt_block_signals (); + if (mbox_lock_mailbox (ctx, 0, 0) == -1) { + mutt_unblock_signals (); + return M_LOCKED; + } + } + + rc = _mbox_check_mailbox (ctx, index_hint); + + if (lock) { + mutt_unblock_signals (); + mbox_unlock_mailbox (ctx); + } + return rc; +} + /* return values: * 0 success * -1 failure */ -int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) +static int _mbox_sync_mailbox (CONTEXT * ctx, int unused __attribute__ ((unused)), int *index_hint) { char tempfile[_POSIX_PATH_MAX]; char buf[32]; @@ -639,7 +529,7 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) int rc = -1; int need_sort = 0; /* flag to resort mailbox if new mail arrives */ int first = -1; /* first message to be written */ - long offset; /* location in mailbox to write changed messages */ + off_t offset; /* location in mailbox to write changed messages */ struct stat statbuf; struct utimbuf utimebuf; struct m_update_t *newOffset = NULL; @@ -651,6 +541,8 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) save_sort = Sort; Sort = SORT_ORDER; mutt_sort_headers (ctx, 0); + Sort = save_sort; + need_sort = 1; } /* need to open the file for writing in such a way that it does not truncate @@ -673,18 +565,16 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) } /* Check to make sure that the file hasn't changed on disk */ - if ((i = mbox_check_mailbox (ctx, index_hint)) == M_NEW_MAIL + if ((i = _mbox_check_mailbox (ctx, index_hint)) == M_NEW_MAIL || i == M_REOPENED) { /* new mail arrived, or mailbox reopened */ need_sort = i; rc = i; goto bail; } - else if (i < 0) { + else if (i < 0) /* fatal error */ - Sort = save_sort; return (-1); - } /* Create a temporary file to write the new version of the mailbox in. */ mutt_mktemp (tempfile); @@ -713,7 +603,7 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) mutt_error _("sync: mbox modified, but no modified messages! (report this bug)"); mutt_sleep (5); /* the mutt_error /will/ get cleared! */ - dprint (1, (debugfile, "mbox_sync_mailbox(): no modified messages.\n")); + debug_print (1, ("no modified messages.\n")); unlink (tempfile); goto bail; } @@ -730,8 +620,8 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) offset -= (sizeof MMDF_SEP - 1); /* allocate space for the new offsets */ - newOffset = safe_calloc (ctx->msgcount - first, sizeof (struct m_update_t)); - oldOffset = safe_calloc (ctx->msgcount - first, sizeof (struct m_update_t)); + newOffset = p_new(struct m_update_t, ctx->msgcount - first); + oldOffset = p_new(struct m_update_t, ctx->msgcount - first); for (i = first, j = 0; i < ctx->msgcount; i++) { /* @@ -749,7 +639,7 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) j++; if (!ctx->quiet && WriteInc && ((i % WriteInc) == 0 || j == 1)) mutt_message (_("Writing messages... %d (%d%%)"), i, - (int) (ftell (ctx->fp) / (ctx->size / 100 + 1))); + (int) (ftello (ctx->fp) / (ctx->size / 100 + 1))); if (ctx->magic == M_MMDF) { if (fputs (MMDF_SEP, fp) == EOF) { @@ -765,7 +655,7 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) * temporary file only contains saved message which are located after * `offset' in the real mailbox */ - newOffset[i - first].hdr = ftell (fp) + offset; + newOffset[i - first].hdr = ftello (fp) + offset; if (mutt_copy_message (fp, ctx, ctx->hdrs[i], M_CM_UPDATE, @@ -783,7 +673,7 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) * if the user accesses it later. */ newOffset[i - first].body = - ftell (fp) - ctx->hdrs[i]->content->length + offset; + ftello (fp) - ctx->hdrs[i]->content->length + offset; mutt_free_body (&ctx->hdrs[i]->content->parts); switch (ctx->magic) { @@ -808,8 +698,7 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) if (fclose (fp) != 0) { fp = NULL; - dprint (1, - (debugfile, "mbox_sync_mailbox: fclose() returned non-zero.\n")); + debug_print (1, ("fclose() returned non-zero.\n")); unlink (tempfile); mutt_perror (tempfile); mutt_sleep (5); @@ -828,29 +717,25 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) if ((fp = fopen (tempfile, "r")) == NULL) { mutt_unblock_signals (); mx_fastclose_mailbox (ctx); - dprint (1, - (debugfile, - "mbox_sync_mailbox: unable to reopen temp copy of mailbox!\n")); + debug_print (1, ("unable to reopen temp copy of mailbox!\n")); mutt_perror (tempfile); mutt_sleep (5); return (-1); } - if (fseek (ctx->fp, offset, SEEK_SET) != 0 || /* seek the append location */ + if (fseeko (ctx->fp, offset, SEEK_SET) != 0 || /* seek the append location */ /* do a sanity check to make sure the mailbox looks ok */ fgets (buf, sizeof (buf), ctx->fp) == NULL || - (ctx->magic == M_MBOX && safe_strncmp ("From ", buf, 5) != 0) || - (ctx->magic == M_MMDF && safe_strcmp (MMDF_SEP, buf) != 0)) { - dprint (1, - (debugfile, - "mbox_sync_mailbox: message not in expected position.")); - dprint (1, (debugfile, "\tLINE: %s\n", buf)); + (ctx->magic == M_MBOX && m_strncmp("From ", buf, 5) != 0) || + (ctx->magic == M_MMDF && m_strcmp(MMDF_SEP, buf) != 0)) { + debug_print (1, ("message not in expected position.\n")); + debug_print (1, ("LINE: %s\n", buf)); i = -1; } else { - if (fseek (ctx->fp, offset, SEEK_SET) != 0) { /* return to proper offset */ + if (fseeko (ctx->fp, offset, SEEK_SET) != 0) { /* return to proper offset */ i = -1; - dprint (1, (debugfile, "mbox_sync_mailbox: fseek() failed\n")); + debug_print (1, ("fseeko() failed\n")); } else { /* copy the temp mailbox back into place starting at the first @@ -864,7 +749,7 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) i = -1; } if (i == 0) { - ctx->size = ftell (ctx->fp); /* update the size of the mailbox */ + ctx->size = ftello (ctx->fp); /* update the size of the mailbox */ ftruncate (fileno (ctx->fp), ctx->size); } } @@ -903,8 +788,6 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) mutt_unblock_signals (); mx_fastclose_mailbox (ctx); mutt_error _("Fatal error! Could not reopen mailbox!"); - - Sort = save_sort; return (-1); } @@ -917,11 +800,10 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) ctx->hdrs[i]->index = j++; } } - FREE (&newOffset); - FREE (&oldOffset); + p_delete(&newOffset); + p_delete(&oldOffset); unlink (tempfile); /* remove partial copy of the mailbox */ mutt_unblock_signals (); - Sort = save_sort; /* Restore the default value. */ return (0); /* signal success */ @@ -944,8 +826,8 @@ bail: /* Come here in case of disaster */ mbox_unlock_mailbox (ctx); mutt_unblock_signals (); - FREE (&newOffset); - FREE (&oldOffset); + p_delete(&newOffset); + p_delete(&oldOffset); if ((ctx->fp = freopen (ctx->path, "r", ctx->fp)) == NULL) { mutt_error _("Could not reopen mailbox!"); @@ -954,32 +836,41 @@ bail: /* Come here in case of disaster */ return (-1); } - if (need_sort || save_sort != Sort) { - Sort = save_sort; + if (need_sort) /* if the mailbox was reopened, the thread tree will be invalid so make * sure to start threading from scratch. */ mutt_sort_headers (ctx, (need_sort == M_REOPENED)); - } return rc; } +static int mbox_sync_mailbox (CONTEXT * ctx, int unused, int *index_hint) { +#ifdef BUFFY_SIZE + BUFFY* tmp = NULL; +#endif + int rc = _mbox_sync_mailbox (ctx, unused, index_hint); + +#ifdef BUFFY_SIZE + if ((tmp = buffy_find_mailbox (ctx->path)) && tmp->new == 0) + buffy_update_mailbox (tmp); +#endif + return (rc); +} + /* close a mailbox opened in write-mode */ int mbox_close_mailbox (CONTEXT * ctx) { mx_unlock_file (ctx->path, fileno (ctx->fp), 1); -#ifdef USE_COMPRESSED if (ctx->compressinfo) mutt_slow_close_compressed (ctx); -#endif mutt_unblock_signals (); mx_fastclose_mailbox (ctx); return 0; } -int mbox_reopen_mailbox (CONTEXT * ctx, int *index_hint) +static int mbox_reopen_mailbox (CONTEXT * ctx, int *index_hint) { int (*cmp_headers) (const HEADER *, const HEADER *) = NULL; HEADER **old_hdrs; @@ -1013,11 +904,11 @@ int mbox_reopen_mailbox (CONTEXT * ctx, int *index_hint) if (ctx->subj_hash) hash_destroy (&ctx->subj_hash, NULL); mutt_clear_threads (ctx); - FREE (&ctx->v2r); + p_delete(&ctx->v2r); if (ctx->readonly) { for (i = 0; i < ctx->msgcount; i++) - mutt_free_header (&(ctx->hdrs[i])); /* nothing to do! */ - FREE (&ctx->hdrs); + header_delete(&(ctx->hdrs[i])); /* nothing to do! */ + p_delete(&ctx->hdrs); } else { /* save the old headers */ @@ -1041,12 +932,12 @@ int mbox_reopen_mailbox (CONTEXT * ctx, int *index_hint) switch (ctx->magic) { case M_MBOX: case M_MMDF: - if (fseek (ctx->fp, 0, SEEK_SET) != 0) { - dprint (1, (debugfile, "mbox_reopen_mailbox: fseek() failed\n")); + if (fseeko (ctx->fp, 0, SEEK_SET) != 0) { + debug_print (1, ("fseeko() failed\n")); rc = -1; } else { - cmp_headers = mbox_strict_cmp_headers; + cmp_headers = mutt_cmp_header; if (ctx->magic == M_MBOX) rc = mbox_parse_mailbox (ctx); else @@ -1062,8 +953,8 @@ int mbox_reopen_mailbox (CONTEXT * ctx, int *index_hint) if (rc == -1) { /* free the old headers */ for (j = 0; j < old_msgcount; j++) - mutt_free_header (&(old_hdrs[j])); - FREE (&old_hdrs); + header_delete(&(old_hdrs[j])); + p_delete(&old_hdrs); ctx->quiet = 0; return (-1); @@ -1120,18 +1011,18 @@ int mbox_reopen_mailbox (CONTEXT * ctx, int *index_hint) mutt_set_flag (ctx, ctx->hdrs[i], M_TAG, old_hdrs[j]->tagged); /* we don't need this header any more */ - mutt_free_header (&(old_hdrs[j])); + header_delete(&(old_hdrs[j])); } } /* free the remaining old headers */ for (j = 0; j < old_msgcount; j++) { if (old_hdrs[j]) { - mutt_free_header (&(old_hdrs[j])); + header_delete(&(old_hdrs[j])); msg_mod = 1; } } - FREE (&old_hdrs); + p_delete(&old_hdrs); } ctx->quiet = 0; @@ -1155,16 +1046,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) + 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); @@ -1176,9 +1066,9 @@ int mbox_is_magic (const char* path) { struct utimbuf times; #endif fgets (tmp, sizeof (tmp), f); - if (safe_strncmp ("From ", tmp, 5) == 0) + if (m_strncmp("From ", tmp, 5) == 0) magic = M_MBOX; - else if (safe_strcmp (MMDF_SEP, tmp) == 0) + else if (m_strcmp(MMDF_SEP, tmp) == 0) magic = M_MMDF; safe_fclose (&f); #ifndef BUFFY_SIZE @@ -1186,8 +1076,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 { @@ -1195,30 +1085,52 @@ int mbox_is_magic (const char* path) { return (-1); /* fopen failed */ } -#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); } +static int commit_message (MESSAGE* msg, CONTEXT* ctx __attribute__ ((unused)), int mbox) { + if ((mbox && fputc ('\n', msg->fp) == EOF) || + (!mbox && fputs (MMDF_SEP, msg->fp) == EOF)) + return (-1); + if ((fflush (msg->fp) == EOF || fsync (fileno (msg->fp)) == -1)) { + mutt_perror (_("Can't write message")); + return (-1); + } + return (0); +} + +static int mbox_commit_message (MESSAGE* msg, CONTEXT* ctx) { + return (commit_message (msg, ctx, 1)); +} + +static int mmdf_commit_message (MESSAGE* msg, CONTEXT* ctx) { + return (commit_message (msg, ctx, 0)); +} + static mx_t* reg_mx (void) { - mx_t* fmt = safe_calloc (1, sizeof (mx_t)); + mx_t* fmt = p_new(mx_t, 1); fmt->local = 1; fmt->mx_check_empty = mbox_check_empty; fmt->mx_is_magic = mbox_is_magic; fmt->mx_access = access; fmt->mx_open_mailbox = mbox_open_mailbox; + fmt->mx_open_new_message = mbox_open_new_message; + fmt->mx_sync_mailbox = mbox_sync_mailbox; + fmt->mx_check_mailbox = mbox_check_mailbox; return (fmt); } mx_t* mbox_reg_mx (void) { mx_t* fmt = reg_mx (); fmt->type = M_MBOX; + fmt->mx_commit_message = mbox_commit_message; return (fmt); } mx_t* mmdf_reg_mx (void) { mx_t* fmt = reg_mx (); fmt->type = M_MMDF; + fmt->mx_commit_message = mmdf_commit_message; return (fmt); }