Commit 2bb68e42 2bb68e42b049f5882385c6e19d29810b5aafb9b7 by Alain Magloire

Pointed by Sam Roberts s/_cplusplus/__cplusplus almost all the headers

had to be fixed.

imap4d server added HEADER.FIELDS.NOT fetch functionality. But still
partial retrieve does not work and I fail to to do proper counting
i.e "\n" must be counted for two bytes "\r\n".

REMINDER: the imap4d/fetch.c is getting heavily bloated, fix later.
1 parent 56461cf8
2001-03-03 Alain Magloire
* imap4d/fetch.c (fetch_operation) : HEADER.FIELDS.NOT implemented.
fetch_opertaion() tak e a new argument.
* imap4d/util.c (util_upper) : New function string upper.
* mailbox/heder.c : Added new functionnalities to help the imap4d
fetch command.
(header_get_field_count) : New function returns the number of header
fields in the header.
(header_get_field_name): New function returns the field name.
(header_get_field_value): New function returns the field value.
2001-03-03 Alain Magloire
* include/mailutils/address.h : s/_cplusplus/__cplusplus/g
(include/mailutils/auth.h) : Likewised.
(include/mailutils/body.h) : Likewised.
(include/mailutils/debug.h) : Likewised.
(include/mailutils/header.h) : Likewised.
(include/mailutils/iterator.h) : Likewised.
(include/mailutils/list.h) : Likewised.
(include/mailutils/mailer.h) : Likewised.
(include/mailutils/message.h) : Likewised.
(include/mailutils/mime.h) : Likewised.
(include/mailutils/observer.h) : Likewised.
(include/mailutils/property.h) : Likewised.
(include/mailutils/registrar.h): Likewised.
(mailbox/include/address0.h) : Likewised.
(mailbox/include/auth0.h) : Likewised.
(mailbox/include/body0.h) : Likewised.
(mailbox/include/debug0.h) : Likewised.
(mailbox/include/header0.h) : Likewised.
(mailbox/include/iterator0.h) : Likewised.
(mailbox/include/list0.h) : Likewised.
(mailbox/include/mailer0.h) : Likewised.
(mailbox/include/message0.h) : Likewised.
(mailbox/include/mime0.h) : Likewised.
(mailbox/include/observer0.h) : Likewised.
Pointed by Sam Roberts.
2001-02-28 Alain Magloire
* mailbox/address.c (address_get_personal) : Remove surrounding quotes.
......
......@@ -47,7 +47,7 @@ static int fetch_body (struct imap4d_command *, char*);
static int fetch_uid (struct imap4d_command *, char*);
static int fetch_send_address (char *addr);
static int fetch_operation (size_t, char *);
static int fetch_operation (size_t, char *, int);
struct imap4d_command fetch_command_table [] =
{
......@@ -236,8 +236,7 @@ fetch_envelope (struct imap4d_command *command, char *arg)
char from[128];
header_t header = NULL;
message_t msg = NULL;
/* FIXME: K&R compilers will choke at this, initializing local arrays was
not permitted. Even AIX xlc use to choke. */
mailbox_get_message (mbox, command->states, &msg);
message_get_header (msg, &header);
util_send ("%s(", command->name);
......@@ -332,7 +331,7 @@ fetch_flags (struct imap4d_command *command, char *arg)
}
/* The internal date of the message. */
/* FIXME: Wrong format. */
/* FIXME: Wrong format? */
static int
fetch_internaldate (struct imap4d_command *command, char *arg)
{
......@@ -357,7 +356,7 @@ fetch_rfc822_header (struct imap4d_command *command, char *arg)
char buffer[16];
util_send ("%s ", command->name);
strcpy (buffer, "[HEADER]");
fetch_operation (command->states, buffer);
fetch_operation (command->states, buffer, 1);
return 0;
}
......@@ -374,7 +373,7 @@ fetch_rfc822_text (struct imap4d_command *command, char *arg)
attribute_set_read (attr);
util_send ("%s ", command->name);
strcpy (buffer, "[TEXT]");
fetch_operation (command->states, buffer);
fetch_operation (command->states, buffer, 1);
return 0;
}
......@@ -428,7 +427,7 @@ fetch_rfc822 (struct imap4d_command *command, char *arg)
attribute_set_read (attr);
util_send ("%s ", command->name);
strcpy (buffer, "[]");
fetch_operation (command->states, buffer);
fetch_operation (command->states, buffer, 1);
}
return 0;
}
......@@ -495,13 +494,15 @@ fetch_body (struct imap4d_command *command, char *arg)
return 0;
}
util_send ("%s", arg);
fetch_operation (command->states, arg);
fetch_operation (command->states, arg, 0);
return 0;
}
/* FIXME: "\n" -->"\r\n" is not handle right still it will not be as messy. */
/* FIXME: Code bloat move some stuff in routines, to be reuse. */
/* FIXME: partial fetch <x.y> still not handle. */
static int
fetch_operation (size_t msgno, char *arg)
fetch_operation (size_t msgno, char *arg, int silent)
{
off_t offset = 0;
size_t limit = -1; /* No limit. */
......@@ -513,6 +514,7 @@ fetch_operation (size_t msgno, char *arg)
{
/* FIXME: This shoud be move in imap4d_fetch() and have more
draconian check. */
*partial = '\0';
partial++;
offset = strtoul (partial, &partial, 10);
if (*partial == '.')
......@@ -520,7 +522,11 @@ fetch_operation (size_t msgno, char *arg)
partial++;
limit = strtoul (partial, NULL, 10);
}
partial = alloca (64);
snprintf (partial, 64, "<%lu>", (unsigned long)offset);
}
else
partial = (char *)"";
mailbox_get_message (mbox, msgno, &msg);
......@@ -533,7 +539,9 @@ fetch_operation (size_t msgno, char *arg)
message_get_stream (msg, &stream);
message_size (msg, &size);
message_size (msg, &lines);
util_send ("{%u}\r\n", size + lines);
if (!silent)
util_send ("%s", arg);
util_send ("%s {%u}\r\n", partial, size + lines);
while (stream_readline (stream, buffer, sizeof (buffer), off, &n) == 0
&& n > 0)
{
......@@ -555,7 +563,12 @@ fetch_operation (size_t msgno, char *arg)
message_get_header (msg, &header);
header_size (header, &size);
header_lines (header, &lines);
util_send ("{%u}\r\n", size + lines);
if (!silent)
{
util_upper (arg);
util_send ("%s", arg);
}
util_send ("%s {%u}\r\n", partial, size + lines);
header_get_stream (header, &stream);
while (stream_readline (stream, buffer, sizeof (buffer), off, &n) == 0
&& n > 0)
......@@ -567,50 +580,178 @@ fetch_operation (size_t msgno, char *arg)
off += n;
}
}
else if (strncasecmp (arg, "[HEADER.FIELDS.NOT", 19) == 0)
else if (strncasecmp (arg, "[HEADER.FIELDS.NOT", 18) == 0)
{
/* Not implemented. */
char **array = NULL;
size_t array_len = 0;
char *buffer = NULL;
size_t total = 0;
arg += 18;
/* Save the field we want to ignore. */
{
char *field;
char *sp = NULL;
for (;(field = strtok_r (arg, " ()]\r\n", &sp));
arg = NULL, array_len++)
{
array = realloc (array, (array_len + 1) * sizeof (*array));
if (!array)
util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
array[array_len] = field;
}
}
/* Build the buffer. */
{
size_t i;
header_t header = NULL;
size_t count = 0;
message_get_header (msg, &header);
header_get_field_count (header, &count);
for (i = 1; i <= count; i++)
{
char *name;
char *value ;
size_t ototal;
size_t name_len = 0;
size_t value_len = 0;
size_t ignore = 0;
/* Get the field name. */
header_get_field_name (header, i, NULL, 0, &name_len);
if (name_len == 0)
continue;
name = calloc (name_len + 1, sizeof (*name));
if (!name)
util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
header_get_field_name (header, i, name, name_len + 1, NULL);
/* Should we ignore the field? */
{
size_t j;
for (j = 0; j < array_len; j++)
{
if (strcasecmp (array[j], name) == 0)
{
ignore = 1;
break;
}
}
if (ignore)
{
free (name);
continue;
}
}
/* Fet the field value. */
header_get_field_value (header, i, NULL, 0, &value_len);
value = calloc (value_len + 1, sizeof (*value));
if (!value)
util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
header_get_field_value (header, i, value, value_len + 1, NULL);
/* Save the field. */
ototal = name_len + value_len + 4; /* 4 for ": \r\n" */
buffer = realloc (buffer, (ototal + total + 1) * sizeof (*buffer));
if (!buffer)
util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
snprintf (buffer + total, ototal + 1, "%s: %s\r\n", name, value);
free (value);
free (name);
total += ototal;
}
}
util_send ("[HEADER.FIELDS.NOT");
{
size_t j;
for (j = 0; j < array_len; j++)
{
util_upper (array[j]);
util_send (" \"%s\"", array[j]);
}
}
util_send ("]%s {%u}\r\n", partial, total + 2);
util_send ("%s\r\n", (buffer) ? buffer : "");
if (buffer)
free (buffer);
if (array)
free (array);
}
else if (strncasecmp (arg, "[HEADER.FIELDS", 14) == 0)
{
char *field;
char *sp = NULL;
header_t header = NULL;
size_t val_len = 0;
size_t total = 0;
char *buffer = NULL;
char **array = NULL;
size_t array_len = 0;
size_t total = 0;
arg += 14;
message_get_header (msg, &header);
for (; field = strtok_r (arg, " ()]\r\n", &sp); arg = NULL, val_len = 0)
{
size_t ototal;
char *value = NULL;
header_get_value (header, field, NULL, 0, &val_len);
if (val_len == 0)
continue;
value = malloc (val_len + 1);
if (!value)
util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
header_get_value (header, field, value, val_len + 1, NULL);
ototal = strlen (field) + val_len + 4; /* 4 for ": \r\n" */
buffer = realloc (buffer, ototal + total + 1);
if (!buffer)
util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
snprintf (buffer + total, ototal + 1, "%s: %s\r\n", field, value);
free (value);
total += ototal;
}
util_send ("{%u}\r\n", total + 2);
/* Save the field. */
{
char *field;
char *sp = NULL;
for (;(field = strtok_r (arg, " ()]\r\n", &sp));
arg = NULL, array_len++)
{
array = realloc (array, (array_len + 1) * sizeof (*array));
if (!array)
util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
array[array_len] = field;
}
}
{
size_t j;
header_t header = NULL;
message_get_header (msg, &header);
for (j = 0; j < array_len; j++)
{
size_t ototal;
char *value;
size_t val_len = 0;
header_get_value (header, array[j], NULL, 0, &val_len);
if (val_len == 0)
continue;
value = calloc (val_len + 1, sizeof (*value));
if (!value)
util_quit (1); /* FIXME: send a "* BYE" to the client. */
header_get_value (header, array[j], value, val_len + 1, NULL);
ototal = strlen (array[j]) + val_len + 4; /* 4 for ": \r\n" */
buffer = realloc (buffer, (ototal + total + 1) * sizeof (*buffer));
if (!buffer)
util_quit (1); /* FIXME: send a "* BYE" to the client. */
snprintf (buffer + total, ototal + 1, "%s: %s\r\n",
array[j], value);
free (value);
total += ototal;
}
}
util_send ("[HEADER.FIELDS");
{
size_t j;
for (j = 0; j < array_len; j++)
{
util_upper (array[j]);
util_send (" \"%s\"", array[j]);
}
}
util_send ("]%s {%u}\r\n", partial, total + 2);
if (total)
util_send ("%s", buffer);
util_send ("\r\n");
if (buffer)
free (buffer);
if (array)
free (array);
}
else if (strncasecmp (arg, "[TEXT]", 6) == 0)
{
......@@ -622,7 +763,9 @@ fetch_operation (size_t msgno, char *arg)
message_get_body (msg, &body);
body_size (body, &size);
body_lines (body, &lines);
util_send ("{%u}\r\n", size + lines);
if (!silent)
util_send ("[TEXT]");
util_send ("%s {%u}\r\n", partial, size + lines);
body_get_stream (body, &stream);
while (stream_readline (stream, buffer, sizeof (buffer), off, &n) == 0
&& n > 0)
......
......@@ -133,6 +133,7 @@ void util_quit __P ((int));
char *util_getword __P ((char *s, char **save_ptr));
int util_token __P ((char *s, size_t, char **save_ptr));
int util_msgset __P ((char *s, int **set, int *n, int isuid));
int util_upper __P ((char *));
struct imap4d_command *util_getcommand __P ((char *cmd,
struct imap4d_command []));
......
......@@ -68,17 +68,17 @@ imap4d_select0 (struct imap4d_command *command, char *arg, int flags)
mailbox_message_unseen (mbox, &unseen);
util_out (RESP_NONE, "%d EXISTS", count);
util_out (RESP_NONE, "%d RECENT", recent);
util_out (RESP_NONE, "FLAGS (%s)", mflags);
util_out (RESP_OK, "[UIDNEXT %d] Predicted next uid", uidnext);
util_out (RESP_OK, "[UIDVALIDITY (%d)] UID valididy status",
uidvalidity);
util_out (RESP_OK, "[UIDNEXT %d] Predicted next uid", uidnext);
if (unseen)
util_out (RESP_OK, "[UNSEEN (%d)] %d is first unseen messsage ",
unseen, unseen);
util_out (RESP_NONE, "FLAGS (%s)", mflags);
/* FIXME:
- '\*' can be supported if we use the attribute_set userflag()
- Answered is still not set in the mailbox code. */
util_out (RESP_OK, "[PERMANENTFLAGS (%s)]", pflags);
util_out (RESP_OK, "[PERMANENTFLAGS (%s)] Permanent flags", pflags);
return util_send ("%s OK [%s] %s Complete\r\n", command->tag,
(MU_STREAM_READ == flags) ?
"READ-ONLY" : "READ-WRITE", command->name);
......
......@@ -16,6 +16,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "imap4d.h"
#include <ctype.h>
static int add2set (int **set, int *n, unsigned long val, size_t max);
static const char * sc2string (int rc);
......@@ -300,6 +301,16 @@ util_do_command (char *prompt)
return command->func (command, sp);
}
int
util_upper (char *s)
{
if (!s)
return 0;
for (; *s; s++)
*s = toupper ((unsigned)*s);
return 0;
}
/* FIXME: What is this for? */
int
util_start (char *tag)
......
......@@ -28,7 +28,7 @@
# endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -47,7 +47,7 @@ extern int address_get_comments __P ((address_t, size_t, char *,
extern int address_to_string __P ((address_t, char *, size_t, size_t *));
extern int address_get_count __P ((address_t, size_t *));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -28,7 +28,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -57,7 +57,7 @@ extern int authority_get_ticket __P ((authority_t, ticket_t *));
extern int authority_authenticate __P ((authority_t));
extern int authority_set_authenticate __P ((authority_t, int (*_authenticate) __P ((authority_t)), void *));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -29,7 +29,7 @@
# endif
#endif /* __P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -55,7 +55,7 @@ extern int body_lines __P ((body_t, size_t *));
extern int body_set_lines __P ((body_t, int (*_lines)
__P ((body_t, size_t*)), void *owner));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -29,7 +29,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -47,7 +47,7 @@ extern int debug_print __P ((debug_t debug, size_t level,
const char *format, ...));
extern int debug_set_print __P ((debug_t, int (*_print) __P ((debug_t, const char *, va_list)), void *owner));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -29,7 +29,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -65,7 +65,7 @@ extern "C" {
#define MU_HEADER_MIME_VERSION "MIME-Version"
#define MU_HEADER_X_UIDL "X-UIDL"
#define MU_HEADER_X_UID "X-UID"
#define MU_HEADER_X_IMAPBASE "X-IMAPbase"
#define MU_HEADER_X_IMAPBASE "X-IMAPbase"
/* Mime support header attribute */
......@@ -73,48 +73,54 @@ extern "C" {
struct _header;
typedef struct _header * header_t;
extern int header_create __P ((header_t *, const char *,
extern int header_create __P ((header_t *, const char *,
size_t, void *));
extern void header_destroy __P ((header_t *, void *));
extern void * header_get_owner __P ((header_t));
extern int header_is_modified __P ((header_t));
extern int header_clear_modified __P ((header_t));
extern int header_set_value __P ((header_t, const char *,
const char *, int));
extern int header_set_set_value __P ((header_t, int (*_set_value)
__P ((header_t, const char *,
const char *, int)), void *));
extern int header_get_value __P ((header_t, const char *, char *,
size_t, size_t *));
extern int header_set_get_value __P ((header_t, int (*_get_value)
__P ((header_t, const char *, char *,
size_t, size_t *)), void *));
extern int header_set_get_fvalue __P ((header_t, int (*_get_value)
__P ((header_t, const char *, char *,
size_t, size_t *)), void *));
extern int header_get_stream __P ((header_t, stream_t *));
extern int header_set_stream __P ((header_t, stream_t, void *));
extern int header_size __P ((header_t, size_t *));
extern int header_set_size __P ((header_t, int (*_size)
__P ((header_t, size_t *)), void *));
extern int header_lines __P ((header_t, size_t *));
extern int header_set_lines __P ((header_t,
int (*_lines) __P ((header_t,
size_t *)),
void *));
extern int header_set_fill __P ((header_t,
int (*_fill) __P ((header_t, char *,
size_t, off_t,
size_t *)),
void *owner));
#ifdef _cplusplus
extern void header_destroy __P ((header_t *, void *));
extern void * header_get_owner __P ((header_t));
extern int header_is_modified __P ((header_t));
extern int header_clear_modified __P ((header_t));
extern int header_set_value __P ((header_t, const char *,
const char *, int));
extern int header_set_set_value __P ((header_t, int (*_set_value)
__P ((header_t, const char *,
const char *, int)), void *));
extern int header_get_value __P ((header_t, const char *, char *,
size_t, size_t *));
extern int header_set_get_value __P ((header_t, int (*_get_value)
__P ((header_t, const char *, char *,
size_t, size_t *)), void *));
extern int header_set_get_fvalue __P ((header_t, int (*_get_value)
__P ((header_t, const char *, char *,
size_t, size_t *)), void *));
extern int header_get_field_count __P ((header_t, size_t *));
extern int header_get_field_value __P ((header_t, size_t, char *,
size_t, size_t *));
extern int header_get_field_name __P ((header_t, size_t, char *,
size_t, size_t *));
extern int header_get_stream __P ((header_t, stream_t *));
extern int header_set_stream __P ((header_t, stream_t, void *));
extern int header_size __P ((header_t, size_t *));
extern int header_set_size __P ((header_t, int (*_size)
__P ((header_t, size_t *)), void *));
extern int header_lines __P ((header_t, size_t *));
extern int header_set_lines __P ((header_t,
int (*_lines) __P ((header_t,
size_t *)),
void *));
extern int header_set_fill __P ((header_t,
int (*_fill) __P ((header_t, char *,
size_t, off_t,
size_t *)),
void *owner));
#ifdef __cplusplus
}
#endif
......
......@@ -29,7 +29,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -43,7 +43,7 @@ extern int iterator_next __P ((iterator_t));
extern int iterator_current __P ((iterator_t, void **pitem));
extern int iterator_is_done __P ((iterator_t));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -28,7 +28,7 @@
# endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -44,7 +44,7 @@ extern int list_count __P ((list_t, size_t *pcount));
extern int list_remove __P ((list_t, void *item));
extern int list_get __P ((list_t, size_t _index, void **pitem));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -33,7 +33,7 @@
# endif
#endif /* __P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -60,7 +60,7 @@ extern int mailer_get_observable __P ((mailer_t, observable_t *));
extern int mailer_get_url __P ((mailer_t, url_t *));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -40,7 +40,7 @@ typedef struct _message *message_t;
# endif
#endif /* __P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -120,7 +120,7 @@ extern int message_encapsulate __P ((message_t msg, message_t *newmsg,
extern int message_unencapsulate __P ((message_t msg, message_t *newmsg,
void **data));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -36,7 +36,7 @@
#define MIME_MULTIPART_MIXED 0x1
#define MIME_MULTIPART_ALT 0x2
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -55,7 +55,7 @@ int mime_add_part __P ((mime_t mime, message_t msg));
int mime_get_message __P ((mime_t mime, message_t *msg));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -28,7 +28,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -64,7 +64,7 @@ extern int observable_attach __P ((observable_t, size_t type, observer_t obse
extern int observable_detach __P ((observable_t, observer_t observer));
extern int observable_notify __P ((observable_t, int type));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -28,25 +28,29 @@
# endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
struct _property;
typedef struct _property *property_t;
enum property_type { TYPE_POINTER, TYPE_LONG };
extern int property_create __P ((property_t *));
extern void property_destroy __P ((property_t *));
extern int property_create __P ((property_t *, void *));
extern void property_destroy __P ((property_t *, void *));
extern void *property_get_owner __P ((property_t));
extern int property_set_value __P ((property_t, const char *k, const void *v,
enum property_type));
extern int property_get_value __P ((property_t, const char *k, void **,
enum property_type *));
extern int property_set_value __P ((property_t, const char *, const void *));
extern int property_get_value __P ((property_t, const char *, void **));
extern int property_set_set_value __P ((property_t, int (*_set_value)
__P ((property_t , const char *,
const void *)), void *));
extern int property_set_get_value __P ((property_t , int (*_get_value)
__P ((property_t, const char *,
void **)), void *owner));
extern int property_set __P ((property_t, const char *k));
extern int property_unset __P ((property_t, const char *k));
extern int property_is_set __P ((property_t, const char *k));
extern int property_set __P ((property_t, const char *));
extern int property_unset __P ((property_t, const char *));
extern int property_is_set __P ((property_t, const char *));
extern int property_set_int __P ((property_t, const char *, int));
extern int property_get_int __P ((property_t, const char *));
......@@ -57,7 +61,7 @@ extern long property_get_long __P ((property_t, const char *));
extern int property_set_pointer __P ((property_t, const char *, void *));
extern void *property_get_pointer __P ((property_t, const char *));
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -34,7 +34,7 @@
# endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -119,7 +119,7 @@ extern record_t smtp_record;
/* Sendmail, "sendmail:" */
extern record_t sendmail_record;
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -204,6 +204,8 @@ header_parse (header_t header, const char *blurb, int len)
{
free (header->blurb);
free (header->hdr);
header->blurb = NULL;
header->hdr = NULL;
return ENOMEM;
}
hdr[header->hdr_count].fn = fn;
......@@ -307,6 +309,7 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
{
memcpy (blurb + len, header->blurb, header->blurb_len);
free (header->blurb);
header->blurb = NULL;
}
else
blurb [len] = '\n';
......@@ -486,6 +489,99 @@ header_get_value (header_t header, const char *name, char *buffer,
}
int
header_get_field_count (header_t header, size_t *pcount)
{
if (header == NULL)
{
if (pcount)
*pcount = 0;
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;
}
if (pcount)
*pcount = header->hdr_count;
return 0;
}
int
header_get_field_name (header_t header, size_t num, char *buf,
size_t buflen, size_t *nwriten)
{
size_t len;
if (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;
}
if (header->hdr_count == 0 || num > header->hdr_count || num == 0)
return ENOENT;
num--;
len = (header->hdr[num].fn_end - header->hdr[num].fn);
if (buf && buflen)
{
/* save one for the null */
--buflen;
len = (len > buflen) ? len : len;
memcpy (buf, header->hdr[num].fn, len);
buf[len] = '\0';
}
if (nwriten)
*nwriten = len;
return 0;
}
int
header_get_field_value (header_t header, size_t num, char *buf,
size_t buflen, size_t *nwritten)
{
size_t len;
if (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;
}
if (header->hdr_count == 0 || num > header->hdr_count || num == 0)
return ENOENT;
num--;
len = header->hdr[num].fv_end - header->hdr[num].fv;
if (buf && buflen > 0)
{
/* save one for the null */
--buflen;
len = (len > buflen) ? buflen : len;
memcpy (buf, header->hdr[num].fv, len);
buf[len] = '\0';
}
if (nwritten)
*nwritten = len;
return 0;
}
int
header_set_lines (header_t header, int (*_lines)
(header_t, size_t *), void *owner)
{
......@@ -646,7 +742,10 @@ fill_blurb (header_t header)
free (header->fhdr[i].fv);
}
if (header->fhdr)
free (header->fhdr);
{
free (header->fhdr);
header->fhdr = NULL;
}
header->_get_fvalue = NULL;
do
......@@ -788,7 +887,6 @@ header_readline (stream_t is, char *buf, size_t buflen, off_t off, size_t *pn)
return 0;
}
int
header_get_stream (header_t header, stream_t *pstream)
{
......
......@@ -32,7 +32,7 @@
# endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -46,7 +46,7 @@ struct _address
struct _address *next;
};
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -33,7 +33,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -53,7 +53,7 @@ struct _authority
};
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -36,7 +36,7 @@
# endif
#endif /* __P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -52,7 +52,7 @@ struct _body
int (*_lines) (body_t, size_t*);
};
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -32,7 +32,7 @@
#include <mailutils/debug.h>
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -45,7 +45,7 @@ struct _debug
int (*_print) __P ((debug_t, const char *, va_list));
};
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -25,7 +25,7 @@
#include <mailutils/header.h>
#include <sys/types.h>
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -75,7 +75,7 @@ struct _header
int (*_fill) __P ((header_t, char *, size_t, off_t, size_t *));
};
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -32,7 +32,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -44,7 +44,7 @@ struct _iterator
};
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -36,7 +36,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -55,7 +55,7 @@ struct _list
};
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -75,6 +75,7 @@ struct _mailbox
int (*_expunge) __P ((mailbox_t));
int (*_uidvalidity) __P ((mailbox_t, unsigned long *num));
int (*_uidnext) __P ((mailbox_t, size_t *num));
int (*_get_property) __P ((mailbox_t, property_t *num));
int (*_scan) __P ((mailbox_t, size_t msgno, size_t *count));
int (*_is_updated) __P ((mailbox_t));
......
......@@ -25,7 +25,7 @@
#include <sys/types.h>
#include <mailutils/mailer.h>
#include <mailutils/monitor.h>
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -86,7 +86,7 @@ if (mailer->debug) debug_print (mailer->debug, type, format, arg1, arg2, arg3)
#define MAILER_DEBUG4(mailer, type, format, arg1, arg2, arg3, arg4) \
if (mailer->debug) debug_print (mailer->debug, type, format, arg1, arg2, arg3, arg4)
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -29,7 +29,7 @@
#include <sys/types.h>
#include <stdio.h>
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -74,7 +74,7 @@ struct _message
int (*_size) __P ((message_t, size_t *));
};
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -33,7 +33,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -97,7 +97,7 @@ struct _mime_part
size_t lines;
};
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -32,7 +32,7 @@
#endif
#endif /*__P */
#ifdef _cplusplus
#ifdef __cplusplus
extern "C" {
#endif
......@@ -60,7 +60,7 @@ typedef struct _event *event_t;
#ifdef _cplusplus
#ifdef __cplusplus
}
#endif
......
......@@ -396,6 +396,15 @@ mailbox_get_property (mailbox_t mbox, property_t *pproperty)
{
if (mbox == NULL || pproperty == NULL)
return EINVAL;
if (mbox->property == NULL)
{
int status;
if (mbox->_get_property)
return mbox->_get_property (mbox, pproperty);
status = property_create (&(mbox->property), mbox);
if (status != 0)
return status;
}
*pproperty = mbox->property;
return 0;
}
......
......@@ -153,6 +153,7 @@ struct _mbox_data
char *sender;
char *date;
off_t off;
property_t property;
mailbox_t mailbox; /* Back pointer. */
};
......@@ -171,6 +172,7 @@ static int mbox_uidnext __P ((mailbox_t, size_t *));
static int mbox_scan __P ((mailbox_t, size_t, size_t *));
static int mbox_is_updated __P ((mailbox_t));
static int mbox_size __P ((mailbox_t, off_t *));
static int mbox_get_property __P ((mailbox_t, property_t *));
/* private stuff */
static int mbox_scan0 __P ((mailbox_t, size_t, size_t *, int));
......@@ -267,6 +269,8 @@ _mailbox_mbox_init (mailbox_t mailbox)
mailbox->_size = mbox_size;
mailbox->_get_property = mbox_get_property;
MAILBOX_DEBUG1 (mailbox, MU_DEBUG_TRACE, "mbox_init(%s)\n", mud->name);
return 0; /* okdoke */
}
......@@ -437,7 +441,7 @@ mbox_scan (mailbox_t mailbox, size_t msgno, size_t *pcount)
return mbox_scan0 (mailbox, msgno, pcount, 1);
/* Since the mailbox is already updated fake the scan. */
if (msgno > 0)
msgno--; /* The fist message is number "1", decremente for the C array. */
msgno--; /* The fist message is number "1", decremente for the C array. */
for (i = msgno; i < mud->messages_count; i++)
{
if (observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD) != 0)
......@@ -966,6 +970,41 @@ mbox_unset_attr_flags (attribute_t attr, int flags)
}
static int
mbox_property_set_value (property_t property, const char *k, const void *v)
{
mailbox_t mbox = property_get_owner (property);
mbox_data_t mud = mbox->data;
return property_set_value (mud->property, k, v);
}
static int
mbox_property_get_value (property_t property, const char *k, void **v)
{
mailbox_t mbox = property_get_owner (property);
mbox_data_t mud = mbox->data;
return property_get_value (mud->property, k, v);
}
static int
mbox_get_property (mailbox_t mbox, property_t *pprop)
{
mbox_data_t mud = mbox->data;
int status = property_create (&(mbox->property), mbox);
if (status != 0)
return status;
status = property_create (&(mud->property), mud);
if (status != 0)
{
property_destroy (&(mbox->property), mbox);
return status;
}
property_set_set_value (mbox->property, mbox_property_set_value, mbox);
property_set_get_value (mbox->property, mbox_property_get_value, mbox);
*pprop = mbox->property;
return 0;
}
static int
mbox_body_readline (stream_t is, char *buffer, size_t buflen,
off_t off, size_t *pnread)
{
......
/* 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
......@@ -26,27 +26,29 @@
#include <mailutils/list.h>
#include <mailutils/iterator.h>
#ifdef DMALLOC
# include <dmalloc.h>
#endif
struct property_data
{
size_t hash;
enum property_type type;
union
{
long l;
void *v;
} value;
const void *value;
};
struct _property
{
void *owner;
list_t list;
int (*_set_value) __P ((property_t , const char *, const void *));
int (*_get_value) __P ((property_t, const char *, void **));
};
static int property_find __P ((list_t, const char *, struct property_data **));
static size_t hash __P ((const char *));
int
property_create (property_t *pp)
property_create (property_t *pp, void *owner)
{
property_t prop;
int status;
......@@ -61,33 +63,57 @@ property_create (property_t *pp)
free (prop);
return status;
}
prop->owner = owner;
*pp = prop;
return 0;
}
void
property_destroy (property_t *pp)
property_destroy (property_t *pp, void *owner)
{
if (pp && *pp)
{
property_t prop = *pp;
list_destroy (&(prop->list));
free (prop);
if (prop->owner == owner)
{
list_destroy (&(prop->list));
free (prop);
}
*pp = NULL;
}
}
void *
property_get_owner (property_t prop)
{
return (prop == NULL) ? NULL : prop->owner;
}
int
property_set_set_value (property_t prop, int (*_set_value)
__P ((property_t , const char *, const void *)),
void *owner)
{
if (prop == NULL)
return EINVAL;
if (prop->owner != owner)
return EACCES;
prop->_set_value = _set_value;
return 0;
}
int
property_set_value (property_t prop, const char *key, const void *value,
enum property_type type)
property_set_value (property_t prop, const char *key, const void *value)
{
struct property_data *pd;
struct property_data *pd = NULL;
int status;
if (prop == NULL)
return EINVAL;
if (prop->_set_value)
return prop->_set_value (prop, key, value);
status = property_find (prop->list, key, &pd);
if (status != 0)
return status;
......@@ -98,34 +124,39 @@ property_set_value (property_t prop, const char *key, const void *value,
if (pd == NULL)
return ENOMEM;
pd->hash = hash (key);
pd->type = type;
switch (type)
{
case TYPE_POINTER:
pd->value.v = (void *)value;
break;
case TYPE_LONG:
pd->value.l = (long)value;
break;
}
pd->value = (void *)value;
list_append (prop->list, (void *)pd);
}
else
pd->value.v = (void *)value;
pd->value = (void *)value;
return 0;
}
int
property_get_value (property_t prop, const char *key, void **pvalue,
enum property_type *ptype)
property_set_get_value (property_t prop, int (*_get_value)
__P ((property_t, const char *, void **)),
void *owner)
{
struct property_data *pd;
if (prop == NULL)
return EINVAL;
if (prop->owner != owner)
return EACCES;
prop->_get_value = _get_value;
return 0;
}
int
property_get_value (property_t prop, const char *key, void **pvalue)
{
struct property_data *pd = NULL;
int status;
if (prop == NULL)
return EINVAL;
if (prop->_get_value)
return prop->_get_value (prop, key, pvalue);
status = property_find (prop->list, key, &pd);
if (status != 0)
return status;
......@@ -133,10 +164,8 @@ property_get_value (property_t prop, const char *key, void **pvalue,
if (pd == NULL)
return ENOENT;
if (ptype)
*ptype = pd->type;
if (pvalue)
*pvalue = pd->value.v;
*pvalue = (void *)pd->value;
return 0;
}
......@@ -161,45 +190,46 @@ property_is_set (property_t prop, const char *k)
int
property_set_int (property_t prop, const char *k, int i)
{
return property_set_value (prop, k, (void *)i, TYPE_LONG);
return property_set_value (prop, k, (void *)i);
}
int
property_get_int (property_t prop, const char *k)
{
int value = 0;
property_get_value (prop, k, (void **)&value, NULL);
property_get_value (prop, k, (void **)&value);
return value;
}
int
property_set_long (property_t prop, const char *k, long l)
{
return property_set_value (prop, k, (const void *)l, TYPE_LONG);
return property_set_value (prop, k, (const void *)l);
}
long
property_get_long (property_t prop, const char *k)
{
long value = 0;
property_get_value (prop, k, (void **)&value, NULL);
property_get_value (prop, k, (void **)&value);
return value;
}
int
property_set_pointer (property_t prop, const char *k, void *p)
{
return property_set_value (prop, k, p, TYPE_POINTER);
return property_set_value (prop, k, p);
}
void *
property_get_pointer (property_t prop, const char *k)
{
void *value = NULL;
property_get_value (prop, k, &value, NULL);
property_get_value (prop, k, &value);
return value;
}
/* Taking from an article in Dr Dobbs. */
static size_t
hash (const char *s)
{
......@@ -207,12 +237,12 @@ hash (const char *s)
for (hashval = 0; *s != '\0' ; s++)
{
hashval += (unsigned)*s ;
hashval += (hashval <<10);
hashval ^= (hashval >>6) ;
hashval += (hashval << 10);
hashval ^= (hashval >> 6) ;
}
hashval += (hashval <<3);
hashval ^= (hashval >>11);
hashval += (hashval <<15);
hashval += (hashval << 3);
hashval ^= (hashval >> 11);
hashval += (hashval << 15);
return hashval;
}
......