/*
elmo - ELectronic Mail Operator
Copyright (C) 2002, 2003, 2004 rzyjontko
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; version 2.
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-1307, USA.
----------------------------------------------------------------------
This is very simple module used to get full list of messages from
file in mbox format.
*/
#define _GNU_SOURCE 1
/****************************************************************************
* IMPLEMENTATION HEADERS
****************************************************************************/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include "xmalloc.h"
#include "mail.h"
#include "mbox.h"
#include "hash.h"
#include "mlex.h"
#include "file.h"
#include "error.h"
#include "gettext.h"
#include "clock.h"
#include "maildir.h"
#include "misc.h"
/****************************************************************************
* IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
****************************************************************************/
#ifndef P_tmpdir
# define P_tmpdir "/tmp"
#endif
#define MAIL_BEG_RE "^From "
/****************************************************************************
* IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE DATA
****************************************************************************/
/****************************************************************************
* INTERFACE DATA
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTIONS
****************************************************************************/
/****************************************************************************
* INTERFACE FUNCTIONS
****************************************************************************/
int
mbox_may_be_valid (const char *fname)
{
struct stat st;
if (stat (fname, &st)){
error_ (errno, "%s", fname);
return 0;
}
if (S_ISREG (st.st_mode))
return 1;
return 0;
}
int
mbox_mail_size (mail_t *mail)
{
mime_t *mime = mail->mime->mime;
return mime->off_bound - mime->off_header;
}
mail_array_t *
mbox_read_file (const char *file)
{
struct stat st;
int ret = 0;
mail_array_t *result;
if (stat (file, &st)){
error_ (errno, "%s", file);
return NULL;
}
if (! S_ISREG (st.st_mode) || st.st_size == 0)
return NULL;
yyin = fopen (file, "r");
if (!yyin){
error_ (errno, "%s", file);
return NULL;
}
/* first invocation of mbox_scan tells us only if we are reading
a mailbox; it does not bring any information yet */
if (mlex_mbox_scan_start () != NEXT_MAIL){
fclose (yyin);
return NULL;
}
result = mail_array_create (BOX_MBOX, file);
while (ret != END_OF_FILE){
ret = mlex_scan ();
switch (ret){
case NEXT_MAIL:
newmail->type = BOX_MBOX;
newmail->mime->file = result->path;
mail_array_insert (result, newmail);
break;
case BROKEN_MAIL:
fclose (yyin);
mail_array_destroy (result);
return NULL;
}
}
fclose (yyin);
return result;
}
int
mbox_mail_header (mail_t *mail, char **place, const char *fname)
{
mime_t *mime = mail->mime->mime;
if (file_part (fname, mime->off_header, mime->off_start, place)){
*place = NULL;
return 1;
}
return 0;
}
int
mbox_mail_body (mail_t *mail, char **place, mime_t *mime, const char *fname)
{
if (file_part (fname, mime->off_start, mime->off_end, place)){
*place = NULL;
return 1;
}
return 0;
}
char *
mbox_fetch_single (const char *mbox, mail_t *mail)
{
int size;
char *dir = P_tmpdir;
char *path;
char *fname;
char *body;
mime_t *mime;
FILE *fp;
if (mbox == NULL || mail == NULL || mail->mime == NULL)
return NULL;
mime = mail->mime->mime;
size = mime->off_bound - mail->place.offset_header;
if (file_part (mbox, mail->place.offset_header, mime->off_bound,
& body))
return NULL;
fname = maildir_valid_file_name ();
path = file_with_dir (dir, fname);
xfree (fname);
fp = file_open (path, "w", O_WRONLY | O_CREAT | O_EXCL, 0600);
if (fp == NULL){
xfree (body);
xfree (path);
return NULL;
}
if (fwrite (body, 1, size, fp) != size){
fclose (fp);
xfree (body);
xfree (path);
return NULL;
}
fclose (fp);
xfree (body);
return path;
}
int
mbox_box_mail_count (const char *box, int *unread)
{
FILE *fp;
int ret;
int size;
int count;
char *body;
char *seek;
regmatch_t matches[1];
if (! mbox_may_be_valid (box))
return -1;
fp = fopen (box, "r");
if (fp == NULL)
return -1;
if (file_whole (fp, & body, & size)){
fclose (fp);
return -1;
}
fclose (fp);
if (unread)
*unread = 0;
count = 0;
seek = body;
while (1){
ret = misc_regex (MAIL_BEG_RE, seek, matches);
if (ret == 0)
break;
seek = seek + matches[0].rm_eo;
count++;
}
xfree (body);
return count;
}
void
mbox_free_resources (void)
{
}
/****************************************************************************
* INTERFACE CLASS BODIES
****************************************************************************/
/****************************************************************************
*
* END MODULE mbox.c
*
****************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1