/*
* Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* This file contains code to parse ``mbox'' and ``mmdf'' style mailboxes */
#include "mutt.h"
#include "mailbox.h"
#include "mx.h"
#include "sort.h"
#include "copy.h"
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <utime.h>
#include <sys/file.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
/* struct used by mutt_sync_mailbox() to store new offsets */
struct m_update_t
{
long hdr;
long body;
};
/* parameters:
* ctx - context to lock
* excl - exclusive lock?
* retry - should retry if unable to lock?
*/
int mbox_lock_mailbox (CONTEXT *ctx, int excl, int retry)
{
int r;
/* XXX - Currently, we force dotlocking.
* Use dotlock -t here.
*/
if ((r = mx_lock_file (ctx->path, fileno (ctx->fp), excl, 1, retry)) == 0)
ctx->locked = 1;
return (r);
}
void mbox_unlock_mailbox (CONTEXT *ctx)
{
if (ctx->locked)
{
fflush (ctx->fp);
mx_unlock_file (ctx->path, fileno (ctx->fp));
ctx->locked = 0;
}
}
int mmdf_parse_mailbox (CONTEXT *ctx)
{
char buf[HUGE_STRING];
char return_path[LONG_STRING];
int lines;
time_t t, tz;
long 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);
}
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 ();
buf[sizeof (buf) - 1] = 0;
FOREVER
{
if (fgets (buf, sizeof (buf) - 1, ctx->fp) == NULL)
break;
if (strcmp (buf, MMDF_SEP) == 0)
{
loc = ftell (ctx->fp);
if (ctx->msgcount == ctx->hdrmax)
mx_alloc_memory (ctx);
ctx->hdrs[ctx->msgcount] = hdr = mutt_new_header ();
hdr->offset = loc;
hdr->index = ctx->msgcount;
if (fgets (buf, sizeof (buf) - 1, ctx->fp) == NULL)
{
dprint (1, (debugfile, "mmdf_parse_mailbox: unexpected EOF\n"));
break;
}
return_path[0] = 0;
t = is_from (buf, return_path, sizeof (return_path));
if (!t)
fseek (ctx->fp, loc, 0);
else
hdr->received = t + tz;
hdr->env = mutt_read_rfc822_header (ctx->fp, hdr);
loc = ftell (ctx->fp);
if (hdr->content->length > 0 && hdr->lines > 0)
{
tmploc = loc + hdr->content->length;
if (tmploc < ctx->size)
{
fseek (ctx->fp, tmploc, 0);
if (fgets (buf, sizeof (buf) - 1, ctx->fp) == NULL ||
strcmp (MMDF_SEP, buf) != 0)
{
fseek (ctx->fp, loc, 0);
hdr->content->length = -1;
}
}
else
hdr->content->length = -1;
}
else
hdr->content->length = -1;
if (hdr->content->length < 0)
{
lines = -1;
do {
loc = ftell (ctx->fp);
if (fgets (buf, sizeof (buf) - 1, ctx->fp) == NULL)
break;
lines++;
} whil