Commit 9f739684 9f73968409cff3e3d5b59dbb5b841d5fcffca582 by Alain Magloire

* mailbox/Makefile.am: filter_trans.c added, trans_stream.c deleted.

	* mailbox/attachment.c (message_create_attachment): use
	filter_create().
	(message_save_attachment): use filter_create().
	* mailbox/body.c (body_set_lines): Wrong comparison for the owner.
	* mailbox/mbx_mbox.c: Do not count the line separtor of part
	of the mailbox.

	* mailbox/url.c (url_is_same_sheme): New function.
	(url_is_same_user): New function.
	(url_is_same_path): New function.
	(url_is_same_host): New function.
	(url_is_same_port): New function.
	* mailbox/folder.c : Moved the is_same_*() functions in url.c
	they can be generally usefull.
	(is_same_sheme): Removed.
	(is_same_user): Removed.
	(is_same_path): Removed.
	(is_same_host): Removed.
	(is_same_port): Removed.

	* mailbox/folder_imap.c (folder_imap_create): New function,
	CREATE a new mailbox.
	(folder_imap_open): Calls folder_imap_create when the MU_STREAM_CREAT
	flag is set.
	* mailbox/mbx_imap.c: Appending messages implemented, if the message
	comes from the same imap folder, it is COPY otherwise APPEND.
	(is_same_folder): New function.
	(imap_append_message): Implemented.
	(attribute_string): New functions.
	(imap_copy_message): New function.
	* mailbox/include/imap0.h: New enum, IMAP_APPEND, IMAP_APPEND_ACK,
	IMAP_APPEND_CONT, IMAP_APPEND_SEND, IMAP_COPY, IMAP_COPY_ACK,
	IMAP_CREATE, IMAP_CREATE_ACK.


* mailbox/parse822.c: New parser.
	* include/mailutils/parse822.h: New file.
	* mailbox/address.c (address_create): Remove the old parsing and use
	parse822 as the underlying engine.
	(address_parse): Removed.
	(gettoken): Removed.
	(quotes): Removed.
	(address_get_personal): Remove the code to unquote, parse822 takes
	care if it. Return value when no field is ENOENT.
	(address_get_comments): Reutrn value when no field ENOENT.
	(address_get_local_part): Reutrn value when no field ENOENT.
	(address_get_domain): Reutrn value when no field ENOENT.
	(address_get_email): Reutrn value when no field ENOENT.
	(address_get_route): Reutrn value when no field ENOENT.
	* mailbox/message.c (message_sender): Use parse822 to retrieve
	the email from the From: field.
	(message_set_mailbox): New function.
	* mailbox/misc.c : Removed the old parsing code.
	(gettoken): Removed.
	(parseaddr): Removed.
	* mailbox/include/misc.h : Removed parseaddr() prototypes.
	From Sam Roberts, the new parse822 parser..
