1 /* -*- Mode: c++; -*- */
2 /* --------------------------------------------------------------------
3 * Filename:
4 * imapparser.cc
5 *
6 * Description:
7 * Implementation of the common items for parsing IMAP input
8 *
9 * Authors:
10 * Andreas Aardal Hanssen <andreas-binc curly bincimap spot org>
11 *
12 * Bugs:
13 *
14 * ChangeLog:
15 *
16 * --------------------------------------------------------------------
17 * Copyright 2002-2005 Andreas Aardal Hanssen
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
32 * --------------------------------------------------------------------
33 */
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include "imapparser.h"
39 #include "io.h"
40 #include "convert.h"
41
42 #include <stdio.h>
43 #include <map>
44 #include <iostream>
45 #include <vector>
46 #include <string>
47 #include <exception>
48
49 using namespace ::std;
50 using namespace Binc;
51
52 //------------------------------------------------------------------------
Request(void)53 Request::Request(void)
54 : extra(0), flags(), statuses(), bset(), searchkey(), fatt()
55 {
56 uidmode = false;
57 }
58
~Request(void)59 Request::~Request(void)
60 {
61 if (extra != 0)
62 delete extra;
63 }
64
65 //------------------------------------------------------------------------
setUidMode(void)66 void Request::setUidMode(void)
67 {
68 uidmode = true;
69 }
70
71 //------------------------------------------------------------------------
getUidMode(void) const72 bool Request::getUidMode(void) const
73 {
74 return uidmode;
75 }
76
77 //------------------------------------------------------------------------
setTag(string & t_in)78 void Request::setTag(string &t_in)
79 {
80 tag = t_in;
81 }
82
83 //------------------------------------------------------------------------
getTag(void) const84 const string &Request::getTag(void) const
85 {
86 return tag;
87 }
88
89 //------------------------------------------------------------------------
setMode(const string & m_in)90 void Request::setMode(const string &m_in)
91 {
92 mode = m_in;
93 }
94
95 //------------------------------------------------------------------------
getMode(void) const96 const string &Request::getMode(void) const
97 {
98 return mode;
99 }
100
101 //------------------------------------------------------------------------
setName(const string & s_in)102 void Request::setName(const string &s_in)
103 {
104 name = s_in;
105 }
106
107 //------------------------------------------------------------------------
getName(void) const108 const string &Request::getName(void) const
109 {
110 return name;
111 }
112
113 //------------------------------------------------------------------------
setAuthType(const string & s_in)114 void Request::setAuthType(const string &s_in)
115 {
116 authtype = s_in;
117 }
118
119 //------------------------------------------------------------------------
getAuthType(void) const120 const string &Request::getAuthType(void) const
121 {
122 return authtype;
123 }
124
125 //------------------------------------------------------------------------
setLiteral(const string & s_in)126 void Request::setLiteral(const string &s_in)
127 {
128 literal = s_in;
129 }
130
131 //------------------------------------------------------------------------
getLiteral(void) const132 const string &Request::getLiteral(void) const
133 {
134 return literal;
135 }
136
137 //------------------------------------------------------------------------
setDate(const string & s_in)138 void Request::setDate(const string &s_in)
139 {
140 date = s_in;
141 }
142
143 //------------------------------------------------------------------------
getDate(void) const144 const string &Request::getDate(void) const
145 {
146 return date;
147 }
148
149 //------------------------------------------------------------------------
setCharSet(const string & s_in)150 void Request::setCharSet(const string &s_in)
151 {
152 charset = s_in;
153 uppercase(charset);
154 }
155
156 //------------------------------------------------------------------------
getCharSet(void) const157 const string &Request::getCharSet(void) const
158 {
159 return charset;
160 }
161
162 //------------------------------------------------------------------------
setUserID(const string & s_in)163 void Request::setUserID(const string &s_in)
164 {
165 userid = s_in;
166 }
167
168 //------------------------------------------------------------------------
getUserID(void) const169 const string &Request::getUserID(void) const
170 {
171 return userid;
172 }
173
174 //------------------------------------------------------------------------
setPassword(const string & s_in)175 void Request::setPassword(const string &s_in)
176 {
177 password = s_in;
178 }
179
180 //------------------------------------------------------------------------
getPassword(void) const181 const string &Request::getPassword(void) const
182 {
183 return password;
184 }
185
186 //------------------------------------------------------------------------
setMailbox(const string & s_in)187 void Request::setMailbox(const string &s_in)
188 {
189 mailbox = s_in;
190 }
191
192 //------------------------------------------------------------------------
getMailbox(void) const193 const string &Request::getMailbox(void) const
194 {
195 return mailbox;
196 }
197
198 //------------------------------------------------------------------------
setListMailbox(const string & s_in)199 void Request::setListMailbox(const string &s_in)
200 {
201 listmailbox = s_in;
202 }
203
204 //------------------------------------------------------------------------
getListMailbox(void) const205 const string &Request::getListMailbox(void) const
206 {
207 return listmailbox;
208 }
209
210 //------------------------------------------------------------------------
setNewMailbox(const string & s_in)211 void Request::setNewMailbox(const string &s_in)
212 {
213 newmailbox = s_in;
214 }
215
216 //------------------------------------------------------------------------
getNewMailbox(void) const217 const string &Request::getNewMailbox(void) const
218 {
219 return newmailbox;
220 }
221
222 //------------------------------------------------------------------------
getSet(void)223 SequenceSet &Request::getSet(void)
224 {
225 return bset;
226 }
227
228 //------------------------------------------------------------------------
getStatuses(void)229 vector<string> &Request::getStatuses(void)
230 {
231 return statuses;
232 }
233
234 //------------------------------------------------------------------------
getFlags(void)235 vector<string> &Request::getFlags(void)
236 {
237 return flags;
238 }
239
240 //------------------------------------------------------------------------
SequenceSet(void)241 SequenceSet::SequenceSet(void) : limited(true), nullSet(false)
242 {
243 }
244
245 //------------------------------------------------------------------------
SequenceSet(const SequenceSet & copy)246 SequenceSet::SequenceSet(const SequenceSet ©)
247 : limited(copy.limited), nullSet(copy.nullSet), internal(copy.internal)
248 {
249 }
250
251 //------------------------------------------------------------------------
operator =(const SequenceSet & copy)252 SequenceSet &SequenceSet::operator = (const SequenceSet ©)
253 {
254 limited = copy.limited;
255 nullSet = copy.nullSet;
256 internal = copy.internal;
257
258 return *this;
259 }
260
261 //------------------------------------------------------------------------
~SequenceSet(void)262 SequenceSet::~SequenceSet(void)
263 {
264 }
265
266 //------------------------------------------------------------------------
null(void)267 SequenceSet &SequenceSet::null(void)
268 {
269 static SequenceSet nil;
270 nil.nullSet = true;
271 return nil;
272 }
273
274 //------------------------------------------------------------------------
isNull(void) const275 bool SequenceSet::isNull(void) const
276 {
277 return nullSet;
278 }
279
280 //------------------------------------------------------------------------
all(void)281 SequenceSet &SequenceSet::all(void)
282 {
283 static bool initialized = false;
284 static SequenceSet all;
285
286 if (!initialized) {
287 all.addRange(1, (unsigned int)-1);
288 initialized = true;
289 }
290
291 return all;
292 }
293
294 //------------------------------------------------------------------------
Range(unsigned int a,unsigned int b)295 SequenceSet::Range::Range(unsigned int a, unsigned int b)
296 {
297 if (a > b) {
298 from = b;
299 to = a;
300 } else {
301 from = a;
302 to = b;
303 }
304 }
305
306 //------------------------------------------------------------------------
addRange(unsigned int a,unsigned int b)307 void SequenceSet::addRange(unsigned int a, unsigned int b)
308 {
309 if (a == (unsigned int)-1 || b == (unsigned int)-1) limited = false;
310 internal.push_back(Range(a, b));
311 }
312
313 //------------------------------------------------------------------------
addNumber(unsigned int a)314 void SequenceSet::addNumber(unsigned int a)
315 {
316 if (a == (unsigned int)-1) limited = false;
317 internal.push_back(Range(a, a));
318 }
319
320 //------------------------------------------------------------------------
isInSet(unsigned int n) const321 bool SequenceSet::isInSet(unsigned int n) const
322 {
323 unsigned int maxvalue = 0;
324 for (vector<Range>::const_iterator i = internal.begin();
325 i != internal.end(); ++i) {
326 const Range &r = *i;
327 if (r.from > maxvalue) maxvalue = r.from;
328 else if (r.to > maxvalue) maxvalue = r.to;
329
330 if (n >= (*i).from && n <= (*i).to) {
331 return true;
332 }
333 }
334
335 return (n > maxvalue && !limited);
336 }
337
338 //------------------------------------------------------------------------
BincImapParserFetchAtt(const std::string & typeName)339 BincImapParserFetchAtt::BincImapParserFetchAtt(const std::string &typeName)
340 : type(typeName)
341 {
342 offsetstart = 0;
343 offsetlength = (unsigned int) -1;
344 hassection = false;
345 }
346
347 //------------------------------------------------------------------------
toString(void)348 string BincImapParserFetchAtt::toString(void)
349 {
350 string tmp;
351 if (type == "BODY.PEEK")
352 tmp = "BODY";
353 else
354 tmp = type;
355
356 if (type == "BODY" || type == "BODY.PEEK") {
357 if (hassection) {
358 tmp += "[";
359 tmp += section;
360 if (sectiontext != "") {
361 if (section != "")
362 tmp += ".";
363 tmp += sectiontext;
364
365 if (headerlist.size() != 0) {
366 tmp += " (";
367 if (headerlist.size() == 0) {
368 tmp += "\"\"";
369 } else {
370 for (vector<string>::iterator i = headerlist.begin();
371 i != headerlist.end(); ++i) {
372 if (i != headerlist.begin())
373 tmp += " ";
374 tmp += Binc::toImapString(*i);
375 }
376 }
377 tmp += ")";
378 }
379 }
380 tmp += "]";
381
382 if (offsetstart == 0 && offsetlength == (unsigned int) -1)
383 tmp += " ";
384 else
385 tmp += "<" + Binc::toString(offsetstart) + "> ";
386 }
387 }
388
389 return tmp;
390 }
391
392 //------------------------------------------------------------------------
BincImapParserSearchKey(void)393 BincImapParserSearchKey::BincImapParserSearchKey(void)
394 {
395 type = 0;
396 number = 0;
397 }
398
399 //------------------------------------------------------------------------
getSet(void) const400 const SequenceSet& BincImapParserSearchKey::getSet(void) const
401 {
402 return bset;
403 }
404