From 39808986b1df661b2a02c9e762eb55ff9a2ea618 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sat, 29 Mar 2014 04:12:02 -0500 Subject: Add preliminary support for uploading crash reports to a central server without requiring Bugzilla --- drkonqi/CMakeLists.txt | 4 +- drkonqi/bugdescription.cpp | 75 +++++++++ drkonqi/bugdescription.h | 58 +++++++ drkonqi/bugdescriptiondialog.cpp | 121 ++++++++++++++ drkonqi/bugdescriptiondialog.h | 72 ++++++++ drkonqi/sha1.cc | 344 +++++++++++++++++++++++++++++++++++++++ drkonqi/sha1.h | 72 ++++++++ drkonqi/toplevel.cpp | 213 +++++++++++++++++++++++- drkonqi/toplevel.h | 14 ++ 9 files changed, 966 insertions(+), 7 deletions(-) create mode 100644 drkonqi/bugdescription.cpp create mode 100644 drkonqi/bugdescription.h create mode 100644 drkonqi/bugdescriptiondialog.cpp create mode 100644 drkonqi/bugdescriptiondialog.h create mode 100644 drkonqi/sha1.cc create mode 100644 drkonqi/sha1.h (limited to 'drkonqi') diff --git a/drkonqi/CMakeLists.txt b/drkonqi/CMakeLists.txt index 47866c464..6296ae32b 100644 --- a/drkonqi/CMakeLists.txt +++ b/drkonqi/CMakeLists.txt @@ -31,7 +31,9 @@ link_directories( tde_add_executable( drkonqi AUTOMOC SOURCES krashdcopinterface.skel main.cpp debugger.cpp - krashconf.cpp drbugreport.cpp backtrace.cpp toplevel.cpp + bugdescription.cpp bugdescriptiondialog.cpp + sha1.cc krashconf.cpp drbugreport.cpp + backtrace.cpp toplevel.cpp LINK tdeio-shared DESTINATION ${BIN_INSTALL_DIR} ) diff --git a/drkonqi/bugdescription.cpp b/drkonqi/bugdescription.cpp new file mode 100644 index 000000000..620ae9554 --- /dev/null +++ b/drkonqi/bugdescription.cpp @@ -0,0 +1,75 @@ +/* This file is part of the TDE project + Copyright (C) 2014 Timothy Pearson + + 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. +*/ + +#include +#include +#include + +#include +#include + +#include "bugdescription.moc" +#include "bugdescription.h" + +BugDescription::BugDescription(TQWidget *parent, bool modal, + const TDEAboutData *aboutData) + : BugDescriptionDialog(parent, modal, aboutData) +{ +} + +void BugDescription::setText(const TQString &str) +{ + m_lineedit->setText(str); + m_startstring = str.simplifyWhiteSpace(); +} + +TQString BugDescription::emailAddress() +{ + return m_email->text(); +} + +TQString BugDescription::crashDescription() +{ + return m_lineedit->text(); +} + +void BugDescription::fullReportViewMode( bool enabled ) { + if (enabled) { + m_email->hide(); + m_emailLabel->hide(); + m_descriptionLabel->hide(); + m_lineedit->setReadOnly(true); + showButtonCancel(false); + setCaption(i18n("Crash Report")); + } + else { + m_email->show(); + m_emailLabel->show(); + m_descriptionLabel->show(); + m_lineedit->setReadOnly(false); + showButtonCancel(true); + setCaption(i18n("Bug Description")); + } +} + +void BugDescription::slotOk() +{ + BugDescriptionDialog::slotOk(); +} + diff --git a/drkonqi/bugdescription.h b/drkonqi/bugdescription.h new file mode 100644 index 000000000..04d31d3de --- /dev/null +++ b/drkonqi/bugdescription.h @@ -0,0 +1,58 @@ +/* This file is part of the TDE project + Copyright (C) 2014 Timothy Pearson + + 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. +*/ + +#ifndef BUGDESCRIPTION_H +#define BUGDESCRIPTION_H + +class TDEAboutData; + +#include "bugdescriptiondialog.h" + +class BugDescription : public BugDescriptionDialog +{ + TQ_OBJECT + + public: + /** + * Constructor. + */ + BugDescription(TQWidget *parent = 0, bool modal = true, const TDEAboutData *aboutData = 0); + + public: + /** + * Allows the debugger to set the default text in the editor. + */ + void setText(const TQString &str); + + TQString emailAddress(); + TQString crashDescription(); + + void fullReportViewMode( bool enabled ); + + protected slots: + /** + * OK has been clicked + */ + virtual void slotOk( void ); + + private: + TQString m_startstring; +}; + +#endif diff --git a/drkonqi/bugdescriptiondialog.cpp b/drkonqi/bugdescriptiondialog.cpp new file mode 100644 index 000000000..6d6b2d75a --- /dev/null +++ b/drkonqi/bugdescriptiondialog.cpp @@ -0,0 +1,121 @@ +/* This file is part of the TDE project + Copyright (C) 2014 Timothy Pearson + + 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. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bugdescriptiondialog.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +class BugDescriptionDialogPrivate { + public: +}; + +BugDescriptionDialog::BugDescriptionDialog( TQWidget * parentw, bool modal, const TDEAboutData *aboutData ) + : KDialogBase( Plain, + i18n("Bug Description"), + Ok | Cancel, + Ok, + parentw, + "BugDescriptionDialog", + modal, // modal + true // separator + ) +{ + d = new BugDescriptionDialogPrivate; + + TQWidget * parent = plainPage(); + + TQVBoxLayout * lay = new TQVBoxLayout( parent, 0, spacingHint() ); + + TQGridLayout *glay = new TQGridLayout( lay, 4, 3 ); + glay->setColStretch( 1, 10 ); + glay->setColStretch( 2, 10 ); + + showButtonOK( true ); + + // Email + TQHBoxLayout * hlay = new TQHBoxLayout( lay ); + m_emailLabel = new TQLabel( i18n("Contact Email: "), parent ); + hlay->addWidget( m_emailLabel ); + m_email = new KLineEdit( parent ); + m_email->setFocus(); + m_emailLabel->setBuddy(m_email); + hlay->addWidget( m_email ); + + TQString text = i18n("Enter the text (in English if possible) that you wish to submit with this crash report.\n"); + m_descriptionLabel = new TQLabel( parent, "label" ); + + m_descriptionLabel->setText( text ); + lay->addWidget( m_descriptionLabel ); + + // The multiline-edit + m_lineedit = new TQMultiLineEdit( parent, TQMULTILINEEDIT_OBJECT_NAME_STRING ); + m_lineedit->setMinimumHeight( 180 ); // make it big + m_lineedit->setWordWrap(TQMultiLineEdit::WidgetWidth); + lay->addWidget( m_lineedit, 10 /*stretch*/ ); +} + +BugDescriptionDialog::~BugDescriptionDialog() +{ + delete d; +} + +void BugDescriptionDialog::slotOk( void ) +{ + accept(); +} + +void BugDescriptionDialog::slotCancel() +{ + KDialogBase::slotCancel(); +} + +void BugDescriptionDialog::virtual_hook( int id, void* data ) +{ KDialogBase::virtual_hook( id, data ); } + +#include "bugdescriptiondialog.moc" diff --git a/drkonqi/bugdescriptiondialog.h b/drkonqi/bugdescriptiondialog.h new file mode 100644 index 000000000..b09ec93fc --- /dev/null +++ b/drkonqi/bugdescriptiondialog.h @@ -0,0 +1,72 @@ +/* This file is part of the TDE project + Copyright (C) 2014 Timothy Pearson + + 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. +*/ +#ifndef _BUGDESCRIPTIONDIALOG_H__ +#define _BUGDESCRIPTIONDIALOG_H__ + +#include + +class TQMultiLineEdit; +class TQLineEdit; +class TQHButtonGroup; +class TDEProcess; +class TDEAboutData; +class BugDescriptionDialogPrivate; + +class TDEUI_EXPORT BugDescriptionDialog : public KDialogBase +{ + TQ_OBJECT + + public: + /** + * Creates a bug-report dialog. + * Note that you shouldn't have to do this manually, + * since KHelpMenu takes care of the menu item + * for "Report Bug..." and of creating a BugDescriptionDialog dialog. + */ + BugDescriptionDialog( TQWidget * parent = 0L, bool modal=true, const TDEAboutData *aboutData = 0L ); + /** + * Destructor + */ + virtual ~BugDescriptionDialog(); + + protected slots: + /** + * OK has been clicked + */ + virtual void slotOk( void ); + /** + * Cancel has been clicked + */ + virtual void slotCancel(); + + protected: + TQLabel * m_emailLabel; + TQLabel * m_descriptionLabel; + TQMultiLineEdit * m_lineedit; + TQLineEdit * m_email; + + protected: + virtual void virtual_hook( int id, void* data ); + + private: + BugDescriptionDialogPrivate *d; +}; + +#endif + diff --git a/drkonqi/sha1.cc b/drkonqi/sha1.cc new file mode 100644 index 000000000..86dd30a99 --- /dev/null +++ b/drkonqi/sha1.cc @@ -0,0 +1,344 @@ +/* This file is part of the KDE project + Copyright (C) 2001 George Staikos + Based heavily on SHA1 code from GPG 1.0.3 (C) 1998 FSF + + 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. +*/ + +#include + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDINT_H +#include /* For uintXX_t on OSX */ +#endif +#ifdef HAVE_SYS_BITYPES_H +#include /* For uintXX_t on Tru64 */ +#endif +#ifdef HAVE_STDINT_H +#include +#endif + +#include "sha1.h" +#include + +// FIXME: this can be optimized to one instruction on most cpus. +#define rol(x,y) ((x << y) | (x >> (32-y))) + + +#define K1 0x5a827999L +#define K2 0x6ed9eba1L +#define K3 0x8f1bbcdcL +#define K4 0xca62c1d6L +#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) +#define F2(x,y,z) ( x ^ y ^ z ) +#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) +#define F4(x,y,z) ( x ^ y ^ z ) + +#define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] \ + ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \ + , (x[i&0x0f] = (tm << 1) | (tm >> 31))) + +#define R(a,b,c,d,e,f,k,m) do { e += rol(a, 5) \ + + f(b, c, d) \ + + k \ + + m; \ + b = rol(b, 30); \ + } while(0) + + +SHA1::SHA1() { + _hashlen = 160; + _init = false; + reset(); +} + + +int SHA1::reset() { + _h0 = 0x67452301; + _h1 = 0xefcdab89; + _h2 = 0x98badcfe; + _h3 = 0x10325476; + _h4 = 0xc3d2e1f0; + _nblocks = 0; + _count = 0; + memset(_buf, 0, 56); // clear the buffer + + _init = true; + return 0; +} + + +int SHA1::size() const { + return _hashlen; +} + + +SHA1::~SHA1() { + +} + + +void SHA1::transform(void *data) { + unsigned int a, b, c, d, e, tm; + unsigned int x[16]; + unsigned char *_data = (unsigned char *)data; + + a = _h0; + b = _h1; + c = _h2; + d = _h3; + e = _h4; + +#ifdef WORDS_BIGENDIAN + memcpy(x, _data, 64); +#else + int i; + unsigned char *p2; + for (i = 0, p2 = (unsigned char *)x; + i < 16; i++, p2 += 4) { + p2[3] = *_data++; + p2[2] = *_data++; + p2[1] = *_data++; + p2[0] = *_data++; + } +#endif + + R(a, b, c, d, e, F1, K1, x[ 0]); + R(e, a, b, c, d, F1, K1, x[ 1]); + R(d, e, a, b, c, F1, K1, x[ 2]); + R(c, d, e, a, b, F1, K1, x[ 3]); + R(b, c, d, e, a, F1, K1, x[ 4]); + R(a, b, c, d, e, F1, K1, x[ 5]); + R(e, a, b, c, d, F1, K1, x[ 6]); + R(d, e, a, b, c, F1, K1, x[ 7]); + R(c, d, e, a, b, F1, K1, x[ 8]); + R(b, c, d, e, a, F1, K1, x[ 9]); + R(a, b, c, d, e, F1, K1, x[10]); + R(e, a, b, c, d, F1, K1, x[11]); + R(d, e, a, b, c, F1, K1, x[12]); + R(c, d, e, a, b, F1, K1, x[13]); + R(b, c, d, e, a, F1, K1, x[14]); + R(a, b, c, d, e, F1, K1, x[15]); + R(e, a, b, c, d, F1, K1, M(16)); + R(d, e, a, b, c, F1, K1, M(17)); + R(c, d, e, a, b, F1, K1, M(18)); + R(b, c, d, e, a, F1, K1, M(19)); + R(a, b, c, d, e, F2, K2, M(20)); + R(e, a, b, c, d, F2, K2, M(21)); + R(d, e, a, b, c, F2, K2, M(22)); + R(c, d, e, a, b, F2, K2, M(23)); + R(b, c, d, e, a, F2, K2, M(24)); + R(a, b, c, d, e, F2, K2, M(25)); + R(e, a, b, c, d, F2, K2, M(26)); + R(d, e, a, b, c, F2, K2, M(27)); + R(c, d, e, a, b, F2, K2, M(28)); + R(b, c, d, e, a, F2, K2, M(29)); + R(a, b, c, d, e, F2, K2, M(30)); + R(e, a, b, c, d, F2, K2, M(31)); + R(d, e, a, b, c, F2, K2, M(32)); + R(c, d, e, a, b, F2, K2, M(33)); + R(b, c, d, e, a, F2, K2, M(34)); + R(a, b, c, d, e, F2, K2, M(35)); + R(e, a, b, c, d, F2, K2, M(36)); + R(d, e, a, b, c, F2, K2, M(37)); + R(c, d, e, a, b, F2, K2, M(38)); + R(b, c, d, e, a, F2, K2, M(39)); + R(a, b, c, d, e, F3, K3, M(40)); + R(e, a, b, c, d, F3, K3, M(41)); + R(d, e, a, b, c, F3, K3, M(42)); + R(c, d, e, a, b, F3, K3, M(43)); + R(b, c, d, e, a, F3, K3, M(44)); + R(a, b, c, d, e, F3, K3, M(45)); + R(e, a, b, c, d, F3, K3, M(46)); + R(d, e, a, b, c, F3, K3, M(47)); + R(c, d, e, a, b, F3, K3, M(48)); + R(b, c, d, e, a, F3, K3, M(49)); + R(a, b, c, d, e, F3, K3, M(50)); + R(e, a, b, c, d, F3, K3, M(51)); + R(d, e, a, b, c, F3, K3, M(52)); + R(c, d, e, a, b, F3, K3, M(53)); + R(b, c, d, e, a, F3, K3, M(54)); + R(a, b, c, d, e, F3, K3, M(55)); + R(e, a, b, c, d, F3, K3, M(56)); + R(d, e, a, b, c, F3, K3, M(57)); + R(c, d, e, a, b, F3, K3, M(58)); + R(b, c, d, e, a, F3, K3, M(59)); + R(a, b, c, d, e, F4, K4, M(60)); + R(e, a, b, c, d, F4, K4, M(61)); + R(d, e, a, b, c, F4, K4, M(62)); + R(c, d, e, a, b, F4, K4, M(63)); + R(b, c, d, e, a, F4, K4, M(64)); + R(a, b, c, d, e, F4, K4, M(65)); + R(e, a, b, c, d, F4, K4, M(66)); + R(d, e, a, b, c, F4, K4, M(67)); + R(c, d, e, a, b, F4, K4, M(68)); + R(b, c, d, e, a, F4, K4, M(69)); + R(a, b, c, d, e, F4, K4, M(70)); + R(e, a, b, c, d, F4, K4, M(71)); + R(d, e, a, b, c, F4, K4, M(72)); + R(c, d, e, a, b, F4, K4, M(73)); + R(b, c, d, e, a, F4, K4, M(74)); + R(a, b, c, d, e, F4, K4, M(75)); + R(e, a, b, c, d, F4, K4, M(76)); + R(d, e, a, b, c, F4, K4, M(77)); + R(c, d, e, a, b, F4, K4, M(78)); + R(b, c, d, e, a, F4, K4, M(79)); + + _h0 += a; + _h1 += b; + _h2 += c; + _h3 += d; + _h4 += e; + +} + + +bool SHA1::readyToGo() const { + return _init; +} + + +int SHA1::process(const void *block, int len) { + if (!_init) { + return -1; + } + + unsigned char *_block = (unsigned char *)block; + + int cnt = 0; + // Flush the buffer before proceeding + if (_count == 64) { + transform(_buf); + _count = 0; + _nblocks++; + } + + if (!_block) { + return 0; + } + + if (_count) { + for (; len && _count < 64; len--, cnt++) { + _buf[_count++] = *_block++; + } + process(0, 0); // flush the buffer if necessary + if (!len) { + return cnt; + } + } + + while (len >= 64) { + transform(_block); + _count = 0; + _nblocks++; + len -= 64; + cnt += 64; + _block += 64; + } + + for (; len && _count < 64; len--, cnt++) { + _buf[_count++] = *_block++; + } + + return cnt; +} + + +const unsigned char *SHA1::hash() { + unsigned int t, msb, lsb; + unsigned char *p; + + + if (!_init) { + return (unsigned char *)_buf; + } + + process(0, 0); + + msb = 0; + t = _nblocks; + + if ((lsb = t << 6) < t) { + msb++; + } + + msb += t >> 26; + t = lsb; + + if ((lsb = t + _count) < t) { + msb++; + } + + t = lsb; + + if ((lsb = t << 3) < t) { + msb++; + } + + msb += t >> 29; + + _buf[_count++] = 0x80; + + if (_count < 56) { + while (_count < 56) { + _buf[_count++] = 0; + } + } else { + while (_count < 64) { + _buf[_count++] = 0; + } + process(0, 0); + memset(_buf, 0, 56); + } + + _buf[56] = msb >> 24; + _buf[57] = msb >> 16; + _buf[58] = msb >> 8; + _buf[59] = msb; + _buf[60] = lsb >> 24; + _buf[61] = lsb >> 16; + _buf[62] = lsb >> 8; + _buf[63] = lsb; + + transform(_buf); + + p = _buf; + +#ifdef WORDS_BIGENDIAN +#define X( a ) do { *( uint32_t * )p = _h##a; p += 4; } while ( 0 ) +#else +#define X(a) do { *p++ = _h##a >> 24; *p++ = _h##a >> 16; \ + *p++ = _h##a >> 8; *p++ = _h##a; } while (0) +#endif + + X(0); + X(1); + X(2); + X(3); + X(4); + +#undef X + + _init = false; + + return (unsigned char *)_buf; +} + + + + diff --git a/drkonqi/sha1.h b/drkonqi/sha1.h new file mode 100644 index 000000000..7923aa31f --- /dev/null +++ b/drkonqi/sha1.h @@ -0,0 +1,72 @@ +/* This file is part of the KDE project + Copyright (C) 2001 George Staikos + Based heavily on SHA1 code from GPG 1.0.3 (C) 1998 FSF + + 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. +*/ + + +#ifndef __sha1__ko__h +#define __sha1__ko__h + + +/* @internal + */ +class SHA1 { + public: + SHA1(); + virtual ~SHA1(); + + /* + * The number of bits in the hash generated. + */ + virtual int size() const; + + /* + * True if all settings are good and we are ready to hash. + */ + virtual bool readyToGo() const; + + /* + * Process a block of data for the hash function. + */ + virtual int process(const void *block, int len); + + /* + * Return the digest as a 20 byte array reference. + * Calling this makes readyToGo() == false. + */ + virtual const unsigned char *hash(); + + /* + * Reset the digest so a new one can be calculated. + */ + virtual int reset(); + + protected: + int _hashlen; + bool _init; + + long _h0, _h1, _h2, _h3, _h4; + long _nblocks; + int _count; + unsigned char _buf[64]; + void transform(void *data); +}; + + +#endif + diff --git a/drkonqi/toplevel.cpp b/drkonqi/toplevel.cpp index 3368f6dcf..6903ad4ff 100644 --- a/drkonqi/toplevel.cpp +++ b/drkonqi/toplevel.cpp @@ -42,8 +42,10 @@ #include "backtrace.h" #include "drbugreport.h" +#include "bugdescription.h" #include "debugger.h" #include "krashconf.h" +#include "sha1.h" #include "toplevel.h" #include "toplevel.moc" @@ -57,9 +59,10 @@ Toplevel :: Toplevel(KrashConfig *krashconf, TQWidget *parent, const char *name) true, // modal false, // no separator i18n("&Bug report"), - i18n("&Debugger") + i18n("&Debugger"), + i18n("&Report Crash") ), - m_krashconf(krashconf), m_bugreport(0) + m_krashconf(krashconf), m_bugreport(0), m_bugdescription(0) { TQHBox *page = addHBoxPage(i18n("&General")); page->setSpacing(20); @@ -82,7 +85,7 @@ Toplevel :: Toplevel(KrashConfig *krashconf, TQWidget *parent, const char *name) showButton( User1, m_krashconf->showBugReport() ); showButton( User2, m_krashconf->showDebugger() ); - showButton( User3, false ); + showButton( User3, true ); connect(this, TQT_SIGNAL(closeClicked()), TQT_SLOT(accept())); connect(m_krashconf, TQT_SIGNAL(newDebuggingApplication(const TQString&)), TQT_SLOT(slotNewDebuggingApp(const TQString&))); @@ -156,8 +159,7 @@ void Toplevel :: slotUser1() // generate the backtrace BackTrace *backtrace = new BackTrace(m_krashconf, TQT_TQOBJECT(this)); connect(backtrace, TQT_SIGNAL(someError()), TQT_SLOT(slotBacktraceSomeError())); - connect(backtrace, TQT_SIGNAL(done(const TQString &)), - TQT_SLOT(slotBacktraceDone(const TQString &))); + connect(backtrace, TQT_SIGNAL(done(const TQString &)), TQT_SLOT(slotBacktraceDone(const TQString &))); backtrace->start(); @@ -190,7 +192,16 @@ void Toplevel :: slotNewDebuggingApp(const TQString& launchName) void Toplevel :: slotUser3() { - m_krashconf->acceptDebuggingApp(); + TQApplication::setOverrideCursor ( tqwaitCursor ); + + // generate the backtrace + BackTrace *backtrace = new BackTrace(m_krashconf, TQT_TQOBJECT(this)); + connect(backtrace, TQT_SIGNAL(someError()), TQT_SLOT(slotSendReportBacktraceSomeError())); + connect(backtrace, TQT_SIGNAL(done(const TQString &)), TQT_SLOT(slotSendReportBacktraceDone(const TQString &))); + + backtrace->start(); + + return; } void Toplevel :: slotBacktraceDone(const TQString &str) @@ -220,3 +231,193 @@ void Toplevel :: slotBacktraceSomeError() m_bugreport = 0; } +void Toplevel::slotSendReportBacktraceSomeError() +{ + TQApplication::restoreOverrideCursor(); + + KMessageBox::sorry(0, i18n("It was not possible to generate a backtrace."), i18n("Backtrace Not Possible")); + + delete m_bugdescription; + m_bugdescription = 0; +} + +void Toplevel::slotSendReportBacktraceDone(const TQString &str) +{ + int i = KMessageBox::No; + if ( m_krashconf->pid() != 0 ) { + i = KMessageBox::warningYesNoCancel + (0, + i18n("

Do you want to include a " + "description of what you were doing " + "when this application crashed? This " + "would help the " + "developers to figure out what went " + "wrong.

\n"), + i18n("Include Description"),i18n("Add Description"),i18n("Just Report the Crash")); + } + + if (i == KMessageBox::Cancel) { + TQApplication::restoreOverrideCursor(); + + return; + } + + m_bugdescription = new BugDescription(0, true, m_krashconf->aboutData()); + + if (i == KMessageBox::Yes) { + // Get description + // Also get Email address if desired + // Possibly reduce hash difficulty if Email address provided? + // BugDescription + if (m_bugdescription->exec() == TQDialog::Rejected) { + delete m_bugdescription; + m_bugdescription = 0; + + return; + } + } + + // Generate automatic crash description + TQString autoCrashDescription = m_krashconf->errorDescriptionText(); + m_krashconf->expandString(autoCrashDescription, false); + + // Generate full crash report + TQString backtraceSubmission = str; + backtraceSubmission.append("\n==== (tdebugreport) automatic crash description ====\n"); + backtraceSubmission.append(TQString("%1\n").arg(autoCrashDescription)); + if (m_bugdescription->emailAddress().contains("@") && m_bugdescription->emailAddress().contains(".")) { + backtraceSubmission.append("\n==== (tdebugreport) reporting Email address ====\n"); + backtraceSubmission.append(TQString("%1\n").arg(m_bugdescription->emailAddress())); + } + if (m_bugdescription->crashDescription() != "") { + backtraceSubmission.append("\n==== (tdebugreport) user-generated crash description ====\n"); + backtraceSubmission.append(TQString("%1\n").arg(m_bugdescription->crashDescription())); + } + + // Calculate proof-of-work hash + SHA1 sha; + TQByteArray hash(sha.size() / 8); + hash.fill(255); + + backtraceSubmission.append("\n==== (tdebugreport) proof of work ====\n"); + int proofOfWorkPos = backtraceSubmission.length(); + backtraceSubmission.append(TQUuid::createUuid().toString()); + TQCString backtraceSubmissionData(backtraceSubmission.ascii()); + + while ((hash[0] != 0) || ((hash[1] & 0xfc) != 0)) { // First 14 bits of the SHA1 hash must be zero + TQCString proofOfWork(TQUuid::createUuid().toString().ascii()); + memcpy(backtraceSubmissionData.data() + proofOfWorkPos, proofOfWork.data(), proofOfWork.size()); + sha.reset(); + sha.process(backtraceSubmissionData, backtraceSubmissionData.length()); + memcpy(hash.data(), sha.hash(), hash.size()); + } + + TQApplication::restoreOverrideCursor(); + + i = KMessageBox::Yes; + while (i == KMessageBox::Yes) { + i = KMessageBox::warningYesNoCancel + (0, + i18n("

The crash report is ready. Do you want to send it now?

\n"), + i18n("Ready to Send"),i18n("View Report"),i18n("Send Report")); + + if (i == KMessageBox::Cancel) { + delete m_bugdescription; + m_bugdescription = 0; + + return; + } + + if (i == KMessageBox::Yes) { + BugDescription fullReport(0, true, NULL); + fullReport.fullReportViewMode(true); + fullReport.setText(TQString(backtraceSubmissionData.data())); + fullReport.showMaximized(); + fullReport.exec(); + } + } + + postCrashDataToServer(backtraceSubmissionData); + + delete m_bugdescription; + m_bugdescription = 0; +} + +int Toplevel::postCrashDataToServer(TQByteArray data) { + serverResponse = ""; + TQCString formDataBoundary = "-----------------------------------DrKonqiCrashReporterBoundary"; + + TQCString postData; + postData += "--"; + postData += formDataBoundary; + postData += "\r\n"; + postData += "Content-Disposition: form-data; name=\"crashreport\"; filename=\"crashreport.txt\"\r\n"; + postData += "Content-Type: application/octet-stream\r\n"; + postData += "Content-Transfer-Encoding: binary\r\n\r\n"; + postData += data; + postData += "--"; + postData += formDataBoundary; + postData += "--"; + + KURL url("https://crashreport.trinitydesktop.org/"); +// TDEIO::TransferJob* job = TDEIO::http_post(url, postData, false); + TDEIO::TransferJob* job = TDEIO::http_post(url, postData, true); + job->addMetaData("content-type", TQString("Content-Type: multipart/form-data, boundary=%1").arg(formDataBoundary)); + job->addMetaData("referrer", "http://drkonqi-client.crashreport.trinitydesktop.org"); + connect(job, TQT_SIGNAL(data(TDEIO::Job *, const TQByteArray &)), TQT_SLOT(postCrashDataToServerData(TDEIO::Job *, const TQByteArray &))); + connect(job, TQT_SIGNAL(result(TDEIO::Job *)), TQT_SLOT(postCrashDataToServerResult(TDEIO::Job *))); +// connect(job, TQT_SIGNAL(totalSize(TDEIO::Job *, TDEIO::filesize_t )), +// TQT_SLOT(totalSize(TDEIO::Job *, TDEIO::filesize_t))); +// connect(job, TQT_SIGNAL(mimetype(TDEIO::Job *, const TQString &)), +// TQT_SLOT(mimetype(TDEIO::Job *, const TQString &))); + connect(job, TQT_SIGNAL(redirection(TDEIO::Job *, const KURL&)), TQT_SLOT(postCrashDataToServerDataRedirection(TDEIO::Job *, const KURL&))); + + return 0; +} + +void Toplevel::postCrashDataToServerData(TDEIO::Job *, const TQByteArray &ba) +{ + uint offset = 0; + if (serverResponse.count() > 0) { + offset = serverResponse.count() - 1; + } + uint size = ba.count(); + + serverResponse.resize(offset + size + 1); + memcpy(serverResponse.data() + offset, ba.data(), size); + *(serverResponse.data() + offset + size) = 0; +} + +void Toplevel::postCrashDataToServerResult(TDEIO::Job *job) +{ + int err = job->error(); + if (err == 0) { + TQString responseString(serverResponse); + if (responseString.startsWith("ACK\n")) { + responseString = responseString.mid(4); + KMessageBox::information + (0, + i18n("

Your crash report has been uploaded!

You may reference it if desired by its unique ID:
%1

").arg(responseString), + i18n("Report uploaded")); + close(); + } + else { + responseString = responseString.mid(4); + KMessageBox::error + (0, + i18n("

Your crash report failed to upload!

Please check your network settings and try again.

The server responded:
%1

").arg(responseString), + i18n("Upload failure")); + } + } + else { + KMessageBox::error + (0, + i18n("

Your crash report failed to upload!

Please check your network settings and try again.

"), + i18n("Upload failure")); + } +} + +void Toplevel::postCrashDataToServerDataRedirection(TDEIO::Job * /*job*/, const KURL& url) +{ + // +} \ No newline at end of file diff --git a/drkonqi/toplevel.h b/drkonqi/toplevel.h index e6d1b84cb..95c1bcb72 100644 --- a/drkonqi/toplevel.h +++ b/drkonqi/toplevel.h @@ -33,9 +33,13 @@ class TDEAboutData; class KrashConfig; class DrKBugReport; +class BugDescription; #include +#include +#include + class Toplevel : public KDialogBase { Q_OBJECT @@ -47,6 +51,7 @@ public: private: // helper methods TQString generateText() const; + int postCrashDataToServer(TQByteArray data); protected slots: void slotUser1(); @@ -58,9 +63,18 @@ protected slots: void slotBacktraceSomeError(); void slotBacktraceDone(const TQString &); + void slotSendReportBacktraceSomeError(); + void slotSendReportBacktraceDone(const TQString &); + + void postCrashDataToServerData(TDEIO::Job *, const TQByteArray &); + void postCrashDataToServerResult(TDEIO::Job *job); + void postCrashDataToServerDataRedirection(TDEIO::Job * /*job*/, const KURL& url); + private: KrashConfig *m_krashconf; DrKBugReport *m_bugreport; + BugDescription* m_bugdescription; + TQCString serverResponse; }; #endif -- cgit v1.2.3