1 /* -*- C -*-
2  * Spamtest connection library
3  * File: addrlist.c
4  *      (C)  Alex Tutubalin <lexa@lexa.ru>
5  *	Apr-May 2003
6  *
7  * Created: Wed Apr 23 22:08:08 2003
8  */
9 
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include "mess822.h"
15 #include "msgstore.h"
16 #include "spamtest.h"
17 
rfc822_unquote_one(char * dest,unsigned int size,char * from,char * defdomain)18 int rfc822_unquote_one(char *dest,unsigned int size, char *from, char *defdomain)
19 {
20     stralloc addrlist={0};
21     int i,j;
22     if(!dest || !from || !defdomain) return -1;
23     if(size<1) return -1;
24     if(strlen(from)<1)
25 	return 0; // GIGO
26     if(!mess822_addrlist(&addrlist,from))
27 	{
28 	    CLEAN_SA(addrlist);
29 	    return -1;
30 	}
31     for(i=j=0; j< addrlist.len;j++)
32 	if(!addrlist.s[j])
33 	    {
34 		if( addrlist.s[i]=='+')
35 		    {
36 			strncpy(dest,addrlist.s+i+1,size);
37 			break;
38 		    }
39 		i=j+1;
40 	    }
41     i = strlen(dest);
42     if(i==1 && dest[0] == '@')
43 	{
44 	    dest[0]='\0'; // emtpy address
45 	}
46     else if(i>1 && dest[i-1]=='@')
47 	{
48 	    strncpy(dest+i,defdomain,size-i);
49 	}
50     if(*dest)
51 	dest[size-1]='\0';
52     CLEAN_SA(addrlist);
53     return 0;
54 }
55 
56 
rfc822_quote_one(char * dest,unsigned int size,char * from,char * defdomain)57 int rfc822_quote_one(char *dest,unsigned int size, char *from, char *defdomain)
58 {
59     stralloc quoted={0},tempaddr={0};
60     int ret;
61     if(!dest || !from || !defdomain) return -1;
62     if(size<1) return 0; //GIGO
63     if(strlen(from)<1)
64 	return 0; // GIGO
65 
66     if((ret=rfc822_unquote_one(dest,size,from,defdomain)))
67 	{
68 	    CLEAN_SA(quoted);
69 	    CLEAN_SA(tempaddr);
70 	    return ret;
71 	}
72     stralloc_copys(&tempaddr,dest);
73     if(!mess822_quotelist(&quoted,&tempaddr))
74 	{
75 	    CLEAN_SA(quoted);
76 	    CLEAN_SA(tempaddr);
77 	    return -1;
78 	}
79     strncpy(dest,quoted.s,quoted.len>size?size:quoted.len);
80     dest[size-1]='\0';
81     CLEAN_SA(quoted);
82     CLEAN_SA(tempaddr);
83     return 0;
84 }
85 
86 
rfc822_unquote_list(recipient_list_t * from,char * defdomain)87 recipient_list_t *rfc822_unquote_list(recipient_list_t *from,char *defdomain)
88 {
89     recipient_list_t *ret;
90     char *tempbuf=NULL;
91     int  allocsize=0,n;
92     int  dlen,l;
93 
94     if(!from || !defdomain) return NULL;
95     dlen = strlen(defdomain);
96     if(!(ret = rcptlist_init(from->storeptr)))
97 	return NULL;
98     // process each addr, gotting MANY replies
99     for(n=0;n<rcptlist_count(from);n++)
100 	{
101 	    // we need some space
102 	    l = strlen(rcptlist_getn(from,n));
103 	    if(allocsize < l+dlen+16)
104 		{
105 		    tempbuf = heap_realloc(from->storeptr,tempbuf,allocsize,l+dlen+16);
106 		    allocsize = l+dlen+16;
107 		}
108 	    if(!tempbuf)
109 		break;
110 	    if(rfc822_unquote_one(tempbuf,allocsize,rcptlist_getn(from,n),defdomain))
111 		break;
112 	    rcptlist_add(ret,tempbuf);
113 	}
114     return ret;
115 }
116 
rfc822_quote_list(recipient_list_t * from,char * defdomain)117 recipient_list_t *rfc822_quote_list(recipient_list_t *from,char *defdomain)
118 {
119     recipient_list_t *ret;
120     char *tempbuf=NULL;
121     int  allocsize=0,n;
122     int  dlen,l;
123 
124     if(!from || !defdomain) return NULL;
125     dlen = strlen(defdomain);
126     if(!(ret = rcptlist_init(from->storeptr)))
127 	return NULL;
128     // process each addr, gotting MANY replies
129     for(n=0;n<rcptlist_count(from);n++)
130 	{
131 	    // we need some space
132 	    l = strlen(rcptlist_getn(from,n));
133 	    if(allocsize < l+dlen+16)
134 		{
135 		    tempbuf = heap_realloc(from->storeptr,tempbuf,allocsize,l+dlen+16);
136 		    allocsize = l+dlen+16;
137 		}
138 	    if(!tempbuf)
139 		break;
140 	    if(rfc822_quote_one(tempbuf,allocsize,rcptlist_getn(from,n),defdomain))
141 		break;
142 	    rcptlist_add(ret,tempbuf);
143 	}
144     return ret;
145 }
146 
147 
148 #ifdef TEST
149 
recipient_writer(const char * rcpt,size_t unused)150 void recipient_writer(const char *rcpt, size_t unused)
151 {
152     printf("RCPT TO: %s\n",rcpt);
153 }
154 
155 
main()156 int main()
157 {
158   char abuf[100],bbuf[100];
159   recipient_list_t *rcpt,*unq,*q;
160   msg_heap_t *heap;
161   int i;
162 
163   for(i=0;i<1;i++)
164       {
165 	  heap = heap_init(10240);
166 
167 	  printf("Single Interface:\n");
168 	  if(rfc822_unquote_one(abuf,100,"(Joe User) joe@user.com","sun.com"))
169 	      exit(1);
170 	  printf("Unquoted: {%s}\n",abuf);
171 	  if(rfc822_quote_one(bbuf,100,abuf,"sun.com"))
172 	      exit(1);
173 	  printf("Final: {%s}\n",bbuf);
174 
175 	  if(rfc822_quote_one(bbuf,100," user ","sun.com"))
176 	      exit(1);
177 	  printf("Final2: {%s}\n",bbuf);
178 
179 	  printf("\n===\nMulti Interface:\nInput:\n");
180 	  if(!(rcpt = rcptlist_init(heap)))
181 	      exit(1);
182 	  rcptlist_add(rcpt,"");
183 	  rcptlist_add(rcpt,"vasya");
184 	  rcptlist_add(rcpt,"<petya>");
185 	  rcptlist_add(rcpt,"\"Kolya\"<petya>");
186 	  rcptlist_add(rcpt,"(AAA )\"Kolya\" petya");
187 	  rcptlist_add(rcpt,"vasya@joe.com");
188 	  rcptlist_add(rcpt,"Comment <vasya@joe.com>");
189 	  rcptlist_iterate(rcpt,recipient_writer);
190 
191 	  unq = rfc822_unquote_list(rcpt,"pupkin.ru");
192 	  if(!unq) exit(1);
193 	  printf("Unquoted:\n",bbuf);
194 	  rcptlist_iterate(unq,recipient_writer);
195 
196 	  q = rfc822_quote_list(unq,"pupkin.ru");
197 	  if(!q) exit(1);
198 	  printf("Quoted:\n",bbuf);
199 	  rcptlist_iterate(q,recipient_writer);
200 	  heap_free(heap);
201       }
202   return 0;
203 }
204 #endif
205