Commit 48832b4a 48832b4ab9ea10b93c70ad756d9814c261b55f7e by Alain Magloire

UIDL is not looking for "X-UIDL" if not do an md5 of the message.

When expunging check if the message as been modified, for example
"X-UIDL" maybe add in the header it will now be save in the message.
expunge reuse the same code of mbox_append_message().
add a new header_set_fill() to get the header of the messages form the mailbox.
1 parent 4737689b
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
......@@ -25,6 +25,8 @@
#include <attribute0.h>
static int flags_to_string __P ((int, char *, size_t, size_t *));
int
attribute_create (attribute_t *pattr, void *owner)
{
......@@ -59,6 +61,12 @@ attribute_get_owner (attribute_t attr)
}
int
attribute_is_modified (attribute_t attr)
{
return (attr) ? attr->flags != 0 : 0;
}
int
attribute_get_flags (attribute_t attr, int *pflags)
{
if (attr == NULL)
......@@ -76,7 +84,7 @@ attribute_set_flags (attribute_t attr, int flags)
if (attr == NULL)
return EINVAL;
if (attr->_set_flags)
return attr->_set_flags (attr, flags);
attr->_set_flags (attr, flags);
attr->flags |= flags;
return 0;
}
......@@ -446,7 +454,15 @@ string_to_flags (const char *buffer, int *pflags)
return 0;
}
int
int
attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn)
{
int flags = 0;;
attribute_get_flags (attr, &flags);
return flags_to_string (flags, buffer, len, pn);
}
static int
flags_to_string (int flags, char *buffer, size_t len, size_t *pn)
{
char status[32];
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
......@@ -307,22 +307,10 @@ body_get_fd (stream_t stream, int *pfd)
static FILE *
lazy_create ()
{
FILE *file;
#ifdef HAVE_MKSTEMP
char tmpbuf[L_tmpnam + 1];
int fd;
if (tmpnam (tmpbuf) == NULL ||
(fd = mkstemp (tmpbuf)) == -1 ||
(file = fdopen(fd, "w+")) == NULL)
return NULL;
(void)remove(tmpbuf);
#else
file = tmpfile ();
FILE *file = tmpfile ();
//file = fopen ("/tmp/mystuff", "w+");
/* make sure the mode is right */
if (file)
fchmod (fileno (file), 0600);
#endif
return file;
}
......
......@@ -334,11 +334,36 @@ folder_list (folder_t folder, const char *dirname, const char *basename,
struct folder_list *pflist)
{
if (folder == NULL || folder->_list == NULL)
return ENOSYS;
return EINVAL;
return folder->_list (folder, dirname, basename, pflist);
}
int
folder_lsub (folder_t folder, const char *dirname, const char *basename,
struct folder_list *pflist)
{
if (folder == NULL || folder->_lsub == NULL)
return ENOSYS;
return folder->_lsub (folder, dirname, basename, pflist);
}
int
folder_subscribe (folder_t folder, const char *name)
{
if (folder == NULL || folder->_subscribe == NULL)
return EINVAL;
return folder->_subscribe (folder, name);
}
int
folder_unsubscribe (folder_t folder, const char *name)
{
if (folder == NULL || folder->_unsubscribe == NULL)
return EINVAL;
return folder->_unsubscribe (folder, name);
}
int
folder_list_destroy (struct folder_list *pflist)
{
size_t i;
......@@ -353,7 +378,10 @@ folder_list_destroy (struct folder_list *pflist)
free (pflist->element[i]);
}
}
free (pflist->element);
if (i > 0)
free (pflist->element);
pflist->element = NULL;
pflist->num = 0;
return 0;
}
......
......@@ -24,6 +24,7 @@
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <fnmatch.h>
#include <imap0.h>
......@@ -384,17 +385,93 @@ folder_imap_list (folder_t folder, const char *ref, const char *name,
{
f_imap_t f_imap = folder->data;
int status = 0;
char *path = NULL;
/* NOOP. */
if (pflist == NULL)
return EINVAL;
if (ref == NULL)
ref = "";
if (name == NULL)
name = "";
path = strdup ("");
if (path == NULL)
return ENOMEM;
/* We break the string to pieces and change the occurences of "*?[" for
the imap magic "%" for expansion. Then reassemble the string:
"/home/?/Mail/a*lain*" --> "/usr/%/Mail/%". */
{
int done = 0;
size_t i;
char **node = NULL;
size_t nodelen = 0;
const char *p = name;
/* Disassemble. */
while (!done && *p)
{
char **n;
n = realloc (node, (nodelen + 1) * sizeof (*node));
if (n == NULL)
break;
node = n;
if (*p == '/')
{
node[nodelen] = strdup ("/");
p++;
}
else
{
const char *s = strchr (p, '/');
if (s)
{
node[nodelen] = calloc (s - p + 1, sizeof (char));
if (node[nodelen])
memcpy (node[nodelen], p, s - p);
p = s;
}
else
{
node[nodelen] = strdup (p);
done = 1;
}
if (node[nodelen] && strpbrk (node[nodelen], "*?["))
{
free (node[nodelen]);
node[nodelen] = strdup ("%");
}
}
nodelen++;
if (done)
break;
}
/* Reassemble. */
for (i = 0; i < nodelen; i++)
{
if (node[i])
{
char *pth;
pth = realloc (path, strlen (path) + strlen (node[i]) + 1);
if (pth)
{
path = pth;
strcat (path, node[i]);
}
free (node[i]);
}
}
if (node)
free (node);
}
switch (f_imap->state)
{
case IMAP_NO_STATE:
status = imap_writeline (f_imap, "g%d LIST \"%s\" \"%s\"\r\n",
f_imap->seq++, ref, name);
f_imap->seq++, ref, path);
free (path);
CHECK_ERROR (f_imap, status);
FOLDER_DEBUG0 (folder, MU_DEBUG_PROT, f_imap->buffer);
f_imap->state = IMAP_LIST;
......@@ -412,6 +489,39 @@ folder_imap_list (folder_t folder, const char *ref, const char *name,
default:
break;
}
/* Build the folder list. */
if (f_imap->callback.flist.num > 0)
{
struct list_response **plist = NULL;
size_t num = f_imap->callback.flist.num;
size_t j = 0;
plist = calloc (num, sizeof (*plist));
if (plist)
{
size_t i;
for (i = 0; i < num; i++)
{
struct list_response *lr = f_imap->callback.flist.element[i];
//printf ("%s --> %s\n", lr->name, name);
if (fnmatch (name, lr->name, 0) == 0)
{
plist[i] = calloc (1, sizeof (**plist));
if (plist[i] == NULL
|| (plist[i]->name = strdup (lr->name)) == NULL)
{
break;
}
plist[i]->type = lr->type;
plist[i]->separator = lr->separator;
j++;
}
}
}
pflist->element = plist;
pflist->num = j;
}
folder_list_destroy (&(f_imap->callback.flist));
f_imap->state = IMAP_NO_STATE;
return status;
}
......@@ -423,10 +533,13 @@ folder_imap_lsub (folder_t folder, const char *ref, const char *name,
f_imap_t f_imap = folder->data;
int status = 0;
if (ref == NULL)
ref = "";
if (name == NULL)
name = "";
/* NOOP. */
if (pflist == NULL)
return EINVAL;
if (ref == NULL) ref = "";
if (name == NULL) name = "";
switch (f_imap->state)
{
case IMAP_NO_STATE:
......@@ -449,6 +562,37 @@ folder_imap_lsub (folder_t folder, const char *ref, const char *name,
default:
break;
}
/* Build the folder list. */
if (f_imap->callback.flist.num > 0)
{
struct list_response **plist = NULL;
size_t num = f_imap->callback.flist.num;
size_t j = 0;
plist = calloc (num, sizeof (*plist));
if (plist)
{
size_t i;
for (i = 0; i < num; i++)
{
struct list_response *lr = f_imap->callback.flist.element[i];
//printf ("%s --> %s\n", lr->name, name);
plist[i] = calloc (1, sizeof (**plist));
if (plist[i] == NULL
|| (plist[i]->name = strdup (lr->name)) == NULL)
{
break;
}
plist[i]->type = lr->type;
plist[i]->separator = lr->separator;
j++;
}
}
pflist->element = plist;
pflist->num = j;
folder_list_destroy (&(f_imap->callback.flist));
}
f_imap->state = IMAP_NO_STATE;
f_imap->state = IMAP_NO_STATE;
return 0;
}
......@@ -755,6 +899,86 @@ imap_string (f_imap_t f_imap)
return status;
}
/* FIXME: does not worl for nobloking. */
static int
imap_list (f_imap_t f_imap)
{
char *tok;
char *sp = NULL;
size_t len = f_imap->nl - f_imap->buffer - 1;
char *buffer;
struct list_response **plr;
struct list_response *lr;
buffer = alloca (len);
memcpy (buffer, f_imap->buffer, len);
buffer[len] = '\0';
plr = realloc (f_imap->callback.flist.element,
(f_imap->callback.flist.num + 1) * sizeof (*plr));
if (plr == NULL)
return ENOMEM;
f_imap->callback.flist.element = plr;
lr = plr[f_imap->callback.flist.num] = calloc (1, sizeof (*lr));
if (lr == NULL)
return ENOMEM;
(f_imap->callback.flist.num)++;
/* Glob untag. */
tok = strtok_r (buffer, " ", &sp);
/* Glob LIST. */
tok = strtok_r (NULL, " ", &sp);
/* Get the attibutes. */
tok = strtok_r (NULL, ")", &sp);
if (tok)
{
char *s = NULL;
char *p = tok;
while ((tok = strtok_r (p, " ()", &s)) != NULL)
{
if (strcasecmp (tok, "\\Noselect") == 0)
{
}
else if (strcasecmp (tok, "\\Marked") == 0)
{
}
else if (strcasecmp (tok, "\\Unmarked") == 0)
{
}
else if (strcasecmp (tok, "\\Noinferiors") == 0)
{
lr->type |= MU_FOLDER_ATTRIBUTE_FILE;
}
else
{
lr->type |= MU_FOLDER_ATTRIBUTE_DIRECTORY;
}
p = NULL;
}
}
/* Hiearchy delimeter. */
tok = strtok_r (NULL, " ", &sp);
if (tok && strlen (tok) > 2)
lr->separator = tok[1];
/* The path. */
tok = strtok_r (NULL, " ", &sp);
if (tok)
{
char *s = strchr (tok, '{');
if (s)
{
size_t n = strtoul (s + 1, NULL, 10);
lr->name = calloc (n + 1, sizeof (char));
f_imap->ptr = f_imap->buffer;
imap_readline (f_imap);
memcpy (lr->name, f_imap->buffer, n);
lr->name[n] = '\0';
}
else
lr->name = strdup (tok);
}
return 0;
}
/* Helping function to figure out the section name of the message: for example
a 2 part message with the first part being sub in two will be:
{1}, {1,1} {1,2} The first subpart of the message and its sub parts
......@@ -803,6 +1027,7 @@ section_name (msg_imap_t msg_imap)
return section;
}
/* FIXME: This does not work for nonblocking. */
/* Recursive call, to parse the dismay of parentesis "()" in a BODYSTRUCTURE
call, not we use the short form of BODYSTRUCTURE, BODY with no argument. */
static int
......@@ -1231,12 +1456,12 @@ imap_parse (f_imap_t f_imap)
char *tag, *response, *remainder;
char *buffer;
status = imap_readline (f_imap);
/* Comment out to see all reading traffic. */
//fprintf (stderr, "\t\t%s", f_imap->buffer);
if (status != 0)
{
break;
}
/* Comment out to see all reading traffic. */
fprintf (stderr, "\t\t%s", f_imap->buffer);
/* We do not want to step over f_imap->buffer since it can be use
further down the chain. */
......@@ -1429,9 +1654,11 @@ imap_parse (f_imap_t f_imap)
}
else if (strcmp (response, "LIST") == 0)
{
status = imap_list (f_imap);
}
else if (strcmp (response, "LSUB") == 0)
{
status = imap_list (f_imap);
}
else if (strcmp (remainder, "RECENT") == 0)
{
......
......@@ -25,6 +25,7 @@
#include <unistd.h>
#include <string.h>
#include <glob.h>
#include <fnmatch.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -83,19 +84,27 @@ static struct _record _path_record =
record_t path_record = &_path_record;
/* lsub/subscribe/unsubscribe are not needed. */
static void folder_mbox_destroy __P ((folder_t));
static int folder_mbox_open __P ((folder_t, int));
static int folder_mbox_close __P ((folder_t));
static int folder_mbox_delete __P ((folder_t, const char *));
static int folder_mbox_rename __P ((folder_t , const char *, const char *));
static int folder_mbox_list __P ((folder_t, const char *, const char *,
struct folder_list *));
static void folder_mbox_destroy __P ((folder_t));
static int folder_mbox_open __P ((folder_t, int));
static int folder_mbox_close __P ((folder_t));
static int folder_mbox_delete __P ((folder_t, const char *));
static int folder_mbox_rename __P ((folder_t , const char *,
const char *));
static int folder_mbox_list __P ((folder_t, const char *, const char *,
struct folder_list *));
static int folder_mbox_subscribe __P ((folder_t, const char *));
static int folder_mbox_unsubscribe __P ((folder_t, const char *));
static int folder_mbox_lsub __P ((folder_t, const char *, const char *,
struct folder_list *));
static char *get_pathname __P ((const char *, const char *));
struct _fmbox
{
char *dirname;
char **subscribe;
size_t sublen;
};
typedef struct _fmbox *fmbox_t;
......@@ -126,9 +135,11 @@ _folder_mbox_init (folder_t folder)
folder->_close = folder_mbox_close;
folder->_list = folder_mbox_list;
folder->_lsub = folder_mbox_lsub;
folder->_subscribe = folder_mbox_subscribe;
folder->_unsubscribe = folder_mbox_unsubscribe;
folder->_delete = folder_mbox_delete;
folder->_rename = folder_mbox_rename;
return 0;
}
......@@ -140,6 +151,8 @@ folder_mbox_destroy (folder_t folder)
fmbox_t fmbox = folder->data;
if (fmbox->dirname)
free (fmbox->dirname);
if (fmbox->subscribe)
free (fmbox->subscribe);
free (folder->data);
folder->data = NULL;
}
......@@ -150,7 +163,6 @@ static int
folder_mbox_open (folder_t folder, int flags)
{
(void)(folder);
(void)(flags);
return 0;
}
......@@ -281,6 +293,84 @@ folder_mbox_list (folder_t folder, const char *dirname, const char *pattern,
return status;
}
static int
folder_mbox_lsub (folder_t folder, const char *ref, const char *name,
struct folder_list *pflist)
{
fmbox_t fmbox = folder->data;
size_t j = 0;
if (pflist == NULL)
return EINVAL;
(void)ref;
if (name == NULL || *name == '\0')
name = "*";
if (fmbox->sublen > 0)
{
struct list_response **plist;
size_t i;
plist = calloc (fmbox->sublen, sizeof (*plist));
for (i = 0; i < fmbox->sublen; i++)
{
if (fmbox->subscribe[i]
&& fnmatch (name, fmbox->subscribe[i], 0) == 0)
{
plist[i] = calloc (1, sizeof (**plist));
if (plist[i] == NULL
|| (plist[i]->name = strdup (fmbox->subscribe[i])) == NULL)
break;
plist[i]->type = MU_FOLDER_ATTRIBUTE_FILE;
plist[i]->separator = '/';
j++;
}
}
pflist->element = plist;
}
pflist->num = j;
return 0;
}
static int
folder_mbox_subscribe (folder_t folder, const char *name)
{
fmbox_t fmbox = folder->data;
char **tmp;
size_t i;
for (i = 0; i < fmbox->sublen; i++)
{
if (fmbox->subscribe[i] && strcmp (fmbox->subscribe[i], name) == 0)
return 0;
}
tmp = realloc (fmbox->subscribe, (fmbox->sublen + 1) * sizeof (*tmp));
if (tmp == NULL)
return ENOMEM;
fmbox->subscribe = tmp;
fmbox->subscribe[fmbox->sublen] = strdup (name);
if (fmbox->subscribe[fmbox->sublen] == NULL)
return ENOMEM;
fmbox->sublen++;
return 0;
}
static int
folder_mbox_unsubscribe (folder_t folder, const char *name)
{
fmbox_t fmbox = folder->data;
size_t i;
for (i = 0; i < fmbox->sublen; i++)
{
if (fmbox->subscribe[i] && strcmp (fmbox->subscribe[i], name) == 0)
{
free (fmbox->subscribe[i]);
fmbox->subscribe[i] = NULL;
return 0;
}
}
return ENOENT;
}
static char *
get_pathname (const char *dirname, const char *basename)
{
......
......@@ -28,12 +28,14 @@
#include <mailutils/stream.h>
#include <header0.h>
static int header_parse (header_t h, const char *blurb, int len);
static int header_read (stream_t is, char *buf, size_t buflen,
off_t off, size_t *pnread);
static int header_write (stream_t os, const char *buf, size_t buflen,
off_t off, size_t *pnwrite);
static int fill_blurb (header_t header);
#define HEADER_MODIFIED 1
static int header_parse __P ((header_t, const char *, int));
static int header_read __P ((stream_t, char *, size_t, off_t, size_t *));
static int header_readline __P ((stream_t, char *, size_t, off_t, size_t *));
static int header_write __P ((stream_t, const char *, size_t, off_t,
size_t *));
static int fill_blurb __P ((header_t));
int
header_create (header_t *ph, const char *blurb, size_t len, void *owner)
......@@ -79,6 +81,12 @@ header_get_owner (header_t header)
return (header) ? header->owner : NULL;
}
int
header_is_modified (header_t header)
{
return (header) ? (header->flags & HEADER_MODIFIED) : 0;
}
/* Parsing is done in a rather simple fashion.
meaning we just consider an entry to be
a field-name an a field-value. So they
......@@ -298,6 +306,7 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
}
header_parse (header, blurb, len + header->blurb_len);
free (blurb);
header->flags |= HEADER_MODIFIED;
return 0;
}
......@@ -498,23 +507,43 @@ header_set_stream (header_t header, stream_t stream, void *owner)
return 0;
}
int
header_set_fill (header_t header, int
(*_fill) __P ((header_t, char *, size_t, off_t, size_t *)),
void *owner)
{
if (header == NULL)
return EINVAL;
if (header->owner != owner)
return EACCES;
header->_fill = _fill;
return 0;
}
static int
fill_blurb (header_t header)
{
stream_t is;
stream_t is = NULL;
int status;
char buf[1024];
char *tbuf;
size_t nread = 0;
status = header_get_stream (header, &is);
if (status != 0)
return status;
if (header->_fill == NULL)
{
status = header_get_stream (header, &is);
if (status != 0)
return status;
}
do
{
status = stream_read (is, buf, sizeof (buf), header->temp_blurb_len,
&nread);
if (header->_fill)
status = header->_fill (header, buf, sizeof (buf),
header->temp_blurb_len, &nread) ;
else
status = stream_read (is, buf, sizeof (buf),
header->temp_blurb_len, &nread);
if (status != 0)
{
if (status != EAGAIN && status != EINTR)
......@@ -572,8 +601,7 @@ header_write (stream_t os, const char *buf, size_t buflen,
}
static int
header_read (stream_t is, char *buf, size_t buflen,
off_t off, size_t *pnread)
header_read (stream_t is, char *buf, size_t buflen, off_t off, size_t *pnread)
{
header_t header = stream_get_owner (is);
int len;
......@@ -581,6 +609,14 @@ header_read (stream_t is, char *buf, size_t buflen,
if (is == NULL || header == NULL)
return EINVAL;
/* Try to fill out the buffer, if we know how. */
if (header->blurb == NULL)
{
int err = fill_blurb (header);
if (err != 0)
return err;
}
len = header->blurb_len - off;
if (len > 0)
{
......@@ -598,6 +634,52 @@ header_read (stream_t is, char *buf, size_t buflen,
return 0;
}
static int
header_readline (stream_t is, char *buf, size_t buflen, off_t off, size_t *pn)
{
header_t header = stream_get_owner (is);
int len;
if (is == NULL || header == NULL)
return EINVAL;
if (buf == NULL || buflen == 0)
{
if (pn)
*pn = 0;
return 0;
}
/* Try to fill out the buffer, if we know how. */
if (header->blurb == NULL)
{
int err = fill_blurb (header);
if (err != 0)
return err;
}
buflen--; /* Space for the null. */
len = header->blurb_len - off;
if (len > 0)
{
char *nl = memchr (header->blurb + off, '\n', len);
if (nl)
len = nl - (header->blurb + off) + 1;
len = (buflen < (size_t)len) ? buflen : len;
memcpy (buf, header->blurb + off, len);
buf[len] = '\0';
}
else
len = 0;
if (pn)
*pn = len;
return 0;
}
int
header_get_stream (header_t header, stream_t *pstream)
{
......@@ -608,7 +690,8 @@ header_get_stream (header_t header, stream_t *pstream)
int status = stream_create (&(header->stream), MU_STREAM_RDWR, header);
if (status != 0)
return status;
stream_set_read (header->stream, header_read, header);
stream_set_read (header->stream, header_read, header);
stream_set_readline (header->stream, header_readline, header);
stream_set_write (header->stream, header_write, header);
}
*pstream = header->stream;
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
......@@ -61,6 +61,7 @@ struct _header
size_t blurb_len;
size_t hdr_count;
struct _hdr *hdr;
int flags;
/* Streams. */
stream_t stream;
......@@ -68,6 +69,7 @@ struct _header
int (*_set_value) __P ((header_t, const char *, const char *, int));
int (*_lines) __P ((header_t, size_t *));
int (*_size) __P ((header_t, size_t *));
int (*_fill) __P ((header_t, char *, size_t, off_t, size_t *));
};
#ifdef _cplusplus
......
......@@ -121,6 +121,7 @@ struct literal_string
size_t total;
msg_imap_t msg_imap;
enum imap_state type;
struct folder_list flist;
size_t nleft; /* nleft to read in the literal. */
};
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
......@@ -32,7 +32,7 @@
/*
*/
int
mailer_create (mailer_t *pmailer, const char *name, int id)
mailer_create (mailer_t *pmailer, const char *name)
{
int status = EINVAL;
record_t record = NULL;
......@@ -42,7 +42,6 @@ mailer_create (mailer_t *pmailer, const char *name, int id)
iterator_t iterator;
int found = 0;
(void)id;
if (pmailer == NULL)
return EINVAL;
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
......@@ -183,15 +183,37 @@ _mapfile_size (stream_t stream, off_t *psize)
{
struct _mapfile_stream *mfs = stream_get_owner (stream);
struct stat stbuf;
int err = 0;
if (mfs == NULL || mfs->ptr == NULL)
return EINVAL;
msync (mfs->ptr, mfs->size, MS_SYNC);
if (fstat(mfs->fd, &stbuf) != 0)
return errno;
if (psize)
*psize = stbuf.st_size;
return 0;
if (mfs->size != (size_t)stbuf.st_size)
{
if (munmap (mfs->ptr, mfs->size) == 0)
{
mfs->size = stbuf.st_size;
mfs->ptr = mmap (0, mfs->size, mfs->flags , MAP_SHARED, mfs->fd, 0);
if (mfs->ptr == MAP_FAILED)
err = errno;
}
else
err = errno;
}
if (err != 0)
{
mfs->ptr = NULL;
close (mfs->fd);
mfs->fd = -1;
}
else
{
if (psize)
*psize = stbuf.st_size;
}
return err;
}
static int
......@@ -277,6 +299,7 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags)
{
int err = errno;
close (mfs->fd);
mfs->ptr = NULL;
return err;
}
mfs->flags = mflag;
......
......@@ -28,6 +28,8 @@
#include <string.h>
#include <ctype.h>
#include "md5.h"
#include <misc.h>
#include <message0.h>
......@@ -155,6 +157,15 @@ message_get_owner (message_t msg)
}
int
message_is_modified (message_t msg)
{
int mod = 0;
mod |= header_is_modified (msg->header);
mod |= attribute_is_modified (msg->attribute);
return mod;
}
int
message_set_mailbox (message_t msg, mailbox_t mailbox)
{
if (msg == NULL)
......@@ -400,6 +411,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner)
return 0;
}
/* FIXME: not nonblocking safe. */
int
message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten)
{
......@@ -411,16 +423,19 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten)
return EINVAL;
buffer[0] = '\0';
/* Try the function overload if error fallback. */
if (msg->_get_uid)
return msg->_get_uid (msg, buffer, buflen, pwriten);
{
status = msg->_get_uid (msg, buffer, buflen, pwriten);
if (status == 0)
return status;
}
/* Be compatible with Qpopper ? qppoper saves the UIDL in "X-UIDL".
We use "Message-ID" as a fallback. Is this bad ? should we generate
a chksum or do the same as Qpopper save it in the header. */
We generate a chksum and save it in the header. */
message_get_header (msg, &header);
if ((status = header_get_value (header, "X-UIDL", buffer, buflen, &n)) == 0
|| (status = header_get_value (header, "Message-ID", buffer,
buflen, &n)) == 0)
status = header_get_value (header, "X-UIDL", buffer, buflen, &n);
if (status == 0 && n > 0)
{
/* FIXME: Is header_get_value suppose to do this ? */
/* We need to collapse the header if it was mutiline. e points to the
......@@ -437,6 +452,32 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten)
}
}
}
else
{
struct md5_ctx md5context;
stream_t stream = NULL;
char buf[1024];
off_t offset = 0;
unsigned char md5digest[16];
char *tmp;
n = 0;
message_get_stream (msg, &stream);
md5_init_ctx (&md5context);
while (stream_read (stream, buf, sizeof (buf), offset, &n) == 0
&& n > 0)
{
md5_process_bytes (buf, n, &md5context);
offset += n;
}
md5_finish_ctx (&md5context, md5digest);
tmp = buf;
for (n = 0; n < 16; n++, tmp += 2)
sprintf (tmp, "%02x", md5digest[n]);
*tmp = '\0';
header_set_value (header, "X-UIDL", buf, 1);
buflen--; /* leave space for the NULL. */
strncpy (buffer, buf, buflen)[buflen] = '\0';
}
return status;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
......@@ -39,7 +39,7 @@
* Need to prevent re-entry into mime lib, but allow non-blocking re-entry into lib.
*/
static int
static int
_mime_is_multipart_digest(mime_t mime)
{
if ( mime->content_type )
......@@ -47,7 +47,7 @@ _mime_is_multipart_digest(mime_t mime)
return 0;
}
static int
static int
_mime_append_part(mime_t mime, message_t msg, int offset, int len, int lines)
{
struct _mime_part *mime_part, **part_arr;
......@@ -131,7 +131,7 @@ char *_strtrim(char *str);
|| ((c) == '\\') || ((c) == '.') || ((c) == '[') \
|| ((c) == ']') )
static void
static void
_mime_munge_content_header(char *field_body )
{
char *p, *e, *str = field_body;
......@@ -195,7 +195,7 @@ _mime_get_param(char *field_body, const char *param, int *len)
return NULL;
}
static int
static int
_mime_setup_buffers(mime_t mime)
{
if ( mime->cur_buf == NULL && ( mime->cur_buf = malloc( mime->buf_size ) ) == NULL ) {
......@@ -208,7 +208,7 @@ _mime_setup_buffers(mime_t mime)
return 0;
}
static void
static void
_mime_append_header_line(mime_t mime)
{
if ( mime->header_length + mime->line_ndx > mime->header_buf_size) {
......@@ -222,7 +222,7 @@ _mime_append_header_line(mime_t mime)
mime->header_length += mime->line_ndx;
}
static int
static int
_mime_parse_mpart_message(mime_t mime)
{
char *cp, *cp2;
......@@ -323,7 +323,7 @@ _mime_parse_mpart_message(mime_t mime)
/*------ Mime message functions for READING a multipart message -----*/
static int
static int
_mimepart_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nbytes)
{
body_t body = stream_get_owner(stream);
......@@ -343,7 +343,7 @@ _mimepart_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t
return stream_read(mime_part->mime->stream, buf, read_len, mime_part->offset + off, nbytes );
}
static int
static int
_mimepart_body_fd(stream_t stream, int *fd)
{
body_t body = stream_get_owner(stream);
......@@ -353,7 +353,7 @@ _mimepart_body_fd(stream_t stream, int *fd)
return stream_get_fd(mime_part->mime->stream, fd);
}
static int
static int
_mimepart_body_size (body_t body, size_t *psize)
{
message_t msg = body_get_owner(body);
......@@ -366,7 +366,7 @@ _mimepart_body_size (body_t body, size_t *psize)
return 0;
}
static int
static int
_mimepart_body_lines (body_t body, size_t *plines)
{
message_t msg = body_get_owner(body);
......@@ -380,14 +380,14 @@ _mimepart_body_lines (body_t body, size_t *plines)
}
/*------ Mime message/header functions for CREATING multipart message -----*/
static int
static int
_mime_set_content_type(mime_t mime)
{
char content_type[256];
char boundary[128];
header_t hdr = NULL;
size_t size;
if ( mime->nmtp_parts > 1 ) {
if ( mime->flags & MIME_ADDED_MULTIPART_CT )
return 0;
......@@ -421,7 +421,7 @@ _mime_set_content_type(mime_t mime)
#define ADD_CHAR(buf, c, offset, buflen, nbytes) {*(buf)++ = c; (offset)++; (nbytes)++;if (--(buflen) == 0) return 0;}
static int
static int
_mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nbytes)
{
body_t body = stream_get_owner(stream);
......@@ -470,7 +470,7 @@ _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nb
}
while(mime->postamble) {
mime->postamble--;
ADD_CHAR(buf, '-', mime->cur_offset, buflen, *nbytes);
ADD_CHAR(buf, '-', mime->cur_offset, buflen, *nbytes);
}
mime->flags &= ~(MIME_INSERT_BOUNDARY|MIME_ADDING_BOUNDARY);
mime->part_offset = 0;
......@@ -502,7 +502,7 @@ _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nb
return ret;
}
static int
static int
_mime_body_fd(stream_t stream, int *fd)
{
body_t body = stream_get_owner(stream);
......@@ -516,7 +516,7 @@ _mime_body_fd(stream_t stream, int *fd)
return stream_get_fd(msg_stream, fd);
}
static int
static int
_mime_body_size (body_t body, size_t *psize)
{
message_t msg = body_get_owner(body);
......@@ -541,7 +541,7 @@ _mime_body_size (body_t body, size_t *psize)
return 0;
}
static int
static int
_mime_body_lines (body_t body, size_t *plines)
{
message_t msg = body_get_owner(body);
......@@ -563,7 +563,7 @@ _mime_body_lines (body_t body, size_t *plines)
return 0;
}
int
int
mime_create(mime_t *pmime, message_t msg, int flags)
{
mime_t mime = NULL;
......@@ -611,7 +611,7 @@ mime_create(mime_t *pmime, message_t msg, int flags)
return ret;
}
void
void
mime_destroy(mime_t *pmime)
{
mime_t mime;
......@@ -648,8 +648,8 @@ mime_destroy(mime_t *pmime)
}
}
int
mime_get_part(mime_t mime, int part, message_t *msg)
int
mime_get_part(mime_t mime, size_t part, message_t *msg)
{
size_t nmtp_parts;
int ret = 0;
......@@ -681,7 +681,7 @@ mime_get_part(mime_t mime, int part, message_t *msg)
return ret;
}
int
int
mime_get_num_parts(mime_t mime, size_t *nmtp_parts)
{
int ret = 0;
......@@ -698,11 +698,11 @@ mime_get_num_parts(mime_t mime, size_t *nmtp_parts)
}
int
int
mime_add_part(mime_t mime, message_t msg)
{
int ret;
if ( mime == NULL || msg == NULL || ( mime->flags & MIME_NEW_MESSAGE ) == 0 )
return EINVAL;
if ( ( ret = _mime_append_part(mime, msg, 0, 0, 0) ) == 0 )
......@@ -710,7 +710,7 @@ mime_add_part(mime_t mime, message_t msg)
return ret;
}
int
int
mime_get_message(mime_t mime, message_t *msg)
{
stream_t body_stream;
......@@ -749,7 +749,7 @@ mime_get_message(mime_t mime, message_t *msg)
return ret;
}
int
int
mime_is_multipart(mime_t mime)
{
if ( mime->content_type )
......