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.
Showing
5 changed files
with
83 additions
and
66 deletions
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; | ... | ... |
-
Please register or sign in to post a comment