pop3: Fixed maintaining fSizes list, and more.

* The list was filled, but never emptied.
* If SyncMessages() was called more than once for the same POP3 instance,
  this could garble the mails retrieved in the second run.
* Maintain the total size of mails in fSizes to be able to report progress
  in more detail.
* Also adapted progress reporting to the argument changes made in MailProtocol
  earlier.
* Minor cleanup.
This commit is contained in:
Axel Dörfler
2015-01-06 15:24:19 +01:00
parent 93608baf60
commit a9de7ece6b
2 changed files with 40 additions and 45 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2007-2012, Haiku, Inc. All rights reserved. * Copyright 2007-2013, Haiku, Inc. All rights reserved.
* Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved. * Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved.
* Copyright 2011, Clemens Zeidler <[email protected]> * Copyright 2011, Clemens Zeidler <[email protected]>
* *
@@ -144,15 +144,16 @@ POP3Protocol::SyncMessages()
_ReadManifest(); _ReadManifest();
SetTotalItems(2); SetTotalItems(2);
ReportProgress(0, 1, B_TRANSLATE("Connect to server" B_UTF8_ELLIPSIS)); ReportProgress(1, 0, B_TRANSLATE("Connect to server" B_UTF8_ELLIPSIS));
status_t error = Connect(); status_t error = Connect();
if (error != B_OK) { if (error != B_OK) {
printf("POP3 could not connect: %s\n", strerror(error));
ResetProgress(); ResetProgress();
return error; return error;
} }
ReportProgress(0, 1, B_TRANSLATE("Getting UniqueIDs" B_UTF8_ELLIPSIS)); ReportProgress(1, 0, B_TRANSLATE("Getting UniqueIDs" B_UTF8_ELLIPSIS));
error = _RetrieveUniqueIDs(); error = _RetrieveUniqueIDs();
if (error < B_OK) { if (error < B_OK) {
@@ -174,6 +175,7 @@ POP3Protocol::SyncMessages()
ResetProgress(); ResetProgress();
SetTotalItems(toDownload.CountStrings()); SetTotalItems(toDownload.CountStrings());
SetTotalItemsSize(fTotalSize);
printf("POP3: Messages to download: %i\n", (int)toDownload.CountStrings()); printf("POP3: Messages to download: %i\n", (int)toDownload.CountStrings());
for (int32 i = 0; i < toDownload.CountStrings(); i++) { for (int32 i = 0; i < toDownload.CountStrings(); i++) {
@@ -230,7 +232,7 @@ POP3Protocol::SyncMessages()
} }
NotifyHeaderFetched(ref, &file); NotifyHeaderFetched(ref, &file);
} }
ReportProgress(0, 1); ReportProgress(1, 0);
if (file.WriteAttr("MAIL:unique_id", B_STRING_TYPE, 0, uid, if (file.WriteAttr("MAIL:unique_id", B_STRING_TYPE, 0, uid,
strlen(uid)) < 0) strlen(uid)) < 0)
@@ -305,7 +307,7 @@ POP3Protocol::FetchBody(const entry_ref& ref)
if (!leaveOnServer) if (!leaveOnServer)
Delete(toRetrieve); Delete(toRetrieve);
ReportProgress(0, 1); ReportProgress(1, 0);
ResetProgress(); ResetProgress();
Disconnect(); Disconnect();
@@ -361,43 +363,31 @@ POP3Protocol::Open(const char* server, int port, int)
if (port != 110) if (port != 110)
errorMessage << ":" << port; errorMessage << ":" << port;
uint32 hostIP = inet_addr(server);
// first see if we can parse it as a numeric address
if (hostIP == 0 || hostIP == ~0UL) {
struct hostent * he = gethostbyname(server);
hostIP = he ? *((uint32*)he->h_addr) : 0;
}
if (hostIP == 0) {
errorMessage << B_TRANSLATE(": Connection refused or host not found");
ShowError(errorMessage.String());
return B_NAME_NOT_FOUND;
}
delete fServerConnection; delete fServerConnection;
fServerConnection = NULL; fServerConnection = NULL;
if (fUseSSL) {
fServerConnection = new(std::nothrow) BSecureSocket(
BNetworkAddress(server, port));
} else {
fServerConnection = new(std::nothrow) BSocket(BNetworkAddress(
server, port));
}
if (fServerConnection == NULL) BNetworkAddress address(server, port);
return B_NO_MEMORY; if (fUseSSL)
if (fServerConnection->InitCheck() != B_OK) fServerConnection = new(std::nothrow) BSecureSocket(address);
return fServerConnection->InitCheck(); else
fServerConnection = new(std::nothrow) BSocket(address);
status_t status = B_NO_MEMORY;
if (fServerConnection != NULL)
status = fServerConnection->InitCheck();
BString line; BString line;
status_t err = ReceiveLine(line); if (status == B_OK) {
ssize_t length = ReceiveLine(line);
if (length < 0)
status = length;
}
if (err < 0) { if (status != B_OK) {
fServerConnection->Disconnect(); fServerConnection->Disconnect();
errorMessage << ": " << strerror(err); errorMessage << ": " << strerror(status);
ShowError(errorMessage.String()); ShowError(errorMessage.String());
return B_ERROR; return status;
} }
if (strncmp(line.String(), "+OK", 3) != 0) { if (strncmp(line.String(), "+OK", 3) != 0) {
@@ -585,7 +575,7 @@ POP3Protocol::Retrieve(int32 message, BPositionIO* to)
BString cmd; BString cmd;
cmd << "RETR " << message + 1 << CRLF; cmd << "RETR " << message + 1 << CRLF;
status_t status = RetrieveInternal(cmd.String(), message, to, true); status_t status = RetrieveInternal(cmd.String(), message, to, true);
ReportProgress(0, 1); ReportProgress(1, 0);
if (status == B_OK) { if (status == B_OK) {
// Check if the actual message size matches the expected one // Check if the actual message size matches the expected one
@@ -624,7 +614,7 @@ POP3Protocol::RetrieveInternal(const char* command, int32 message,
// after the message. Of course, if we get it wrong (or it is a huge // after the message. Of course, if we get it wrong (or it is a huge
// message or has lines starting with escaped periods), it will then switch // message or has lines starting with escaped periods), it will then switch
// back to receiving full buffers until the message is done. // back to receiving full buffers until the message is done.
int amountToReceive = MessageSize (message) + 3; int amountToReceive = MessageSize(message) + 3;
if (amountToReceive >= bufSize || amountToReceive <= 0) if (amountToReceive >= bufSize || amountToReceive <= 0)
amountToReceive = bufSize - 1; amountToReceive = bufSize - 1;
@@ -721,7 +711,7 @@ POP3Protocol::RetrieveInternal(const char* command, int32 message,
if (amountInBuffer > 4) { if (amountInBuffer > 4) {
to->Write(buf, amountInBuffer - 4); to->Write(buf, amountInBuffer - 4);
if (postProgress) if (postProgress)
ReportProgress(amountInBuffer - 4, 0); ReportProgress(0, amountInBuffer - 4);
memmove (buf, buf + amountInBuffer - 4, 4); memmove (buf, buf + amountInBuffer - 4, 4);
amountInBuffer = 4; amountInBuffer = 4;
} }
@@ -729,7 +719,7 @@ POP3Protocol::RetrieveInternal(const char* command, int32 message,
// Dump everything - end of message or flushing the whole buffer. // Dump everything - end of message or flushing the whole buffer.
to->Write(buf, amountInBuffer); to->Write(buf, amountInBuffer);
if (postProgress) if (postProgress)
ReportProgress(amountInBuffer, 0); ReportProgress(0, amountInBuffer);
amountInBuffer = 0; amountInBuffer = 0;
} }
} }
@@ -761,10 +751,10 @@ POP3Protocol::MessageSize(int32 index)
} }
int32 ssize_t
POP3Protocol::ReceiveLine(BString& line) POP3Protocol::ReceiveLine(BString& line)
{ {
int32 len = 0; int32 length = 0;
bool flag = false; bool flag = false;
line = ""; line = "";
@@ -790,16 +780,16 @@ POP3Protocol::ReceiveLine(BString& line)
flag = true; flag = true;
} else { } else {
if (flag) { if (flag) {
len++; length++;
line += '\r'; line += '\r';
flag = false; flag = false;
} }
len++; length++;
line += (char)c; line += (char)c;
} }
} }
return len; return length;
} }
@@ -874,6 +864,8 @@ status_t
POP3Protocol::_RetrieveUniqueIDs() POP3Protocol::_RetrieveUniqueIDs()
{ {
fUniqueIDs.MakeEmpty(); fUniqueIDs.MakeEmpty();
fSizes.MakeEmpty();
fTotalSize = 0;
status_t status = SendCommand("UIDL" CRLF); status_t status = SendCommand("UIDL" CRLF);
if (status != B_OK) if (status != B_OK)
@@ -903,6 +895,8 @@ POP3Protocol::_RetrieveUniqueIDs()
size = atol(&result.String()[index]); size = atol(&result.String()[index]);
else else
size = 0; size = 0;
fTotalSize += size;
fSizes.AddItem((void*)size); fSizes.AddItem((void*)size);
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2007-2012, Haiku Inc. All Rights Reserved. * Copyright 2007-2013, Haiku Inc. All Rights Reserved.
* Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved. * Copyright 2001-2002 Dr. Zoidberg Enterprises. All rights reserved.
* Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de> * Copyright 2011, Clemens Zeidler <haiku@clemens-zeidler.de>
* *
@@ -59,7 +59,7 @@ protected:
int32 message, BPositionIO *writeTo, int32 message, BPositionIO *writeTo,
bool showProgress); bool showProgress);
int32 ReceiveLine(BString &line); ssize_t ReceiveLine(BString& line);
status_t SendCommand(const char* cmd); status_t SendCommand(const char* cmd);
void MD5Digest(unsigned char *in, char *out); void MD5Digest(unsigned char *in, char *out);
@@ -73,6 +73,7 @@ private:
int32 fNumMessages; int32 fNumMessages;
size_t fMailDropSize; size_t fMailDropSize;
BList fSizes; BList fSizes;
off_t fTotalSize;
BMessage fSettings; BMessage fSettings;
BStringList fManifest; BStringList fManifest;