diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch) | |
tree | 5ac38a06f3dde268dc7927dc155896926aaf7012 /kio/misc/ksendbugmail | |
download | tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kio/misc/ksendbugmail')
-rw-r--r-- | kio/misc/ksendbugmail/Makefile.am | 26 | ||||
-rw-r--r-- | kio/misc/ksendbugmail/main.cpp | 142 | ||||
-rw-r--r-- | kio/misc/ksendbugmail/main.h | 20 | ||||
-rw-r--r-- | kio/misc/ksendbugmail/smtp.cpp | 336 | ||||
-rw-r--r-- | kio/misc/ksendbugmail/smtp.h | 144 |
5 files changed, 668 insertions, 0 deletions
diff --git a/kio/misc/ksendbugmail/Makefile.am b/kio/misc/ksendbugmail/Makefile.am new file mode 100644 index 000000000..f2bb2aebc --- /dev/null +++ b/kio/misc/ksendbugmail/Makefile.am @@ -0,0 +1,26 @@ +# This file is part of the KDE libraries +# Copyright (C) 2000 Stephan Kulow <coolo@kde.org> + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. + +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public License +# along with this library; see the file COPYING.LIB. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +bin_PROGRAMS = ksendbugmail +INCLUDES= -I$(srcdir)/.. $(all_includes) + +ksendbugmail_SOURCES = main.cpp smtp.cpp +ksendbugmail_LDFLAGS = $(all_libraries) $(KDE_RPATH) +ksendbugmail_LDADD = ../../libkio.la + +METASOURCES = AUTO diff --git a/kio/misc/ksendbugmail/main.cpp b/kio/misc/ksendbugmail/main.cpp new file mode 100644 index 000000000..0d12f9e93 --- /dev/null +++ b/kio/misc/ksendbugmail/main.cpp @@ -0,0 +1,142 @@ +// $Id$ + +#include <sys/types.h> +#include "main.h" +#include <pwd.h> +#include <stdlib.h> +#include <unistd.h> + +#include <qtextstream.h> + +#include <kapplication.h> +#include <kemailsettings.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kaboutdata.h> +#include <kdebug.h> +#include <kconfig.h> + +#include "smtp.h" + +static KCmdLineOptions options[] = { + { "subject <argument>", I18N_NOOP("Subject line"), 0 }, + { "recipient <argument>", I18N_NOOP("Recipient"), "submit@bugs.kde.org" }, + KCmdLineLastOption +}; + +void BugMailer::slotError(int errornum) { + kdDebug() << "slotError\n"; + QString str, lstr; + + switch(errornum) { + case SMTP::CONNECTERROR: + lstr = i18n("Error connecting to server."); + break; + case SMTP::NOTCONNECTED: + lstr = i18n("Not connected."); + break; + case SMTP::CONNECTTIMEOUT: + lstr = i18n("Connection timed out."); + break; + case SMTP::INTERACTTIMEOUT: + lstr = i18n("Time out waiting for server interaction."); + break; + default: + lstr = sm->getLastLine().stripWhiteSpace(); + lstr = i18n("Server said: \"%1\"").arg(lstr); + } + fputs(lstr.utf8().data(), stdout); + fflush(stdout); + + ::exit(1); +} + +void BugMailer::slotSend() { + kdDebug() << "slotSend\n"; + ::exit(0); +} + +int main(int argc, char **argv) { + + KLocale::setMainCatalogue("kdelibs"); + KAboutData d("ksendbugmail", I18N_NOOP("KSendBugMail"), "1.0", + I18N_NOOP("Sends a short bug report to submit@bugs.kde.org"), + KAboutData::License_GPL, "(c) 2000 Stephan Kulow"); + d.addAuthor("Stephan Kulow", I18N_NOOP("Author"), "coolo@kde.org"); + + KCmdLineArgs::init(argc, argv, &d); + KCmdLineArgs::addCmdLineOptions(options); + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + KApplication a(false, false); + + QCString recipient = args->getOption("recipient"); + if (recipient.isEmpty()) + recipient = "submit@bugs.kde.org"; + else { + if (recipient.at(0) == '\'') { + recipient = recipient.mid(1).left(recipient.length() - 2); + } + } + kdDebug() << "recp \"" << recipient << "\"\n"; + + QCString subject = args->getOption("subject"); + if (subject.isEmpty()) + subject = "(no subject)"; + else { + if (subject.at(0) == '\'') + subject = subject.mid(1).left(subject.length() - 2); + } + QTextIStream input(stdin); + QString text, line; + while (!input.eof()) { + line = input.readLine(); + text += line + "\r\n"; + } + kdDebug() << text << endl; + + KEMailSettings emailConfig; + emailConfig.setProfile(emailConfig.defaultProfileName()); + QString fromaddr = emailConfig.getSetting(KEMailSettings::EmailAddress); + if (!fromaddr.isEmpty()) { + QString name = emailConfig.getSetting(KEMailSettings::RealName); + if (!name.isEmpty()) + fromaddr = name + QString::fromLatin1(" <") + fromaddr + QString::fromLatin1(">"); + } else { + struct passwd *p; + p = getpwuid(getuid()); + fromaddr = QString::fromLatin1(p->pw_name); + fromaddr += "@"; + char buffer[256]; + buffer[0] = '\0'; + if(!gethostname(buffer, sizeof(buffer))) + buffer[sizeof(buffer)-1] = '\0'; + fromaddr += buffer; + } + kdDebug() << "fromaddr \"" << fromaddr << "\"" << endl; + + QString server = emailConfig.getSetting(KEMailSettings::OutServer); + if (server.isEmpty()) + server=QString::fromLatin1("bugs.kde.org"); + + SMTP *sm = new SMTP; + BugMailer bm(sm); + + QObject::connect(sm, SIGNAL(messageSent()), &bm, SLOT(slotSend())); + QObject::connect(sm, SIGNAL(error(int)), &bm, SLOT(slotError(int))); + sm->setServerHost(server); + sm->setPort(25); + sm->setSenderAddress(fromaddr); + sm->setRecipientAddress(recipient); + sm->setMessageSubject(subject); + sm->setMessageHeader(QString::fromLatin1("From: %1\r\nTo: %2\r\n").arg(fromaddr).arg(recipient)); + sm->setMessageBody(text); + sm->sendMessage(); + + int r = a.exec(); + kdDebug() << "execing " << r << endl; + delete sm; + return r; +} + +#include "main.moc" diff --git a/kio/misc/ksendbugmail/main.h b/kio/misc/ksendbugmail/main.h new file mode 100644 index 000000000..cd7de398d --- /dev/null +++ b/kio/misc/ksendbugmail/main.h @@ -0,0 +1,20 @@ +#ifndef BUG_MAILER_H +#define BUG_MAILER_H "$Id$" + +#include <qobject.h> + +class SMTP; + +class BugMailer : public QObject { + Q_OBJECT +public: + BugMailer(SMTP* s) : QObject(0, "mailer"), sm(s) {} + +public slots: + void slotError(int); + void slotSend(); +private: + SMTP *sm; +}; + +#endif diff --git a/kio/misc/ksendbugmail/smtp.cpp b/kio/misc/ksendbugmail/smtp.cpp new file mode 100644 index 000000000..fd8211281 --- /dev/null +++ b/kio/misc/ksendbugmail/smtp.cpp @@ -0,0 +1,336 @@ +/* $Id$ */ + +#include <sys/utsname.h> +#include <unistd.h> +#include <stdio.h> + +#include <kdebug.h> + +#include "smtp.h" + +SMTP::SMTP(char *serverhost, unsigned short int port, int timeout) +{ + struct utsname uts; + + serverHost = serverhost; + hostPort = port; + timeOut = timeout * 1000; + + senderAddress = "user@example.net"; + recipientAddress = "user@example.net"; + messageSubject = "(no subject)"; + messageBody = "empty"; + messageHeader = ""; + + connected = false; + finished = false; + + sock = 0L; + state = INIT; + serverState = NONE; + + uname(&uts); + domainName = uts.nodename; + + + if(domainName.isEmpty()) + domainName = "somemachine.example.net"; + + kdDebug() << "SMTP object created" << endl; + + connect(&connectTimer, SIGNAL(timeout()), this, SLOT(connectTimerTick())); + connect(&timeOutTimer, SIGNAL(timeout()), this, SLOT(connectTimedOut())); + connect(&interactTimer, SIGNAL(timeout()), this, SLOT(interactTimedOut())); + + // some sendmail will give 'duplicate helo' error, quick fix for now + connect(this, SIGNAL(messageSent()), SLOT(closeConnection())); +} + +SMTP::~SMTP() +{ + if(sock){ + delete sock; + sock = 0L; + } + connectTimer.stop(); + timeOutTimer.stop(); +} + +void SMTP::setServerHost(const QString& serverhost) +{ + serverHost = serverhost; +} + +void SMTP::setPort(unsigned short int port) +{ + hostPort = port; +} + +void SMTP::setTimeOut(int timeout) +{ + timeOut = timeout; +} + +void SMTP::setSenderAddress(const QString& sender) +{ + senderAddress = sender; + int index = senderAddress.find('<'); + if (index == -1) + return; + senderAddress = senderAddress.mid(index + 1); + index = senderAddress.find('>'); + if (index != -1) + senderAddress = senderAddress.left(index); + senderAddress = senderAddress.simplifyWhiteSpace(); + while (1) { + index = senderAddress.find(' '); + if (index != -1) + senderAddress = senderAddress.mid(index + 1); // take one side + else + break; + } + index = senderAddress.find('@'); + if (index == -1) + senderAddress.append("@localhost"); // won't go through without a local mail system + +} + +void SMTP::setRecipientAddress(const QString& recipient) +{ + recipientAddress = recipient; +} + +void SMTP::setMessageSubject(const QString& subject) +{ + messageSubject = subject; +} + +void SMTP::setMessageBody(const QString& message) +{ + messageBody = message; +} + +void SMTP::setMessageHeader(const QString &header) +{ + messageHeader = header; +} + +void SMTP::openConnection(void) +{ + kdDebug() << "started connect timer" << endl; + connectTimer.start(100, true); +} + +void SMTP::closeConnection(void) +{ + socketClose(sock); +} + +void SMTP::sendMessage(void) +{ + if(!connected) + connectTimerTick(); + if(state == FINISHED && connected){ + kdDebug() << "state was == FINISHED\n" << endl; + finished = false; + state = IN; + writeString = QString::fromLatin1("helo %1\r\n").arg(domainName); + write(sock->socket(), writeString.ascii(), writeString.length()); + } + if(connected){ + kdDebug() << "enabling read on sock...\n" << endl; + interactTimer.start(timeOut, true); + sock->enableRead(true); + } +} +#include <stdio.h> + +void SMTP::connectTimerTick(void) +{ + connectTimer.stop(); +// timeOutTimer.start(timeOut, true); + + kdDebug() << "connectTimerTick called..." << endl; + + if(sock){ + delete sock; + sock = 0L; + } + + kdDebug() << "connecting to " << serverHost << ":" << hostPort << " ..... " << endl; + sock = new KSocket(serverHost.ascii(), hostPort); + + if(sock == 0L || sock->socket() < 0) { + timeOutTimer.stop(); + kdDebug() << "connection failed!" << endl; + socketClose(sock); + emit error(CONNECTERROR); + connected = false; + return; + } + connected = true; + finished = false; + state = INIT; + serverState = NONE; + + connect(sock, SIGNAL(readEvent(KSocket *)), this, SLOT(socketRead(KSocket *))); + connect(sock, SIGNAL(closeEvent(KSocket *)), this, SLOT(socketClose(KSocket *))); + // sock->enableRead(true); + timeOutTimer.stop(); + kdDebug() << "connected" << endl; +} + +void SMTP::connectTimedOut(void) +{ + timeOutTimer.stop(); + + if(sock) + sock->enableRead(false); + kdDebug() << "socket connection timed out" << endl; + socketClose(sock); + emit error(CONNECTTIMEOUT); +} + +void SMTP::interactTimedOut(void) +{ + interactTimer.stop(); + + if(sock) + sock->enableRead(false); + kdDebug() << "time out waiting for server interaction" << endl; + socketClose(sock); + emit error(INTERACTTIMEOUT); +} + +void SMTP::socketRead(KSocket *socket) +{ + int n, nl; + + kdDebug() << "socketRead() called..." << endl; + interactTimer.stop(); + + if(socket == 0L || socket->socket() < 0) + return; + n = read(socket->socket(), readBuffer, SMTP_READ_BUFFER_SIZE-1 ); + + if(n < 0) + return; + + readBuffer[n] = '\0'; + lineBuffer += readBuffer; + nl = lineBuffer.find('\n'); + if(nl == -1) + return; + lastLine = lineBuffer.left(nl); + lineBuffer = lineBuffer.right(lineBuffer.length() - nl - 1); + processLine(&lastLine); + if(connected) + interactTimer.start(timeOut, true); +} + +void SMTP::socketClose(KSocket *socket) +{ + timeOutTimer.stop(); + disconnect(sock, SIGNAL(readEvent(KSocket *)), this, SLOT(socketRead(KSocket *))); + disconnect(sock, SIGNAL(closeEvent(KSocket *)), this, SLOT(socketClose(KSocket *))); + socket->enableRead(false); + kdDebug() << "connection terminated" << endl; + connected = false; + if(socket){ + delete socket; + socket = 0L; + sock = 0L; + } + emit connectionClosed(); +} + +void SMTP::processLine(QString *line) +{ + int i, stat; + QString tmpstr; + + i = line->find(' '); + tmpstr = line->left(i); + if(i > 3) + kdDebug() << "warning: SMTP status code longer then 3 digits: " << tmpstr << endl; + stat = tmpstr.toInt(); + serverState = (SMTPServerStatus)stat; + lastState = state; + + kdDebug() << "smtp state: [" << stat << "][" << *line << "]" << endl; + + switch(stat){ + case GREET: //220 + state = IN; + writeString = QString::fromLatin1("helo %1\r\n").arg(domainName); + kdDebug() << "out: " << writeString << endl; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case GOODBYE: //221 + state = QUIT; + break; + case SUCCESSFUL://250 + switch(state){ + case IN: + state = READY; + writeString = QString::fromLatin1("mail from: %1\r\n").arg(senderAddress); + kdDebug() << "out: " << writeString << endl; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case READY: + state = SENTFROM; + writeString = QString::fromLatin1("rcpt to: %1\r\n").arg(recipientAddress); + kdDebug() << "out: " << writeString << endl; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case SENTFROM: + state = SENTTO; + writeString = QString::fromLatin1("data\r\n"); + kdDebug() << "out: " << writeString << endl; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case DATA: + state = FINISHED; + finished = true; + sock->enableRead(false); + emit messageSent(); + break; + default: + state = CERROR; + kdDebug() << "smtp error (state error): [" << lastState << "]:[" << stat << "][" << *line << "]" << endl; + socketClose(sock); + emit error(COMMAND); + break; + } + break; + case READYDATA: //354 + state = DATA; + writeString = QString::fromLatin1("Subject: %1\r\n").arg(messageSubject); + writeString += messageHeader; + writeString += "\r\n"; + writeString += messageBody; + writeString += QString::fromLatin1(".\r\n"); + kdDebug() << "out: " << writeString; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case ERROR: //501 + state = CERROR; + kdDebug() << "smtp error (command error): [" << lastState << "]:[" << stat << "][" << *line << "]\n" << endl; + socketClose(sock); + emit error(COMMAND); + break; + case UNKNOWN: //550 + state = CERROR; + kdDebug() << "smtp error (unknown user): [" << lastState << "]:[" << stat << "][" << *line << "]" << endl; + socketClose(sock); + emit error(UNKNOWNUSER); + break; + default: + state = CERROR; + kdDebug() << "unknown response: [" << lastState << "]:[" << stat << "][" << *line << "]" << endl; + socketClose(sock); + emit error(UNKNOWNRESPONSE); + } +} + +#include "smtp.moc" diff --git a/kio/misc/ksendbugmail/smtp.h b/kio/misc/ksendbugmail/smtp.h new file mode 100644 index 000000000..71a464e98 --- /dev/null +++ b/kio/misc/ksendbugmail/smtp.h @@ -0,0 +1,144 @@ +/* $Id$ */ + +#ifndef SMTP_H +#define SMTP_H + +#include <qobject.h> +#include <qtimer.h> +#include <ksock.h> + +/*int SMTPServerStatus[] = { + 220, // greeting from server + 221, // server acknolages goodbye + 250, // command successful + 354, // ready to receive data + 501, // error + 550, // user unknown + 0 // null +}; + +int SMTPClientStatus[] = { + 50, // not logged in yet. + 100, // logged in, got 220 + 150, // sent helo, got 250 + 200, // sent mail from, got 250 + 250, // sent rctp to, got 250 + 300, // data sent, got 354 + 350, // sent data/., got 250 + 400, // send quit, got 221 + 450, // finished, logged out + 0 // null +}; +*/ + +#define DEFAULT_SMTP_PORT 25 +#define DEFAULT_SMTP_SERVER localhost +#define DEFAULT_SMTP_TIMEOUT 60 + +#define SMTP_READ_BUFFER_SIZE 256 + +class SMTP:public QObject +{ + Q_OBJECT +public: + SMTP(char *serverhost = 0, unsigned short int port = 0, int timeout = DEFAULT_SMTP_TIMEOUT); + ~SMTP(); + + void setServerHost(const QString& serverhost); + void setPort(unsigned short int port); + void setTimeOut(int timeout); + + bool isConnected(){return connected;}; + bool isFinished(){return finished;}; + QString getLastLine(){return lastLine;}; + + void setSenderAddress(const QString& sender); + void setRecipientAddress(const QString& recipient); + void setMessageSubject(const QString& subject); + void setMessageBody(const QString& message); + void setMessageHeader(const QString &header); + + typedef enum { + NONE = 0, // null + GREET = 220, // greeting from server + GOODBYE = 221, // server acknolages quit + SUCCESSFUL = 250, // command successful + READYDATA = 354, // server ready to receive data + ERROR = 501, // error + UNKNOWN = 550 // user unknown + }SMTPServerStatus; + + typedef enum { + INIT = 50, // not logged in yet + IN = 100, // logged in, got 220 + READY = 150, // sent HELO, got 250 + SENTFROM = 200, // sent MAIL FROM:, got 250 + SENTTO = 250, // sent RCTP TO:, got 250 + DATA = 300, // DATA sent, got 354 + FINISHED = 350, // finished sending data, got 250 + QUIT = 400, // sent QUIT, got 221 + OUT = 450, // finished, logged out + CERROR = 500 // didn't finish, had error or connection drop + }SMTPClientStatus; + + typedef enum { + NOERROR = 0, + CONNECTERROR = 10, + NOTCONNECTED = 11, + CONNECTTIMEOUT = 15, + INTERACTTIMEOUT = 16, + UNKNOWNRESPONSE = 20, + UNKNOWNUSER = 30, + COMMAND = 40 + }SMTPError; + +protected: + void processLine(QString *line); + +public slots: + void openConnection(); + void sendMessage(); + void closeConnection(); + + void connectTimerTick(); + void connectTimedOut(); + void interactTimedOut(); + + void socketRead(KSocket *); + void socketClose(KSocket *); + +signals: + void connectionClosed(); + void messageSent(); + void error(int); + +private: + QString serverHost; + unsigned short int hostPort; + int timeOut; + + bool connected; + bool finished; + + QString senderAddress; + QString recipientAddress; + QString messageSubject; + QString messageBody, messageHeader; + + SMTPClientStatus state; + SMTPClientStatus lastState; + SMTPServerStatus serverState; + + QString domainName; + + KSocket *sock; + QTimer connectTimer; + QTimer timeOutTimer; + QTimer interactTimer; + + char readBuffer[SMTP_READ_BUFFER_SIZE]; + QString lineBuffer; + QString lastLine; + QString writeString; +}; +#endif |