Bincimap 2.0.16
Easy Imapping
Loading...
Searching...
No Matches
operator-search.cc
Go to the documentation of this file.
1
7#include <string>
8#include <iostream>
9#include <algorithm>
10
11#include <ctype.h>
12
13#include "convert.h"
14#include "depot.h"
15#include "imapparser.h"
16#include "iodevice.h"
17#include "iofactory.h"
18#include "mailbox.h"
19#include "mime.h"
20#include "operators.h"
21#include "recursivedescent.h"
22#include "session.h"
23
24using namespace ::std;
25using namespace Binc;
26
27//----------------------------------------------------------------------
29 time_t &t, const string &delim)
30{
31 vector<string> parts;
32 split(date, delim, parts);
33 if (parts.size() < 3) return false;
34
35 struct tm mold;
36 memset((char *) &mold, 0, sizeof(struct tm));
37 mold.tm_mday = atoi(parts[0].c_str());
38 mold.tm_year = atoi(parts[2].c_str()) - 1900;
39
40 // accept mixed case months. this is more than the standard
41 // accepts.
42 string month = parts[1];
43 lowercase(month);
44
45 if (month == "jan") mold.tm_mon = 0;
46 else if (month == "feb") mold.tm_mon = 1;
47 else if (month == "mar") mold.tm_mon = 2;
48 else if (month == "apr") mold.tm_mon = 3;
49 else if (month == "may") mold.tm_mon = 4;
50 else if (month == "jun") mold.tm_mon = 5;
51 else if (month == "jul") mold.tm_mon = 6;
52 else if (month == "aug") mold.tm_mon = 7;
53 else if (month == "sep") mold.tm_mon = 8;
54 else if (month == "oct") mold.tm_mon = 9;
55 else if (month == "nov") mold.tm_mon = 10;
56 else if (month == "dec") mold.tm_mon = 11;
57
58 t = mktime(&mold);
59 return true;
60}
61
62//----------------------------------------------------------------------
64 time_t &t)
65{
66 string date = d_in;
67 string::size_type n = date.find(',');
68 if (n != string::npos)
69 date = date.substr(n + 1);
70 trim(date);
71
72 bool result = convertDate(date, t, " ");
73 return result;
74}
75
76//----------------------------------------------------------------------
78{
79}
80
81//----------------------------------------------------------------------
83{
84 init(a);
85}
86
87//----------------------------------------------------------------------
89{
90 return type;
91}
92
93//----------------------------------------------------------------------
95 Message *m, unsigned int seqnr,
96 unsigned int lastmessage,
97 unsigned int lastuid) const
98{
99 HeaderItem hitem;
100 string tmp;
101
102 switch (type) {
103 //--------------------------------------------------------------------
104 case S_ALL:
105 return true;
106 //--------------------------------------------------------------------
107 case S_ANSWERED:
108 return (m->getStdFlags() & Message::F_ANSWERED);
109 //--------------------------------------------------------------------
110 case S_BCC:
111 return m->headerContains("bcc", astring);
112 //--------------------------------------------------------------------
113 case S_BEFORE: {
114 time_t mtime = m->getInternalDate();
115 struct tm *mtime_ = localtime(&mtime);
116 mtime_->tm_sec = 0;
117 mtime_->tm_min = 0;
118 mtime_->tm_hour = 0;
119 mtime_->tm_wday = 0;
120 mtime_->tm_yday = 0;
121 mtime_->tm_isdst = 0;
122 mtime = mktime(mtime_);
123
124 time_t atime;
125 if (!convertDate(date, atime)) {
126 bincWarning << "warning, unable to convert " << date <<
127 " to a time_t" << endl;
128 return false;
129 }
130
131 return mtime < atime;
132 } //--------------------------------------------------------------------
133 case S_BODY:
134 return m->bodyContains(astring);
135 //--------------------------------------------------------------------
136 case S_CC:
137 return m->headerContains("cc", astring);
138 //--------------------------------------------------------------------
139 case S_DELETED:
140 return (m->getStdFlags() & Message::F_DELETED);
141 //--------------------------------------------------------------------
142 case S_FLAGGED:
143 return (m->getStdFlags() & Message::F_FLAGGED);
144 //--------------------------------------------------------------------
145 case S_FROM:
146 return m->headerContains("from", astring);
147 //--------------------------------------------------------------------
148 case S_KEYWORD:
149 // the server does not support keywords
150 return false;
151 //--------------------------------------------------------------------
152 case S_NEW:
153 return (m->getStdFlags() & Message::F_RECENT)
154 && !(m->getStdFlags() & Message::F_SEEN);
155 //--------------------------------------------------------------------
156 case S_OLD:
157 return !(m->getStdFlags() & Message::F_RECENT);
158 //--------------------------------------------------------------------
159 case S_ON: {
160 time_t mtime = m->getInternalDate();
161 struct tm *mtime_ = localtime(&mtime);
162 mtime_->tm_sec = 0;
163 mtime_->tm_min = 0;
164 mtime_->tm_hour = 0;
165 mtime_->tm_wday = 0;
166 mtime_->tm_yday = 0;
167 mtime_->tm_isdst = 0;
168 mtime = mktime(mtime_);
169
170 time_t atime;
171 if (!convertDate(date, atime)) {
172 bincWarning << "warning, unable to convert " << date <<
173 " to a time_t" << endl;
174 return false;
175 }
176
177 return mtime == atime;
178 } //--------------------------------------------------------------------
179 case S_RECENT:
180 return (m->getStdFlags() & Message::F_RECENT);
181 //--------------------------------------------------------------------
182 case S_SEEN:
183 return (m->getStdFlags() & Message::F_SEEN);
184 //--------------------------------------------------------------------
185 case S_SINCE: {
186 time_t mtime = m->getInternalDate();
187 struct tm *mtime_ = localtime(&mtime);
188 mtime_->tm_sec = 0;
189 mtime_->tm_min = 0;
190 mtime_->tm_hour = 0;
191 mtime_->tm_wday = 0;
192 mtime_->tm_yday = 0;
193 mtime_->tm_isdst = 0;
194 mtime = mktime(mtime_);
195
196 time_t atime;
197 if (!convertDate(date, atime)) {
198 bincWarning << "warning, unable to convert " << date <<
199 " to a time_t" << endl;
200 return false;
201 }
202
203 return mtime >= atime;
204 } //--------------------------------------------------------------------
205 case S_SUBJECT:
206 return m->headerContains("subject", astring);
207 //--------------------------------------------------------------------
208 case S_TEXT:
209 return m->textContains(astring);
210 //--------------------------------------------------------------------
211 case S_TO:
212 return m->headerContains("to", astring);
213 //--------------------------------------------------------------------
214 case S_UNANSWERED:
215 return !(m->getStdFlags() & Message::F_ANSWERED);
216 //--------------------------------------------------------------------
217 case S_UNDELETED:
218 return !(m->getStdFlags() & Message::F_DELETED);
219 //--------------------------------------------------------------------
220 case S_UNFLAGGED:
221 return !(m->getStdFlags() & Message::F_FLAGGED);
222 //--------------------------------------------------------------------
223 case S_UNKEYWORD:
224 // the server does not support keywords
225 return true;
226 //--------------------------------------------------------------------
227 case S_UNSEEN:
228 return !(m->getStdFlags() & Message::F_SEEN);
229 //--------------------------------------------------------------------
230 case S_DRAFT:
231 return (m->getStdFlags() & Message::F_DRAFT);
232 //--------------------------------------------------------------------
233 case S_HEADER:
234 return m->headerContains(astring, bstring);
235 //--------------------------------------------------------------------
236 case S_LARGER: {
237 return (m->getSize(true) > number);
238 }
239 //--------------------------------------------------------------------
240 case S_NOT:
241 for (vector<SearchNode>::const_iterator i = children.begin();
242 i != children.end(); ++i)
243 if ((*i).match(mailbox, m, seqnr, lastmessage, lastuid)) return false;
244 return true;
245 //--------------------------------------------------------------------
246 case S_OR:
247 for (vector<SearchNode>::const_iterator i = children.begin();
248 i != children.end(); ++i)
249 if ((*i).match(mailbox, m, seqnr, lastmessage, lastuid)) return true;
250 return false;
251 //--------------------------------------------------------------------
252 case S_SENTBEFORE: {
253 string tmp = m->getHeader("date");
254 if (tmp == "")
255 return false;
256
257 lowercase(tmp);
258
259 time_t mtime;
260 if (!convertDateHeader(tmp, mtime)) return false;
261
262 if (mtime == (time_t) -1) return false;
263
264 time_t atime;
265 if (!convertDate(date, atime)) {
266 bincWarning << "warning, unable to convert " << date <<
267 " to a time_t" << endl;
268 return false;
269 }
270
271 return mtime < atime;
272 } //--------------------------------------------------------------------
273 case S_SENTON: {
274 string tmp = m->getHeader("date");
275 if (tmp == "") return false;
276
277 lowercase(tmp);
278
279 time_t mtime;
280 if (!convertDateHeader(tmp, mtime)) return false;
281
282 if (mtime == (time_t) -1) return false;
283
284 time_t atime;
285 if (!convertDate(date, atime)) {
286 bincWarning << "warning, unable to convert " << date <<
287 " to a time_t" << endl;
288 return false;
289 }
290
291 return mtime == atime;
292 } //--------------------------------------------------------------------
293 case S_SENTSINCE: {
294 string tmp = m->getHeader("date");
295 if (tmp == "") return false;
296
297 lowercase(tmp);
298
299 time_t mtime;
300 if (!convertDateHeader(tmp, mtime)) return false;
301
302 if (mtime == (time_t) -1) return false;
303
304 time_t atime;
305 if (!convertDate(date, atime)) {
306 bincWarning << "warning, unable to convert " << date
307 << " to a time_t" << endl;
308 return false;
309 }
310
311 return mtime >= atime;
312 } //--------------------------------------------------------------------
313 case S_SMALLER:
314 return (m->getSize(true) < number);
315 //--------------------------------------------------------------------
316 case S_UID:
317 if (!bset->isInSet(m->getUID()))
318 if (!(m->getUID() == lastuid && !bset->isLimited())) return false;
319 return true;
320 //--------------------------------------------------------------------
321 case S_UNDRAFT:
322 return !(m->getStdFlags() & Message::F_DRAFT);
323 //--------------------------------------------------------------------
324 case S_SET:
325 if (!bset->isInSet(seqnr))
326 if (!(seqnr == lastmessage && !bset->isLimited())) return false;
327 return true;
328 //--------------------------------------------------------------------
329 case S_AND:
330 for (vector<SearchNode>::const_iterator i = children.begin();
331 i != children.end(); ++i)
332 if (!(*i).match(mailbox, m, seqnr, lastmessage, lastuid)) return false;
333 return true;
334 }
335
336 return false;
337}
338
339//----------------------------------------------------------------------
341{
342 astring = a.astring;
343 bstring = a.bstring;
344 date = a.date;
345 number = a.number;
346 uppercase(astring);
347 uppercase(bstring);
348 uppercase(date);
349
350 if (a.name == "ALL") { type = S_ALL; weight = 1; }
351 else if (a.name == "ANSWERED") { type = S_ANSWERED; weight = 1; }
352 else if (a.name == "BCC") { type = S_BCC; weight = 2; }
353 else if (a.name == "BEFORE") { type = S_BEFORE; weight = 2; }
354 else if (a.name == "BODY") { type = S_BODY; weight = 1; }
355 else if (a.name == "CC") { type = S_CC; weight = 2; }
356 else if (a.name == "DELETED") { type = S_DELETED; weight = 1; }
357 else if (a.name == "FLAGGED") { type = S_FLAGGED; weight = 1; }
358 else if (a.name == "FROM") { type = S_FROM; weight = 2; }
359 else if (a.name == "KEYWORD") { type = S_KEYWORD; weight = 3; }
360 else if (a.name == "NEW") { type = S_NEW; weight = 1; }
361 else if (a.name == "OLD") { type = S_OLD; weight = 1; }
362 else if (a.name == "ON") { type = S_ON; weight = 1; }
363 else if (a.name == "RECENT") { type = S_RECENT; weight = 1; }
364 else if (a.name == "SEEN") { type = S_SEEN; weight = 1; }
365 else if (a.name == "SINCE") { type = S_SINCE; weight = 1; }
366 else if (a.name == "SUBJECT") { type = S_SUBJECT; weight = 2; }
367 else if (a.name == "TEXT") { type = S_TEXT; weight = 4; }
368 else if (a.name == "TO") { type = S_TO; weight = 2; }
369 else if (a.name == "UNANSWERED") { type = S_UNANSWERED; weight = 1; }
370 else if (a.name == "UNDELETED") { type = S_UNDELETED; weight = 1; }
371 else if (a.name == "UNFLAGGED") { type = S_UNFLAGGED; weight = 1; }
372 else if (a.name == "UNKEYWORD") { type = S_UNKEYWORD; weight = 1; }
373 else if (a.name == "UNSEEN") { type = S_UNSEEN; weight = 1; }
374 else if (a.name == "DRAFT") { type = S_DRAFT; weight = 1; }
375 else if (a.name == "HEADER") { type = S_HEADER; weight = 3; }
376 else if (a.name == "LARGER") { type = S_LARGER; weight = 4; }
377 else if (a.name == "NOT") {
378 // ******* NOT
379 type = S_NOT;
380 weight = 1;
381
382 vector<BincImapParserSearchKey>::const_iterator i = a.children.begin();
383 while (i != a.children.end()) {
384 SearchNode b(*i);
385 weight += b.getWeight();
386 children.push_back(b);
387 ++i;
388 }
389
390 } else if (a.name == "OR") {
391 // ******* OR
392 type = S_OR;
393 weight = 0;
394
395 vector<BincImapParserSearchKey>::const_iterator i = a.children.begin();
396 while (i != a.children.end()) {
397 SearchNode b(*i);
398 weight += b.getWeight();
399
400 children.push_back(b);
401 ++i;
402 }
403
404 } else if (a.name == "SENTBEFORE") { type = S_SENTBEFORE; weight = 1; }
405 else if (a.name == "SENTON") { type = S_SENTON; weight = 1; }
406 else if (a.name == "SENTSINCE") { type = S_SENTSINCE; weight = 1; }
407 else if (a.name == "SMALLER") { type = S_SMALLER; weight = 4; }
408 else if (a.name == "UID") {
409 bset = &a.getSet();
410 type = S_UID;
411 weight = 1;
412 } else if (a.name == "UNDRAFT") { type = S_UNDRAFT; weight = 1; }
414 bset = &a.getSet();
415 type = S_SET;
416 weight = 1;
417 } else if (a.type == BincImapParserSearchKey::KEY_AND) {
418 // ******* AND
419 type = S_AND;
420 weight = 0;
421
422 vector<BincImapParserSearchKey>::const_iterator i = a.children.begin();
423 while (i != a.children.end()) {
424 SearchNode b(*i);
425 weight += b.getWeight();
426 children.push_back(b);
427 ++i;
428 }
429 }
430}
431
432//----------------------------------------------------------------------
434{
435 return weight;
436}
437
438//----------------------------------------------------------------------
440{
441 weight = i;
442}
443
444//----------------------------------------------------------------------
446{
447 for (vector<SearchNode>::iterator i = children.begin();
448 i != children.end(); ++i)
449 (*i).order();
450 ::stable_sort(children.begin(), children.end(), compareNodes);
451}
452
453//----------------------------------------------------------------------
455{
456}
457
458//----------------------------------------------------------------------
460{
461}
462
463//----------------------------------------------------------------------
464const string SearchOperator::getName(void) const
465{
466 return "SEARCH";
467}
468
469//----------------------------------------------------------------------
471{
472 return Session::SELECTED;
473}
474
475//------------------------------------------------------------------------
477 Request &command)
478{
479 Session &session = Session::getInstance();
480
481 Mailbox *mailbox = depot.getSelected();
482
483 if (command.getCharSet() != "" && command.getCharSet() != "US-ASCII") {
484 session.setLastError("The " + command.getCharSet()
485 + " charset is not supported");
486 session.setResponseCode("[BADCHARSET (\"US-ASCII\")]");
487 return NO;
488 }
489
490 bincClient << "* SEARCH";
491 bincClient.flush();
492
493 SearchNode s(command.searchkey);
494 s.order();
495
496 const unsigned int maxsqnr = mailbox->getMaxSqnr();
497 const unsigned int maxuid = mailbox->getMaxUid();
498
501 for (; i != mailbox->end(); ++i) {
502 Message &message = *i;
503
504 if (s.match(mailbox, &message, i.getSqnr(), maxsqnr, maxuid)) {
505 bincClient << " "
506 << (command.getUidMode() ? message.getUID() : i.getSqnr());
507 bincClient.flush();
508 }
509
510 message.close();
511 }
512
513 bincClient << endl;
514 return OK;
515}
516
517//------------------------------------------------------------------------
519{
520 Session &session = Session::getInstance();
521
523 if ((res = expectSPACE()) != ACCEPT) {
524 session.setLastError("Expected SPACE");
525 return res;
526 }
527
528 if ((res = expectThisString("CHARSET")) == ACCEPT) {
529 if ((res = expectSPACE()) != ACCEPT) {
530 session.setLastError("Expected SPACE after CHARSET");
531 return res;
532 }
533
534 string charset;
535 if ((res = expectAstring(charset)) != ACCEPT) {
536 session.setLastError("Expected astring after CHARSET SPACE");
537 return res;
538 }
539
540 c_in.setCharSet(charset);
541
542 if ((res = expectSPACE()) != ACCEPT) {
543 session.setLastError("Expected SPACE after CHARSET SPACE astring");
544 return res;
545 }
546 }
547
549 if ((res = expectSearchKey(b)) != ACCEPT) {
550 session.setLastError("Expected search_key");
551 return res;
552 }
553
555 c_in.searchkey.children.push_back(b);
556
557 while (1) {
558 if ((res = expectSPACE()) != ACCEPT)
559 break;
560
562 if ((res = expectSearchKey(c)) != ACCEPT) {
563 session.setLastError("Expected search_key after search_key SPACE");
564 return res;
565 }
566
567 c_in.searchkey.children.push_back(c);
568 }
569
570 if ((res = expectCRLF()) != ACCEPT) {
571 session.setLastError("Expected CRLF after search_key");
572 return res;
573 }
574
575 c_in.setName("SEARCH");
576 return ACCEPT;
577}
578
579//----------------------------------------------------------------------
582{
583 Session &session = Session::getInstance();
585
587 if ((res = expectThisString("ALL")) == ACCEPT) s_in.name = "ALL";
588 else if ((res = expectThisString("ANSWERED")) == ACCEPT) s_in.name = "ANSWERED";
589 else if ((res = expectThisString("BCC")) == ACCEPT) {
590 s_in.name = "BCC";
591 if ((res = expectSPACE()) != ACCEPT) {
592 session.setLastError("Expected SPACE");
593 return res;
594 }
595
596 if ((res = expectAstring(s_in.astring)) != ACCEPT) {
597 session.setLastError("Expected astring");
598 return res;
599 }
600 } else if ((res = expectThisString("BEFORE")) == ACCEPT) {
601 s_in.name = "BEFORE";
602
603 if ((res = expectSPACE()) != ACCEPT) {
604 session.setLastError("Expected SPACE");
605 return res;
606 }
607
608 if ((res = expectDate(s_in.date)) != ACCEPT) {
609 session.setLastError("Expected date");
610 return res;
611 }
612 } else if ((res = expectThisString("BODY")) == ACCEPT) {
613 s_in.name = "BODY";
614 if ((res = expectSPACE()) != ACCEPT) {
615 session.setLastError("Expected SPACE");
616 return res;
617 }
618
619 if ((res = expectAstring(s_in.astring)) != ACCEPT) {
620 session.setLastError("Expected astring");
621 return res;
622 }
623 } else if ((res = expectThisString("CC")) == ACCEPT) {
624 s_in.name = "CC";
625 if ((res = expectSPACE()) != ACCEPT) {
626 session.setLastError("Expected SPACE");
627 return res;
628 }
629
630 if ((res = expectAstring(s_in.astring)) != ACCEPT) {
631 session.setLastError("Expected astring");
632 return res;
633 }
634 } else if ((res = expectThisString("DELETED")) == ACCEPT) s_in.name = "DELETED";
635 else if ((res = expectThisString("FLAGGED")) == ACCEPT) s_in.name = "FLAGGED";
636 else if ((res = expectThisString("FROM")) == ACCEPT) {
637 s_in.name = "FROM";
638 if ((res = expectSPACE()) != ACCEPT) {
639 session.setLastError("Expected SPACE");
640 return res;
641 }
642
643 if ((res = expectAstring(s_in.astring)) != ACCEPT) {
644 session.setLastError("Expected astring");
645 return res;
646 }
647 } else if ((res = expectThisString("KEYWORD")) == ACCEPT) {
648 s_in.name = "KEYWORD";
649 if ((res = expectSPACE()) != ACCEPT) {
650 session.setLastError("Expected SPACE");
651 return res;
652 }
653
654 if ((res = expectAtom(s_in.astring)) != ACCEPT) {
655 session.setLastError("Expected flag_keyword");
656 return res;
657 }
658 } else if ((res = expectThisString("NEW")) == ACCEPT) s_in.name = "NEW";
659 else if ((res = expectThisString("OLD")) == ACCEPT) s_in.name = "OLD";
660 else if ((res = expectThisString("ON")) == ACCEPT) {
661 s_in.name = "ON";
662
663 if ((res = expectSPACE()) != ACCEPT) {
664 session.setLastError("Expected SPACE");
665 return res;
666 }
667
668 if ((res = expectDate(s_in.date)) != ACCEPT) {
669 session.setLastError("Expected date");
670 return res;
671 }
672 } else if ((res = expectThisString("RECENT")) == ACCEPT) s_in.name = "RECENT";
673 else if ((res = expectThisString("SEEN")) == ACCEPT) s_in.name = "SEEN";
674 else if ((res = expectThisString("SINCE")) == ACCEPT) {
675 s_in.name = "SINCE";
676
677 if ((res = expectSPACE()) != ACCEPT) {
678 session.setLastError("Expected SPACE");
679 return res;
680 }
681
682 if ((res = expectDate(s_in.date)) != ACCEPT) {
683 session.setLastError("Expected date");
684 return res;
685 }
686 } else if ((res = expectThisString("SUBJECT")) == ACCEPT) {
687 s_in.name = "SUBJECT";
688 if ((res = expectSPACE()) != ACCEPT) {
689 session.setLastError("Expected SPACE");
690 return res;
691 }
692
693 if ((res = expectAstring(s_in.astring)) != ACCEPT) {
694 session.setLastError("Expected astring");
695 return res;
696 }
697 } else if ((res = expectThisString("TEXT")) == ACCEPT) {
698 s_in.name = "TEXT";
699 if ((res = expectSPACE()) != ACCEPT) {
700 session.setLastError("Expected SPACE");
701 return res;
702 }
703
704 if ((res = expectAstring(s_in.astring)) != ACCEPT) {
705 session.setLastError("Expected astring");
706 return res;
707 }
708 } else if ((res = expectThisString("TO")) == ACCEPT) {
709 s_in.name = "TO";
710 if ((res = expectSPACE()) != ACCEPT) {
711 session.setLastError("Expected SPACE");
712 return res;
713 }
714
715 if ((res = expectAstring(s_in.astring)) != ACCEPT) {
716 session.setLastError("Expected astring");
717 return res;
718 }
719 } else if ((res = expectThisString("UNANSWERED")) == ACCEPT)
720 s_in.name = "UNANSWERED";
721 else if ((res = expectThisString("UNDELETED")) == ACCEPT) s_in.name = "UNDELETED";
722 else if ((res = expectThisString("UNFLAGGED")) == ACCEPT) s_in.name = "UNFLAGGED";
723 else if ((res = expectThisString("UNKEYWORD")) == ACCEPT) {
724 s_in.name = "UNKEYWORD";
725 if ((res = expectSPACE()) != ACCEPT) {
726 session.setLastError("Expected SPACE");
727 return res;
728 }
729
730 if ((res = expectAtom(s_in.astring)) != ACCEPT) {
731 session.setLastError("Expected flag_keyword");
732 return res;
733 }
734 } else if ((res = expectThisString("UNSEEN")) == ACCEPT) s_in.name = "UNSEEN";
735 else if ((res = expectThisString("DRAFT")) == ACCEPT) s_in.name = "DRAFT";
736 else if ((res = expectThisString("HEADER")) == ACCEPT) {
737 s_in.name = "HEADER";
738
739 if ((res = expectSPACE()) != ACCEPT) {
740 session.setLastError("Expected SPACE");
741 return res;
742 }
743
744 if ((res = expectAstring(s_in.astring)) != ACCEPT) {
745 session.setLastError("Expected astring");
746 return res;
747 }
748
749 if ((res = expectSPACE()) != ACCEPT) {
750 session.setLastError("Expected SPACE");
751 return res;
752 }
753
754 if ((res = expectAstring(s_in.bstring)) != ACCEPT) {
755 session.setLastError("Expected astring");
756 return res;
757 }
758 } else if ((res = expectThisString("LARGER")) == ACCEPT) {
759 s_in.name = "LARGER";
760 if ((res = expectSPACE()) != ACCEPT) {
761 session.setLastError("Expected SPACE");
762 return res;
763 }
764
765 if ((res = expectNumber(s_in.number)) != ACCEPT) {
766 session.setLastError("Expected number");
767 return res;
768 }
769 } else if ((res = expectThisString("NOT")) == ACCEPT) {
770 s_in.name = "NOT";
772
773 if ((res = expectSPACE()) != ACCEPT) {
774 session.setLastError("Expected SPACE");
775 return res;
776 }
777
779 if ((res = expectSearchKey(s)) != ACCEPT) {
780 session.setLastError("Expected search_key");
781 return res;
782 }
783 s_in.children.push_back(s);
784 } else if ((res = expectThisString("OR")) == ACCEPT) {
785 s_in.name = "OR";
787
788 if ((res = expectSPACE()) != ACCEPT) {
789 session.setLastError("Expected SPACE");
790 return res;
791 }
792
794 if ((res = expectSearchKey(s)) != ACCEPT) {
795 session.setLastError("Expected search_key");
796 return res;
797 }
798 s_in.children.push_back(s);
799
800 if ((res = expectSPACE()) != ACCEPT) {
801 session.setLastError("Expected SPACE");
802 return res;
803 }
804
806 if ((res = expectSearchKey(t)) != ACCEPT) {
807 session.setLastError("Expected search_key");
808 return res;
809 }
810 s_in.children.push_back(t);
811 } else if ((res = expectThisString("SENTBEFORE")) == ACCEPT) {
812 s_in.name = "SENTBEFORE";
813
814 if ((res = expectSPACE()) != ACCEPT) {
815 session.setLastError("Expected SPACE");
816 return res;
817 }
818
819 if ((res = expectDate(s_in.date)) != ACCEPT) {
820 session.setLastError("Expected date");
821 return res;
822 }
823 } else if ((res = expectThisString("SENTON")) == ACCEPT) {
824 s_in.name = "SENTON";
825
826 if ((res = expectSPACE()) != ACCEPT) {
827 session.setLastError("Expected SPACE");
828 return res;
829 }
830
831 if ((res = expectDate(s_in.date)) != ACCEPT) {
832 session.setLastError("Expected date");
833 return res;
834 }
835
836 } else if ((res = expectThisString("SENTSINCE")) == ACCEPT) {
837 s_in.name = "SENTSINCE";
838
839 if ((res = expectSPACE()) != ACCEPT) {
840 session.setLastError("Expected SPACE");
841 return res;
842 }
843
844 if ((res = expectDate(s_in.date)) != ACCEPT) {
845 session.setLastError("Expected date");
846 return res;
847 }
848 } else if ((res = expectThisString("SMALLER")) == ACCEPT) {
849 s_in.name = "SMALLER";
850 if ((res = expectSPACE()) != ACCEPT) {
851 session.setLastError("Expected SPACE");
852 return res;
853 }
854
855 if ((res = expectNumber(s_in.number)) != ACCEPT) {
856 session.setLastError("Expected number");
857 return res;
858 }
859 } else if ((res = expectThisString("UID")) == ACCEPT) {
860 s_in.name = "UID";
861 if ((res = expectSPACE()) != ACCEPT) {
862 session.setLastError("Expected SPACE");
863 return res;
864 }
865
866 if ((res = expectSet(s_in.bset)) != ACCEPT) {
867 session.setLastError("Expected number");
868 return res;
869 }
870 } else if ((res = expectThisString("UNDRAFT")) == ACCEPT)
871 s_in.name = "UNDRAFT";
872 else if ((res = expectSet(s_in.bset)) == ACCEPT) {
873 s_in.name = "";
875 } else if ((res = expectThisString("(")) == ACCEPT) {
877
878 while (1) {
880 if ((res = expectSearchKey(c)) != ACCEPT) {
881 session.setLastError("Expected search_key");
882 return res;
883 }
884
885 s_in.children.push_back(c);
886
887 if ((res = expectSPACE()) != ACCEPT) break;
888 }
889
890 if ((res = expectThisString(")")) != ACCEPT) {
891 session.setLastError("Expected )");
892 return res;
893 }
894 } else
895 return REJECT;
896
897 return ACCEPT;
898}
std::vector< BincImapParserSearchKey > children
Definition: imapparser.h:79
const SequenceSet & getSet(void) const
Definition: imapparser.cc:376
virtual Mailbox * getSelected(void) const
Definition: depot.cc:183
unsigned int getSqnr() const
Definition: mailbox.cc:85
virtual unsigned int getMaxSqnr(void) const =0
virtual iterator begin(const SequenceSet &bset, unsigned int mod=INCLUDE_EXPUNGED|SQNR_MODE) const =0
virtual iterator end(void) const =0
@ SKIP_EXPUNGED
Definition: mailbox.h:69
virtual unsigned int getMaxUid(void) const =0
The Message class provides an interface for IMAP messages.
Definition: message.h:31
virtual time_t getInternalDate(void) const =0
virtual bool textContains(const std::string &text)=0
virtual void close(void)=0
virtual unsigned int getUID(void) const =0
virtual unsigned int getSize(bool render=false) const =0
virtual bool bodyContains(const std::string &text)=0
virtual const std::string & getHeader(const std::string &header)=0
virtual unsigned char getStdFlags(void) const =0
virtual bool headerContains(const std::string &header, const std::string &text)=0
void setCharSet(const std::string &s_in)
Definition: imapparser.cc:118
void setName(const std::string &s_in)
Definition: imapparser.cc:70
bool getUidMode(void) const
Definition: imapparser.cc:40
const std::string & getCharSet(void) const
Definition: imapparser.cc:125
BincImapParserSearchKey searchkey
Definition: imapparser.h:116
bool match(Mailbox *, Message *, unsigned seqnr, unsigned int lastmessage, unsigned int lastuid) const
static bool convertDate(const std::string &date, time_t &t, const std::string &delim="-")
static bool convertDateHeader(const std::string &d_in, time_t &t)
void init(const BincImapParserSearchKey &a)
virtual ParseResult parse(Request &) const
int getState(void) const
ProcessResult process(Depot &, Request &)
ParseResult expectSearchKey(BincImapParserSearchKey &s_in) const
const std::string getName(void) const
static SequenceSet & all(void)
Definition: imapparser.cc:261
void setLastError(const std::string &error) const
Definition: session.cc:185
void setResponseCode(const std::string &error) const
Definition: session.cc:197
static Session & getInstance(void)
Definition: session.cc:33
Declaration of miscellaneous convertion functions.
Declaration of the common items for parsing IMAP input.
Declaration of the IODevice class.
Declaration of the IOFactory class.
#define bincWarning
Definition: iofactory.h:44
#define bincClient
Definition: iofactory.h:31
Declaration of the Mailbox class (Mailbox is logical container)
Declaration of main mime parser components.
Definition: bincimapd.cc:9
Operator::ParseResult expectNumber(unsigned int &i_in)
Operator::ParseResult expectAstring(std::string &s_in)
Operator::ParseResult expectSPACE(void)
Operator::ParseResult expectThisString(const std::string &s_in)
Operator::ParseResult expectAtom(std::string &s_in)
int atoi(const std::string &s_in)
Definition: convert.h:55
void split(const std::string &s_in, const std::string &delim, std::vector< std::string > &dest, bool skipempty=true)
Definition: convert.h:177
void uppercase(std::string &input)
Definition: convert.h:115
void lowercase(std::string &input)
Definition: convert.h:122
void trim(std::string &s_in, const std::string &chars=" \t\r\n")
Definition: convert.h:137
Operator::ParseResult expectDate(std::string &s_in)
Operator::ParseResult expectSet(SequenceSet &s_in)
Operator::ParseResult expectCRLF(void)
Declaration of all operators.
Declaration of a recursive descent IMAP command parser.