1 /*
2 ** Copyright 2002-2011, Double Precision Inc.
3 **
4 ** See COPYING for distribution information.
5 */
6 #include "libmail_config.h"
7 #include <cstring>
8
9 #include "addressbook.H"
10 #include "addressbookadd.H"
11 #include "addressbookget.H"
12 #include "addressbookopen.H"
13 #include "addressbooksearch.H"
14 #include "rfc2047decode.H"
15 #include "misc.H"
16 #include <errno.h>
17
18 using namespace std;
19
Entry()20 mail::addressbook::Entry::Entry()
21 {
22 }
23
~Entry()24 mail::addressbook::Entry::~Entry()
25 {
26 }
27
addressbook(mail::account * serverArg,mail::folder * folderArg)28 mail::addressbook::addressbook(mail::account *serverArg,
29 mail::folder *folderArg)
30 : server(serverArg),
31 folder(folderArg)
32 {
33 }
34
~addressbook()35 mail::addressbook::~addressbook()
36 {
37 }
38
addEntry(Entry & newEntry,string olduid,mail::callback & callback)39 void mail::addressbook::addEntry(Entry &newEntry, string olduid,
40 mail::callback &callback)
41 {
42 vector<Index>::iterator b=index.begin(), e=index.end();
43
44 while (b != e)
45 {
46 Index &i= *b++;
47
48 if (olduid.size() > 0 && i.uid == olduid)
49 continue;
50
51 if (newEntry.nickname == i.nickname)
52 {
53 callback.fail("Address book entry with the same name already exists.");
54 return;
55 }
56 }
57
58 Add *add=new Add(this, newEntry, olduid, callback);
59
60 try {
61 add->go();
62 } catch (...) {
63 delete add;
64 }
65 }
66
importEntries(std::list<Entry> & newEntries,mail::callback & callback)67 void mail::addressbook::importEntries(std::list<Entry> &newEntries,
68 mail::callback &callback)
69 {
70 Add *add=new Add(this, newEntries, callback);
71
72 try {
73 add->go();
74 } catch (...) {
75 delete add;
76 }
77 }
78
79 // Delete an address book entry.
80
del(std::string uid,mail::callback & callback)81 void mail::addressbook::del(std::string uid, mail::callback &callback)
82 {
83 vector<Index>::iterator b=index.begin(), e=index.end();
84
85 while (b != e)
86 {
87 if (b->uid == uid)
88 {
89 vector<size_t> msgList;
90
91 msgList.push_back(b - index.begin());
92
93 server->removeMessages(msgList, callback);
94 return;
95 }
96
97 b++;
98 }
99
100 callback.success("OK");
101 }
102
open(mail::callback & callback)103 void mail::addressbook::open(mail::callback &callback)
104 {
105 Open *o=new Open(this, callback);
106
107 try {
108 o->go();
109 } catch (...) {
110 delete o;
111 }
112 }
113
Index()114 mail::addressbook::Index::Index() : nickname("(corrupted entry)")
115 {
116 }
117
~Index()118 mail::addressbook::Index::~Index()
119 {
120 }
121
setIndex(size_t messageNumber,string subject)122 void mail::addressbook::setIndex(size_t messageNumber,
123 string subject)
124 {
125 subject= mail::rfc2047::decoder().decode(subject, "utf-8");
126
127 if (messageNumber < index.size())
128 {
129 Index newEntry;
130
131 size_t i=subject.find('[');
132
133 if (i != std::string::npos)
134 {
135 subject=subject.substr(i+1);
136
137 i=subject.find(']');
138
139 if (i != std::string::npos)
140 {
141 newEntry.nickname=subject.substr(0, i);
142 if (newEntry.nickname.size() == 0)
143 newEntry.nickname="(none)";
144
145 char *p=unicode_convert_tobuf(newEntry
146 .nickname
147 .c_str(),
148 "utf-8",
149 unicode_default_chset(),
150 NULL);
151
152 if (!p)
153 LIBMAIL_THROW(strerror(errno));
154
155 try {
156 newEntry.nickname=p;
157 free(p);
158 } catch (...) {
159 free(p);
160 LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
161 }
162 }
163 }
164
165 newEntry.uid=server->getFolderIndexInfo(messageNumber).uid;
166 index[messageNumber]=newEntry;
167 }
168 }
169
newMessages()170 void mail::addressbook::newMessages()
171 {
172 }
173
messagesRemoved(vector<pair<size_t,size_t>> & r)174 void mail::addressbook::messagesRemoved(vector< pair<size_t, size_t> > &r)
175 {
176 vector< pair<size_t, size_t> >::iterator b=r.begin(), e=r.end();
177
178 while (b != e)
179 {
180 --e;
181
182 size_t from=e->first, to=e->second;
183
184 if (from >= index.size())
185 continue;
186
187 if (to > index.size())
188 to=index.size();
189
190 index.erase(index.begin() + from, index.begin() + to + 1);
191 }
192 }
193
messageChanged(size_t n)194 void mail::addressbook::messageChanged(size_t n)
195 {
196 }
197
getIndex(list<pair<string,std::string>> & listArg,mail::callback & callback)198 void mail::addressbook::getIndex( list< pair<string, std::string> > &listArg,
199 mail::callback &callback)
200 {
201 size_t n=index.size();
202 size_t i;
203
204 for (i=0; i<n; i++)
205 {
206 string nickname=index[i].nickname;
207 string uid=index[i].uid;
208
209 if (nickname.size() > 0 && uid.size() > 0)
210 listArg.push_back( make_pair(nickname, uid));
211 }
212
213 callback.success("Address book index retrieved");
214 }
215
216 template<class T>
searchNickname(string nickname,vector<T> & addrListArg,mail::callback & callback)217 void mail::addressbook::searchNickname( string nickname,
218 vector<T> &addrListArg,
219 mail::callback &callback)
220 {
221 Search<T> *s=new Search<T>(this, addrListArg, callback);
222
223 if (!s)
224 {
225 callback.fail(strerror(errno));
226 return;
227 }
228
229 try {
230 size_t n=index.size();
231 size_t i;
232
233 for (i=0; i<n; i++)
234 if (index[i].nickname == nickname)
235 s->uidList.push_back(server->
236 getFolderIndexInfo(i)
237 .uid);
238 s->go();
239 } catch (...) {
240 delete s;
241 LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
242 }
243 }
244
245 template
246 void mail::addressbook::searchNickname( string nickname,
247 vector<mail::address> &addrListArg,
248 mail::callback &callback);
249 template
250 void mail::addressbook::searchNickname( string nickname,
251 vector<mail::emailAddress> &addrListArg,
252 mail::callback &callback);
253
254 template<class T>
getEntry(string uid,vector<T> & addrListArg,mail::callback & callback)255 void mail::addressbook::getEntry( string uid,
256 vector<T> &addrListArg,
257 mail::callback &callback)
258 {
259 size_t n=index.size();
260 size_t i;
261
262 for (i=0; i<n; i++)
263 if (server->getFolderIndexInfo(i).uid == uid)
264 {
265 GetAddressList<T> *get=
266 new GetAddressList<T>(this, i,
267 addrListArg,
268 callback);
269
270 if (!get)
271 {
272 callback.fail(strerror(errno));
273 return;
274 }
275
276 try {
277 get->go();
278 } catch (...) {
279 delete get;
280 LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
281 }
282 return;
283 }
284
285 callback.success("NOT FOUND.");
286 }
287
288 template
289 void mail::addressbook::getEntry( string uid,
290 vector<mail::address> &addrListArg,
291 mail::callback &callback);
292 template
293 void mail::addressbook::getEntry( string uid,
294 vector<mail::emailAddress>
295 &addrListArg,
296 mail::callback &callback);
297