1 /*
2 ** Copyright 1998 - 2009 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5 
6 /*
7 */
8 #include	"rfc822.h"
9 #include	<stdlib.h>
10 
cntlen(char c,void * p)11 static void cntlen(char c, void *p)
12 {
13 	c=c;
14 	++ *(size_t *)p;
15 }
16 
cntlensep(const char * p,void * ptr)17 static void cntlensep(const char *p, void *ptr)
18 {
19 	while (*p)	cntlen(*p++, ptr);
20 }
21 
saveaddr(char c,void * ptr)22 static void saveaddr(char c, void *ptr)
23 {
24 	*(*(char **)ptr)++=c;
25 }
26 
saveaddrsep(const char * p,void * ptr)27 static void saveaddrsep(const char *p, void *ptr)
28 {
29 	while (*p)	saveaddr(*p++, ptr);
30 }
31 
rfc822_getaddrs(const struct rfc822a * rfc)32 char *rfc822_getaddrs(const struct rfc822a *rfc)
33 {
34 	size_t	addrbuflen=0;
35 	char	*addrbuf, *ptr;
36 
37 	if (rfc822_print(rfc, &cntlen, &cntlensep, &addrbuflen) < 0)
38 		return NULL;
39 
40 	if (!(addrbuf=malloc(addrbuflen+1)))
41 		return (0);
42 
43 	ptr=addrbuf;
44 	if (rfc822_print(rfc, &saveaddr, &saveaddrsep, &ptr) < 0)
45 	{
46 		free(addrbuf);
47 		return NULL;
48 	}
49 
50 	addrbuf[addrbuflen]=0;
51 	return (addrbuf);
52 }
53 
saveaddrsep_wrap(const char * p,void * ptr)54 static void saveaddrsep_wrap(const char *p, void *ptr)
55 {
56 int	c;
57 
58 	while ((c=*p++) != 0)
59 	{
60 		if (c == ' ')	c='\n';
61 		saveaddr(c, ptr);
62 	}
63 }
64 
rfc822_getaddrs_wrap(const struct rfc822a * rfc,int w)65 char *rfc822_getaddrs_wrap(const struct rfc822a *rfc, int w)
66 {
67 	size_t	addrbuflen=0;
68 	char	*addrbuf, *ptr, *start, *lastnl;
69 
70 	if (rfc822_print(rfc, &cntlen, &cntlensep, &addrbuflen) < 0)
71 		return NULL;
72 
73 	if (!(addrbuf=malloc(addrbuflen+1)))
74 		return (0);
75 
76 	ptr=addrbuf;
77 
78 	if (rfc822_print(rfc, &saveaddr, &saveaddrsep_wrap, &ptr) < 0)
79 	{
80 		free(addrbuf);
81 		return NULL;
82 	}
83 
84 	addrbuf[addrbuflen]=0;
85 
86 	for (lastnl=0, start=ptr=addrbuf; *ptr; )
87 	{
88 		while (*ptr && *ptr != '\n')	ptr++;
89 		if (ptr-start < w)
90 		{
91 			if (lastnl)	*lastnl=' ';
92 			lastnl=ptr;
93 			if (*ptr)	++ptr;
94 		}
95 		else
96 		{
97 			if (lastnl)
98 				start=lastnl+1;
99 			else
100 			{
101 				start=ptr+1;
102 				if (*ptr)	++ptr;
103 			}
104 			lastnl=0;
105 		}
106 	}
107 	return (addrbuf);
108 }
109