Commit 690b1bf8 690b1bf8506e50cb85d2634ba2db2fddbff99dfe by Sergey Poznyakoff

Fix API for obtaining full email address.

Old API relied on passing a pointer to the buffer string and its size,
which is defective.  The new API, in addtion to that, provides functions
for obtaining a pointer to the statically allocated original value, a
pointer to dynamically allocated copy, and a function for formatting the
address directly to a MU stream.

Two functions are marked as deprecated: mu_address_to_string and
mu_address_format_string.  Both assume a pointer to an allocated string
of a fixed size, which is far from being convenient nor reliable enough.

* include/mailutils/address.h (MU_ADDR_HINT_ADDR): Rename to
MU_ADDR_HINT_PRINTABLE
(mu_address)<addr>: Rename to printable.
(mu_address_sget_printable,mu_address_aget_printable)
(mu_address_get_printable): New protos.
(mu_stream_format_address): New proto.
(mu_address_to_string)
(mu_address_format_string): Mark as deprecated.
(mu_validate_email): New proto.
* examples/mta.c: Use mu_address_sget_printable instead
of (mu_address_to_string)
* libmailutils/address/addrstream.c: New file.
* libmailutils/address/Makefile.am (libaddress_la_SOURCES): Add
addrstream.c
* libmailutils/address/address.c (mu_address_format_string): Rewrite using
streams.
(mu_address_to_string): Rewrite as a wrapper over
mu_address_get_printable.
(mu_address_sget_printable,mu_address_aget_printable)
(mu_address_get_printable): New functions.
* libmailutils/mime/mimehdr.c (_mime_header_parse): Initialize rc.
* mail/util.c (util_merge_addresses): Use mu_address_aget_printable.
* mh/mh.h (mh_annotate): Both string args are const.
* mh/mh_init.c (mh_annotate): Likewise.
* mh/mh_format.c (builtin_formataddr): Use mu_address_sget_printable.
* mh/mh_whatnow.c (anno_data)<field,value>: Both are consts.
(annotate): Use mu_address_sget_printable.
* mh/send.c (set_address_header): Use mu_address_sget_printable.
* mu/imap.c (format_email): Use mu_stream_format_address.
* python/libmu_py/address.c (api_address_to_string): Likewise.
1 parent 924bc727
...@@ -112,8 +112,8 @@ addr_fieldptr_by_mask (mu_address_t addr, int mask) ...@@ -112,8 +112,8 @@ addr_fieldptr_by_mask (mu_address_t addr, int mask)
112 { 112 {
113 switch (mask) 113 switch (mask)
114 { 114 {
115 case MU_ADDR_HINT_ADDR: 115 case MU_ADDR_HINT_PRINTABLE:
116 return &addr->addr; 116 return &addr->printable;
117 117
118 case MU_ADDR_HINT_COMMENTS: 118 case MU_ADDR_HINT_COMMENTS:
119 return &addr->comments; 119 return &addr->comments;
......
...@@ -437,26 +437,17 @@ message_finalize (mu_message_t msg, int warn) ...@@ -437,26 +437,17 @@ message_finalize (mu_message_t msg, int warn)
437 437
438 if (finalize_option && !have_to) 438 if (finalize_option && !have_to)
439 { 439 {
440 size_t n; 440 char const *sptr;
441 int c; 441 int c;
442 442
443 c = mu_address_to_string (recipients, NULL, 0, &n); 443 c = mu_address_sget_printable (recipients, &sptr);
444 if (c) 444 if (c)
445 { 445 {
446 mu_error ("%s: mu_address_to_string failure: %s", 446 mu_error ("%s: mu_address_sget_printable failure: %s",
447 progname, mu_strerror (c)); 447 progname, mu_strerror (c));
448 return 1; 448 return 1;
449 } 449 }
450 value = malloc (n + 1); 450 mu_header_set_value (header, MU_HEADER_TO, sptr, 1);
451 if (!value)
452 {
453 mu_error ("%s: not enough memory", progname);
454 return 1;
455 }
456
457 mu_address_to_string (recipients, value, n + 1, &n);
458 mu_header_set_value (header, MU_HEADER_TO, value, 1);
459 free (value);
460 } 451 }
461 return 0; 452 return 0;
462 } 453 }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
25 extern "C" { 25 extern "C" {
26 #endif 26 #endif
27 27
28 #define MU_ADDR_HINT_ADDR 0x0001 /* Not used yet */ 28 #define MU_ADDR_HINT_PRINTABLE 0x0001 /* Not used yet */
29 #define MU_ADDR_HINT_COMMENTS 0x0002 29 #define MU_ADDR_HINT_COMMENTS 0x0002
30 #define MU_ADDR_HINT_PERSONAL 0x0004 30 #define MU_ADDR_HINT_PERSONAL 0x0004
31 #define MU_ADDR_HINT_EMAIL 0x0008 31 #define MU_ADDR_HINT_EMAIL 0x0008
...@@ -42,9 +42,11 @@ extern "C" { ...@@ -42,9 +42,11 @@ extern "C" {
42 */ 42 */
43 struct mu_address 43 struct mu_address
44 { 44 {
45 char *addr; 45 char *printable;
46 /* the original string that this list of addresses was created 46 /* Printable representation of this address. Normally, it is
47 * from, only present at the head of the list */ 47 * the original string that this list of addresses was created
48 * from, only present at the head of the list
49 */
48 50
49 char *comments; 51 char *comments;
50 /* the collection of comments stripped during parsing this MAILBOX */ 52 /* the collection of comments stripped during parsing this MAILBOX */
...@@ -129,8 +131,12 @@ extern int mu_address_aget_route ...@@ -129,8 +131,12 @@ extern int mu_address_aget_route
129 131
130 extern int mu_address_is_group 132 extern int mu_address_is_group
131 (mu_address_t, size_t, int*); 133 (mu_address_t, size_t, int*);
132 134
133 extern int mu_address_to_string (mu_address_t, char *, size_t, size_t *); 135 extern int mu_address_sget_printable (mu_address_t addr, const char **sptr);
136 extern int mu_address_aget_printable (mu_address_t addr, char **presult);
137 extern int mu_address_get_printable (mu_address_t addr, char *buf, size_t len,
138 size_t *n);
139
134 extern int mu_address_get_count (mu_address_t, size_t *); 140 extern int mu_address_get_count (mu_address_t, size_t *);
135 extern int mu_address_get_group_count (mu_address_t, size_t *); 141 extern int mu_address_get_group_count (mu_address_t, size_t *);
136 extern int mu_address_get_email_count (mu_address_t, size_t *); 142 extern int mu_address_get_email_count (mu_address_t, size_t *);
...@@ -139,8 +145,21 @@ extern int mu_address_get_unix_mailbox_count (mu_address_t, size_t *); ...@@ -139,8 +145,21 @@ extern int mu_address_get_unix_mailbox_count (mu_address_t, size_t *);
139 extern int mu_address_contains_email (mu_address_t addr, const char *email); 145 extern int mu_address_contains_email (mu_address_t addr, const char *email);
140 extern int mu_address_union (mu_address_t *a, mu_address_t b); 146 extern int mu_address_union (mu_address_t *a, mu_address_t b);
141 147
142 extern size_t mu_address_format_string (mu_address_t addr, char *buf, size_t buflen); 148 extern int mu_stream_format_address (mu_stream_t str, mu_address_t addr);
149
150 /* Deprecated calls */
151
152 extern int mu_address_to_string (mu_address_t, char *, size_t, size_t *)
153 MU_DEPRECATED; /* Use mu_address_get_printable, if you really have to */
154
155 extern size_t mu_address_format_string (mu_address_t addr, char *buf,
156 size_t buflen)
157 MU_DEPRECATED; /* Use mu_stream_format_address, or any of the
158 _get_printable functions */
143 159
160 extern int mu_validate_email (mu_address_t subaddr);
161
162
144 #ifdef __cplusplus 163 #ifdef __cplusplus
145 } 164 }
146 #endif 165 #endif
......
...@@ -19,6 +19,7 @@ noinst_LTLIBRARIES = libaddress.la ...@@ -19,6 +19,7 @@ noinst_LTLIBRARIES = libaddress.la
19 19
20 libaddress_la_SOURCES = \ 20 libaddress_la_SOURCES = \
21 address.c\ 21 address.c\
22 addrstream.c\
22 parse822.c 23 parse822.c
23 24
24 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils 25 INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
35 #include <mailutils/parse822.h> 35 #include <mailutils/parse822.h>
36 #include <mailutils/address.h> 36 #include <mailutils/address.h>
37 #include <mailutils/cstr.h> 37 #include <mailutils/cstr.h>
38 #include <mailutils/stream.h>
38 39
39 int 40 int
40 mu_address_create_null (mu_address_t *pa) 41 mu_address_create_null (mu_address_t *pa)
...@@ -70,8 +71,8 @@ mu_address_create_hint (mu_address_t *a, const char *s, mu_address_t hint, ...@@ -70,8 +71,8 @@ mu_address_create_hint (mu_address_t *a, const char *s, mu_address_t hint,
70 if (!*a) 71 if (!*a)
71 return MU_ERR_EMPTY_ADDRESS; 72 return MU_ERR_EMPTY_ADDRESS;
72 73
73 (*a)->addr = strdup (s); 74 (*a)->printable = strdup (s);
74 if (!(*a)->addr) 75 if (!(*a)->printable)
75 { 76 {
76 mu_address_destroy (a); 77 mu_address_destroy (a);
77 return ENOMEM; 78 return ENOMEM;
...@@ -159,8 +160,8 @@ mu_address_destroy (mu_address_t *paddress) ...@@ -159,8 +160,8 @@ mu_address_destroy (mu_address_t *paddress)
159 mu_address_t current; 160 mu_address_t current;
160 for (; address; address = current) 161 for (; address; address = current)
161 { 162 {
162 if (address->addr) 163 if (address->printable)
163 free (address->addr); 164 free (address->printable);
164 if (address->comments) 165 if (address->comments)
165 free (address->comments); 166 free (address->comments);
166 if (address->personal) 167 if (address->personal)
...@@ -195,19 +196,19 @@ mu_address_concatenate (mu_address_t to, mu_address_t *from) ...@@ -195,19 +196,19 @@ mu_address_concatenate (mu_address_t to, mu_address_t *from)
195 *from = NULL; 196 *from = NULL;
196 197
197 /* discard the current string cache as it is now inaccurate */ 198 /* discard the current string cache as it is now inaccurate */
198 if (to->addr) 199 if (to->printable)
199 { 200 {
200 free (to->addr); 201 free (to->printable);
201 to->addr = NULL; 202 to->printable = NULL;
202 } 203 }
203 204
204 to = to->next; 205 to = to->next;
205 206
206 /* only the first address must have a cache */ 207 /* only the first address must have a cache */
207 if (to->addr) 208 if (to->printable)
208 { 209 {
209 free (to->addr); 210 free (to->printable);
210 to->addr = NULL; 211 to->printable = NULL;
211 } 212 }
212 213
213 return 0; 214 return 0;
...@@ -432,8 +433,8 @@ mu_address_set_email (mu_address_t addr, size_t no, const char *buf) ...@@ -432,8 +433,8 @@ mu_address_set_email (mu_address_t addr, size_t no, const char *buf)
432 return 0; 433 return 0;
433 } 434 }
434 435
435 static int 436 int
436 validate_email (mu_address_t subaddr) 437 mu_validate_email (mu_address_t subaddr)
437 { 438 {
438 if (!subaddr->email) 439 if (!subaddr->email)
439 { 440 {
...@@ -473,82 +474,45 @@ mu_address_sget_email (mu_address_t addr, size_t no, char const **sptr) ...@@ -473,82 +474,45 @@ mu_address_sget_email (mu_address_t addr, size_t no, char const **sptr)
473 if (!subaddr) 474 if (!subaddr)
474 return MU_ERR_NOENT; 475 return MU_ERR_NOENT;
475 476
476 validate_email (subaddr); 477 mu_validate_email (subaddr);
477 *sptr = subaddr->email; 478 *sptr = subaddr->email;
478 return 0; 479 return 0;
479 } 480 }
480 481
481 DECL_GET(email) 482 DECL_GET(email)
482 DECL_AGET(email) 483 DECL_AGET(email)
483
484
485
486 484
487 #define format_char(c) do {\
488 if (buflen) \
489 {\
490 *buf++ = c;\
491 buflen--;\
492 }\
493 else\
494 rc++;\
495 } while(0)
496
497 #define format_string(str) do {\
498 if (buflen) \
499 {\
500 int n = snprintf (buf, buflen, "%s", str);\
501 buf += n;\
502 buflen -= n;\
503 }\
504 else\
505 rc += strlen (str);\
506 } while (0)
507
508 size_t 485 size_t
509 mu_address_format_string (mu_address_t addr, char *buf, size_t buflen) 486 mu_address_format_string (mu_address_t addr, char *buf, size_t buflen)
510 { 487 {
511 int rc = 0; 488 mu_stream_t str;
512 int comma = 0; 489 int rc;
513 490
514 for (;addr; addr = addr->next) 491 if (!buf)
492 rc = mu_nullstream_create (&str, MU_STREAM_WRITE);
493 else
494 rc = mu_fixed_memory_stream_create (&str, buf, buflen, MU_STREAM_WRITE);
495 if (rc == 0)
515 { 496 {
516 validate_email (addr); 497 size_t size;
517 if (addr->email) 498
499 mu_stream_stat_buffer statbuf;
500 mu_stream_set_stat (str, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT),
501 statbuf);
502 rc = mu_stream_format_address (str, addr);
503 mu_stream_destroy (&str);
504 if (rc)
505 return 0;
506 size = statbuf[MU_STREAM_STAT_OUT];
507 if (buf)
518 { 508 {
519 int space = 0; 509 if (size + 1 >= buflen)
520 510 size = buflen - 1;
521 if (comma) 511 buf[size] = 0;
522 format_char (',');
523
524 if (addr->personal)
525 {
526 format_char ('"');
527 format_string (addr->personal);
528 format_char ('"');
529 space++;
530 }
531
532 if (addr->comments)
533 {
534 if (space)
535 format_char (' ');
536 format_char ('(');
537 format_string (addr->comments);
538 format_char (')');
539 space++;
540 }
541
542 if (space)
543 format_char (' ');
544 format_char ('<');
545 format_string (addr->email);
546 format_char ('>');
547 comma++;
548 } 512 }
513 return size;
549 } 514 }
550 format_char (0); 515 return 0;
551 return rc;
552 } 516 }
553 517
554 static int 518 static int
...@@ -593,27 +557,86 @@ mu_address_is_group (mu_address_t addr, size_t no, int *yes) ...@@ -593,27 +557,86 @@ mu_address_is_group (mu_address_t addr, size_t no, int *yes)
593 } 557 }
594 558
595 int 559 int
596 mu_address_to_string (mu_address_t addr, char *buf, size_t len, size_t *n) 560 mu_address_sget_printable (mu_address_t addr, const char **sptr)
597 { 561 {
598 size_t i;
599 if (addr == NULL) 562 if (addr == NULL)
600 return EINVAL; 563 return EINVAL;
601 if (buf) 564 if (!sptr)
602 *buf = '\0'; 565 return MU_ERR_OUT_PTR_NULL;
566 if (!addr->printable)
567 {
568 mu_stream_t str;
569 int rc;
570
571 rc = mu_memory_stream_create (&str, MU_STREAM_RDWR);
572 if (rc)
573 return rc;
574 rc = mu_stream_format_address (str, addr);
575 if (rc == 0)
576 {
577 mu_off_t size;
578 mu_stream_size (str, &size);
579 addr->printable = malloc (size + 1);
580 if (!addr->printable)
581 rc = ENOMEM;
582 else
583 {
584 mu_stream_seek (str, 0, MU_SEEK_SET, NULL);
585 rc = mu_stream_read (str, addr->printable, size, NULL);
586 addr->printable[size] = 0;
587 }
588 }
589 mu_stream_destroy (&str);
590 if (rc)
591 return rc;
592 }
593 *sptr = addr->printable;
594 return 0;
595 }
603 596
604 if (!addr->addr) 597 int
598 mu_address_aget_printable (mu_address_t addr, char **presult)
599 {
600 int rc;
601 const char *s;
602
603 if (addr == NULL)
604 return EINVAL;
605 if (!presult)
606 return MU_ERR_OUT_PTR_NULL;
607 rc = mu_address_sget_printable (addr, &s);
608 if (rc == 0)
605 { 609 {
606 i = mu_address_format_string (addr, NULL, 0); 610 char *result = strdup (s);
607 addr->addr = malloc (i + 1); 611 if (result)
608 if (!addr->addr) 612 *presult = result;
609 return ENOMEM; 613 else
610 mu_address_format_string (addr, addr->addr, i+1); 614 rc = ENOMEM;
611 } 615 }
616 return rc;
617 }
612 618
613 i = mu_cpystr (buf, addr->addr, len); 619 int
614 if (n) 620 mu_address_get_printable (mu_address_t addr, char *buf, size_t len, size_t *n)
615 *n = i; 621 {
616 return 0; 622 const char *s;
623 int rc;
624
625 rc = mu_address_sget_printable (addr, &s);
626 if (rc == 0)
627 {
628 size_t i;
629 i = mu_cpystr (buf, addr->printable, len);
630 if (n)
631 *n = i;
632 }
633 return rc;
634 }
635
636 int
637 mu_address_to_string (mu_address_t addr, char *buf, size_t len, size_t *n)
638 {
639 return mu_address_get_printable (addr, buf, len, n);
617 } 640 }
618 641
619 int 642 int
...@@ -687,8 +710,8 @@ mu_address_dup (mu_address_t src) ...@@ -687,8 +710,8 @@ mu_address_dup (mu_address_t src)
687 return NULL; 710 return NULL;
688 711
689 /* FIXME: How about: 712 /* FIXME: How about:
690 if (src->addr) 713 if (src->printable)
691 dst->addr = strdup (src->addr); 714 dst->printable = strdup (src->printable);
692 ? 715 ?
693 */ 716 */
694 if (src->comments) 717 if (src->comments)
...@@ -725,10 +748,10 @@ mu_address_union (mu_address_t *a, mu_address_t b) ...@@ -725,10 +748,10 @@ mu_address_union (mu_address_t *a, mu_address_t b)
725 } 748 }
726 else 749 else
727 { 750 {
728 if ((*a)->addr) 751 if ((*a)->printable)
729 { 752 {
730 free ((*a)->addr); 753 free ((*a)->printable);
731 (*a)->addr = NULL; 754 (*a)->printable = NULL;
732 } 755 }
733 for (last = *a; last->next; last = last->next) 756 for (last = *a; last->next; last = last->next)
734 ; 757 ;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2005, 2006, 2007, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22 #include <stdlib.h>
23 #include <mailutils/address.h>
24 #include <mailutils/stream.h>
25
26 int
27 mu_stream_format_address (mu_stream_t str, mu_address_t addr)
28 {
29 int comma = 0;
30
31 for (;addr; addr = addr->next)
32 {
33 mu_validate_email (addr);
34 if (addr->email)
35 {
36 int space = 0;
37
38 if (comma)
39 mu_stream_write (str, ",", 1, NULL);
40
41 if (addr->personal)
42 {
43 mu_stream_printf (str, "\"%s\"", addr->personal);
44 space++;
45 }
46
47 if (addr->comments)
48 {
49 if (space)
50 mu_stream_write (str, " ", 1, NULL);
51 mu_stream_printf (str, "(%s)", addr->comments);
52 space++;
53 }
54
55 if (space)
56 mu_stream_write (str, " ", 1, NULL);
57 mu_stream_printf (str, "<%s>", addr->email);
58 comma++;
59 }
60 }
61 return mu_stream_err (str) ? mu_stream_last_error (str) : 0;
62 }
...@@ -713,8 +713,8 @@ addr_field_by_mask (mu_address_t addr, int mask) ...@@ -713,8 +713,8 @@ addr_field_by_mask (mu_address_t addr, int mask)
713 { 713 {
714 switch (mask) 714 switch (mask)
715 { 715 {
716 case MU_ADDR_HINT_ADDR: 716 case MU_ADDR_HINT_PRINTABLE:
717 return addr->addr; 717 return addr->printable;
718 718
719 case MU_ADDR_HINT_COMMENTS: 719 case MU_ADDR_HINT_COMMENTS:
720 return addr->comments; 720 return addr->comments;
...@@ -758,7 +758,7 @@ addr_free_fields (mu_address_t a, int memflag) ...@@ -758,7 +758,7 @@ addr_free_fields (mu_address_t a, int memflag)
758 { 758 {
759 char *p; 759 char *p;
760 760
761 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_ADDR))) 761 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_PRINTABLE)))
762 free (p); 762 free (p);
763 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_COMMENTS))) 763 if ((p = addr_field_by_mask (a, memflag & MU_ADDR_HINT_COMMENTS)))
764 free (p); 764 free (p);
......
...@@ -172,8 +172,8 @@ assoc_remove (mu_assoc_t assoc, struct _mu_assoc_elem *elem) ...@@ -172,8 +172,8 @@ assoc_remove (mu_assoc_t assoc, struct _mu_assoc_elem *elem)
172 while ((j < r && r <= i) || (i < j && j < r) || (r <= i && i < j)); 172 while ((j < r && r <= i) || (i < j && j < r) || (r <= i && i < j));
173 173
174 if (j != i) 174 if (j != i)
175 memcpy (ASSOC_ELEM (assoc, j), ASSOC_ELEM (assoc, i), 175 memcpy (ASSOC_ELEM (assoc, j), ASSOC_ELEM (assoc, i),
176 assoc->elsize); 176 assoc->elsize);
177 } 177 }
178 return 0; 178 return 0;
179 } 179 }
......
...@@ -287,7 +287,7 @@ static int ...@@ -287,7 +287,7 @@ static int
287 _mime_header_parse (const char *text, char **pvalue, 287 _mime_header_parse (const char *text, char **pvalue,
288 mu_assoc_t assoc, const char *outcharset, int subset) 288 mu_assoc_t assoc, const char *outcharset, int subset)
289 { 289 {
290 int rc; 290 int rc = 0;
291 struct mu_wordsplit ws; 291 struct mu_wordsplit ws;
292 struct param_continuation cont; 292 struct param_continuation cont;
293 size_t i; 293 size_t i;
......
...@@ -861,17 +861,13 @@ util_merge_addresses (char **addr_str, const char *value) ...@@ -861,17 +861,13 @@ util_merge_addresses (char **addr_str, const char *value)
861 rc = mu_address_union (&addr, new_addr); 861 rc = mu_address_union (&addr, new_addr);
862 if (rc == 0) 862 if (rc == 0)
863 { 863 {
864 size_t n; 864 char *val;
865 865
866 rc = mu_address_to_string (addr, NULL, 0, &n); 866 rc = mu_address_aget_printable (addr, &val);
867 if (rc == 0) 867 if (rc == 0)
868 { 868 {
869 free (*addr_str); 869 free (*addr_str);
870 *addr_str = malloc (n + 1); 870 *addr_str = val;
871 if (!*addr_str)
872 rc = ENOMEM;
873 else
874 mu_address_to_string (addr, *addr_str, n + 1, &n);
875 } 871 }
876 } 872 }
877 873
...@@ -972,15 +968,12 @@ util_header_expand (mu_header_t *phdr) ...@@ -972,15 +968,12 @@ util_header_expand (mu_header_t *phdr)
972 968
973 if (addr) 969 if (addr)
974 { 970 {
975 char *newvalue; 971 const char *newvalue;
976 size_t n = 0;
977 972
978 mu_address_to_string (addr, NULL, 0, &n); 973 rc = mu_address_sget_printable (addr, &newvalue);
979 newvalue = xmalloc (n + 1); 974 if (rc == 0)
980 mu_address_to_string (addr, newvalue, n + 1, NULL); 975 mu_header_set_value (hdr, name, newvalue, 1);
981 mu_address_destroy (&addr); 976 mu_address_destroy (&addr);
982 mu_header_set_value (hdr, name, newvalue, 1);
983 free (newvalue);
984 } 977 }
985 } 978 }
986 else 979 else
......
...@@ -358,7 +358,8 @@ typedef int (*mh_alias_enumerator_t) (char *alias, mu_list_t names, void *data); ...@@ -358,7 +358,8 @@ typedef int (*mh_alias_enumerator_t) (char *alias, mu_list_t names, void *data);
358 void mh_alias_enumerate (mh_alias_enumerator_t fun, void *data); 358 void mh_alias_enumerate (mh_alias_enumerator_t fun, void *data);
359 359
360 360
361 void mh_annotate (mu_message_t msg, char *field, char *text, int date); 361 void mh_annotate (mu_message_t msg, const char *field, const char *text,
362 int date);
362 363
363 #define MHL_DECODE 1 364 #define MHL_DECODE 1
364 #define MHL_CLEARSCREEN 2 365 #define MHL_CLEARSCREEN 2
......
...@@ -1801,7 +1801,6 @@ static void ...@@ -1801,7 +1801,6 @@ static void
1801 builtin_formataddr (struct mh_machine *mach) 1801 builtin_formataddr (struct mh_machine *mach)
1802 { 1802 {
1803 mu_address_t addr, dest; 1803 mu_address_t addr, dest;
1804 size_t size;
1805 int i; 1804 int i;
1806 size_t num; 1805 size_t num;
1807 const char *buf; 1806 const char *buf;
...@@ -1837,12 +1836,12 @@ builtin_formataddr (struct mh_machine *mach) ...@@ -1837,12 +1836,12 @@ builtin_formataddr (struct mh_machine *mach)
1837 } 1836 }
1838 } 1837 }
1839 1838
1840 if (mu_address_to_string (dest, NULL, 0, &size) == 0) 1839 if (mu_address_sget_printable (dest, &buf) == 0)
1841 { 1840 {
1842 strobj_realloc (&mach->reg_str, size + 1); 1841 strobj_realloc (&mach->reg_str, strlen (buf) + 1);
1843 mu_address_to_string (dest, strobj_ptr (&mach->reg_str), size + 1, NULL); 1842 strcpy (strobj_ptr (&mach->reg_str), buf);
1844 mu_address_destroy (&dest);
1845 } 1843 }
1844 mu_address_destroy (&dest);
1846 } 1845 }
1847 1846
1848 /* putaddr literal print str address list with 1847 /* putaddr literal print str address list with
......
...@@ -852,7 +852,7 @@ mh_install (char *name, int automode) ...@@ -852,7 +852,7 @@ mh_install (char *name, int automode)
852 } 852 }
853 853
854 void 854 void
855 mh_annotate (mu_message_t msg, char *field, char *text, int date) 855 mh_annotate (mu_message_t msg, const char *field, const char *text, int date)
856 { 856 {
857 mu_header_t hdr; 857 mu_header_t hdr;
858 mu_attribute_t attr; 858 mu_attribute_t attr;
......
...@@ -264,8 +264,8 @@ invoke (const char *compname, const char *defval, int argc, char **argv, ...@@ -264,8 +264,8 @@ invoke (const char *compname, const char *defval, int argc, char **argv,
264 264
265 struct anno_data 265 struct anno_data
266 { 266 {
267 char *field; 267 const char *field;
268 char *value; 268 const char *value;
269 int date; 269 int date;
270 }; 270 };
271 271
...@@ -299,16 +299,12 @@ annotate (struct mh_whatnow_env *wh) ...@@ -299,16 +299,12 @@ annotate (struct mh_whatnow_env *wh)
299 299
300 if (mu_address_get_nth (addr, i, &subaddr) == 0) 300 if (mu_address_get_nth (addr, i, &subaddr) == 0)
301 { 301 {
302 size_t size;
303 struct anno_data d; 302 struct anno_data d;
304 303
305 mu_address_to_string (subaddr, NULL, 0, &size);
306 d.value = xmalloc (size + 1);
307 d.field = wh->anno_field; 304 d.field = wh->anno_field;
308 d.date = i == 1; 305 d.date = i == 1;
309 mu_address_to_string (subaddr, d.value, size + 1, NULL); 306 if (mu_address_sget_printable (subaddr, &d.value) == 0)
310 mu_list_foreach (wh->anno_list, anno, &d); 307 mu_list_foreach (wh->anno_list, anno, &d);
311 free (d.value);
312 mu_address_destroy (&subaddr); 308 mu_address_destroy (&subaddr);
313 } 309 }
314 } 310 }
......
...@@ -475,11 +475,10 @@ get_sender_personal () ...@@ -475,11 +475,10 @@ get_sender_personal ()
475 static void 475 static void
476 set_address_header (mu_header_t hdr, char *name, mu_address_t addr) 476 set_address_header (mu_header_t hdr, char *name, mu_address_t addr)
477 { 477 {
478 size_t s = mu_address_format_string (addr, NULL, 0); 478 const char *value;
479 char *value = xmalloc (s + 1); 479 if (mu_address_sget_printable (addr, &value) == 0)
480 mu_address_format_string (addr, value, s); 480 mu_header_set_value (hdr, name, value, 1);
481 mu_header_set_value (hdr, name, value, 1); 481 /* FIXME: Error reporting */
482 free (value);
483 } 482 }
484 483
485 void 484 void
......
...@@ -196,12 +196,7 @@ format_email (mu_stream_t str, const char *name, mu_address_t addr) ...@@ -196,12 +196,7 @@ format_email (mu_stream_t str, const char *name, mu_address_t addr)
196 if (!addr) 196 if (!addr)
197 mu_stream_printf (str, "NIL"); 197 mu_stream_printf (str, "NIL");
198 else 198 else
199 { 199 mu_stream_format_address (str, addr);
200 size_t sz = mu_address_format_string (addr, NULL, 0);
201 char *buf = xmalloc (sz + 1);
202 mu_address_format_string (addr, buf, sz);
203 mu_stream_write (str, buf, strlen (buf), NULL);
204 }
205 mu_stream_printf (str, "\n"); 200 mu_stream_printf (str, "\n");
206 } 201 }
207 202
......
...@@ -267,17 +267,14 @@ static PyObject * ...@@ -267,17 +267,14 @@ static PyObject *
267 api_address_to_string (PyObject *self, PyObject *args) 267 api_address_to_string (PyObject *self, PyObject *args)
268 { 268 {
269 int status; 269 int status;
270 size_t n; 270 char const *sptr;
271 char buf[256];
272 PyAddress *py_addr; 271 PyAddress *py_addr;
273 272
274 memset (buf, 0, sizeof (buf));
275
276 if (!PyArg_ParseTuple (args, "O!", &PyAddressType, &py_addr)) 273 if (!PyArg_ParseTuple (args, "O!", &PyAddressType, &py_addr))
277 return NULL; 274 return NULL;
278 275
279 status = mu_address_to_string (py_addr->addr, buf, sizeof (buf), &n); 276 status = mu_address_sget_printable (py_addr->addr, &sptr);
280 return status_object (status, PyString_FromString (buf)); 277 return status_object (status, PyString_FromString (sptr));
281 } 278 }
282 279
283 static PyMethodDef methods[] = { 280 static PyMethodDef methods[] = {
......