summaryrefslogtreecommitdiff
path: root/noncore/unsupported/mailit/popclient.cpp
Unidiff
Diffstat (limited to 'noncore/unsupported/mailit/popclient.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/unsupported/mailit/popclient.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/noncore/unsupported/mailit/popclient.cpp b/noncore/unsupported/mailit/popclient.cpp
new file mode 100644
index 0000000..a406af2
--- a/dev/null
+++ b/noncore/unsupported/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
24extern "C" {
25#include "md5.h"
26}
27
28#include <qcstring.h>
29
30PopClient::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
46PopClient::~PopClient()
47{
48 delete socket;
49 delete stream;
50}
51
52void 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
68void PopClient::setAccount(QString popUser, QString popPasswd)
69{
70 popUserName = popUser;
71 popPassword = popPasswd;
72}
73
74void PopClient::setSynchronize(int lastCount)
75{
76 synchronize = TRUE;
77 lastSync = lastCount;
78}
79
80void PopClient::removeSynchronize()
81{
82 synchronize = FALSE;
83 lastSync = 0;
84}
85
86void PopClient::headersOnly(bool headers, int limit)
87{
88 preview = headers;
89 headerLimit = limit;
90}
91
92void PopClient::setSelectedMails(MailList *list)
93{
94 selected = TRUE;
95 mailList = list;
96}
97
98void PopClient::connectionEstablished()
99{
100 emit updateStatus("Connection established");
101}
102
103void PopClient::errorHandling(int status)
104{
105 emit updateStatus("Error Occured");
106 emit errorOccurred(status);
107 socket->close();
108 receiving = FALSE;
109}
110
111void 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// }