Bincimap 2.0.16
Easy Imapping
Loading...
Searching...
No Matches
operator-lsub.cc
Go to the documentation of this file.
1
7#include <algorithm>
8#include <string>
9#include <vector>
10#include <iostream>
11
12#include "convert.h"
13#include "depot.h"
14#include "iodevice.h"
15#include "iofactory.h"
16#include "mailbox.h"
17#include "operators.h"
18#include "recursivedescent.h"
19#include "regmatch.h"
20#include "session.h"
21
22namespace {
23 const int DIR_SELECT = 0x01;
24 const int DIR_MARKED = 0x02;
25 const int DIR_NOINFERIORS = 0x04;
26 const int DIR_LEAF = 0x08;
27}
28
29using namespace ::std;
30using namespace Binc;
31
32//----------------------------------------------------------------------
34{
35}
36
37//----------------------------------------------------------------------
39{
40}
41
42//----------------------------------------------------------------------
43const string LsubOperator::getName(void) const
44{
45 return "LSUB";
46}
47
48//----------------------------------------------------------------------
50{
52}
53
54//------------------------------------------------------------------------
56 Request &command)
57{
58 const char delim = depot.getDelimiter();
59
60 // remove leading or trailing delimiter in wildcard
61 string wildcard = command.getListMailbox();
62 trim(wildcard, string(&delim, 1));
63
64 // convert wildcard to regular expression
65 string regex = toRegex(wildcard, depot.getDelimiter());
66 string wildcardLower = regex;
67 lowercase(wildcardLower);
68 if (wildcardLower.substr(0, 6) == "^inbox")
69 regex = "^[iI][nN][bB][oO][xX]" + regex.substr(6);
70
71 // remove leading or trailing delimiter in reference
72 string ref = command.getMailbox();
73 trim(ref, string(&delim, 1));
74 wildcardLower = ref;
75 lowercase(wildcardLower);
76 if (wildcardLower.substr(0, 5) == "inbox"
77 && (wildcardLower.length() == 5 || wildcardLower[5] == delim))
78 ref = "INBOX" + ref.substr(5);
79
80 // a multimap from mailbox name to flags
81 multimap<string, int> mailboxes;
82
83 // read through all entries in depository.
84 for (Depot::iterator i = depot.begin("."); i != depot.end(); ++i) {
85 const string path = *i;
86 const string mpath = depot.filenameToMailbox(path);
87 Mailbox *m = 0;
88
89 // skip entries that are not identified as mailboxes
90 if ((m = depot.get(mpath)) == 0)
91 continue;
92
93 // convert file name to mailbox name. skip it if there is no
94 // corresponding mailbox name.
95 string tmp = toCanonMailbox(depot.filenameToMailbox(path));
96 trim(tmp, string(&delim, 1));
97 if (tmp == "")
98 continue;
99 else {
100 int flags = DIR_SELECT;
101 multimap<string, int>::iterator mi = mailboxes.find(tmp);
102 if (mi != mailboxes.end()) {
103 flags |= mi->second;
104 mailboxes.erase(mi);
105 }
106 mailboxes.insert(make_pair(tmp, flags));
107 }
108
109 // now add all superior mailboxes with no flags set if not
110 // added already.
111 string::size_type pos = tmp.rfind(delim);
112 while (pos != string::npos) {
113 tmp = tmp.substr(0, pos);
114 trim(tmp, string(&delim, 1));
115
116 multimap<string, int>::iterator mi = mailboxes.find(tmp);
117 if (mi == mailboxes.end()) mailboxes.insert(make_pair(tmp, 0));
118
119 pos = tmp.rfind(delim);
120 }
121 }
122
123 // find leaf nodes O(N^2)
124 multimap<string, int>::iterator i;
125 for (i = mailboxes.begin(); i != mailboxes.end(); ++i) {
126 string mailbox = i->first;
127 mailbox += delim;
128
129 bool leaf = true;
130 multimap<string, int>::const_iterator j;
131 for (j = mailboxes.begin(); j != mailboxes.end(); ++j) {
132 string::size_type pos = j->first.rfind(delim);
133 if (pos == string::npos) continue;
134 string base = j->first.substr(0, pos + 1);
135 if (mailbox == base) {
136 leaf = false;
137 break;
138 }
139 }
140 if (leaf) {
141 unsigned int flags = i->second;
142 flags |= DIR_LEAF;
143 i->second = flags;
144 }
145 }
146
147 depot.loadSubscribes();
148
149 vector<string> subscribed = depot.getSubscriptions();
150 sort(subscribed.begin(), subscribed.end());
151
152 // finally, print all mailbox entries with flags.
153 for (vector<string>::const_iterator j = subscribed.begin();
154 j != subscribed.end(); ++j) {
155 if (ref == "" || (ref.length() <= (*j).length() && ref == (*j).substr(0, ref.length())))
156 if (regexMatch((*j).substr(ref.length()), regex) == 0) {
157 int flags = 0;
158 for (i = mailboxes.begin(); i != mailboxes.end(); ++i) {
159 if (i->first == *j) {
160 flags = i->second;
161 break;
162 }
163 }
164 bincClient << "* LSUB (";
165 string sep = "";
166 bool noselect = false;
167 if (!(flags & DIR_SELECT)) {
168 bincClient << sep << "\\Noselect";
169 sep = " ";
170 noselect = true;
171 }
172 if (!noselect) {
173 if (flags & DIR_MARKED)
174 bincClient << sep << "\\Marked";
175 else
176 bincClient << sep << "\\Unmarked";
177 sep = " ";
178 }
179 if (flags & DIR_LEAF)
180 bincClient << sep << "\\HasNoChildren";
181 else
182 bincClient << sep << "\\HasChildren";
183 sep = " ";
184 if (flags & DIR_NOINFERIORS)
185 bincClient << sep << "\\Noinferiors";
186 bincClient << ") \"" << depot.getDelimiter() << "\" "
187 << toImapString(*j) << endl;
188 }
189 }
190
191 return OK;
192}
193
194//----------------------------------------------------------------------
196{
197 Session &session = Session::getInstance();
198
199 if (c_in.getUidMode())
200 return REJECT;
201
203 if ((res = expectSPACE()) != ACCEPT) {
204 session.setLastError("Expected SPACE after LSUB");
205 return ERROR;
206 }
207
208 string mailbox;
209 if ((res = expectMailbox(mailbox)) != ACCEPT) {
210 session.setLastError("Expected mailbox after LSUB SPACE");
211 return ERROR;
212 }
213
214 c_in.setMailbox(mailbox);
215
216 if ((res = expectSPACE()) != ACCEPT) {
217 session.setLastError("Expected SPACE after LSUB SPACE mailbox");
218 return ERROR;
219 }
220
221 string listmailbox;
222 if ((res = expectListMailbox(listmailbox)) != ACCEPT) {
223 session.setLastError("Expected list_mailbox after LSUB SPACE"
224 " mailbox SPACE");
225 return ERROR;
226 }
227
228 if ((res = expectCRLF()) != ACCEPT) {
229 session.setLastError("Expected CRLF after LSUB SPACE"
230 " mailbox SPACE list_mailbox");
231 return ERROR;
232 }
233
234 c_in.setListMailbox(listmailbox);
235 c_in.setName("LSUB");
236
237 return ACCEPT;
238}
virtual Mailbox * get(const std::string &path) const
Definition: depot.cc:107
virtual iterator begin(const std::string &) const
Definition: depot.cc:537
virtual void loadSubscribes(void)
Definition: depot.cc:354
virtual const iterator & end(void) const
Definition: depot.cc:552
const char getDelimiter(void) const
Definition: depot.cc:163
virtual std::string filenameToMailbox(const std::string &m) const =0
virtual std::vector< std::string > getSubscriptions(void) const
Definition: depot.cc:322
virtual ParseResult parse(Request &) const
int getState(void) const
ProcessResult process(Depot &, Request &)
const std::string getName(void) const
void setMailbox(const std::string &s_in)
Definition: imapparser.cc:155
void setName(const std::string &s_in)
Definition: imapparser.cc:70
const std::string & getListMailbox(void) const
Definition: imapparser.cc:173
const std::string & getMailbox(void) const
Definition: imapparser.cc:161
bool getUidMode(void) const
Definition: imapparser.cc:40
void setListMailbox(const std::string &s_in)
Definition: imapparser.cc:167
void setLastError(const std::string &error) const
Definition: session.cc:185
@ AUTHENTICATED
Definition: session.h:37
static Session & getInstance(void)
Definition: session.cc:33
Declaration of miscellaneous convertion functions.
Declaration of the IODevice class.
Declaration of the IOFactory class.
#define bincClient
Definition: iofactory.h:31
Declaration of the Mailbox class (Mailbox is logical container)
Definition: bincimapd.cc:9
std::string toImapString(const std::string &s_in)
Definition: convert.h:103
Operator::ParseResult expectSPACE(void)
std::string toCanonMailbox(const std::string &s_in)
Definition: convert.h:216
std::string toRegex(const std::string &s_in, char delimiter)
Definition: convert.h:231
int regexMatch(const std::string &data_in, const std::string &p_in)
Operator::ParseResult expectListMailbox(std::string &s_in)
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 expectCRLF(void)
Operator::ParseResult expectMailbox(std::string &s_in)
Declaration of all operators.
Declaration of a recursive descent IMAP command parser.