mess822x 1.23
mess822x
Loading...
Searching...
No Matches
mess822_addr.c
Go to the documentation of this file.
1#include "mess822.h"
2#include "str.h"
3
4static stralloc tokens = {0};
5static stralloc comment = {0};
6
7static stralloc addr = {0};
8static int state; /* 0: no address; 1: address without @; 2: address with @ */
9
10static int docomment(stralloc *out)
11{
12 int i;
13 int j;
14 char ch;
15
16 for (j = i = 0;j < comment.len;++j) {
17 ch = comment.s[j];
18 if (ch == ' ') if (!i || (comment.s[i - 1] == ' ')) continue;
19 comment.s[i++] = ch;
20 }
21 while (i && (comment.s[i - 1] == ' ')) --i;
22 comment.len = 0;
23
24 if (i) {
25 if (!stralloc_0(out)) return 0;
26 if (!stralloc_catb(out,comment.s,i)) return 0;
27 if (!stralloc_append(out,"(")) return 0;
28 }
29
30 return 1;
31}
32
33static int doit(stralloc *out)
34{
35 if (!state) return 1;
36
37 if (!stralloc_0(out)) return 0;
38 if (state == 1)
39 if (!stralloc_append(out,"@")) return 0;
40 if (!stralloc_catb(out,addr.s,addr.len)) return 0;
41 if (!stralloc_append(out,"+")) return 0;
42
43 if (!docomment(out)) return 0;
44
45 state = 0;
46 addr.len = 0;
47 return 1;
48}
49
50static int addcomment(char *tok)
51{
52 int i;
53
54 if (*tok == ',') return 1;
55 if (*tok == ':') return 1;
56 if (*tok == ';') return 1;
57 if (*tok == '<') return 1;
58 if (*tok == '>') return 1;
59
60 if ((*tok == '|') || (*tok == '(')) ++tok;
61
62 i = str_len(tok);
63 while (i--)
64 if (!stralloc_append(&comment,tok + i)) return 0;
65
66 return 1;
67}
68
69static int addaddr(char *tok)
70{
71 int i;
72
73 if ((*tok != '|') && (*tok != '.') && (*tok != '@'))
74 return addcomment(tok);
75
76 if (!state) state = 1;
77 if (*tok == '@') state = 2;
78
79 if (*tok == '|') ++tok;
80
81 i = str_len(tok);
82 while (i--)
83 if (!stralloc_append(&addr,tok + i)) return 0;
84
85 return 1;
86}
87
88int mess822_keyvalue(stralloc *out,char *in)
89{
90 int j;
91 int keyvalue;
92 char ch;
93
94 if (!mess822_token(&tokens,in)) return 0;
95
96 if (!stralloc_copys(out,"")) return 0;
97
98 keyvalue = 0;
99
100 for (j = 0; j <= tokens.len; j++) {
101 ch = tokens.s[j];
102 if (!keyvalue)
103 if ((ch == ' ') || (ch == '\t') || (ch == '<') || (ch == '(') || (ch == '[')) continue;
104 if (!stralloc_catb(out,&ch,1)) return 0;
105 if (ch == '=') keyvalue = 1;
106 if (keyvalue)
107 if ((ch == ' ') || (ch == '\t') || (ch == '>') || (ch == ')') || (ch == ']') || (ch == ';')) break;
108 if (!stralloc_catb(out,&ch,1)) return 0;
109 }
110
111 if (!keyvalue) {
112 if (!stralloc_copys(out,"")) return 0;
113 out->len = 0;
114 }
115
116 return keyvalue;
117}
118
119int mess822_addrlist(stralloc *out,char *in)
120{
121 int flagwordok = 1;
122 int flagphrase = 0;
123 int j;
124 int i;
125 char ch;
126
127 if (!mess822_token(&tokens,in)) return 0;
128
129 if (!stralloc_copys(out,"")) return 0;
130 if (!stralloc_copys(&comment,"")) return 0;
131 if (!stralloc_copys(&addr,"")) return 0;
132 state = 0;
133
134 j = tokens.len;
135
136 while (j) {
137 while (j--) if (!j || !tokens.s[j - 1]) break;
138
139 ch = tokens.s[j];
140 if (flagphrase) {
141 if ((ch != ',') && (ch != ';') && (ch != ':') && (ch != '>')) {
142 if (!addcomment(tokens.s + j)) return 0;
143 continue;
144 }
145 if (!doit(out)) return 0;
146 flagphrase = 0;
147 flagwordok = 1;
148 }
149
150 switch (tokens.s[j]) {
151 case ' ': case '\t':
152 if (!addcomment(" ")) return 0;
153 break;
154
155 case ';': case ',':
156 if (!doit(out)) return 0;
157 if (!docomment(out)) return 0;
158 flagwordok = 1;
159 break;
160
161 case '(':
162 if (!addcomment(" ")) return 0;
163 if (!addcomment(tokens.s + j)) return 0;
164 if (!addcomment(" ")) return 0;
165 break;
166
167 case '=':
168 if (!flagwordok)
169 if (!doit(out)) return 0;
170 if (!addaddr(tokens.s + j)) return 0;
171 flagwordok = 0;
172 break;
173
174 case '>':
175 if (!doit(out)) return 0;
176
177 if (!state) state = 1; /* <> is an address */
178
179 for (;;) {
180 if (!addaddr(tokens.s + j)) return 0;
181 if (!j) break;
182 while (j--) if (!j || !tokens.s[j - 1]) break;
183 if (tokens.s[j] == ':') break;
184 if (tokens.s[j] == '<') break;
185 }
186
187 if (tokens.s[j] == ':')
188 for (;;) {
189 if (!addcomment(tokens.s + j)) return 0;
190 if (!j) break;
191 while (j--) if (!j || !tokens.s[j - 1]) break;
192 if (tokens.s[j] == '<') break;
193 }
194 /* fall through */
195
196 case ':':
197 flagphrase = 1;
198 break;
199
200 default:
201 if (!addaddr(tokens.s + j)) return 0;
202 flagwordok = 1;
203 break;
204 }
205 }
206
207 if (!doit(out)) return 0;
208 if (!docomment(out)) return 0;
209
210 i = 0;
211 j = out->len - 1;
212
213 while (i < j) {
214 ch = out->s[i];
215 out->s[i] = out->s[j];
216 out->s[j] = ch;
217 ++i;
218 --j;
219 }
220
221 return 1;
222}
int mess822_addrlist(stralloc *out, char *in)
Definition: mess822_addr.c:119
int mess822_keyvalue(stralloc *out, char *in)
Definition: mess822_addr.c:88
stralloc tokens
Definition: 822received.c:25
stralloc out
Definition: b64decode.c:12
int mess822_token(stralloc *, char *)
Definition: mess822_token.c:5