Commit 7d43411a 7d43411a434ec7404f7f52b7bbf801415ddddf23 by Sergey Poznyakoff

Fix semantics of mu_attribute_to_string

* include/mailutils/attribute.h (MU_STATUS_BUF_SIZE): New define.
* libproto/mbox/mbox.c: Update use of mu_attribute_to_string.
* mailbox/amd.c: Likewise.
* mailbox/attribute.c (mu_string_to_flags): Rewrite.
(mu_attribute_to_string): Fill the string with flag letters only, without
"Status:" prefix and final newline.
* NEWS: Update.
1 parent cf9c751d
GNU mailutils NEWS -- history of user-visible changes. 2009-03-03
GNU mailutils NEWS -- history of user-visible changes. 2009-03-04
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009 Free Software Foundation, Inc.
See the end of file for copying conditions.
......@@ -22,7 +22,7 @@ All MU client utilities make use of the user ticket file,
** Changed functions
- mu_message_save_to_mailbox: removed `ticket' argument.
*** mu_message_save_to_mailbox: removed `ticket' argument.
New prototype is:
......@@ -30,7 +30,11 @@ int mu_message_save_to_mailbox (mu_message_t msg,
mu_debug_t debug,
const char *toname,
int perms);
*** mu_attribute_to_string
This function now returns a string consisting of flag letters only, without
"Status:" prefix or final newline.
Version 2.0:
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2005, 2007,
2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......@@ -96,6 +97,9 @@ extern int mu_attribute_is_equal (mu_attribute_t, mu_attribute_t att2);
extern int mu_attribute_copy (mu_attribute_t, mu_attribute_t);
/* Maximum size of buffer for mu_attribute_to_string call, including nul */
#define MU_STATUS_BUF_SIZE sizeof("OAFRd")
extern int mu_attribute_to_string (mu_attribute_t, char *, size_t, size_t *);
extern int mu_string_to_flags (const char *, int *);
......
......@@ -1585,14 +1585,19 @@ mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize,
case MBOX_STATE_APPEND_ATTRIBUTE:
/* Put the new attributes. */
{
char abuf[64];
#define STATUS_PREFIX_LEN (sizeof(MU_HEADER_STATUS) - 1 + 2)
char abuf[STATUS_PREFIX_LEN + MU_STATUS_BUF_SIZE + 1];
size_t na = 0;
mu_attribute_t attr = NULL;
abuf[0] = '\0';
mu_message_get_attribute (msg, &attr);
mu_attribute_to_string (attr, abuf, sizeof(abuf), &na);
status = mu_stream_write (mailbox->stream, abuf, na, *psize, &n);
strcpy(abuf, MU_HEADER_STATUS);
strcat(abuf, ": ");
mu_message_get_attribute (msg, &attr);
mu_attribute_to_string (attr, abuf + STATUS_PREFIX_LEN,
sizeof(abuf) - STATUS_PREFIX_LEN - 1, &na);
strcat (abuf, "\n");
na = strlen (abuf);
mu_stream_write (mailbox->stream, abuf, na, *psize, &n);
if (status != 0)
break;
*psize += n;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......@@ -613,7 +613,8 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm,
mu_body_t body;
const char *sbuf;
mu_envelope_t env = NULL;
char statbuf[MU_STATUS_BUF_SIZE];
status = mu_message_size (msg, &bsize);
if (status)
return status;
......@@ -661,7 +662,7 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm,
while ((status = mu_stream_readline (stream, buf, bsize, off, &n)) == 0
&& n != 0)
{
if (_amd_delim(buf))
if (_amd_delim (buf))
break;
if (!(strncasecmp (buf, "status:", 7) == 0
......@@ -710,10 +711,10 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm,
/* Add status */
mu_message_get_attribute (msg, &attr);
mu_attribute_to_string (attr, buf, bsize, &n);
mu_attribute_to_string (attr, statbuf, sizeof (statbuf), &n);
if (n)
{
nbytes += fprintf (fp, "%s", buf);
nbytes += fprintf (fp, "Status: %s\n", statbuf);
nlines++;
}
nbytes += fprintf (fp, "\n");
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2004, 2005,
2007 Free Software Foundation, Inc.
2007, 2009 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......@@ -31,10 +31,9 @@
#endif
#include <mailutils/errno.h>
#include <mailutils/mutil.h>
#include <attribute0.h>
static int flags_to_string (int, char *, size_t, size_t *);
int
mu_attribute_create (mu_attribute_t *pattr, void *owner)
{
......@@ -384,6 +383,31 @@ mu_attribute_copy (mu_attribute_t dest, mu_attribute_t src)
return 0;
}
struct flagtrans
{
int flag;
char letter;
};
/* The two macros below are taken from gnulib module verify.h */
#define mu_verify_true(R) \
(!!sizeof \
(struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; }))
#define mu_verify(R) extern int (* verify_function__ (void)) [mu_verify_true (R)]
static struct flagtrans flagtrans[] = {
{ MU_ATTRIBUTE_SEEN, 'O' },
{ MU_ATTRIBUTE_ANSWERED, 'A' },
{ MU_ATTRIBUTE_FLAGGED, 'F' },
{ MU_ATTRIBUTE_READ, 'R' },
{ MU_ATTRIBUTE_DELETED, 'd' },
{ 0 }
};
/* If cc reports an error in this statement, fix the MU_STATUS_BUF_SIZE
declaration in include/mailutils/attribute.h */
mu_verify (MU_ARRAY_SIZE (flagtrans) == MU_STATUS_BUF_SIZE);
int
mu_string_to_flags (const char *buffer, int *pflags)
{
......@@ -401,64 +425,43 @@ mu_string_to_flags (const char *buffer, int *pflags)
else
sep = buffer;
while (*sep)
for (; *sep; sep++)
{
if (strchr (sep, 'R') != NULL || strchr (sep, 'r') != NULL)
*pflags |= MU_ATTRIBUTE_READ;
if (strchr (sep, 'O') != NULL || strchr (sep, 'o') != NULL)
*pflags |= MU_ATTRIBUTE_SEEN;
if (strchr (sep, 'A') != NULL || strchr (sep, 'a') != NULL)
*pflags |= MU_ATTRIBUTE_ANSWERED;
if (strchr (sep, 'F') != NULL || strchr (sep, 'f') != NULL)
*pflags |= MU_ATTRIBUTE_FLAGGED;
sep++;
struct flagtrans *ft;
for (ft = flagtrans; ft->flag; ft++)
if (ft->letter == *sep)
{
*pflags |= ft->flag;
break;
}
}
return 0;
}
/* NOTE: When adding/removing flags, make sure to update the
MU_STATUS_BUF_SIZE define in include/mailutils/attribute.h */
int
mu_attribute_to_string (mu_attribute_t attr, char *buffer, size_t len, size_t *pn)
{
int flags = 0;;
mu_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)
mu_attribute_to_string (mu_attribute_t attr, char *buffer, size_t len,
size_t *pn)
{
char status[32];
char a[8];
size_t i;
*status = *a = '\0';
if (flags & MU_ATTRIBUTE_SEEN)
strcat (a, "O");
if (flags & MU_ATTRIBUTE_ANSWERED)
strcat (a, "A");
if (flags & MU_ATTRIBUTE_FLAGGED)
strcat (a, "F");
if (flags & MU_ATTRIBUTE_READ)
strcat (a, "R");
if (flags & MU_ATTRIBUTE_DELETED)
strcat (a, "d");
if (*a != '\0')
{
strcpy (status, "Status: ");
strcat (status, a);
strcat (status, "\n");
}
int flags = 0;
char buf[MU_STATUS_BUF_SIZE];
int i;
int rc;
struct flagtrans *ft;
rc = mu_attribute_get_flags (attr, &flags);
if (rc)
return rc;
i = strlen (status);
i = 0;
for (ft = flagtrans; ft->flag; ft++)
if (ft->flag & flags)
buf[i++] = ft->letter;
buf[i++] = 0;
if (buffer && len != 0)
{
strncpy (buffer, status, len - 1);
buffer[len - 1] = '\0';
i = strlen (buffer);
}
i = mu_cpystr (buffer, buf, i);
if (pn)
*pn = i;
return 0;
......