X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=mbox.c;h=3cdd76e31f5bd621e6d78a9dd0a596f94df271ed;hp=63a86337bffaaf7bd0ef6ba33c28522c9ab2f017;hb=18ea5e8b861632627335b8d94787c742dbf5f567;hpb=74a2265af51ce89bca845adc1d68f273c9933c13 diff --git a/mbox.c b/mbox.c index 63a8633..3cdd76e 100644 --- a/mbox.c +++ b/mbox.c @@ -14,8 +14,9 @@ #endif #include "mutt.h" -#include "mailbox.h" #include "mx.h" +#include "buffy.h" +#include "mbox.h" #include "sort.h" #include "copy.h" @@ -26,6 +27,7 @@ #include "lib/mem.h" #include "lib/intl.h" #include "lib/str.h" +#include "lib/debug.h" #include #include @@ -45,6 +47,16 @@ struct m_update_t { long length; }; + +static int mbox_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) +{ + msg->fp = dest->fp; + return 0; +} + +/* prototypes */ +static int mbox_reopen_mailbox (CONTEXT*, int*); + /* parameters: * ctx - context to lock * excl - exclusive lock? @@ -74,7 +86,7 @@ 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]; @@ -131,7 +143,7 @@ int mmdf_parse_mailbox (CONTEXT * ctx) 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; } @@ -139,7 +151,7 @@ int mmdf_parse_mailbox (CONTEXT * ctx) 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")); + debug_print (1, ("fseek() failed\n")); mutt_error _("Mailbox is corrupt!"); return (-1); @@ -160,7 +172,7 @@ int mmdf_parse_mailbox (CONTEXT * ctx) fgets (buf, sizeof (buf) - 1, ctx->fp) == NULL || mutt_strcmp (MMDF_SEP, buf) != 0) { if (fseek (ctx->fp, loc, SEEK_SET) != 0) - dprint (1, (debugfile, "mmdf_parse_mailbox: fseek() failed\n")); + debug_print (1, ("fseek() failed\n")); hdr->content->length = -1; } } @@ -193,7 +205,7 @@ int mmdf_parse_mailbox (CONTEXT * ctx) 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); @@ -212,7 +224,7 @@ 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]; @@ -298,14 +310,12 @@ int mbox_parse_mailbox (CONTEXT * ctx) */ if (fseek (ctx->fp, tmploc, SEEK_SET) != 0 || fgets (buf, sizeof (buf), ctx->fp) == NULL || - mutt_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)); + safe_strncmp ("From ", buf, 5) != 0) { + debug_print (1, ("bad content-length in message %d (cl=%ld)\n", + curhdr->index, curhdr->content->length)); + debug_print (1, ("LINE: %s\n", buf)); if (fseek (ctx->fp, loc, SEEK_SET) != 0) { /* nope, return the previous position */ - dprint (1, (debugfile, "mbox_parse_mailbox: fseek() failed\n")); + debug_print (1, ("fseek() failed\n")); } curhdr->content->length = -1; } @@ -326,7 +336,7 @@ int mbox_parse_mailbox (CONTEXT * ctx) /* 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")); + debug_print (1, ("fseek() failed\n")); while (cl-- > 0) { if (fgetc (ctx->fp) == '\n') curhdr->lines++; @@ -335,7 +345,7 @@ 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")); + debug_print (1, ("fseek() failed\n")); } } @@ -381,7 +391,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; @@ -526,7 +536,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]; @@ -565,12 +575,12 @@ int mbox_check_mailbox (CONTEXT * ctx, int *index_hint) * folder. */ if (fseek (ctx->fp, ctx->size, SEEK_SET) != 0) - dprint (1, (debugfile, "mbox_check_mailbox: fseek() failed\n")); + debug_print (1, ("fseek() failed\n")); if (fgets (buffer, sizeof (buffer), ctx->fp) != NULL) { - if ((ctx->magic == M_MBOX && mutt_strncmp ("From ", buffer, 5) == 0) + if ((ctx->magic == M_MBOX && safe_strncmp ("From ", buffer, 5) == 0) || (ctx->magic == M_MMDF && mutt_strcmp (MMDF_SEP, buffer) == 0)) { if (fseek (ctx->fp, ctx->size, SEEK_SET) != 0) - dprint (1, (debugfile, "mbox_check_mailbox: fseek() failed\n")); + debug_print (1, ("fseek() failed\n")); if (ctx->magic == M_MBOX) mbox_parse_mailbox (ctx); else @@ -592,7 +602,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; } } @@ -601,7 +611,7 @@ int mbox_check_mailbox (CONTEXT * ctx, int *index_hint) } if (modified) { - if (mutt_reopen_mailbox (ctx, index_hint) != -1) { + if (mbox_reopen_mailbox (ctx, index_hint) != -1) { if (unlock) { mbox_unlock_mailbox (ctx); mutt_unblock_signals (); @@ -620,11 +630,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, int *index_hint) { char tempfile[_POSIX_PATH_MAX]; char buf[32]; @@ -666,7 +696,7 @@ 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; @@ -706,7 +736,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; } @@ -801,8 +831,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); @@ -821,9 +850,7 @@ 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); @@ -832,18 +859,16 @@ int mbox_sync_mailbox (CONTEXT * ctx, int *index_hint) if (fseek (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 && mutt_strncmp ("From ", buf, 5) != 0) || + (ctx->magic == M_MBOX && safe_strncmp ("From ", buf, 5) != 0) || (ctx->magic == M_MMDF && mutt_strcmp (MMDF_SEP, buf) != 0)) { - dprint (1, - (debugfile, - "mbox_sync_mailbox: message not in expected position.")); - dprint (1, (debugfile, "\tLINE: %s\n", buf)); + 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 */ i = -1; - dprint (1, (debugfile, "mbox_sync_mailbox: fseek() failed\n")); + debug_print (1, ("fseek() failed\n")); } else { /* copy the temp mailbox back into place starting at the first @@ -957,6 +982,19 @@ bail: /* Come here in case of disaster */ 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) { @@ -972,7 +1010,7 @@ int mbox_close_mailbox (CONTEXT * ctx) return 0; } -int mutt_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; @@ -1035,7 +1073,7 @@ int mutt_reopen_mailbox (CONTEXT * ctx, int *index_hint) case M_MBOX: case M_MMDF: if (fseek (ctx->fp, 0, SEEK_SET) != 0) { - dprint (1, (debugfile, "mutt_reopen_mailbox: fseek() failed\n")); + debug_print (1, ("fseek() failed\n")); rc = -1; } else { @@ -1147,3 +1185,73 @@ int mbox_check_empty (const char *path) return ((st.st_size == 0)); } + +int mbox_is_magic (const char* path, struct stat* st) { + int magic = -1; + FILE* f; + char tmp[_POSIX_PATH_MAX]; + + if (S_ISDIR(st->st_mode)) + return (-1); + + 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); + else + return (M_MBOX); + } + else if ((f = fopen (path, "r")) != NULL) { +#ifndef BUFFY_SIZE + struct utimbuf times; +#endif + fgets (tmp, sizeof (tmp), f); + if (safe_strncmp ("From ", tmp, 5) == 0) + magic = M_MBOX; + else if (mutt_strcmp (MMDF_SEP, tmp) == 0) + magic = M_MMDF; + safe_fclose (&f); +#ifndef BUFFY_SIZE + /* need to restore the times here, the file was not really accessed, + * 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; + utime (path, ×); +#endif + } else { + mutt_perror (path); + return (-1); /* fopen failed */ + } + +#ifdef USE_COMPRESSED + if (magic == -1 && mutt_can_read_compressed (path)) + return (M_COMPRESSED); +#endif + return (magic); +} + +static mx_t* reg_mx (void) { + mx_t* fmt = safe_calloc (1, sizeof (mx_t)); + 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; + return (fmt); +} +mx_t* mmdf_reg_mx (void) { + mx_t* fmt = reg_mx (); + fmt->type = M_MMDF; + return (fmt); +}