1 parent f9979c0e
......@@ -22,6 +22,7 @@ envelope.c \
file_stream.c \
filter.c \
filter_rfc822.c \
filter_trans.c \
folder.c \
folder_imap.c \
folder_mbox.c \
......@@ -50,7 +51,6 @@ sendmail.c \
smtp.c \
stream.c \
tcp.c \
trans_stream.c \
url.c \
url_file.c \
url_imap.c \
......
......@@ -27,297 +27,38 @@
#include <stdlib.h>
#include <errno.h>
#include <address0.h>
#include <mailutils/parse822.h>
#include <misc.h>
/*
* parseaddr.c Read a valid RFC822 address with all the comments
* etc in it, and return _just_ the email address.
*
* Version: @(#)parseaddr.c 1.00 02-Apr-1999 miquels@cistron.nl
*
*/
struct token
{
struct token *next;
char word[1];
};
#define SKIPSPACE(p) do { while(*p && isspace((unsigned char)*p)) p++; } while(0)
/* Skip everything between quotes. */
static void
quotes (const char **ptr)
{
const char *p = *ptr;
p++;
while (*p && *p != '"')
{
if (*p == '\\' && p[1])
p++;
p++;
}
*ptr = p;
}
/* Return the next token. A token can be "<>()," or any "word". */
static struct token *
gettoken (const char **ptr)
{
struct token *tok;
const char *p = *ptr;
const char *begin;
int l, quit = 0;
SKIPSPACE(p);
begin = p;
while (!quit)
{
switch (*p)
{
case 0:
case ' ':
case '\t':
case '\n':
quit = 1;
break;
case '(':
case ')':
case '<':
case '>':
case ',':
if (p == begin)
p++;
quit = 1;
break;
case '\\':
if (p[1])
p++;
break;
case '"':
quotes (&p);
break;
}
if (!quit)
p++;
}
l = p - begin;
if (l == 0)
return NULL;
tok = malloc (sizeof (struct token) + l);
if (tok == NULL)
return NULL;
tok->next = NULL;
strncpy (tok->word, begin, l);
tok->word[l] = 0;
SKIPSPACE (p);
*ptr = p;
return tok;
}
#include <address0.h>
/* Get email address from rfc822 address. */
/* Note: This again as for header.c an awfull way of doing things.
Meaning I need a correct rfc822 Parser. This one does not
understand group. There is not doubt a better way to do this. */
static int
address_parse (address_t *paddress, const char **paddr)
{
const char *p;
struct token *t, *tok, *last;
struct token *brace = NULL;
struct token *comments = NULL;
struct token *start_comments = NULL;
address_t address;
int in_comment = 0;
int status = 0;
tok = last = NULL;
address = *paddress = calloc (1, sizeof (*address));
if (address == NULL)
return ENOMEM;
/* Read address, remove comments right away. */
p = *paddr;
while ((t = gettoken(&p)) != NULL && (t->word[0] != ',' || in_comment))
{
if (t->word[0] == '(' || t->word[0] == ')' || in_comment)
{
if (t->word[0] == '(')
in_comment++;
if (t->word[0] == ')')
in_comment--;
if (!start_comments)
comments = start_comments = t;
else
{
comments->next = t;
comments = t;
}
continue;
}
if (t->word[0] == '<')
brace = t;
if (tok)
last->next = t;
else
tok = t;
last = t;
}
if (t != NULL)
free (t);
/* Put extracted address into email */
t = brace ? brace->next : tok;
for (; t && t->word[0] != ',' && t->word[0] != '>'; t = t->next)
{
char *tmp;
if (address->email
&& (tmp = realloc (address->email, strlen (address->email)
+ strlen (t->word) + 1)) != NULL)
{
address->email = tmp;
strcat (address->email, t->word);
}
else if ((tmp = calloc (strlen (t->word) + 1, sizeof (char))) != NULL)
{
address->email = tmp;
strcat (address->email, t->word);
}
else
{
address_destroy (&address);
status = ENOMEM;
goto freenodes;
}
}
/* Extract Comments. */
for (t = start_comments; t ; t = t->next)
{
char *tmp;
if (t->word[0] == '(' || t->word[0] == ')')
continue;
if (address->comments
&& (tmp = realloc (address->comments, strlen (address->comments)
+ strlen (t->word) + 2)) != NULL)
{
address->comments = tmp;
strcat (address->comments, " ");
strcat (address->comments, t->word);
}
else if ((tmp = calloc (strlen (t->word) + 1, sizeof (char))) != NULL)
{
address->comments = tmp;
strcat (address->comments, t->word);
}
else
{
address_destroy (&address);
status = ENOMEM;
goto freenodes;
}
}
/* Extract Personal. */
if (brace == NULL)
{
address->personal = strdup ("");
}
else
{
int in_brace = 0;
for (t = tok; t ; t = t->next)
{
char *tmp;
if (t->word[0] == '<' || t->word[0] == '>' || in_brace)
{
if (t->word[0] == '<')
in_brace++;
else if (t->word[0] == '>')
in_brace--;
continue;
}
if (address->personal
&& (tmp = realloc (address->personal, strlen (address->personal)
+ strlen (t->word) + 2)) != NULL)
{
address->personal = tmp;
strcat (address->personal, " ");
strcat (address->personal, t->word);
}
else if ((tmp = calloc (strlen (t->word) + 1, sizeof (char))) != NULL)
{
address->personal = tmp;
strcat (address->personal, t->word);
}
else
{
address_destroy (&address);
status = ENOMEM;
goto freenodes;
}
}
}
/* Free list of tokens. */
freenodes:
for (t = tok; t; t = last)
{
last = t->next;
free (t);
}
for (t = start_comments; t; t = last)
{
last = t->next;
free (t);
}
*paddr = p;
return status;
}
int
address_create (address_t *paddress, const char *addr)
address_create (address_t *a, const char *s)
{
address_t address = NULL;
address_t current = NULL;
address_t head = NULL;
const char *p = addr;
int status = 0;
/* 'paddress' must exist, and can't already have been initialized
*/
int status;
if (paddress == NULL)
if (!a)
return EINVAL;
if (addr)
*a = NULL;
status = parse822_address_list (a, (char*) s);
if (status == 0)
{
while (*addr != 0)
/* There was a group that got parsed correctly, but had
* no addresses...
*/
if (!*a)
return ENOENT;
(*a)->addr = strdup (s);
if (!(*a)->addr)
{
status = address_parse (&address, &addr);
if (status == 0)
{
if (head == NULL)
{
head = address;
head->addr = strdup (p);
}
else
current->next = address;
current = address;
p = addr;
}
}
address_destroy (a);
return ENOMEM;
}
}
*paddress = head;
return status;
}
......@@ -356,7 +97,7 @@ address_get_personal (address_t addr, size_t no, char *buf, size_t len,
size_t *n)
{
size_t i, j;
int status = EINVAL;
int status = ENOENT;
if (addr == NULL)
return EINVAL;
for (i = 0, j = 1; addr; addr = addr->next, j++)
......@@ -368,18 +109,6 @@ address_get_personal (address_t addr, size_t no, char *buf, size_t len,
break;
}
}
/* Remove the leading doublequotes. */
if (i && buf && *buf == '"')
{
memmove (buf, buf + 1, i - 1);
i--;
}
/* Remove the trailing doublequotes. */
if (i && buf && buf[i - 1] == '"')
{
buf[i - 1] = '\0';
i--;
}
if (n)
*n = i;
return status;
......@@ -390,7 +119,7 @@ address_get_comments (address_t addr, size_t no, char *buf, size_t len,
size_t *n)
{
size_t i, j;
int status = EINVAL;
int status = ENOENT;
if (addr == NULL)
return EINVAL;
for (j = 1; addr; addr = addr->next, j++)
......@@ -411,7 +140,7 @@ int
address_get_email (address_t addr, size_t no, char *buf, size_t len, size_t *n)
{
size_t i, j;
int status = EINVAL;
int status = ENOENT;
if (addr == NULL)
return EINVAL;
for (j = 1; addr; addr = addr->next, j++)
......@@ -432,7 +161,7 @@ int
address_get_local_part (address_t addr, size_t no, char *buf, size_t len, size_t *n)
{
size_t i, j;
int status = EINVAL;
int status = ENOENT;
if (addr == NULL)
return EINVAL;
for (j = 1; addr; addr = addr->next, j++)
......@@ -453,7 +182,7 @@ int
address_get_domain (address_t addr, size_t no, char *buf, size_t len, size_t *n)
{
size_t i, j;
int status = EINVAL;
int status = ENOENT;
if (addr == NULL)
return EINVAL;
for (j = 1; addr; addr = addr->next, j++)
......@@ -474,7 +203,7 @@ int
address_get_route (address_t addr, size_t no, char *buf, size_t len, size_t *n)
{
size_t i, j;
int status = EINVAL;
int status = ENOENT;
if (addr == NULL)
return EINVAL;
for (j = 1; addr; addr = addr->next, j++)
......
......@@ -23,9 +23,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <mailutils/message.h>
#include <mailutils/filter.h>
#include <mailutils/stream.h>
#define MAX_HDR_LEN 256
......@@ -75,7 +77,7 @@ int message_create_attachment(const char *content_type, const char *encoding, co
message_get_body(*newmsg, &body);
if ( ( ret = file_stream_create(&fstream) ) == 0 ) {
if ( ( ret = stream_open(fstream, filename, 0, MU_STREAM_READ) ) == 0 ) {
if ( ( ret = encoder_stream_create(&tstream, fstream, encoding) ) == 0 ) {
if ( ( ret = filter_create(&tstream, fstream, encoding, MU_FILTER_ENCODE, MU_STREAM_READ) ) == 0 ) {
body_set_stream(body, tstream, *newmsg);
message_set_header(*newmsg, hdr, NULL);
}
......@@ -245,7 +247,7 @@ int message_save_attachment(message_t msg, const char *filename, void **data)
header_get_value(hdr, "Content-Transfer-Encoding", content_encoding, size+1, 0);
} else
content_encoding = (char *)"7bit";
ret = decoder_stream_create(&info->ostream, fstream, content_encoding);
ret = filter_create(&info->ostream, fstream, content_encoding, MU_FILTER_DECODE, MU_STREAM_READ);
}
}
}
......
......@@ -211,7 +211,7 @@ body_set_lines (body_t body, int (*_lines)(body_t, size_t *), void *owner)
{
if (body == NULL)
return EINVAL;
if (body->owner == owner)
if (body->owner != owner)
return EACCES;
body->_lines = _lines;
return 0;
......
......@@ -28,7 +28,7 @@
# include <pthread.h>
#endif
#include <mailutils/filter.h>
#include <filter0.h>
#include <mailutils/property.h>
static int rfc822_property __P ((property_t, const char *, const char *));
......@@ -46,23 +46,17 @@ struct rfc822
int residue;
};
static struct _filter _rfc822_filter =
static struct _filter_record _rfc822_filter =
{
"RFC822",
rfc822_init,
rfc822_read,
rfc822_readline,
NULL,
rfc822_destroy,
NULL,
NULL,
NULL,
0,
NULL
};
/* Exported. */
filter_t rfc822_filter = &_rfc822_filter;
filter_record_t rfc822_filter = &_rfc822_filter;
static int
rfc822_property (property_t property, const char *key, const char *value)
......@@ -82,6 +76,11 @@ rfc822_init (filter_t filter)
filter->data = calloc (1, sizeof (struct rfc822));
if (filter->data == NULL)
return ENOMEM;
filter->_read = rfc822_read;
filter->_readline = rfc822_readline;
filter->_destroy = rfc822_destroy;
/* We are interested in this property. */
if ((status = stream_get_property (filter->filter_stream, &property) != 0)
|| (status = property_add_defaults (property, "LINES", "0",
......
......@@ -34,11 +34,6 @@
/* Internal folder list. */
static list_t known_folder_list;
static int is_known_folder __P ((url_t, folder_t *));
static int is_same_scheme __P ((url_t, url_t));
static int is_same_user __P ((url_t, url_t));
static int is_same_path __P ((url_t, url_t));
static int is_same_host __P ((url_t, url_t));
static int is_same_port __P ((url_t, url_t));
/* Static folder lock. */
static struct _monitor folder_lock = MU_MONITOR_INITIALIZER;
......@@ -200,6 +195,7 @@ folder_destroy (folder_t *pfolder)
if (folder->stream)
stream_destroy (&(folder->stream), folder);
if (folder->url)
url_destroy (&(folder->url));
free (folder);
}
......@@ -210,7 +206,6 @@ folder_destroy (folder_t *pfolder)
}
}
/* Cover functions. */
int
folder_open (folder_t folder, int flags)
......@@ -410,8 +405,6 @@ folder_get_url (folder_t folder, url_t *purl)
return 0;
}
/* ---------------------- Private ---------------------- */
static int is_known_folder (url_t url, folder_t *pfolder)
{
int ret = 0;
......@@ -430,126 +423,18 @@ static int is_known_folder (url_t url, folder_t *pfolder)
iterator_current (iterator, (void **)&folder);
/* Check if the same URL type. */
if (folder && folder->url
&& is_same_scheme (url, folder->url)
&& is_same_user (url, folder->url)
&& is_same_path (url, folder->url)
&& is_same_host (url, folder->url)
&& is_same_port (url, folder->url))
&& url_is_same_scheme (url, folder->url)
&& url_is_same_user (url, folder->url)
&& url_is_same_host (url, folder->url)
/*&& url_is_same_path (url, folder->url) */
&& url_is_same_port (url, folder->url))
{
ret = 1;
break;
}
}
if (ret)
*pfolder = folder;
iterator_destroy (&iterator);
return ret;
}
static int
is_same_scheme (url_t url1, url_t url2)
{
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 1;
url_get_scheme (url1, NULL, 0, &i);
url_get_scheme (url2, NULL, 0, &j);
s1 = calloc (i + 1, sizeof (char));
if (s1)
{
url_get_scheme (url1, s1, i + 1, NULL);
s2 = calloc (j + 1, sizeof (char));
if (s2)
{
url_get_scheme (url2, s2, j + 1, NULL);
ret = !strcasecmp (s1, s2);
free (s2);
}
free (s1);
}
return ret;
}
static int
is_same_user (url_t url1, url_t url2)
{
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 0;
url_get_user (url1, NULL, 0, &i);
url_get_user (url2, NULL, 0, &j);
s1 = calloc (i + 1, sizeof (char));
if (s1)
{
url_get_user (url1, s1, i + 1, NULL);
s2 = calloc (j + 1, sizeof (char));
if (s2)
{
url_get_user (url2, s2, j + 1, NULL);
ret = !strcasecmp (s1, s2);
free (s2);
}
free (s1);
}
return ret;
}
static int
is_same_path (url_t url1, url_t url2)
{
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 0;
url_get_path (url1, NULL, 0, &i);
url_get_path (url2, NULL, 0, &j);
s1 = calloc (i + 1, sizeof (char));
if (s1)
{
url_get_path (url1, s1, i + 1, NULL);
s2 = calloc (j + 1, sizeof (char));
if (s2)
{
url_get_path (url2, s2, j + 1, NULL);
ret = !strcasecmp (s1, s2);
free (s2);
}
free (s1);
}
return ret;
}
static int
is_same_host (url_t url1, url_t url2)
{
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 0;
url_get_host (url1, NULL, 0, &i);
url_get_host (url2, NULL, 0, &j);
s1 = calloc (i + 1, sizeof (char));
if (s1)
{
url_get_host (url1, s1, i + 1, NULL);
s2 = calloc (j + 1, sizeof (char));
if (s2)
{
url_get_host (url2, s2, j + 1, NULL);
ret = !strcasecmp (s1, s2);
free (s2);
}
free (s1);
}
return ret;
}
static int
is_same_port (url_t url1, url_t url2)
{
long p1 = 0, p2 = 0;
url_get_port (url1, &p1);
url_get_port (url2, &p2);
return (p1 == p2);
}
......
......@@ -53,6 +53,7 @@ record_t imap_record = &_imap_record;
/* Concrete IMAP implementation. */
static int folder_imap_open __P ((folder_t, int));
static int folder_imap_create __P ((folder_t));
static int folder_imap_close __P ((folder_t));
static void folder_imap_destroy __P ((folder_t));
static int folder_imap_delete __P ((folder_t, const char *));
......@@ -211,7 +212,9 @@ folder_imap_open (folder_t folder, int flags)
monitor_wrlock (folder->monitor);
if (f_imap->isopen)
{
monitor_wrlock (folder->monitor);
monitor_unlock (folder->monitor);
if (flags & MU_STREAM_CREAT)
status = folder_imap_create (folder);
return 0;
}
monitor_unlock (folder->monitor);
......@@ -324,6 +327,11 @@ folder_imap_open (folder_t folder, int flags)
monitor_wrlock (folder->monitor);
f_imap->isopen++;
monitor_unlock (folder->monitor);
if (flags & MU_STREAM_CREAT)
{
status = folder_imap_create (folder);
CHECK_EAGAIN (f_imap, status);
}
return 0;
}
......@@ -372,6 +380,51 @@ folder_imap_close (folder_t folder)
return 0;
}
/* Create a folder/mailbox. */
static int
folder_imap_create (folder_t folder)
{
f_imap_t f_imap = folder->data;
int status = 0;
switch (f_imap->state)
{
case IMAP_NO_STATE:
{
char *path;
size_t len;
url_get_path (folder->url, NULL, 0, &len);
if (len == 0)
return 0;
path = calloc (len + 1, sizeof (*path));
if (path == NULL)
return ENOMEM;
url_get_path (folder->url, path, len + 1, NULL);
status = imap_writeline (f_imap, "g%d CREATE %s\r\n", f_imap->seq++,
path);
free (path);
CHECK_ERROR (f_imap, status);
FOLDER_DEBUG0 (folder, MU_DEBUG_PROT, f_imap->buffer);
f_imap->state = IMAP_CREATE;
}
case IMAP_CREATE:
status = imap_send (f_imap);
CHECK_EAGAIN (f_imap, status);
f_imap->state = IMAP_DELETE_ACK;
case IMAP_CREATE_ACK:
status = imap_parse (f_imap);
CHECK_EAGAIN (f_imap, status);
FOLDER_DEBUG0 (folder, MU_DEBUG_PROT, f_imap->buffer);
default:
break;
}
f_imap->state = IMAP_NO_STATE;
return status;
}
/* Remove a mailbox. */
static int
folder_imap_delete (folder_t folder, const char *name)
......@@ -1528,9 +1581,9 @@ int
imap_send (f_imap_t f_imap)
{
int status = 0;
size_t len;
if (f_imap->ptr > f_imap->buffer)
{
size_t len;
len = f_imap->ptr - f_imap->buffer;
status = stream_write (f_imap->folder->stream, f_imap->buffer, len,
0, &len);
......@@ -1543,7 +1596,6 @@ imap_send (f_imap_t f_imap)
else
{
f_imap->ptr = f_imap->buffer;
len = 0;
}
return status;
}
......@@ -1823,18 +1875,18 @@ imap_parse (f_imap_t f_imap)
{
/* Not sure why we would get an untagged ok...but we do... */
/* Still should we be verbose about is ? */
printf("Untagged OK: %s\n", remainder);
fprintf (stderr, "Untagged OK: %s\n", remainder);
}
}
else if (strcasecmp (response, "NO") == 0)
{
/* This does not mean failure but rather a strong warning. */
printf ("Untagged NO: %s\n", remainder);
fprintf (stderr, "Untagged NO: %s\n", remainder);
}
else if (strcasecmp (response, "BAD") == 0)
{
/* We're dead, protocol/syntax error. */
printf ("Untagged BAD: %s\n", remainder);
fprintf (stderr, "Untagged BAD: %s\n", remainder);
}
else if (strcasecmp (response, "PREAUTH") == 0)
{
......@@ -1893,8 +1945,8 @@ imap_parse (f_imap_t f_imap)
else
{
/* Once again, check for something strange. */
printf("unknown untagged response: \"%s\" %s\n",
response, remainder);
fprintf (stderr, "unknown untagged response: \"%s\" %s\n",
response, remainder);
}
}
/* Continuation token ???. */
......@@ -1917,7 +1969,7 @@ imap_parse (f_imap_t f_imap)
folder_get_observable (f_imap->folder, &observable);
observable_notify (observable, MU_EVT_AUTHORITY_FAILED);
}
printf("NO/Bad Tagged: %s %s\n", response, remainder);
fprintf (stderr, "NO/Bad Tagged: %s %s\n", response, remainder);
status = EINVAL;
}
}
......
......@@ -5,6 +5,7 @@ auth0.h \
body0.h \
debug0.h \
envelope0.h \
filter0.h \
folder0.h \
header0.h \
iterator0.h \
......
/* GNU mailutils - a suite of utilities for electronic mail
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
the Free Software Foundation; either version 2, 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Notes:
*/
#ifndef _FILTER0_H
#define _FILTER0_H
#include <mailutils/filter.h>
#include <mailutils/list.h>
#include <mailutils/monitor.h>
#include <mailutils/property.h>
#ifndef __P
# ifdef __STDC__
# define __P(args) args
# else
# define __P(args) ()
# endif
#endif /*__P */
#ifdef __cplusplus
extern "C" {
#endif
struct _filter
{
stream_t stream;
stream_t filter_stream;
property_t property;
int direction;
int type;
void *data;
int (*_read) __P ((filter_t, char *, size_t, off_t, size_t *));
int (*_readline) __P ((filter_t, char *, size_t, off_t, size_t *));
int (*_write) __P ((filter_t, const char *, size_t, off_t, size_t *));
void (*_destroy) __P ((filter_t));
};
#ifdef __cplusplus
}
#endif
#endif /* _FILTER0_H */
......@@ -93,8 +93,11 @@ enum imap_state
{
IMAP_NO_STATE=0,
IMAP_AUTH, IMAP_AUTH_DONE,
IMAP_APPEND, IMAP_APPEND_CONT, IMAP_APPEND_SEND, IMAP_APPEND_ACK,
IMAP_BODY,
IMAP_CLOSE, IMAP_CLOSE_ACK,
IMAP_COPY, IMAP_COPY_ACK,
IMAP_CREATE, IMAP_CREATE_ACK,
IMAP_DELETE, IMAP_DELETE_ACK,
IMAP_FETCH, IMAP_FETCH_ACK,
IMAP_GREETINGS,
......
/* 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,8 +39,8 @@ extern "C" {
# define __P(x)
# endif
#endif
extern size_t _cpystr __P ((char *dst, const char *src, size_t size));
extern int parseaddr __P ((const char *addr, char *buf, size_t bufsz));
#ifdef __cplusplus
}
......
......@@ -69,7 +69,7 @@ mailbox_create (mailbox_t *pmbox, const char *name)
if (found)
{
url_t url = NULL;
mailbox_t mbox = NULL;
mailbox_t mbox;
/* Allocate memory for mbox. */
mbox = calloc (1, sizeof (*mbox));
......
......@@ -1124,7 +1124,7 @@ mbox_body_size (body_t body, size_t *psize)
if (mum == NULL)
return EINVAL;
if (psize)
*psize = mum->body_end - mum->body + 1;
*psize = mum->body_end - mum->body;
return 0;
}
......
......@@ -1770,9 +1770,9 @@ static int
pop_write (pop_data_t mpd)
{
int status = 0;
size_t len;
if (mpd->ptr > mpd->buffer)
{
size_t len;
len = mpd->ptr - mpd->buffer;
status = stream_write (mpd->mbox->stream, mpd->buffer, len, 0, &len);
if (status == 0)
......@@ -1782,10 +1782,7 @@ pop_write (pop_data_t mpd)
}
}
else
{
mpd->ptr = mpd->buffer;
len = 0;
}
mpd->ptr = mpd->buffer;
return status;
}
......
......@@ -30,8 +30,8 @@
#include "md5.h"
#include <misc.h>
#include <message0.h>
#include <mailutils/address.h>
static int message_read __P ((stream_t is, char *buf, size_t buflen,
off_t off, size_t *pnread ));
......@@ -213,6 +213,15 @@ message_get_property (message_t msg, property_t *pproperty)
}
int
message_get_mailbox (message_t msg, mailbox_t *pmailbox)
{
if (msg == NULL || pmailbox == NULL)
return EINVAL;
*pmailbox = msg->mailbox;
return 0;
}
int
message_set_mailbox (message_t msg, mailbox_t mailbox, void *owner)
{
if (msg == NULL)
......@@ -894,34 +903,16 @@ message_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
if (status == 0 && n != 0)
{
char *sender;
char *addr;
address_t address = NULL;
sender = calloc (1, n + 1);
if (sender == NULL)
return ENOMEM;
addr = calloc (1, n + 1);
if (addr == NULL)
{
free (sender);
return ENOMEM;
}
header_get_value (header, MU_HEADER_FROM, sender, n + 1, NULL);
if (parseaddr (sender, addr, n + 1) == 0)
{
size_t i = strlen (addr);
n = (i > len) ? len : i;
if (buf && len > 0)
{
memcpy (buf, addr, n);
buf[n] = '\0';
}
free (addr);
free (sender);
if (pnwrite)
*pnwrite = n;
return 0;
}
free (addr);
if (address_create (&address, sender) == 0)
address_get_email (address, 1, buf, n + 1, pnwrite);
free (sender);
address_destroy (&address);
return 0;
}
else if (status == EAGAIN)
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
......@@ -27,6 +27,8 @@
#include <ctype.h>
#include <stdlib.h>
/* Smart strncpy that always add the null and returns the number of bytes
written. */
size_t
_cpystr (char *dst, const char *src, size_t size)
{
......@@ -39,153 +41,3 @@ _cpystr (char *dst, const char *src, size_t size)
dst[len] = '\0';
return len;
}
/*
* parseaddr.c Read a valid RFC822 address with all the comments
* etc in it, and return _just_ the email address.
*
* Version: @(#)parseaddr.c 1.00 02-Apr-1999 miquels@cistron.nl
*
*/
struct token
{
struct token *next;
char word[1];
};
#define SKIPSPACE(p) do { while(*p && isspace((unsigned char)*p)) p++; } while(0)
/* Skip everything between quotes. */
static void
quotes (const char **ptr)
{
const char *p = *ptr;
p++;
while (*p && *p != '"')
{
if (*p == '\\' && p[1])
p++;
p++;
}
*ptr = p;
}
/* Return the next token. A token can be "<>()," or any "word". */
static struct token *
gettoken (const char **ptr)
{
struct token *tok;
const char *p = *ptr;
const char *begin;
int l, quit = 0;
SKIPSPACE(p);
begin = p;
while (!quit)
{
switch (*p)
{
case 0:
case ' ':
case '\t':
case '\n':
quit = 1;
break;
case '(':
case ')':
case '<':
case '>':
case ',':
if (p == begin)
p++;
quit = 1;
break;
case '\\':
if (p[1])
p++;
break;
case '"':
quotes (&p);
break;
}
if (!quit)
p++;
}
l = p - begin;
if (l == 0)
return NULL;
tok = malloc (sizeof (struct token) + l);
if (tok == NULL)
return NULL;
tok->next = NULL;
strncpy (tok->word, begin, l);
tok->word[l] = 0;
SKIPSPACE (p);
*ptr = p;
return tok;
}
/* Get email address from rfc822 address. */
int
parseaddr (const char *addr, char *buf, size_t bufsz)
{
const char *p;
struct token *t, *tok, *last;
struct token *brace = NULL;
int comment = 0;
int status = 0;
tok = last = NULL;
/* Read address, remove comments right away. */
p = addr;
while ((t = gettoken(&p)) != NULL && t->word[0] != ',')
{
if (t->word[0] == '(' || t->word[0] == ')' || comment)
{
free (t);
if (t->word[0] == '(')
comment++;
if (t->word[0] == ')')
comment--;
continue;
}
if (t->word[0] == '<')
brace = t;
if (tok)
last->next = t;
else
tok = t;
last = t;
}
/* Put extracted address into "buf" */
buf[0] = 0;
t = brace ? brace->next : tok;
for (; t && t->word[0] != ',' && t->word[0] != '>'; t = t->next)
{
if (strlen (t->word) >= bufsz)
{
status = -1;
break;
}
bufsz -= strlen (t->word);
strcat (buf, t->word);
}
/* Free list of tokens. */
for (t = tok; t; t = last)
{
last = t->next;
free (t);
}
return status;
}
......
......@@ -95,7 +95,7 @@ static int str_append_n(char** to, const char* from, size_t n)
if(!bigger) {
return ENOMEM;
}
*to = bigger;
} else {
*to = malloc(n + 1);
......@@ -283,7 +283,7 @@ int parse822_comment(const char** p, const char* e, char** comment)
if((rc = parse822_special(p, e, '('))) {
return rc;
}
while(*p != e) {
char c = **p;
......@@ -307,7 +307,7 @@ int parse822_comment(const char** p, const char* e, char** comment)
if(rc != EOK)
break;
}
if(*p == e) {
rc = EPARSE; /* end-of-comment not found */
}
......@@ -536,6 +536,8 @@ static int fill_mb(
return rc;
}
/* FIXME: Delete this one. adddress.c do the work now. */
#if 0
int address_create0 (address_t* a, const char* s)
{
/* 'a' must exist, and can't already have been initialized
......@@ -546,7 +548,7 @@ int address_create0 (address_t* a, const char* s)
if(!a || *a) {
return EINVAL;
}
status = parse822_address_list(a, (char*) s);
if(status == EOK) {
......@@ -566,6 +568,7 @@ int address_create0 (address_t* a, const char* s)
return status;
}
#endif
int parse822_address_list(address_t* a, const char* s)
{
......@@ -585,7 +588,7 @@ int parse822_address_list(address_t* a, const char* s)
{
/* An address can contain a group, so an entire
* list of addresses may have been appended, or no
* addresses at all. Walk to the end.
* addresses at all. Walk to the end.
*/
while(*n) {
n = &(*n)->next;
......@@ -626,7 +629,7 @@ int parse822_address(const char** p, const char* e, address_t* a)
/* address = mailbox / group */
int rc;
if((rc = parse822_mail_box(p, e, a)) == EPARSE)
rc = parse822_group(p, e, a);
......@@ -672,7 +675,7 @@ int parse822_group(const char** p, const char* e, address_t* a)
} else if(rc != EPARSE) {
break;
}
if((rc = parse822_special(p, e, ','))) {
/* the commas aren't optional */
break;
......@@ -785,7 +788,7 @@ int parse822_route_addr(const char** p, const char* e, address_t* a)
*p = save;
address_destroy(a);
return rc;
}
......@@ -898,7 +901,7 @@ int parse822_local_part(const char** p, const char* e, char** local_part)
return rc;
}
/* We've got a local-part, but keep looking for more. */
parse822_skip_comments(p, e);
/* If we get a parse error, we roll back to save2, but if
......@@ -992,7 +995,7 @@ int parse822_sub_domain(const char** p, const char* e, char** sub_domain)
*/
int rc;
if((rc = parse822_domain_ref(p, e, sub_domain)) == EPARSE)
rc = parse822_domain_literal(p, e, sub_domain);
......@@ -1157,6 +1160,4 @@ int parse822_field_body(const char** p, const char* e, Rope& fieldbody)
return 1;
}
#endif
......
/* 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
......@@ -196,3 +196,113 @@ url_to_string (const url_t url)
return "";
return url->name;
}
int
url_is_same_scheme (url_t url1, url_t url2)
{
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 1;
url_get_scheme (url1, NULL, 0, &i);
url_get_scheme (url2, NULL, 0, &j);
s1 = calloc (i + 1, sizeof (char));
if (s1)
{
url_get_scheme (url1, s1, i + 1, NULL);
s2 = calloc (j + 1, sizeof (char));
if (s2)
{
url_get_scheme (url2, s2, j + 1, NULL);
ret = !strcasecmp (s1, s2);
free (s2);
}
free (s1);
}
return ret;
}
int
url_is_same_user (url_t url1, url_t url2)
{
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 0;
url_get_user (url1, NULL, 0, &i);
url_get_user (url2, NULL, 0, &j);
s1 = calloc (i + 1, sizeof (char));
if (s1)
{
url_get_user (url1, s1, i + 1, NULL);
s2 = calloc (j + 1, sizeof (char));
if (s2)
{
url_get_user (url2, s2, j + 1, NULL);
ret = !strcasecmp (s1, s2);
free (s2);
}
free (s1);
}
return ret;
}
int
url_is_same_path (url_t url1, url_t url2)
{
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 0;
url_get_path (url1, NULL, 0, &i);
url_get_path (url2, NULL, 0, &j);
s1 = calloc (i + 1, sizeof (char));
if (s1)
{
url_get_path (url1, s1, i + 1, NULL);
s2 = calloc (j + 1, sizeof (char));
if (s2)
{
url_get_path (url2, s2, j + 1, NULL);
ret = !strcasecmp (s1, s2);
free (s2);
}
free (s1);
}
return ret;
}
int
url_is_same_host (url_t url1, url_t url2)
{
size_t i = 0, j = 0;
char *s1, *s2;
int ret = 0;
url_get_host (url1, NULL, 0, &i);
url_get_host (url2, NULL, 0, &j);
s1 = calloc (i + 1, sizeof (char));
if (s1)
{
url_get_host (url1, s1, i + 1, NULL);
s2 = calloc (j + 1, sizeof (char));
if (s2)
{
url_get_host (url2, s2, j + 1, NULL);
ret = !strcasecmp (s1, s2);
free (s2);
}
free (s1);
}
return ret;
}
int
url_is_same_port (url_t url1, url_t url2)
{
long p1 = 0, p2 = 0;
url_get_port (url1, &p1);
url_get_port (url2, &p2);
return (p1 == p2);
}
......