summaryrefslogtreecommitdiffstats
path: root/kio/misc/ksendbugmail
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kio/misc/ksendbugmail
downloadtdelibs-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.am26
-rw-r--r--kio/misc/ksendbugmail/main.cpp142
-rw-r--r--kio/misc/ksendbugmail/main.h20
-rw-r--r--kio/misc/ksendbugmail/smtp.cpp336
-rw-r--r--kio/misc/ksendbugmail/smtp.h144
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