Source Code (Use browser search to find items of interest.)
Class Index
kmail'KMAcctPop (./kdenetwork/kmail/kmacctpop.h:18)
class KMAcctPop: public KMAccount
{
Q_OBJECT
public:
virtual ~KMAcctPop();
virtual void init(void);
/** Pop user login name */
const QString& login(void) const { return mLogin; }
virtual void setLogin(const QString&);
/** Pop user password */
const QString passwd(void) const;
virtual void setPasswd(const QString&, bool storeInConfig=FALSE);
/** Will the password be stored in the config file ? */
bool storePasswd(void) const { return mStorePasswd; }
virtual void setStorePasswd(bool);
/** Pop host */
const QString& host(void) const { return mHost; }
virtual void setHost(const QString&);
/** Port on pop host */
unsigned short int port(void) { return mPort; }
virtual void setPort(unsigned short int);
/** Pop protocol: shall be 2 or 3 */
short protocol(void) { return mProtocol; }
virtual bool setProtocol(short);
/** Shall messages be left on the server upon retreival (TRUE)
or deleted (FALSE). */
bool leaveOnServer(void) const { return mLeaveOnServer; }
virtual void setLeaveOnServer(bool);
/** Retrieve all messages from server (TRUE) or unread messages only. */
bool retrieveAll(void) const { return mRetrieveAll; }
virtual void setRetrieveAll(bool);
/** Inherited methods. */
virtual const char* type(void) const;
virtual void readConfig(KConfig&);
virtual void writeConfig(KConfig&);
virtual void processNewMail(bool interactive);
protected:
friend class KMAcctMgr;
friend class KMPasswdDialog;
KMAcctPop(KMAcctMgr* owner, const char* accountName);
/** Very primitive en/de-cryption so that the password is not
readable in the config file. But still very easy breakable. */
const QString encryptStr(const QString inStr) const;
const QString decryptStr(const QString inStr) const;
/** Mail processing main worker method. */
virtual bool doProcessNewMail(bool interactive);
/** Authenticate at POP server. Returns TRUE on success and FALSE
on failure. Automatically asks for user/password if necessary. */
virtual bool authenticate(DwPopClient&);
/** Display POP error message. Always returns FALSE to simplify the
code in doProcessNewMail(). */
virtual bool popError(const QString stage, DwPopClient&) const;
QString mLogin, mPasswd;
QString mHost;
unsigned short int mPort;
short mProtocol;
bool mStorePasswd;
bool mLeaveOnServer;
bool mRetrieveAll;
bool gotMsgs;
};
//-----------------------------------------------------------------------------
kmail'KMAcctPop::KMAcctPop() (./kdenetwork/kmail/kmacctpop.cpp:35)
KMAcctPop::KMAcctPop(KMAcctMgr* aOwner, const char* aAccountName):
KMAcctPopInherited(aOwner, aAccountName)
{
initMetaObject();
mStorePasswd = FALSE;
mLeaveOnServer = FALSE;
mRetrieveAll = TRUE;
mProtocol = 3;
mPort = 110;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::~KMAcctPop() (./kdenetwork/kmail/kmacctpop.cpp:49)
KMAcctPop::~KMAcctPop()
{
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::type() (./kdenetwork/kmail/kmacctpop.cpp:55)
const char* KMAcctPop::type(void) const
{
return "pop";
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::init() (./kdenetwork/kmail/kmacctpop.cpp:62)
void KMAcctPop::init(void)
{
mHost = "";
mPort = 110;
mLogin = "";
mPasswd = "";
mProtocol = 3;
mStorePasswd = FALSE;
mLeaveOnServer = FALSE;
mRetrieveAll = TRUE;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::processNewMail() (./kdenetwork/kmail/kmacctpop.cpp:76)
void KMAcctPop::processNewMail(bool interactive)
{
void (*oldHandler)(int);
void (*pipeHandler)(int);
bool hasNewMail;
// Before we do anything else let's ignore the friggin' SIGALRM signal
// This signal somehow interrupts the network functions and messed up
// DwPopClient::Open().
oldHandler = signal(SIGALRM, SIG_IGN);
// Another one of those nice little SIGNALS which default action is to
// abort the app when received. SIGPIPE is send when e.g the client attempts
// to write to a TCP socket when the connection was shutdown by the server.
pipeHandler = signal(SIGPIPE, SIG_IGN);
KMBroadcastStatus::instance()->reset();
KMBroadcastStatus::instance()->setStatusMsg(
i18n( "Preparing transmission..." ));
KMBroadcastStatus::instance()->setStatusProgressEnable( true );
hasNewMail = doProcessNewMail(interactive);
KMBroadcastStatus::instance()->setStatusProgressEnable( false );
KMBroadcastStatus::instance()->reset();
signal(SIGALRM, oldHandler);
signal(SIGPIPE, pipeHandler);
emit finishedCheck(hasNewMail);
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::authenticate() (./kdenetwork/kmail/kmacctpop.cpp:105)
bool KMAcctPop::authenticate(DwPopClient& client)
{
QString passwd;
const char* msg=0;
KMPasswdDialog* dlg;
bool opened = FALSE;
int replyCode;
if(mPasswd.isEmpty() || mLogin.isEmpty())
msg = i18n("Please set Password and Username");
passwd = decryptStr(mPasswd);
while (1)
{
if (msg)
{
dlg = new KMPasswdDialog(NULL, NULL, this, msg,
mLogin, passwd);
if (!dlg->exec()) return FALSE;
delete dlg;
msg = 0;
}
// Some POP servers close the connection upon failed
// user/password. So we close the connection here to
// be sure that everything below runs as we expect it.
if (opened)
{
client.Quit();
client.Close();
}
// Open connection to server
if (client.Open(mHost,mPort) != '+')
return popError("OPEN", client);
opened = TRUE;
kapp->processEvents();
// Send user name
replyCode = client.User((const char*)mLogin);
if (replyCode == '-')
{
msg = i18n("Incorrect Username");
continue;
}
else if (replyCode != '+')
return popError("USER", client);
kapp->processEvents();
// Send password
passwd = decryptStr(mPasswd);
replyCode = client.Pass((const char*)passwd);
if (replyCode == '-')
{
msg = i18n("Incorrect Password");
continue;
}
else if (replyCode != '+')
return popError("PASS", client);
// Ok, we are done
break;
}
KMBroadcastStatus::instance()->setStatusMsg(
i18n( "Transmission completed..." ));
return TRUE;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::doProcessNewMail() (./kdenetwork/kmail/kmacctpop.cpp:179)
bool KMAcctPop::doProcessNewMail(bool /* interactive */)
{
DwPopClient client;
QString passwd;
QString response, status;
int num, size; // number of all msgs / size of all msgs
int id, i; // id of message to read
int tmout;
int dummy;
char dummyStr[32];
// int replyCode; // ReplyCode need from User & Passwd call.
KMMessage* msg;
gotMsgs = FALSE;
bool doFetchMsg;
bool addedOk; //Flag if msg was delivered succesfully
// is everything specified ?
kapp->processEvents();
if (mHost.isEmpty() || mPort==0)
{
KMessageBox::information(0,i18n("Please specify Host, Port and\n"
"destination folder in the settings\n"
"and try again."));
return FALSE;
}
client.SetReceiveTimeout(20);
// Handle connect, user, and password.
if (!authenticate(client)) return FALSE;
if (client.Stat() != '+') return popError("STAT", client);
response = client.SingleLineResponse().c_str();
sscanf(response.data(), "%3s %d %d", dummyStr, &num, &size);
//#warning "*** If client.Last() cannot be found then install the latest kdesupport"
if (client.Last() == '+' && !mRetrieveAll)
{
response = client.SingleLineResponse().c_str();
sscanf(response.data(), "%3s %d", dummyStr, &id);
id++;
}
else id = 1;
// workaround but still is no good. If msgs are too big in size
// we will get a timeout.
client.SetReceiveTimeout(40);
addedOk = true;
// do while there are mesages to take and last msg wass added succesfully
while (id <= num && addedOk)
{
client.SetReceiveTimeout(40);
if (KMBroadcastStatus::instance()->abortRequested()) {
client.Quit();
return gotMsgs;
}
KMBroadcastStatus::instance()->setStatusMsg( i18n("Message ") +
QString("%1/%2").arg(id).arg(num) );
KMBroadcastStatus::instance()->setStatusProgressPercent( (id*100) / num );
kapp->processEvents();
if (client.List(id) != '+')
return popError("LIST", client);
response = client.SingleLineResponse().c_str();
sscanf(response.data(), "%3s %d %d", dummyStr, &dummy, &size);
doFetchMsg = TRUE;
if (size > 4500 && !mRetrieveAll)
{
// If the message is large it is cheaper to first load
// the header to check the status of the message.
// We will have to load the entire message with the RETR
// command below, so we will not fetch the header for
// small messages.
if (client.Top(id,1) != '+')
return popError("TOP", client);
response = client.MultiLineResponse().c_str();
i = response.find("\nStatus:");
if (i<0) i = response.find("\rStatus:");
if (i>=0)
{
status = response.mid(i+8,32).stripWhiteSpace();
if (strnicmp(status,"RO",2)==0 ||
strnicmp(status,"OR",2)==0)
{
doFetchMsg=FALSE;
debug("message %d is old -- no need to download it", id);
}
}
}
if (doFetchMsg)
{
// set timeout depending on size
tmout = size >> 8;
if (tmout < 30) tmout = 30;
client.SetReceiveTimeout(tmout);
if (client.Retr(id) != '+')
return popError("RETR", client);
response = client.MultiLineResponse().c_str();
msg = new KMMessage;
msg->fromString(response,TRUE);
if (mRetrieveAll || msg->status()!=KMMsgStatusOld)
addedOk = processNewMsg(msg); //added ok? Error displayed if not.
else delete msg;
}
// If we should delete from server _and_ we added ok then delete it
if(!mLeaveOnServer && addedOk)
{
if(client.Dele(id) != '+')
return popError("DELE",client);
else
cout << client.SingleLineResponse().c_str();
}
gotMsgs = TRUE;
id++;
}
client.Quit();
return gotMsgs;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::popError() (./kdenetwork/kmail/kmacctpop.cpp:312)
bool KMAcctPop::popError(const QString aStage, DwPopClient& aClient) const
{
QString msg, caption;
kernel->kbp()->idle();
caption = i18n("Pop Mail Error");
// First we assume the worst: A network error
if (aClient.LastFailure() != DwProtocolClient::kFailNoFailure)
{
caption = i18n("Pop Mail Network Error");
msg = aClient.LastFailureStr();
}
// Maybe it is an app specific error
else if (aClient.LastError() != DwProtocolClient::kErrNoError)
{
msg = aClient.LastErrorStr();
}
// Not all commands return multiLineResponses. If they do not
// they return singleLineResponses and the multiLR command return NULL
else
{
msg = aClient.MultiLineResponse().c_str();
if (msg.isEmpty()) msg = aClient.SingleLineResponse().c_str();
if (msg.isEmpty()) msg = i18n("Unknown error");
// Negative response by the server e.g STAT responses '- ....'
}
QString tmp;
tmp = i18n("Account: %1\nIn %2:\n%3")
.arg(name())
.arg(aStage)
.arg(msg);
KMessageBox::information(0, tmp, caption);
//kernel->kbp()->busy();
aClient.Quit();
return gotMsgs;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::readConfig() (./kdenetwork/kmail/kmacctpop.cpp:355)
void KMAcctPop::readConfig(KConfig& config)
{
KMAcctPopInherited::readConfig(config);
mLogin = config.readEntry("login", "");
mStorePasswd = config.readNumEntry("store-passwd", TRUE);
if (mStorePasswd) mPasswd = config.readEntry("passwd");
else mPasswd = "";
mHost = config.readEntry("host");
mPort = config.readNumEntry("port");
mProtocol = config.readNumEntry("protocol");
mLeaveOnServer = config.readNumEntry("leave-on-server", FALSE);
mRetrieveAll = config.readNumEntry("retrieve-all", FALSE);
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::writeConfig() (./kdenetwork/kmail/kmacctpop.cpp:373)
void KMAcctPop::writeConfig(KConfig& config)
{
KMAcctPopInherited::writeConfig(config);
config.writeEntry("login", mLogin);
config.writeEntry("store-passwd", mStorePasswd);
if (mStorePasswd) config.writeEntry("passwd", mPasswd);
else config.writeEntry("passwd", "");
config.writeEntry("host", mHost);
config.writeEntry("port", static_cast<int>(mPort));
config.writeEntry("protocol", mProtocol);
config.writeEntry("leave-on-server", mLeaveOnServer);
config.writeEntry("retrieve-all", mRetrieveAll);
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::encryptStr() (./kdenetwork/kmail/kmacctpop.cpp:391)
const QString KMAcctPop::encryptStr(const QString aStr) const
{
unsigned int i, val;
unsigned int len = aStr.length();
QCString result;
result.resize(len+1);
for (i=0; i<len; i++)
{
val = aStr[i] - ' ';
val = (255-' ') - val;
result[i] = (char)(val + ' ');
}
result[i] = '\0';
return result;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::decryptStr() (./kdenetwork/kmail/kmacctpop.cpp:411)
const QString KMAcctPop::decryptStr(const QString aStr) const
{
return encryptStr(aStr);
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::setStorePasswd() (./kdenetwork/kmail/kmacctpop.cpp:418)
void KMAcctPop::setStorePasswd(bool b)
{
mStorePasswd = b;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::setLeaveOnServer() (./kdenetwork/kmail/kmacctpop.cpp:424)
void KMAcctPop::setLeaveOnServer(bool b)
{
mLeaveOnServer = b;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::setRetrieveAll() (./kdenetwork/kmail/kmacctpop.cpp:431)
void KMAcctPop::setRetrieveAll(bool b)
{
mRetrieveAll = b;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::setLogin() (./kdenetwork/kmail/kmacctpop.cpp:438)
void KMAcctPop::setLogin(const QString& aLogin)
{
mLogin = aLogin;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::passwd() (./kdenetwork/kmail/kmacctpop.cpp:443)
const QString KMAcctPop::passwd(void) const
{
return decryptStr(mPasswd);
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::setPasswd() (./kdenetwork/kmail/kmacctpop.cpp:449)
void KMAcctPop::setPasswd(const QString& aPasswd, bool aStoreInConfig)
{
mPasswd = encryptStr(aPasswd);
mStorePasswd = aStoreInConfig;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::setHost() (./kdenetwork/kmail/kmacctpop.cpp:457)
void KMAcctPop::setHost(const QString& aHost)
{
mHost = aHost;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::setPort() (./kdenetwork/kmail/kmacctpop.cpp:464)
void KMAcctPop::setPort(unsigned short int aPort)
{
mPort = aPort;
}
//-----------------------------------------------------------------------------
kmail'KMAcctPop::setProtocol() (./kdenetwork/kmail/kmacctpop.cpp:471)
bool KMAcctPop::setProtocol(short aProtocol)
{
//assert(aProtocol==2 || aProtocol==3);
if(aProtocol != 2 || aProtocol != 3)
return false;
mProtocol = aProtocol;
return true;
}
//=============================================================================
//
// Class KMPasswdDialog
//
//=============================================================================