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
1 GNU mailutils NEWS -- history of user-visible changes. 2009-03-03 1 GNU mailutils NEWS -- history of user-visible changes. 2009-03-04
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007,
3 2008, 2009 Free Software Foundation, Inc. 3 2008, 2009 Free Software Foundation, Inc.
4 See the end of file for copying conditions. 4 See the end of file for copying conditions.
...@@ -22,7 +22,7 @@ All MU client utilities make use of the user ticket file, ...@@ -22,7 +22,7 @@ All MU client utilities make use of the user ticket file,
22 22
23 ** Changed functions 23 ** Changed functions
24 24
25 - mu_message_save_to_mailbox: removed `ticket' argument. 25 *** mu_message_save_to_mailbox: removed `ticket' argument.
26 26
27 New prototype is: 27 New prototype is:
28 28
...@@ -30,7 +30,11 @@ int mu_message_save_to_mailbox (mu_message_t msg, ...@@ -30,7 +30,11 @@ int mu_message_save_to_mailbox (mu_message_t msg,
30 mu_debug_t debug, 30 mu_debug_t debug,
31 const char *toname, 31 const char *toname,
32 int perms); 32 int perms);
33 33
34 *** mu_attribute_to_string
35
36 This function now returns a string consisting of flag letters only, without
37 "Status:" prefix or final newline.
34 38
35 39
36 Version 2.0: 40 Version 2.0:
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2005, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2005, 2007,
3 2009 Free Software Foundation, Inc.
3 4
4 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public 6 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); ...@@ -96,6 +97,9 @@ extern int mu_attribute_is_equal (mu_attribute_t, mu_attribute_t att2);
96 97
97 extern int mu_attribute_copy (mu_attribute_t, mu_attribute_t); 98 extern int mu_attribute_copy (mu_attribute_t, mu_attribute_t);
98 99
100 /* Maximum size of buffer for mu_attribute_to_string call, including nul */
101 #define MU_STATUS_BUF_SIZE sizeof("OAFRd")
102
99 extern int mu_attribute_to_string (mu_attribute_t, char *, size_t, size_t *); 103 extern int mu_attribute_to_string (mu_attribute_t, char *, size_t, size_t *);
100 extern int mu_string_to_flags (const char *, int *); 104 extern int mu_string_to_flags (const char *, int *);
101 105
......
...@@ -1585,14 +1585,19 @@ mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize, ...@@ -1585,14 +1585,19 @@ mbox_append_message0 (mu_mailbox_t mailbox, mu_message_t msg, mu_off_t *psize,
1585 case MBOX_STATE_APPEND_ATTRIBUTE: 1585 case MBOX_STATE_APPEND_ATTRIBUTE:
1586 /* Put the new attributes. */ 1586 /* Put the new attributes. */
1587 { 1587 {
1588 char abuf[64]; 1588 #define STATUS_PREFIX_LEN (sizeof(MU_HEADER_STATUS) - 1 + 2)
1589 char abuf[STATUS_PREFIX_LEN + MU_STATUS_BUF_SIZE + 1];
1589 size_t na = 0; 1590 size_t na = 0;
1590 mu_attribute_t attr = NULL; 1591 mu_attribute_t attr = NULL;
1591 abuf[0] = '\0';
1592 mu_message_get_attribute (msg, &attr);
1593 mu_attribute_to_string (attr, abuf, sizeof(abuf), &na);
1594 1592
1595 status = mu_stream_write (mailbox->stream, abuf, na, *psize, &n); 1593 strcpy(abuf, MU_HEADER_STATUS);
1594 strcat(abuf, ": ");
1595 mu_message_get_attribute (msg, &attr);
1596 mu_attribute_to_string (attr, abuf + STATUS_PREFIX_LEN,
1597 sizeof(abuf) - STATUS_PREFIX_LEN - 1, &na);
1598 strcat (abuf, "\n");
1599 na = strlen (abuf);
1600 mu_stream_write (mailbox->stream, abuf, na, *psize, &n);
1596 if (status != 0) 1601 if (status != 0)
1597 break; 1602 break;
1598 *psize += n; 1603 *psize += n;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2 Copyright (C) 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. 3 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 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, ...@@ -613,7 +613,8 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm,
613 mu_body_t body; 613 mu_body_t body;
614 const char *sbuf; 614 const char *sbuf;
615 mu_envelope_t env = NULL; 615 mu_envelope_t env = NULL;
616 616 char statbuf[MU_STATUS_BUF_SIZE];
617
617 status = mu_message_size (msg, &bsize); 618 status = mu_message_size (msg, &bsize);
618 if (status) 619 if (status)
619 return status; 620 return status;
...@@ -661,7 +662,7 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, ...@@ -661,7 +662,7 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm,
661 while ((status = mu_stream_readline (stream, buf, bsize, off, &n)) == 0 662 while ((status = mu_stream_readline (stream, buf, bsize, off, &n)) == 0
662 && n != 0) 663 && n != 0)
663 { 664 {
664 if (_amd_delim(buf)) 665 if (_amd_delim (buf))
665 break; 666 break;
666 667
667 if (!(strncasecmp (buf, "status:", 7) == 0 668 if (!(strncasecmp (buf, "status:", 7) == 0
...@@ -710,10 +711,10 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, ...@@ -710,10 +711,10 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm,
710 711
711 /* Add status */ 712 /* Add status */
712 mu_message_get_attribute (msg, &attr); 713 mu_message_get_attribute (msg, &attr);
713 mu_attribute_to_string (attr, buf, bsize, &n); 714 mu_attribute_to_string (attr, statbuf, sizeof (statbuf), &n);
714 if (n) 715 if (n)
715 { 716 {
716 nbytes += fprintf (fp, "%s", buf); 717 nbytes += fprintf (fp, "Status: %s\n", statbuf);
717 nlines++; 718 nlines++;
718 } 719 }
719 nbytes += fprintf (fp, "\n"); 720 nbytes += fprintf (fp, "\n");
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004, 2005, 2 Copyright (C) 1999, 2000, 2001, 2004, 2005,
3 2007 Free Software Foundation, Inc. 3 2007, 2009 Free Software Foundation, Inc.
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
...@@ -31,10 +31,9 @@ ...@@ -31,10 +31,9 @@
31 #endif 31 #endif
32 32
33 #include <mailutils/errno.h> 33 #include <mailutils/errno.h>
34 #include <mailutils/mutil.h>
34 #include <attribute0.h> 35 #include <attribute0.h>
35 36
36 static int flags_to_string (int, char *, size_t, size_t *);
37
38 int 37 int
39 mu_attribute_create (mu_attribute_t *pattr, void *owner) 38 mu_attribute_create (mu_attribute_t *pattr, void *owner)
40 { 39 {
...@@ -384,6 +383,31 @@ mu_attribute_copy (mu_attribute_t dest, mu_attribute_t src) ...@@ -384,6 +383,31 @@ mu_attribute_copy (mu_attribute_t dest, mu_attribute_t src)
384 return 0; 383 return 0;
385 } 384 }
386 385
386 struct flagtrans
387 {
388 int flag;
389 char letter;
390 };
391
392 /* The two macros below are taken from gnulib module verify.h */
393 #define mu_verify_true(R) \
394 (!!sizeof \
395 (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; }))
396 #define mu_verify(R) extern int (* verify_function__ (void)) [mu_verify_true (R)]
397
398 static struct flagtrans flagtrans[] = {
399 { MU_ATTRIBUTE_SEEN, 'O' },
400 { MU_ATTRIBUTE_ANSWERED, 'A' },
401 { MU_ATTRIBUTE_FLAGGED, 'F' },
402 { MU_ATTRIBUTE_READ, 'R' },
403 { MU_ATTRIBUTE_DELETED, 'd' },
404 { 0 }
405 };
406
407 /* If cc reports an error in this statement, fix the MU_STATUS_BUF_SIZE
408 declaration in include/mailutils/attribute.h */
409 mu_verify (MU_ARRAY_SIZE (flagtrans) == MU_STATUS_BUF_SIZE);
410
387 int 411 int
388 mu_string_to_flags (const char *buffer, int *pflags) 412 mu_string_to_flags (const char *buffer, int *pflags)
389 { 413 {
...@@ -401,64 +425,43 @@ mu_string_to_flags (const char *buffer, int *pflags) ...@@ -401,64 +425,43 @@ mu_string_to_flags (const char *buffer, int *pflags)
401 else 425 else
402 sep = buffer; 426 sep = buffer;
403 427
404 while (*sep) 428 for (; *sep; sep++)
405 { 429 {
406 if (strchr (sep, 'R') != NULL || strchr (sep, 'r') != NULL) 430 struct flagtrans *ft;
407 *pflags |= MU_ATTRIBUTE_READ; 431
408 if (strchr (sep, 'O') != NULL || strchr (sep, 'o') != NULL) 432 for (ft = flagtrans; ft->flag; ft++)
409 *pflags |= MU_ATTRIBUTE_SEEN; 433 if (ft->letter == *sep)
410 if (strchr (sep, 'A') != NULL || strchr (sep, 'a') != NULL) 434 {
411 *pflags |= MU_ATTRIBUTE_ANSWERED; 435 *pflags |= ft->flag;
412 if (strchr (sep, 'F') != NULL || strchr (sep, 'f') != NULL) 436 break;
413 *pflags |= MU_ATTRIBUTE_FLAGGED; 437 }
414 sep++;
415 } 438 }
416 return 0; 439 return 0;
417 } 440 }
418 441
442 /* NOTE: When adding/removing flags, make sure to update the
443 MU_STATUS_BUF_SIZE define in include/mailutils/attribute.h */
419 int 444 int
420 mu_attribute_to_string (mu_attribute_t attr, char *buffer, size_t len, size_t *pn) 445 mu_attribute_to_string (mu_attribute_t attr, char *buffer, size_t len,
421 { 446 size_t *pn)
422 int flags = 0;;
423 mu_attribute_get_flags (attr, &flags);
424 return flags_to_string (flags, buffer, len, pn);
425 }
426
427 static int
428 flags_to_string (int flags, char *buffer, size_t len, size_t *pn)
429 { 447 {
430 char status[32]; 448 int flags = 0;
431 char a[8]; 449 char buf[MU_STATUS_BUF_SIZE];
432 size_t i; 450 int i;
433 451 int rc;
434 *status = *a = '\0'; 452 struct flagtrans *ft;
435 453
436 if (flags & MU_ATTRIBUTE_SEEN) 454 rc = mu_attribute_get_flags (attr, &flags);
437 strcat (a, "O"); 455 if (rc)
438 if (flags & MU_ATTRIBUTE_ANSWERED) 456 return rc;
439 strcat (a, "A");
440 if (flags & MU_ATTRIBUTE_FLAGGED)
441 strcat (a, "F");
442 if (flags & MU_ATTRIBUTE_READ)
443 strcat (a, "R");
444 if (flags & MU_ATTRIBUTE_DELETED)
445 strcat (a, "d");
446
447 if (*a != '\0')
448 {
449 strcpy (status, "Status: ");
450 strcat (status, a);
451 strcat (status, "\n");
452 }
453 457
454 i = strlen (status); 458 i = 0;
459 for (ft = flagtrans; ft->flag; ft++)
460 if (ft->flag & flags)
461 buf[i++] = ft->letter;
462 buf[i++] = 0;
455 463
456 if (buffer && len != 0) 464 i = mu_cpystr (buffer, buf, i);
457 {
458 strncpy (buffer, status, len - 1);
459 buffer[len - 1] = '\0';
460 i = strlen (buffer);
461 }
462 if (pn) 465 if (pn)
463 *pn = i; 466 *pn = i;
464 return 0; 467 return 0;
......