Diffstat (limited to 'noncore/net/mailit/popclient.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/net/mailit/popclient.cpp | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/noncore/net/mailit/popclient.cpp b/noncore/net/mailit/popclient.cpp new file mode 100644 index 0000000..a406af2 --- a/dev/null +++ b/noncore/net/mailit/popclient.cpp | |||
@@ -0,0 +1,375 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2001 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qt Palmtop Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | #include "popclient.h" | ||
21 | #include "emailhandler.h" | ||
22 | //#define APOP_TEST | ||
23 | |||
24 | extern "C" { | ||
25 | #include "md5.h" | ||
26 | } | ||
27 | |||
28 | #include <qcstring.h> | ||
29 | |||
30 | PopClient::PopClient() | ||
31 | { | ||
32 | socket = new QSocket(this, "popClient"); | ||
33 | connect(socket, SIGNAL(error(int)), this, SLOT(errorHandling(int))); | ||
34 | connect(socket, SIGNAL(connected()), this, SLOT(connectionEstablished())); | ||
35 | connect(socket, SIGNAL(readyRead()), this, SLOT(incomingData())); | ||
36 | |||
37 | stream = new QTextStream(socket); | ||
38 | |||
39 | receiving = FALSE; | ||
40 | synchronize = FALSE; | ||
41 | lastSync = 0; | ||
42 | headerLimit = 0; | ||
43 | preview = FALSE; | ||
44 | } | ||
45 | |||
46 | PopClient::~PopClient() | ||
47 | { | ||
48 | delete socket; | ||
49 | delete stream; | ||
50 | } | ||
51 | |||
52 | void PopClient::newConnection(QString target, int port) | ||
53 | { | ||
54 | if (receiving) { | ||
55 | qWarning("socket in use, connection refused"); | ||
56 | return; | ||
57 | } | ||
58 | |||
59 | status = Init; | ||
60 | |||
61 | socket->connectToHost(target, port); | ||
62 | receiving = TRUE; | ||
63 | selected = FALSE; | ||
64 | |||
65 | emit updateStatus("DNS lookup"); | ||
66 | } | ||
67 | |||
68 | void PopClient::setAccount(QString popUser, QString popPasswd) | ||
69 | { | ||
70 | popUserName = popUser; | ||
71 | popPassword = popPasswd; | ||
72 | } | ||
73 | |||
74 | void PopClient::setSynchronize(int lastCount) | ||
75 | { | ||
76 | synchronize = TRUE; | ||
77 | lastSync = lastCount; | ||
78 | } | ||
79 | |||
80 | void PopClient::removeSynchronize() | ||
81 | { | ||
82 | synchronize = FALSE; | ||
83 | lastSync = 0; | ||
84 | } | ||
85 | |||
86 | void PopClient::headersOnly(bool headers, int limit) | ||
87 | { | ||
88 | preview = headers; | ||
89 | headerLimit = limit; | ||
90 | } | ||
91 | |||
92 | void PopClient::setSelectedMails(MailList *list) | ||
93 | { | ||
94 | selected = TRUE; | ||
95 | mailList = list; | ||
96 | } | ||
97 | |||
98 | void PopClient::connectionEstablished() | ||
99 | { | ||
100 | emit updateStatus("Connection established"); | ||
101 | } | ||
102 | |||
103 | void PopClient::errorHandling(int status) | ||
104 | { | ||
105 | emit updateStatus("Error Occured"); | ||
106 | emit errorOccurred(status); | ||
107 | socket->close(); | ||
108 | receiving = FALSE; | ||
109 | } | ||
110 | |||
111 | void PopClient::incomingData() | ||
112 | { | ||
113 | QString response, temp, temp2, timeStamp; | ||
114 | QString md5Source; | ||
115 | int start, end; | ||
116 | // char *md5Digest; | ||
117 | char md5Digest[16]; | ||
118 | // if ( !socket->canReadLine() ) | ||
119 | // return; | ||
120 | |||
121 | response = socket->readLine(); | ||
122 | qDebug(response +" %d", status); | ||
123 | |||
124 | switch(status) { | ||
125 | //logging in | ||
126 | case Init: { | ||
127 | #ifdef APOP_TEST | ||
128 | start = response.find('<',0); | ||
129 | end = response.find('>', start); | ||
130 | if( start >= 0 && end > start ) | ||
131 | { | ||
132 | timeStamp = response.mid( start , end - start + 1); | ||
133 | md5Source = timeStamp + popPassword; | ||
134 | qDebug( md5Source); | ||
135 | // for( int i = 0; i < md5Source.length(); i++) { | ||
136 | // buff[i] = (QChar)md5Source[i]; | ||
137 | // } | ||
138 | |||
139 | md5_buffer( (char const *)md5Source, md5Source.length(),&md5Digest[0]); | ||
140 | // md5_buffer(char const *buffer, unsigned int len, char *digest); | ||
141 | |||
142 | // MD5_Init( &ctx); | ||
143 | // MD5_Update( &ctx, buff, sizeof( buff) ); | ||
144 | // MD5_Final( md5Digest, &ctx); | ||
145 | // MD5( buff, md5Source.length(), md5Digest); | ||
146 | |||
147 | for(int j =0;j < MD5_DIGEST_LENGTH ;j++) | ||
148 | { | ||
149 | printf("%x", md5Digest[j]); | ||
150 | } | ||
151 | printf("\n"); | ||
152 | // qDebug(md5Digest); | ||
153 | *stream << "APOP " << popUserName << " " << md5Digest << "\r\n"; | ||
154 | // qDebug("%s", stream); | ||
155 | status = Stat; | ||
156 | } | ||
157 | else | ||
158 | #endif | ||
159 | { | ||
160 | timeStamp = ""; | ||
161 | *stream << "USER " << popUserName << "\r\n"; | ||
162 | status = Pass; | ||
163 | } | ||
164 | |||
165 | break; | ||
166 | } | ||
167 | //password shhh. don't tell anyone (implement APOP...) | ||
168 | case Pass: { | ||
169 | *stream << "PASS " << popPassword << "\r\n"; | ||
170 | status = Stat; | ||
171 | break; | ||
172 | } | ||
173 | //ask for number of messages | ||
174 | case Stat: { | ||
175 | if (response[0] == '+') { | ||
176 | *stream << "STAT" << "\r\n"; | ||
177 | status = Mcnt; | ||
178 | } else errorHandling(ErrLoginFailed); | ||
179 | break; | ||
180 | } | ||
181 | //get count of messages, eg "+OK 4 900.." -> int 4 | ||
182 | case Mcnt: { | ||
183 | if (response[0] == '+') { | ||
184 | temp = response.replace(0, 4, ""); | ||
185 | int x = temp.find(" ", 0); | ||
186 | temp.truncate((uint) x); | ||
187 | newMessages = temp.toInt(); | ||
188 | messageCount = 1; | ||
189 | status = List; | ||
190 | |||
191 | if (synchronize) { | ||
192 | //messages deleted from server, reload all | ||
193 | if (newMessages < lastSync) | ||
194 | lastSync = 0; | ||
195 | messageCount = lastSync + 1; | ||
196 | } | ||
197 | |||
198 | if (selected) { | ||
199 | int *ptr = mailList->first(); | ||
200 | if (ptr != 0) { | ||
201 | newMessages++; //to ensure no early jumpout | ||
202 | messageCount = *(mailList->first()); | ||
203 | } else newMessages = 0; | ||
204 | } | ||
205 | } else errorHandling(ErrUnknownResponse); | ||
206 | } | ||
207 | //Read message number x, count upwards to messageCount | ||
208 | case List: { | ||
209 | if (messageCount <= newMessages) { | ||
210 | *stream << "LIST " << messageCount << "\r\n"; | ||
211 | status = Size; | ||
212 | temp2.setNum(newMessages - lastSync); | ||
213 | temp.setNum(messageCount - lastSync); | ||
214 | if (!selected) { | ||
215 | emit updateStatus("Retrieving " + temp + "/" + temp2); | ||
216 | } else { | ||
217 | //completing a previously closed transfer | ||
218 | if ( (messageCount - lastSync) <= 0) { | ||
219 | temp.setNum(messageCount); | ||
220 | emit updateStatus("Previous message " + temp); | ||
221 | } else { | ||
222 | emit updateStatus("Completing message " + temp); | ||
223 | } | ||
224 | } | ||
225 | break; | ||
226 | } else { | ||
227 | emit updateStatus("No new Messages"); | ||
228 | status = Quit; | ||
229 | } | ||
230 | } | ||
231 | //get size of message, eg "500 characters in message.." -> int 500 | ||
232 | case Size: { | ||
233 | if (status != Quit) { //because of idiotic switch | ||
234 | if (response[0] == '+') { | ||
235 | temp = response.replace(0, 4, ""); | ||
236 | int x = temp.find(" ", 0); | ||
237 | temp = temp.right(temp.length() - ((uint) x + 1) ); | ||
238 | mailSize = temp.toInt(); | ||
239 | emit currentMailSize(mailSize); | ||
240 | |||
241 | status = Retr; | ||
242 | } else { | ||
243 | qWarning(response); | ||
244 | errorHandling(ErrUnknownResponse); | ||
245 | } | ||
246 | } | ||
247 | } | ||
248 | //Read message number x, count upwards to messageCount | ||
249 | case Retr: { | ||
250 | if (status != Quit) { | ||
251 | if (!preview || mailSize <= headerLimit) { | ||
252 | *stream << "RETR " << messageCount << "\r\n"; | ||
253 | } else { //only header | ||
254 | *stream << "TOP " << messageCount << " 0\r\n"; | ||
255 | } | ||
256 | messageCount++; | ||
257 | status = Ignore; | ||
258 | break; | ||
259 | } } | ||
260 | case Ignore: { | ||
261 | if (status != Quit) { //because of idiotic switch | ||
262 | if (response[0] == '+') { | ||
263 | message = ""; | ||
264 | status = Read; | ||
265 | if (!socket->canReadLine()) //sync. problems | ||
266 | break; | ||
267 | response = socket->readLine(); | ||
268 | } else errorHandling(ErrUnknownResponse); | ||
269 | } | ||
270 | } | ||
271 | //add all incoming lines to body. When size is reached, send | ||
272 | //message, and go back to read new message | ||
273 | case Read: { | ||
274 | if (status != Quit) { //because of idiotic switch | ||
275 | message += response; | ||
276 | while ( socket->canReadLine() ) { | ||
277 | response = socket->readLine(); | ||
278 | message += response; | ||
279 | } | ||
280 | emit downloadedSize(message.length()); | ||
281 | int x = message.find("\r\n.\r\n",-5); | ||
282 | if (x == -1) { | ||
283 | break; | ||
284 | } else { //message reach entire size | ||
285 | //complete mail downloaded | ||
286 | if ( (!preview ) || ((preview) && (mailSize <= headerLimit)) ){ | ||
287 | emit newMessage(message, messageCount-1, mailSize, TRUE); | ||
288 | } else { //incomplete mail downloaded | ||
289 | emit newMessage(message, messageCount-1, mailSize, FALSE); | ||
290 | } | ||
291 | if (messageCount > newMessages) //that was the last message | ||
292 | status = Quit; | ||
293 | else { //ask for new message | ||
294 | if (selected) { //grab next from queue | ||
295 | int *ptr = mailList->next(); | ||
296 | if (ptr != 0) { | ||
297 | messageCount = *ptr; | ||
298 | *stream << "LIST " << messageCount << "\r\n"; | ||
299 | status = Size; | ||
300 | //completing a previously closed transfer | ||
301 | if ( (messageCount - lastSync) <= 0) { | ||
302 | temp.setNum(messageCount); | ||
303 | emit updateStatus("Previous message " + temp); | ||
304 | } else { | ||
305 | temp.setNum(messageCount - lastSync); | ||
306 | emit updateStatus("Completing message " + temp); | ||
307 | } | ||
308 | break; | ||
309 | } else { | ||
310 | newMessages--; | ||
311 | status = Quit; | ||
312 | } | ||
313 | } else { | ||
314 | *stream << "LIST " << messageCount << "\r\n"; | ||
315 | status = Size; | ||
316 | temp2.setNum(newMessages - lastSync); | ||
317 | temp.setNum(messageCount - lastSync); | ||
318 | emit updateStatus("Retrieving " + temp + "/" + temp2); | ||
319 | |||
320 | break; | ||
321 | } | ||
322 | } | ||
323 | } | ||
324 | if (status != Quit) | ||
325 | break; | ||
326 | } | ||
327 | } | ||
328 | case Quit: { | ||
329 | *stream << "Quit\r\n"; | ||
330 | status = Done; | ||
331 | int newM = newMessages - lastSync; | ||
332 | if (newM > 0) { | ||
333 | temp.setNum(newM); | ||
334 | emit updateStatus(temp + " new messages"); | ||
335 | } else { | ||
336 | emit updateStatus("No new messages"); | ||
337 | } | ||
338 | |||
339 | socket->close(); | ||
340 | receiving = FALSE; | ||
341 | emit mailTransfered(newM); | ||
342 | break; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | } | ||
347 | |||
348 | // if( bAPOPAuthentication ) | ||
349 | // { | ||
350 | // if( m_strTimeStamp.IsEmpty() ) | ||
351 | // { | ||
352 | // SetLastError("Apop error!"); | ||
353 | // return false; | ||
354 | // } | ||
355 | // strMD5Source = m_strTimeStamp+pszPassword; | ||
356 | // strMD5Dst = MD5_GetMD5( (BYTE*)(const char*)strMD5Source , strMD5Source.GetLength() ); | ||
357 | // sprintf(msg , "apop %s %s\r\n" , pszUser , strMD5Dst); | ||
358 | // ret = send(m_sPop3Socket , msg , strlen(msg) , NULL); | ||
359 | // if(ret == SOCKET_ERROR) | ||
360 | // { | ||
361 | // SetLastError("Socket error!"); | ||
362 | // m_bSocketOK = false; | ||
363 | // m_bConnected = false; | ||
364 | // return false; | ||
365 | // } | ||
366 | // if( !GetSocketResult(&strResult , COMMAND_END_FLAG) ) | ||
367 | // return false; | ||
368 | // if( 0 == strResult.Find('-' , 0) ) | ||
369 | // { | ||
370 | // SetLastError("Username or Password error!"); | ||
371 | // return false; | ||
372 | // } | ||
373 | // m_bConnected = true; | ||
374 | |||
375 | // } | ||