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 &copy)
247   : limited(copy.limited), nullSet(copy.nullSet), internal(copy.internal)
248 {
249 }
250 
251 //------------------------------------------------------------------------
operator =(const SequenceSet & copy)252 SequenceSet &SequenceSet::operator = (const SequenceSet &copy)
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