From fdab4808d40eac3334cc4b36821360b5f3d45022 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 11 Mar 2017 18:10:14 +0100 Subject: [PATCH 001/118] added minimum version number for debian stretch --- build_scripts/Debian+Ubuntu/control.stretch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/Debian+Ubuntu/control.stretch b/build_scripts/Debian+Ubuntu/control.stretch index 9b557e3b8..6968c9964 100644 --- a/build_scripts/Debian+Ubuntu/control.stretch +++ b/build_scripts/Debian+Ubuntu/control.stretch @@ -2,7 +2,7 @@ Source: retroshare06 Section: devel Priority: standard Maintainer: Cyril Soler -Build-Depends: debhelper (>= 7), libglib2.0-dev, libupnp-dev, libssl-dev, libxss-dev, libgnome-keyring-dev, libbz2-dev, libspeex-dev, libspeexdsp-dev, libxslt1-dev, cmake, libcurl4-openssl-dev, libopencv-dev, tcl8.6, libsqlcipher-dev, libmicrohttpd-dev, libavcodec-dev, qtmultimedia5-dev, qttools5-dev, libqt5x11extras5-dev, qt5-default +Build-Depends: debhelper (>= 7), libglib2.0-dev, libupnp-dev, libssl-dev, libxss-dev, libgnome-keyring-dev, libbz2-dev, libspeex-dev, libspeexdsp-dev, libxslt1-dev, cmake, libcurl4-openssl-dev, libopencv-dev, tcl8.6, libsqlcipher-dev (>= 3.4.0), libmicrohttpd-dev, libavcodec-dev, qtmultimedia5-dev, qttools5-dev, libqt5x11extras5-dev, qt5-default Standards-Version: 3.9.6 Homepage: http://retroshare.sourceforge.net From a0d1089559c5cfb6219e0bddd814c96bd48f83ae Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 11 Mar 2017 18:15:35 +0100 Subject: [PATCH 002/118] added branch parameter to makeSourcePackage script --- build_scripts/Debian+Ubuntu/makeSourcePackage.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh index 45c4ffc33..5cbb59f24 100755 --- a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh +++ b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh @@ -4,6 +4,7 @@ version="0.6.2" gitpath="https://github.com/RetroShare/RetroShare.git" workdir=retroshare06-${version} +branch="v0.6.2-official_release" #bubba3="Y" # comment out to compile for bubba3 ###################################################### @@ -66,6 +67,7 @@ echo " "Commit count : ${ccount} echo " "Date : ${date} echo " "Time : ${time} echo " "Hash : ${hhsh} +echo " "Using branch : ${branch} echo " "Using revision : ${rev} echo Done. @@ -80,7 +82,7 @@ echo Extracting base archive... mkdir -p ${workdir}/src echo Checking out latest snapshot... cd ${workdir}/src -git clone --depth 1 https://github.com/RetroShare/RetroShare.git . +git clone --depth 1 https://github.com/RetroShare/RetroShare.git --single-branch --branch $branch . cd - if ! test -d ${workdir}/src/libretroshare/; then From 21143742fd7acdc04dd6b51739f12a7cad3300b6 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 15 Mar 2017 19:26:07 +0100 Subject: [PATCH 003/118] fixed update of Tor proxy address in hidden nodes server page --- libretroshare/src/rsserver/p3peers.cc | 3 +++ retroshare-gui/src/gui/settings/ServerPage.cpp | 8 +++++++- retroshare-gui/src/gui/settings/ServerPage.h | 1 + retroshare-gui/src/gui/settings/ServerPage.ui | 4 ++-- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 73a5801fd..f43dfb485 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -1037,6 +1037,9 @@ bool p3Peers::setProxyServer(const uint32_t type, const std::string &addr_str, c std::cerr << "(EE) attempt to set proxy server address to something not allowed: " << addr_str << ":" << port << std::endl; return false ; } + + std::cerr << "Settign proxy server address to " << addr_str << ":" << port << std::endl; + struct sockaddr_storage addr; struct sockaddr_in *addrv4p = (struct sockaddr_in *) &addr; addrv4p->sin_family = AF_INET; diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index 4357f0d2c..d9dd900fb 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -109,7 +109,7 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) connect( ui.netModeComboBox, SIGNAL( activated ( int ) ), this, SLOT( toggleUPnP( ) ) ); connect( ui.allowIpDeterminationCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleIpDetermination(bool) ) ); connect( ui.cleanKnownIPs_PB, SIGNAL( clicked( ) ), this, SLOT( clearKnownAddressList() ) ); - connect( ui.testIncoming_PB, SIGNAL( clicked( ) ), this, SLOT( updateInProxyIndicator() ) ); + connect( ui.testIncoming_PB, SIGNAL( clicked( ) ), this, SLOT( saveAndTestInProxy() ) ); connect( ui.showDiscStatusBar,SIGNAL(toggled(bool)),this,SLOT(updateShowDiscStatusBar())) ; #ifdef SERVER_DEBUG @@ -132,6 +132,12 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) connect(ui.totalUploadRate, SIGNAL(valueChanged(int)),this,SLOT(saveRates())); } +void ServerPage::saveAndTestInProxy() +{ + saveAddresses(); + updateInProxyIndicator() ; +} + void ServerPage::checkIpRange(const QString& ipstr) { QColor color; diff --git a/retroshare-gui/src/gui/settings/ServerPage.h b/retroshare-gui/src/gui/settings/ServerPage.h index 02685bfc0..5b300e084 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.h +++ b/retroshare-gui/src/gui/settings/ServerPage.h @@ -61,6 +61,7 @@ private slots: // ban list void updateSelectedBlackListIP(int row, int, int, int); void updateSelectedWhiteListIP(int row,int,int,int); + void saveAndTestInProxy(); void addIpRangeToBlackList(); void addIpRangeToWhiteList(); void moveToWhiteList0(); diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index 3755b0536..a0f16a62b 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -26,7 +26,7 @@ - 0 + 2 @@ -985,7 +985,7 @@ You can connect to Hidden Nodes, even if you are running a standard Node, so why <html><head/><body><p>This button simulates a SSL connection to your hidden address using the corresponding proxy. If your hidden node is reachable, it should cause a SSL handshake error, which RS will interpret as a valid connection state. This operation might also cause several &quot;security warning&quot; about connections from your local host IP (127.0.0.1) in the News Feed if you enabled it, which you should interpret as a sign of good communication.</p></body></html> - Test + Apply From e4fad4530d7101937e80cc8540ec78bdda0bb2ec Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 15 Mar 2017 20:51:40 +0100 Subject: [PATCH 004/118] fixed layout in ConfCertDialog, removed overnumerous tabs --- .../src/gui/connect/ConfCertDialog.cpp | 4 +- .../src/gui/connect/ConfCertDialog.ui | 280 +++++++----------- 2 files changed, 114 insertions(+), 170 deletions(-) diff --git a/retroshare-gui/src/gui/connect/ConfCertDialog.cpp b/retroshare-gui/src/gui/connect/ConfCertDialog.cpp index 958b2be54..bf66ce5ce 100644 --- a/retroshare-gui/src/gui/connect/ConfCertDialog.cpp +++ b/retroshare-gui/src/gui/connect/ConfCertDialog.cpp @@ -239,9 +239,9 @@ void ConfCertDialog::load() ui.version->show(); ui.label_version->show(); - ui.groupBox->show(); + //ui.groupBox->show(); ui.groupBox_4->show(); - ui.tabWidget->show(); + //ui.tabWidget->show(); //ui.rsid->hide(); //ui.label_rsid->hide(); ui.pgpfingerprint->show(); diff --git a/retroshare-gui/src/gui/connect/ConfCertDialog.ui b/retroshare-gui/src/gui/connect/ConfCertDialog.ui index 469bae218..fec736831 100644 --- a/retroshare-gui/src/gui/connect/ConfCertDialog.ui +++ b/retroshare-gui/src/gui/connect/ConfCertDialog.ui @@ -6,8 +6,8 @@ 0 0 - 722 - 651 + 1104 + 1086 @@ -69,7 +69,7 @@ - 1 + 0 @@ -85,7 +85,7 @@ - Friend info + Node info: @@ -249,6 +249,114 @@ + + + + Current address: + + + + + + + + 0 + + + 65535 + + + 7812 + + + + + + + + + + 0 + + + 65535 + + + 7812 + + + + + + + Dynamic DNS + + + + + + + + + + External Address + + + + + + + + + + Port + + + + + + + Port + + + + + + + Qt::LeftToRight + + + Local Address + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + List of known addresses: + + + + + + Qt::DefaultContextMenu + + + QAbstractItemView::MultiSelection + + + + + + @@ -264,170 +372,6 @@ - - - - :/images/kcmsystem24.png:/images/kcmsystem24.png - - - Connectivity - - - - - - 1 - - - - Peer Addresses - - - - - - Peer Address - - - - - - Qt::Vertical - - - - 20 - 47 - - - - - - - - Qt::Vertical - - - - 20 - 47 - - - - - - - - - - Qt::LeftToRight - - - Local Address - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - External Address - - - - - - - - - - Dynamic DNS - - - - - - - - - - Port - - - - - - - Port - - - - - - - 0 - - - 65535 - - - 7812 - - - - - - - 0 - - - 65535 - - - 7812 - - - - - - - - - - - - - Addresses list - - - - - - Addresses list - - - - - - - Qt::DefaultContextMenu - - - QAbstractItemView::MultiSelection - - - - - - - - - Retroshare Certificate From 107d48f1b8152bde58c0ecfaa2c632c6c4259f7d Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 15 Mar 2017 22:50:51 +0100 Subject: [PATCH 005/118] Fix windows height at first start. --- retroshare-gui/src/gui/common/rwindow.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/gui/common/rwindow.cpp b/retroshare-gui/src/gui/common/rwindow.cpp index 32cfba943..e86be7fa2 100644 --- a/retroshare-gui/src/gui/common/rwindow.cpp +++ b/retroshare-gui/src/gui/common/rwindow.cpp @@ -76,11 +76,20 @@ RWindow::restoreWindowState() m_bSaveStateOnClose = true; // now we save the window state on close #if QT_VERSION >= 0x040200 - QByteArray geometry = getSetting("Geometry", QByteArray()).toByteArray(); - if (geometry.isEmpty()) + QByteArray geo = getSetting("Geometry", QByteArray()).toByteArray(); + if (geo.isEmpty()) + { adjustSize(); + QRect rect = geometry(); + int h = fontMetrics().height()*40; + if (rect.height() Date: Thu, 16 Mar 2017 21:01:27 +0100 Subject: [PATCH 006/118] allowed to edit subject hen editing forum posts. Only the latest subject is visible --- retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp index 788490e40..aaab89231 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -308,7 +308,7 @@ void CreateGxsForumMsg::loadFormInformation() ui.forumName->setText(misc::removeNewLine(name)); ui.forumSubject->setText(misc::removeNewLine(subj)); - ui.forumSubject->setReadOnly(!mOrigMsgId.isNull()); + //ui.forumSubject->setReadOnly(!mOrigMsgId.isNull()); if (ui.forumSubject->text().isEmpty()) { From 5efa8e3f3f9f4c177150e254e28dc5c430ac2fdf Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 17 Mar 2017 22:14:14 +0100 Subject: [PATCH 007/118] Fix Windows Compilation with CONFIG+=no_sqlcipher --- libretroshare/src/libretroshare.pro | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 551fbf335..03c50d954 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -279,7 +279,12 @@ win32 { CONFIG += upnp_miniupnpc - LIBS += -lsqlcipher + no_sqlcipher { + PKGCONFIG *= sqlite3 + LIBS += -lsqlite3 + } else { + LIBS += -lsqlcipher + } DEPENDPATH += . $$INC_DIR INCLUDEPATH += . $$INC_DIR From 19bd51dfae0f9dca910b5ea7d1552b81dd9f8fc4 Mon Sep 17 00:00:00 2001 From: RetroPooh Date: Tue, 21 Mar 2017 14:57:06 +0300 Subject: [PATCH 008/118] searchdialog - mark current downloads green --- .../src/gui/FileTransfer/SearchDialog.cpp | 18 ++++++++++++++++++ .../src/gui/FileTransfer/SearchDialog.h | 4 ++++ .../src/gui/qss/stylesheet/qss.default | 1 + 3 files changed, 23 insertions(+) diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp index 851679931..4728dde14 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp @@ -407,6 +407,13 @@ void SearchDialog::download() for(std::list::const_iterator it(srcIds.begin()); it!=srcIds.end(); ++it) { std::cout << *it << "-" << std::endl; }//for(std::list::const_iterator + //QColor foreground = QColor(0, 128, 0); // green + QColor foreground = textColorDownloading(); + QBrush brush(foreground); + for (int i = 0; i < item->columnCount(); ++i) + { + item->setForeground(i, brush); + } }//if(!rsFiles -> FileRequest( }//if (item->text(SR_HASH_COL).isEmpty()) }//for (int i = 0 @@ -1189,6 +1196,11 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s found = true ; if (!item->data(SR_DATA_COL, SR_ROLE_LOCAL).toBool()) { + + FileInfo fi; + if (rsFiles->FileDetails(file.hash, RS_FILE_HINTS_DOWNLOAD, fi)) + break; + QColor foreground; int sources = friendSource + anonymousSource ; @@ -1281,6 +1293,12 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s setForeground = true; } } + if (rsFiles->FileDetails(file.hash, RS_FILE_HINTS_DOWNLOAD, fi)) + { + //foreground = QColor(0, 128, 0); // green + foreground = textColorDownloading(); + setForeground = true; + } if (setForeground) { QBrush brush(foreground); diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h index bfc5892cc..57846692c 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h @@ -38,6 +38,7 @@ class SearchDialog : public MainPage Q_OBJECT Q_PROPERTY(QColor textColorLocal READ textColorLocal WRITE setTextColorLocal) + Q_PROPERTY(QColor textColorDownloading READ textColorDownloading WRITE setTextColorDownloading) Q_PROPERTY(QColor textColorNoSources READ textColorNoSources WRITE setTextColorNoSources) Q_PROPERTY(QColor textColorLowSources READ textColorLowSources WRITE setTextColorLowSources) Q_PROPERTY(QColor textColorHighSources READ textColorHighSources WRITE setTextColorHighSources) @@ -51,11 +52,13 @@ public: void searchKeywords(const QString& keywords); QColor textColorLocal() const { return mTextColorLocal; } + QColor textColorDownloading() const { return mTextColorDownloading; } QColor textColorNoSources() const { return mTextColorNoSources; } QColor textColorLowSources() const { return mTextColorLowSources; } QColor textColorHighSources() const { return mTextColorHighSources; } void setTextColorLocal(QColor color) { mTextColorLocal = color; } + void setTextColorDownloading(QColor color) { mTextColorDownloading = color; } void setTextColorNoSources(QColor color) { mTextColorNoSources = color; } void setTextColorLowSources(QColor color) { mTextColorLowSources = color; } void setTextColorHighSources(QColor color) { mTextColorHighSources = color; } @@ -154,6 +157,7 @@ private: /* Color definitions (for standard see qss.default) */ QColor mTextColorLocal; + QColor mTextColorDownloading; QColor mTextColorNoSources; QColor mTextColorLowSources; QColor mTextColorHighSources; diff --git a/retroshare-gui/src/gui/qss/stylesheet/qss.default b/retroshare-gui/src/gui/qss/stylesheet/qss.default index b762d626a..db24fd45e 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/qss.default +++ b/retroshare-gui/src/gui/qss/stylesheet/qss.default @@ -174,6 +174,7 @@ FriendList SearchDialog { qproperty-textColorLocal: red; + qproperty-textColorDownloading: green; qproperty-textColorNoSources: rgb(0, 0, 19); qproperty-textColorLowSources: rgb(0, 0, 38); qproperty-textColorHighSources: rgb(0, 0, 228); From 000dabfaedf733347147aa9de55ac457c4c3f6dc Mon Sep 17 00:00:00 2001 From: RetroPooh Date: Tue, 21 Mar 2017 15:02:46 +0300 Subject: [PATCH 009/118] chat lobby list - add tree item counters --- retroshare-gui/src/gui/ChatLobbyWidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index 07d5112be..ac197991b 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -653,7 +653,9 @@ void ChatLobbyWidget::updateDisplay() updateItem(ui.lobbyTreeWidget, item, lobby.lobby_id, lobby.lobby_name,lobby.lobby_topic, lobby.gxs_ids.size(), true, autoSubscribe,lobby_flags); } publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0); + publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed chat rooms")+ QString(" (") + QString::number(publicSubLobbyItem->childCount())+QString(")")); privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0); + publicLobbyItem->setText(COLUMN_NAME, tr("Public chat rooms")+ " (" + QString::number(publicLobbyItem->childCount())+QString(")")); } void ChatLobbyWidget::createChatLobby() From 50c81d7142aa3502065025b914b180571d08522b Mon Sep 17 00:00:00 2001 From: RetroPooh Date: Tue, 21 Mar 2017 16:41:39 +0300 Subject: [PATCH 010/118] chat lobby list - mark signed lobbies with color --- retroshare-gui/src/gui/ChatLobbyWidget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index ac197991b..dadf04939 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -378,8 +378,12 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby +QObject::tr("Id:")+" "+QString::number(id,16) ; if(lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) + { tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ; - + QColor foreground = QColor(0, 128, 0); // green + for (int column = 0; column < COLUMN_COUNT; ++column) + item->setTextColor(column, foreground); + } item->setToolTip(0,tooltipstr) ; } From 85cfda196313bd12d0b92c3ac7d155faa640bd84 Mon Sep 17 00:00:00 2001 From: RetroPooh Date: Tue, 21 Mar 2017 16:52:40 +0300 Subject: [PATCH 011/118] add tree item counters for channels,forums,posted --- retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index 2bfdb6c0d..6ab4ca165 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -841,8 +841,11 @@ void GxsGroupFrameDialog::insertGroupsData(const std::list &gro /* now we can add them in as a tree! */ ui->groupTreeWidget->fillGroupItems(mYourGroups, adminList); ui->groupTreeWidget->fillGroupItems(mSubscribedGroups, subList); + mSubscribedGroups->setText(2, QString::number(mSubscribedGroups->childCount())); // 1 COLUMN_UNREAD 2 COLUMN_POPULARITY ui->groupTreeWidget->fillGroupItems(mPopularGroups, popList); + mPopularGroups->setText(2, QString::number(mPopularGroups->childCount())); ui->groupTreeWidget->fillGroupItems(mOtherGroups, otherList); + mOtherGroups->setText(2, QString::number(mOtherGroups->childCount())); mInFill = false; From f5e7217bb4e81c4bfe8b6233f047449ef7f3cd8e Mon Sep 17 00:00:00 2001 From: RetroPooh Date: Tue, 21 Mar 2017 17:24:59 +0300 Subject: [PATCH 012/118] statistics - router - fix bold marking for tunnel speeds over 1mbs --- retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp b/retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp index 6d8a46e32..a76b5b5c3 100644 --- a/retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp +++ b/retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp @@ -153,7 +153,7 @@ void TurtleRouterDialog::updateTunnelRequests( const std::vectorsetFont(0,font); } - if(strtol(tunnels_info[i][5].c_str(), NULL, 0)>1000) // fast + if(strtof(tunnels_info[i][5].c_str(), NULL)>1000) // fast { font.setBold(true); item->setFont(0,font); From b0d2249ebcec3f7794b3204f217eced4bf957ade Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 25 Mar 2017 18:12:39 +0100 Subject: [PATCH 013/118] Added Windows support to retroshare-android-service --- .../src/retroshare-android-service.pro | 31 ++++++++++++++++++- retroshare-android-service/src/service.cpp | 10 +++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/retroshare-android-service/src/retroshare-android-service.pro b/retroshare-android-service/src/retroshare-android-service.pro index c2caa12a0..e45067f81 100644 --- a/retroshare-android-service/src/retroshare-android-service.pro +++ b/retroshare-android-service/src/retroshare-android-service.pro @@ -6,11 +6,40 @@ QT += core network QT -= gui CONFIG += c++11 -CONFIG += dll +android-g++:CONFIG += dll android-g++:TEMPLATE = lib !android-g++:TEMPLATE = app +win32 { + OBJECTS_DIR = temp/obj + + LIBS_DIR = $$PWD/../../libs/lib + LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a + LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a + + for(lib, LIB_DIR):LIBS += -L"$$lib" + for(bin, BIN_DIR):LIBS += -L"$$bin" + + + LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32 + LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 + LIBS += -lwinmm + + DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T + + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR + + greaterThan(QT_MAJOR_VERSION, 4) { + # Qt 5 + RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src + } else { + # Qt 4 + QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src + } +} + SOURCES += service.cpp DEPENDPATH *= ../../libresapi/src diff --git a/retroshare-android-service/src/service.cpp b/retroshare-android-service/src/service.cpp index d3759dc61..afe73bfc3 100644 --- a/retroshare-android-service/src/service.cpp +++ b/retroshare-android-service/src/service.cpp @@ -39,11 +39,19 @@ int main(int argc, char *argv[]) #endif QCoreApplication a(argc, argv); + + RsInit::InitRsConfig(); + ApiServer api; RsControlModule ctrl_mod(argc, argv, api.getStateTokenServer(), &api, true); api.addResourceHandler("control", dynamic_cast(&ctrl_mod), &resource_api::RsControlModule::handleRequest); - QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory()); +#ifdef QT_DEBUG + QString sockPath = "RS/"; +#else + QString sockPath = QCoreApplication::applicationDirPath(); +#endif + sockPath.append("/libresapi.sock"); qDebug() << "Listening on:" << sockPath; ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal; From cb041341143edaf6d5b9321d2f9208cfb857a7eb Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 25 Mar 2017 18:15:47 +0100 Subject: [PATCH 014/118] Added Windows support to libresapi when working with retroshare_android_service --- libresapi/src/libresapi.pro | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/libresapi/src/libresapi.pro b/libresapi/src/libresapi.pro index f310198fb..f1a3aa8d5 100644 --- a/libresapi/src/libresapi.pro +++ b/libresapi/src/libresapi.pro @@ -10,6 +10,40 @@ DESTDIR = lib INCLUDEPATH += ../../libretroshare/src +retroshare_android_service { + win32 { + OBJECTS_DIR = temp/obj + + LIBS_DIR = $$PWD/../../libs/lib + LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a + LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a + + for(lib, LIB_DIR):LIBS += -L"$$lib" + for(bin, BIN_DIR):LIBS += -L"$$bin" + + + LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32 + LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 + LIBS += -lwinmm + + DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T + + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR + + greaterThan(QT_MAJOR_VERSION, 4) { + # Qt 5 + RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src + } else { + # Qt 4 + QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src + } + } + + DEPENDPATH += . ../../libretroshare/src/ + INCLUDEPATH += ../../libretroshare/src/ +} + libresapihttpserver { CONFIG += libmicrohttpd From ae95b49f8a1a235f8fe64632915c48b99f5d6849 Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 25 Mar 2017 18:20:53 +0100 Subject: [PATCH 015/118] Added SettingsHandler to handle response to settings requests --- libresapi/src/api/ApiServer.cpp | 10 +- libresapi/src/api/SettingsHandler.cpp | 182 ++++++++++++++++++++++++++ libresapi/src/api/SettingsHandler.h | 59 +++++++++ libresapi/src/libresapi.pro | 6 +- 4 files changed, 253 insertions(+), 4 deletions(-) create mode 100644 libresapi/src/api/SettingsHandler.cpp create mode 100644 libresapi/src/api/SettingsHandler.h diff --git a/libresapi/src/api/ApiServer.cpp b/libresapi/src/api/ApiServer.cpp index b9606a003..593e9386a 100644 --- a/libresapi/src/api/ApiServer.cpp +++ b/libresapi/src/api/ApiServer.cpp @@ -17,6 +17,8 @@ #include "ChannelsHandler.h" #include "StatsHandler.h" +#include "SettingsHandler.h" + /* data types in json http://json.org/ string (utf-8 unicode) @@ -236,7 +238,8 @@ public: mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler), mApiPluginHandler(sts, ifaces), mChannelsHandler(ifaces.mGxsChannels), - mStatsHandler() + mStatsHandler(), + mSettingsHandler(sts) { // the dynamic cast is to not confuse the addResourceHandler template like this: // addResourceHandler(derived class, parent class) @@ -262,7 +265,9 @@ public: &ChannelsHandler::handleRequest); router.addResourceHandler("stats", dynamic_cast(&mStatsHandler), &StatsHandler::handleRequest); - } + router.addResourceHandler("settings", dynamic_cast(&mSettingsHandler), + &SettingsHandler::handleRequest); + } PeersHandler mPeersHandler; IdentityHandler mIdentityHandler; @@ -274,6 +279,7 @@ public: ApiPluginHandler mApiPluginHandler; ChannelsHandler mChannelsHandler; StatsHandler mStatsHandler; + SettingsHandler mSettingsHandler; }; ApiServer::ApiServer(): diff --git a/libresapi/src/api/SettingsHandler.cpp b/libresapi/src/api/SettingsHandler.cpp new file mode 100644 index 000000000..6e1aa75da --- /dev/null +++ b/libresapi/src/api/SettingsHandler.cpp @@ -0,0 +1,182 @@ +#include "SettingsHandler.h" + +#include + +#include + +namespace resource_api +{ + #define SETTINGS_FILE (QString::fromUtf8(RsAccounts::AccountDirectory().c_str()) + "/Sonet.conf") + + SettingsHandler::SettingsHandler(StateTokenServer *sts, const QString settingsGroup) : + QSettings(SETTINGS_FILE, QSettings::IniFormat), + mStateTokenServer(sts), + mMtx("SettingsHandler Mutex"), + mStateToken(sts->getNewToken()) + { + RsPeerId sPreferedId; + m_bValid = RsAccounts::GetPreferredAccountId(sPreferedId); + + if (!settingsGroup.isEmpty()) + beginGroup(settingsGroup); + + addResourceHandler("*", this, &SettingsHandler::handleSettingsRequest); + addResourceHandler("get_advanced_mode", this, &SettingsHandler::handleGetAdvancedMode); + addResourceHandler("set_advanced_mode", this, &SettingsHandler::handleSetAdvancedMode); + addResourceHandler("get_flickable_grid_mode", this, &SettingsHandler::handleGetFlickableGridMode); + addResourceHandler("set_flickable_grid_mode", this, &SettingsHandler::handleSetFlickableGridMode); + addResourceHandler("get_auto_login", this, &SettingsHandler::handleGetAutoLogin); + addResourceHandler("set_auto_login", this, &SettingsHandler::handleSetAutoLogin); + } + + SettingsHandler::~SettingsHandler() + { + sync(); + } + + void SettingsHandler::handleSettingsRequest(Request &/*req*/, Response &resp) + { + + } + + void SettingsHandler::handleGetAdvancedMode(Request &/*req*/, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool advanced_mode = valueFromGroup("General", "Advanced", false).toBool(); + resp.mDataStream << makeKeyValueReference("advanced_mode", advanced_mode); + resp.setOk(); + sync(); + } + + void SettingsHandler::handleSetAdvancedMode(Request &req, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool advanced_mode; + req.mStream << makeKeyValueReference("advanced_mode", advanced_mode); + setValueToGroup("General", "Advanced", advanced_mode); + resp.setOk(); + sync(); + } + + void SettingsHandler::handleGetFlickableGridMode(Request &/*req*/, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool flickable_grid_mode = valueFromGroup("General", "FlickableGrid", false).toBool(); + resp.mDataStream << makeKeyValueReference("flickable_grid_mode", flickable_grid_mode); + resp.setOk(); + sync(); + } + + void SettingsHandler::handleSetFlickableGridMode(Request &req, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool flickable_grid_mode; + req.mStream << makeKeyValueReference("flickable_grid_mode", flickable_grid_mode); + setValueToGroup("General", "FlickableGrid", flickable_grid_mode); + + resp.setOk(); + sync(); + } + + void SettingsHandler::handleGetAutoLogin(Request &/*req*/, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool autoLogin = RsInit::getAutoLogin();; + resp.mDataStream << makeKeyValueReference("auto_login", autoLogin); + resp.setOk(); + sync(); + } + + void SettingsHandler::handleSetAutoLogin(Request &req, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool autoLogin; + req.mStream << makeKeyValueReference("auto_login", autoLogin); + RsInit::setAutoLogin(autoLogin); + + resp.setOk(); + sync(); + } + + QVariant SettingsHandler::value(const QString &key, const QVariant &defaultVal) const + { + if (m_bValid == false) + { + return defaultVal.isNull() ? defaultValue(key) : defaultVal; + } + return QSettings::value(key, defaultVal.isNull() ? defaultValue(key) : defaultVal); + } + + void SettingsHandler::setValue(const QString &key, const QVariant &val) + { + if (m_bValid == false) + { + std::cerr << "RSettings::setValue() Calling on invalid object, key = " << key.toStdString() << std::endl; + return; + } + if (val == defaultValue(key)) + QSettings::remove(key); + else if (val != value(key)) + QSettings::setValue(key, val); + } + + QVariant SettingsHandler::valueFromGroup(const QString &group, const QString &key, const QVariant &defaultVal) + { + beginGroup(group); + QVariant val = value(key, defaultVal); + endGroup(); + + return val; + } + + void SettingsHandler::setValueToGroup(const QString &group, const QString &key, const QVariant &val) + { + beginGroup(group); + setValue(key, val); + endGroup(); + } + + void SettingsHandler::setDefault(const QString &key, const QVariant &val) + { + _defaults.insert(key, val); + } + + QVariant SettingsHandler::defaultValue(const QString &key) const + { + if (_defaults.contains(key)) + return _defaults.value(key); + return QVariant(); + } + + void SettingsHandler::reset() + { + /* Static method, so we have to create a QSettings object. */ + QSettings settings(SETTINGS_FILE, QSettings::IniFormat); + settings.clear(); + } +} // namespace resource_api + diff --git a/libresapi/src/api/SettingsHandler.h b/libresapi/src/api/SettingsHandler.h new file mode 100644 index 000000000..b4c21fae2 --- /dev/null +++ b/libresapi/src/api/SettingsHandler.h @@ -0,0 +1,59 @@ +#ifndef SETTINGSHANDLER_H +#define SETTINGSHANDLER_H + +#include + +#include + +#include "ResourceRouter.h" +#include "StateTokenServer.h" + +/* Reimplemented class RSettings*/ +namespace resource_api +{ + class SettingsHandler : public ResourceRouter, public QSettings + { + public: + SettingsHandler(StateTokenServer* sts, const QString group = QString()); + ~SettingsHandler(); + + static void reset(); + + QVariant value(const QString &key, + const QVariant &defaultVal = QVariant()) const; + + void setValue(const QString &key, const QVariant &val); + + QVariant valueFromGroup(const QString &group, const QString &key, + const QVariant &defaultVal = QVariant()); + void setValueToGroup(const QString &group, const QString &key, + const QVariant &val); + + protected: + void setDefault(const QString &key, const QVariant &val); + QVariant defaultValue(const QString &key) const; + + bool m_bValid; + + private: + void handleSettingsRequest(Request& req, Response& resp); + + void handleGetAdvancedMode(Request& req, Response& resp); + void handleSetAdvancedMode(Request& req, Response& resp); + + void handleGetFlickableGridMode(Request& req, Response& resp); + void handleSetFlickableGridMode(Request& req, Response& resp); + + void handleGetAutoLogin(Request& req, Response& resp); + void handleSetAutoLogin(Request& req, Response& resp); + + QHash _defaults; + + StateTokenServer* mStateTokenServer; + + RsMutex mMtx; + StateToken mStateToken; // mutex protected + }; +} // namespace resource_api + +#endif // SETTINGSHANDLER_H diff --git a/libresapi/src/libresapi.pro b/libresapi/src/libresapi.pro index f1a3aa8d5..31de982b3 100644 --- a/libresapi/src/libresapi.pro +++ b/libresapi/src/libresapi.pro @@ -182,7 +182,8 @@ SOURCES += \ util/ContentTypes.cpp \ api/ApiPluginHandler.cpp \ api/ChannelsHandler.cpp \ - api/StatsHandler.cpp + api/StatsHandler.cpp \ + api/SettingsHandler.cpp HEADERS += \ api/ApiServer.h \ @@ -209,7 +210,8 @@ HEADERS += \ util/ContentTypes.h \ api/ApiPluginHandler.h \ api/ChannelsHandler.h \ - api/StatsHandler.h + api/StatsHandler.h \ + api/SettingsHandler.h libresapilocalserver { CONFIG *= qt From 39967b7ce7e62b0acaf17b96d5a32d3b91506df4 Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 25 Mar 2017 18:23:28 +0100 Subject: [PATCH 016/118] Added name of requests to be used by GUI --- libresapi/src/api/ApiServer.cpp | 3 +++ libresapi/src/api/ApiTypes.h | 3 +++ libresapi/src/api/ResourceRouter.cpp | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/libresapi/src/api/ApiServer.cpp b/libresapi/src/api/ApiServer.cpp index 593e9386a..6efadeaf6 100644 --- a/libresapi/src/api/ApiServer.cpp +++ b/libresapi/src/api/ApiServer.cpp @@ -368,6 +368,9 @@ std::string ApiServer::handleRequest(Request &request) if(data.isRawData()) return data.getRawData(); + if(!resp.mCallbackName.empty()) + outstream << resource_api::makeKeyValueReference("callback_name", resp.mCallbackName); + outstream << resource_api::makeKeyValue("debug_msg", debugString.str()); outstream << resource_api::makeKeyValueReference("returncode", returncode); if(!resp.mStateToken.isNull()) diff --git a/libresapi/src/api/ApiTypes.h b/libresapi/src/api/ApiTypes.h index c443eb170..6d6d5c746 100644 --- a/libresapi/src/api/ApiTypes.h +++ b/libresapi/src/api/ApiTypes.h @@ -252,6 +252,9 @@ public: StateToken mStateToken; + //Just for GUI benefit + std::string mCallbackName; + // the result StreamBase& mDataStream; diff --git a/libresapi/src/api/ResourceRouter.cpp b/libresapi/src/api/ResourceRouter.cpp index a13201a27..48050cdb6 100644 --- a/libresapi/src/api/ResourceRouter.cpp +++ b/libresapi/src/api/ResourceRouter.cpp @@ -37,6 +37,13 @@ ResponseTask* ResourceRouter::handleRequest(Request& req, Response& resp) if(vit->first == req.mPath.top()) { req.mPath.pop(); + + //Just for GUI benefit + std::string callbackName; + req.mStream << makeKeyValueReference("callback_name", callbackName); + resp.mCallbackName = callbackName; + // + return vit->second->handleRequest(req, resp); } } From 28d37c2968b305a2163a11d3efd1690a3ad495d0 Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 25 Mar 2017 18:25:26 +0100 Subject: [PATCH 017/118] Added password storing to RsControlModule for GUI benefits --- libresapi/src/api/RsControlModule.cpp | 135 ++++++++++++++++++++++++-- libresapi/src/api/RsControlModule.h | 10 +- 2 files changed, 135 insertions(+), 10 deletions(-) diff --git a/libresapi/src/api/RsControlModule.cpp b/libresapi/src/api/RsControlModule.cpp index 9430df170..228bb691a 100644 --- a/libresapi/src/api/RsControlModule.cpp +++ b/libresapi/src/api/RsControlModule.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "api/ApiServer.h" #include "api/Operators.h" @@ -301,6 +302,7 @@ void RsControlModule::handlePassword(Request &req, Response &resp) mPassword = passwd; mWantPassword = false; mStateTokenServer->replaceToken(mStateToken); + mFixedPassword = passwd; } resp.mDataStream @@ -425,17 +427,17 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp) RsPeerId ssl_id; std::string err_string; // give the password to the password callback - { - RsStackMutex stack(mDataMtx); // ********** LOCKED ********** - mFixedPassword = pgp_password; - } + { + RsStackMutex stack(mDataMtx); // ********** LOCKED ********** + mFixedPassword = pgp_password; + } bool ssl_ok = RsAccounts::GenerateSSLCertificate(pgp_id, "", ssl_name, "", hidden_port!=0, ssl_password, ssl_id, err_string); // clear fixed password to restore normal password operation - { - RsStackMutex stack(mDataMtx); // ********** LOCKED ********** - mFixedPassword = ""; - } +// { +// RsStackMutex stack(mDataMtx); // ********** LOCKED ********** +// mFixedPassword = ""; +// } if (ssl_ok) { @@ -456,6 +458,123 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp) resp.setFail("could not create a new location. Error: "+err_string); } +class SignatureEventData +{ + public: + SignatureEventData(const void *_data,int32_t _len,unsigned int _signlen, std::string _reason) + { + // We need a new memory chnk because there's no guarranty _sign nor _signlen are not in the stack + + sign = (unsigned char *)rs_malloc(_signlen); + + if(!sign) + { + signlen = NULL; + signature_result = SELF_SIGNATURE_RESULT_FAILED; + return; + } + + signlen = new unsigned int; + *signlen = _signlen; + signature_result = SELF_SIGNATURE_RESULT_PENDING; + data = rs_malloc(_len); + + if(!data) + { + len = 0; + return; + } + len = _len; + memcpy(data,_data,len); + reason = _reason; + } + + ~SignatureEventData() + { + free(sign); + delete signlen; + free(data); + } + + void performSignature() + { + if(rsPeers->gpgSignData(data,len,sign,signlen,reason)) + signature_result = SELF_SIGNATURE_RESULT_SUCCESS; + else + signature_result = SELF_SIGNATURE_RESULT_FAILED; + } + + void *data; + uint32_t len; + unsigned char *sign; + unsigned int *signlen; + int signature_result; // 0=pending, 1=done, 2=failed/cancelled. + std::string reason; +}; + +bool RsControlModule::askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason /*=""*/) +{ + + { + RsStackMutex stack(mDataMtx); + std::cerr << "NotifyTxt:: deferred signature event requeted. " << std::endl; + + // Look into the queue + + Sha1CheckSum chksum = RsDirUtil::sha1sum((uint8_t*)data,len); + + std::map::iterator it = _deferred_signature_queue.find(chksum.toStdString()); + signature_result = SELF_SIGNATURE_RESULT_PENDING; + + if(it != _deferred_signature_queue.end()) + { + signature_result = it->second->signature_result; + + if(it->second->signature_result != SELF_SIGNATURE_RESULT_PENDING) // found it. Copy the result, and remove from the queue. + { + // We should check for the exact data match, for the sake of being totally secure. + // + std::cerr << "Found into queue: returning it" << std::endl; + + memcpy(sign,it->second->sign,*it->second->signlen); + *signlen = *(it->second->signlen); + + delete it->second; + _deferred_signature_queue.erase(it); + } + + return true; // already registered, but not done yet. + } + + // Not found. Store in the queue and emit a signal. + // + std::cerr << "NotifyTxt:: deferred signature event requeted. Pushing into queue" << std::endl; + + SignatureEventData *edta = new SignatureEventData(data,len,*signlen, reason); + + _deferred_signature_queue[chksum.toStdString()] = edta; + } + handleSignatureEvent(); + return true; +} + +void RsControlModule::handleSignatureEvent() +{ + std::cerr << "NotifyTxt:: performing a deferred signature in the main GUI thread." << std::endl; + + static bool working = false ; + + if(!working) + { + working = true ; + + for(std::map::const_iterator it(_deferred_signature_queue.begin());it!=_deferred_signature_queue.end();++it) + it->second->performSignature() ; + + working = false ; + } +} + void RsControlModule::setRunState(RunState s, std::string errstr) { RsStackMutex stack(mDataMtx); // ********** LOCKED ********** diff --git a/libresapi/src/api/RsControlModule.h b/libresapi/src/api/RsControlModule.h index d3c8ad18b..338027e15 100644 --- a/libresapi/src/api/RsControlModule.h +++ b/libresapi/src/api/RsControlModule.h @@ -9,6 +9,8 @@ namespace resource_api{ class StateTokenServer; class ApiServer; +class SignatureEventData; + // resource api module to control accounts, startup and shutdown of retroshare // - this module handles everything, no things are required from outside // - exception: users of this module have to create an api server and register this module @@ -31,8 +33,9 @@ public: // returns true if the process should terminate bool processShouldExit(); - // from NotifyClient - virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled); + // from NotifyClient + virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled) override; + virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason = "") override; protected: // from RsThread @@ -84,6 +87,9 @@ private: // we store the password in this variable, it has higher priority than the normal password variable // it is also to avoid a lock, when we make a synchronous call into librs, like in ssl cert generation std::string mFixedPassword; + + void handleSignatureEvent(); + std::map _deferred_signature_queue ; }; } // namespace resource_api From cb32f304a98e9ca953b4ec5c478730fb905d042a Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 25 Mar 2017 18:28:31 +0100 Subject: [PATCH 018/118] Added states handling to PeersHandler --- libresapi/src/api/PeersHandler.cpp | 226 ++++++++++++++++++++++++++++- libresapi/src/api/PeersHandler.h | 6 + 2 files changed, 228 insertions(+), 4 deletions(-) diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index 0f35e59e9..d77a39651 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -12,6 +13,12 @@ namespace resource_api { +#define PEER_STATE_ONLINE 1 +#define PEER_STATE_BUSY 2 +#define PEER_STATE_AWAY 3 +#define PEER_STATE_AVAILABLE 4 +#define PEER_STATE_INACTIVE 5 +#define PEER_STATE_OFFLINE 6 // todo: groups, add friend, remove friend, permissions void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details) @@ -21,7 +28,50 @@ void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details) << makeKeyValueReference("name", details.name) << makeKeyValueReference("location", details.location) << makeKeyValueReference("pgp_id", details.gpg_id) - ; + << makeKeyValueReference("pgp_id", details.gpg_id); + + if(details.state & RS_PEER_STATE_CONNECTED) + { + std::list statusInfo; + rsStatus->getStatusList(statusInfo); + + std::string state_string; + std::list::iterator it; + for (it = statusInfo.begin(); it != statusInfo.end(); ++it) + { + if (it->id == details.id) + { + switch (it->status) + { + case RS_STATUS_INACTIVE: + state_string = "inactive"; + break; + + case RS_STATUS_ONLINE: + state_string = "online"; + break; + + case RS_STATUS_AWAY: + state_string = "away"; + break; + + case RS_STATUS_BUSY: + state_string = "busy"; + break; + default: + state_string = "undefined"; + break; + } + break; + } + } + stream << makeKeyValueReference("state_string", state_string); + } + else + { + std::string state_string = "undefined"; + stream << makeKeyValueReference("state_string", state_string); + } } bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers, std::list& grpInfo, bool have_avatar) @@ -29,7 +79,9 @@ bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers bool ok = true; peerDetailsToStream(stream, details); stream << makeKeyValue("is_online", peers->isOnline(details.id)) - << makeKeyValue("chat_id", ChatId(details.id).toStdString()); + << makeKeyValue("chat_id", ChatId(details.id).toStdString()) + << makeKeyValue("custom_state_string", rsMsgs->getCustomStateString(details.id)); + std::string avatar_address = "/"+details.id.toStdString()+"/avatar_image"; @@ -63,7 +115,11 @@ PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *pee mNotify->registerNotifyClient(this); mStateTokenServer->registerTickClient(this); addResourceHandler("*", this, &PeersHandler::handleWildcard); - addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert); + addResourceHandler("get_state_string", this, &PeersHandler::handleGetStateString); + addResourceHandler("set_state_string", this, &PeersHandler::handleSetStateString); + addResourceHandler("get_custom_state_string", this, &PeersHandler::handleGetCustomStateString); + addResourceHandler("set_custom_state_string", this, &PeersHandler::handleSetCustomStateString); + addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert); } PeersHandler::~PeersHandler() @@ -121,6 +177,83 @@ static bool have_avatar(RsMsgs* msgs, const RsPeerId& id) return size != 0; } +void PeersHandler::handleGetStateString(Request& req, Response& resp) +{ + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + std::string state_string; + StatusInfo statusInfo; + if (rsStatus->getOwnStatus(statusInfo)) + { + if(statusInfo.status == RS_STATUS_ONLINE) + state_string = "online"; + else if(statusInfo.status == RS_STATUS_BUSY) + state_string = "busy"; + else if(statusInfo.status == RS_STATUS_AWAY) + state_string = "away"; + else if(statusInfo.status == RS_STATUS_INACTIVE) + state_string = "inactive"; + else + state_string = "undefined"; + } + else + state_string = "undefined"; + + resp.mDataStream << makeKeyValueReference("state_string", state_string); + resp.setOk(); +} + +void PeersHandler::handleSetStateString(Request& req, Response& resp) +{ + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + std::string state_string; + req.mStream << makeKeyValueReference("state_string", state_string); + + uint32_t status; + if(state_string == "online") + status = RS_STATUS_ONLINE; + else if(state_string == "busy") + status = RS_STATUS_BUSY; + else if(state_string == "away") + status = RS_STATUS_AWAY; + + rsStatus->sendStatus(RsPeerId(), status); + resp.setOk(); +} + +void PeersHandler::handleGetCustomStateString(Request& req, Response& resp) +{ + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + std::string custom_state_string = rsMsgs->getCustomStateString(); + resp.mDataStream << makeKeyValueReference("custom_state_string", custom_state_string); + resp.setOk(); +} + +void PeersHandler::handleSetCustomStateString(Request& req, Response& resp) +{ + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + std::string custom_state_string; + req.mStream << makeKeyValueReference("custom_state_string", custom_state_string); + + rsMsgs->setCustomStateString(custom_state_string); + resp.setOk(); +} + void PeersHandler::handleWildcard(Request &req, Response &resp) { bool ok = false; @@ -176,6 +309,9 @@ void PeersHandler::handleWildcard(Request &req, Response &resp) RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ unread_msgs = mUnreadMsgsCounts; } + std::list statusInfo; + rsStatus->getStatusList(statusInfo); + // list all peers ok = true; std::list identities; @@ -216,6 +352,11 @@ void PeersHandler::handleWildcard(Request &req, Response &resp) StreamBase& locationStream = itemStream.getStreamToMember("locations"); // mark as list (in case list is empty) locationStream.getStreamToMember(); + + int bestPeerState = 0; + unsigned int bestRSState = 0; + std::string bestCustomStateString; + for(std::vector::iterator vit = detailsVec.begin(); vit != detailsVec.end(); ++vit) { if(vit->gpg_id == *lit) @@ -226,8 +367,85 @@ void PeersHandler::handleWildcard(Request &req, Response &resp) unread = unread_msgs.find(vit->id)->second; stream << makeKeyValueReference("unread_msgs", unread); peerInfoToStream(stream,*vit, mRsPeers, grpInfo, have_avatar(mRsMsgs, vit->id)); - } + + + /* Custom state string */ + std::string customStateString; + if (vit->state & RS_PEER_STATE_CONNECTED) + { + customStateString = rsMsgs->getCustomStateString(vit->id); + } + + int peerState = 0; + + if (vit->state & RS_PEER_STATE_CONNECTED) + { + // get the status info for this ssl id + int rsState = 0; + std::list::iterator it; + for (it = statusInfo.begin(); it != statusInfo.end(); ++it) + { + if (it->id == vit->id) + { + rsState = it->status; + switch (rsState) + { + case RS_STATUS_INACTIVE: + peerState = PEER_STATE_INACTIVE; + break; + + case RS_STATUS_ONLINE: + peerState = PEER_STATE_ONLINE; + break; + + case RS_STATUS_AWAY: + peerState = PEER_STATE_AWAY; + break; + + case RS_STATUS_BUSY: + peerState = PEER_STATE_BUSY; + break; + } + + /* find the best ssl contact for the gpg item */ + if (bestPeerState == 0 || peerState < bestPeerState) + { + bestPeerState = peerState; + bestRSState = rsState; + bestCustomStateString = customStateString; + } + else if (peerState == bestPeerState) + { + /* equal state */ + if (bestCustomStateString.empty() && !customStateString.empty()) + { + bestPeerState = peerState; + bestRSState = rsState; + bestCustomStateString = customStateString; + } + } + break; + } + } + } + } } + itemStream << makeKeyValue("custom_state_string", bestCustomStateString); + + std::string state_string; + + if(bestRSState == RS_STATUS_ONLINE) + state_string = "online"; + else if(bestRSState == RS_STATUS_BUSY) + state_string = "busy"; + else if(bestRSState == RS_STATUS_AWAY) + state_string = "away"; + else if(bestRSState == RS_STATUS_INACTIVE) + state_string = "inactive"; + else + state_string = "undefined"; + + itemStream << makeKeyValue("state_string", state_string); } resp.mStateToken = getCurrentStateToken(); } diff --git a/libresapi/src/api/PeersHandler.h b/libresapi/src/api/PeersHandler.h index dfcc9e10c..a2eab706b 100644 --- a/libresapi/src/api/PeersHandler.h +++ b/libresapi/src/api/PeersHandler.h @@ -35,6 +35,12 @@ private: void handleWildcard(Request& req, Response& resp); void handleExamineCert(Request& req, Response& resp); + void handleGetStateString(Request& req, Response& resp); + void handleSetStateString(Request& req, Response& resp); + + void handleGetCustomStateString(Request& req, Response& resp); + void handleSetCustomStateString(Request& req, Response& resp); + // a helper which ensures proper mutex locking StateToken getCurrentStateToken(); From 194878a3585bda4c53862269e7862c39bd901945 Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 25 Mar 2017 18:31:13 +0100 Subject: [PATCH 019/118] Added functions for handling own and not own identities to IdentityHandler --- libresapi/src/api/IdentityHandler.cpp | 115 +++++++++++++++++++++++++- libresapi/src/api/IdentityHandler.h | 3 + 2 files changed, 115 insertions(+), 3 deletions(-) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 4d3f0ff80..9f01442df 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -101,9 +101,12 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden { mNotify->registerNotifyClient(this); - addResourceHandler("*", this, &IdentityHandler::handleWildcard); - addResourceHandler("own", this, &IdentityHandler::handleOwn); - addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity); + addResourceHandler("*", this, &IdentityHandler::handleWildcard); + //addResourceHandler("own", this, &IdentityHandler::handleOwn); + addResourceHandler("own", this, &IdentityHandler::handleOwnIdsRequest); + addResourceHandler("notown", this, &IdentityHandler::handleNotOwnIdsRequest); + + addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity); } IdentityHandler::~IdentityHandler() @@ -172,6 +175,112 @@ void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp) else resp.setFail(); } + +void IdentityHandler::handleNotOwnIdsRequest(Request & /*req*/, Response &resp) +{ + bool ok = true; + + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts); + + time_t start = time(NULL); + while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + &&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + &&((time(NULL) < (start+10))) + ) + { +#ifdef WINDOWS_SYS + Sleep(500); +#else + usleep(500*1000); +#endif + } + + if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::vector grps; + ok &= mRsIdentity->getGroupData(token, grps); + for(std::vector::iterator vit = grps.begin(); vit != grps.end(); vit++) + { + RsGxsIdGroup& grp = *vit; + //electron: not very happy about this, i think the flags should stay hidden in rsidentities + if(!(grp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) && grp.mIsAContact) + { + bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ) ; + resp.mDataStream.getStreamToMember() + << makeKeyValueReference("id", grp.mMeta.mGroupId) /// @deprecated using "id" as key can cause problems in some JS based languages like Qml @see gxs_id instead + << makeKeyValueReference("gxs_id", grp.mMeta.mGroupId) + << makeKeyValueReference("pgp_id",grp.mPgpId ) + << makeKeyValueReference("name", grp.mMeta.mGroupName) + << makeKeyValueReference("pgp_linked", pgp_linked); + } + } + } + else ok = false; + + if(ok) resp.setOk(); + else resp.setFail(); +} + +void IdentityHandler::handleOwnIdsRequest(Request & /*req*/, Response &resp) +{ + bool ok = true; + + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts); + + time_t start = time(NULL); + while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + &&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + &&((time(NULL) < (start+10))) + ) + { +#ifdef WINDOWS_SYS + Sleep(500); +#else + usleep(500*1000); +#endif + } + + if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::vector grps; + ok &= mRsIdentity->getGroupData(token, grps); + for(std::vector::iterator vit = grps.begin(); vit != grps.end(); vit++) + { + RsGxsIdGroup& grp = *vit; + //electron: not very happy about this, i think the flags should stay hidden in rsidentities + if(vit->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) + { + bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ) ; + resp.mDataStream.getStreamToMember() + << makeKeyValueReference("own_gxs_id", grp.mMeta.mGroupId) + << makeKeyValueReference("pgp_id",grp.mPgpId ) + << makeKeyValueReference("name", grp.mMeta.mGroupName) + << makeKeyValueReference("pgp_linked", pgp_linked); + } + } + + } + else + ok = false; + + if(ok) resp.setOk(); + else resp.setFail(); +} + ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp) { StateToken state; diff --git a/libresapi/src/api/IdentityHandler.h b/libresapi/src/api/IdentityHandler.h index 5e5d67f13..1b54f5438 100644 --- a/libresapi/src/api/IdentityHandler.h +++ b/libresapi/src/api/IdentityHandler.h @@ -23,6 +23,9 @@ public: private: void handleWildcard(Request& req, Response& resp); + void handleNotOwnIdsRequest(Request& req, Response& resp); + void handleOwnIdsRequest(Request& req, Response& resp); + ResponseTask *handleOwn(Request& req, Response& resp); ResponseTask *handleCreateIdentity(Request& req, Response& resp); From 8624c9374de788394df09b5acb8913019302adf0 Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 25 Mar 2017 18:33:35 +0100 Subject: [PATCH 020/118] Added functions for hadling particular lobbies types to ChatHandler --- libresapi/src/api/ChatHandler.cpp | 107 ++++++++++++++++++++++++++++-- libresapi/src/api/ChatHandler.h | 4 ++ 2 files changed, 106 insertions(+), 5 deletions(-) diff --git a/libresapi/src/api/ChatHandler.cpp b/libresapi/src/api/ChatHandler.cpp index 4335389df..f50eaae9e 100644 --- a/libresapi/src/api/ChatHandler.cpp +++ b/libresapi/src/api/ChatHandler.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -158,6 +159,10 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs, addResourceHandler("initiate_distant_chat", this, &ChatHandler::handleInitiateDistantChatConnexion); addResourceHandler("distant_chat_status", this, &ChatHandler::handleDistantChatStatus); addResourceHandler("close_distant_chat", this, &ChatHandler::handleCloseDistantChatConnexion); + + addResourceHandler("private_lobbies", this, &ChatHandler::handlePrivateLobbies); + addResourceHandler("subscribed_public_lobbies", this, &ChatHandler::handleSubscribedPublicLobbies); + addResourceHandler("unsubscribed_public_lobbies", this, &ChatHandler::handleUnsubscribedPublicLobbies); } ChatHandler::~ChatHandler() @@ -928,15 +933,19 @@ void ChatHandler::handleMessages(Request &req, Response &resp) * doing it? */ tick(); + std::string chat_id; + req.mStream << makeKeyValueReference("chat_id", chat_id); + ChatId id(chat_id); + { RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ - ChatId id(req.mPath.top()); + // make response a list resp.mDataStream.getStreamToMember(); if(id.isNotSet()) { - resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); - return; + resp.setFail("\""+chat_id+"\" is not a valid chat id"); + return; } std::map >::iterator mit = mMsgs.find(id); if(mit == mMsgs.end()) @@ -973,10 +982,14 @@ void ChatHandler::handleSendMessage(Request &req, Response &resp) void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp) { RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ - ChatId id(req.mPath.top()); + + std::string chat_id; + req.mStream << makeKeyValueReference("chat_id", chat_id); + ChatId id(chat_id); + if(id.isNotSet()) { - resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); + resp.setFail("\""+chat_id+"\" is not a valid chat id"); return; } std::map >::iterator mit = mMsgs.find(id); @@ -1197,4 +1210,88 @@ void ChatHandler::handleCloseDistantChatConnexion(Request& req, Response& resp) else resp.setFail("Failed to close distant chat"); } +void ChatHandler::handlePrivateLobbies(Request &req, Response &resp) +{ + tick(); + + { + RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ + resp.mDataStream.getStreamToMember(); + for(std::vector::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit) + { + if(!vit->is_private) + continue; + uint32_t unread_msgs = 0; + ChatId chat_id(vit->id); + std::map >::iterator mit = mMsgs.find(chat_id); + if(mit != mMsgs.end()) + { + std::list& msgs = mit->second; + for(std::list::iterator lit = msgs.begin(); lit != msgs.end(); ++lit) + if(!lit->read) + unread_msgs++; + } + resp.mDataStream.getStreamToMember() << *vit << makeKeyValueReference("unread_msg_count", unread_msgs); + } + resp.mStateToken = mLobbiesStateToken; + } + resp.setOk(); +} + +void ChatHandler::handleSubscribedPublicLobbies(Request &req, Response &resp) +{ + tick(); + + { + RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ + resp.mDataStream.getStreamToMember(); + for(std::vector::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit) + { + if(!vit->subscribed || vit->is_private || vit->is_broadcast) + continue; + uint32_t unread_msgs = 0; + ChatId chat_id(vit->id); + std::map >::iterator mit = mMsgs.find(chat_id); + if(mit != mMsgs.end()) + { + std::list& msgs = mit->second; + for(std::list::iterator lit = msgs.begin(); lit != msgs.end(); ++lit) + if(!lit->read) + unread_msgs++; + } + resp.mDataStream.getStreamToMember() << *vit << makeKeyValueReference("unread_msg_count", unread_msgs); + } + resp.mStateToken = mLobbiesStateToken; + } + resp.setOk(); +} + +void ChatHandler::handleUnsubscribedPublicLobbies(Request &req, Response &resp) +{ + tick(); + + { + RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ + resp.mDataStream.getStreamToMember(); + for(std::vector::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit) + { + if(vit->subscribed || vit->is_private) + continue; + uint32_t unread_msgs = 0; + ChatId chat_id(vit->id); + std::map >::iterator mit = mMsgs.find(chat_id); + if(mit != mMsgs.end()) + { + std::list& msgs = mit->second; + for(std::list::iterator lit = msgs.begin(); lit != msgs.end(); ++lit) + if(!lit->read) + unread_msgs++; + } + resp.mDataStream.getStreamToMember() << *vit << makeKeyValueReference("unread_msg_count", unread_msgs); + } + resp.mStateToken = mLobbiesStateToken; + } + resp.setOk(); +} + } // namespace resource_api diff --git a/libresapi/src/api/ChatHandler.h b/libresapi/src/api/ChatHandler.h index dc075c77f..056629c06 100644 --- a/libresapi/src/api/ChatHandler.h +++ b/libresapi/src/api/ChatHandler.h @@ -133,6 +133,10 @@ private: void handleDistantChatStatus(Request& req, Response& resp); void handleCloseDistantChatConnexion(Request& req, Response& resp); + void handlePrivateLobbies(Request &req, Response &resp); + void handleSubscribedPublicLobbies(Request &req, Response &resp); + void handleUnsubscribedPublicLobbies(Request &req, Response &resp); + void getPlainText(const std::string& in, std::string &out, std::vector &links); // last parameter is only used for lobbies! void locked_storeTypingInfo(const ChatId& chat_id, std::string status, RsGxsId lobby_gxs_id = RsGxsId()); From bef75408da0d4c58e996f02b6ac34daca0672110 Mon Sep 17 00:00:00 2001 From: Konrad Date: Sun, 26 Mar 2017 15:11:07 +0200 Subject: [PATCH 021/118] Fixed building on Travis CI --- libresapi/src/libresapi.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libresapi/src/libresapi.pro b/libresapi/src/libresapi.pro index 31de982b3..33c4f726c 100644 --- a/libresapi/src/libresapi.pro +++ b/libresapi/src/libresapi.pro @@ -3,7 +3,8 @@ TEMPLATE = lib CONFIG += staticlib CONFIG += create_prl -CONFIG -= qt +CONFIG += qt +QT += core TARGET = resapi TARGET_PRL = libresapi DESTDIR = lib From c33107c1cc4bc17cf154c33039690e6047eff72a Mon Sep 17 00:00:00 2001 From: Konrad Date: Sun, 26 Mar 2017 19:12:04 +0200 Subject: [PATCH 022/118] Fixed: backward comptiblity --- libresapi/src/api/ChatHandler.cpp | 14 ++++---------- libresapi/src/api/IdentityHandler.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/libresapi/src/api/ChatHandler.cpp b/libresapi/src/api/ChatHandler.cpp index f50eaae9e..68f0bd356 100644 --- a/libresapi/src/api/ChatHandler.cpp +++ b/libresapi/src/api/ChatHandler.cpp @@ -933,18 +933,15 @@ void ChatHandler::handleMessages(Request &req, Response &resp) * doing it? */ tick(); - std::string chat_id; - req.mStream << makeKeyValueReference("chat_id", chat_id); - ChatId id(chat_id); - { RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ + ChatId id(req.mPath.top()); // make response a list resp.mDataStream.getStreamToMember(); if(id.isNotSet()) { - resp.setFail("\""+chat_id+"\" is not a valid chat id"); + resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); return; } std::map >::iterator mit = mMsgs.find(id); @@ -982,14 +979,11 @@ void ChatHandler::handleSendMessage(Request &req, Response &resp) void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp) { RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ - - std::string chat_id; - req.mStream << makeKeyValueReference("chat_id", chat_id); - ChatId id(chat_id); + ChatId id(req.mPath.top()); if(id.isNotSet()) { - resp.setFail("\""+chat_id+"\" is not a valid chat id"); + resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); return; } std::map >::iterator mit = mMsgs.find(id); diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 9f01442df..1a43211ea 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -102,9 +102,10 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden mNotify->registerNotifyClient(this); addResourceHandler("*", this, &IdentityHandler::handleWildcard); - //addResourceHandler("own", this, &IdentityHandler::handleOwn); - addResourceHandler("own", this, &IdentityHandler::handleOwnIdsRequest); - addResourceHandler("notown", this, &IdentityHandler::handleNotOwnIdsRequest); + addResourceHandler("own", this, &IdentityHandler::handleOwn); + + addResourceHandler("own_ids", this, &IdentityHandler::handleOwnIdsRequest); + addResourceHandler("notown_ids", this, &IdentityHandler::handleNotOwnIdsRequest); addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity); } From 4031e493fba5c275e3b9d7c89630e5bdc3da56bd Mon Sep 17 00:00:00 2001 From: Konrad Date: Mon, 27 Mar 2017 16:11:04 +0200 Subject: [PATCH 023/118] Deleted: unused stateTokens --- libresapi/src/api/PeersHandler.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index d77a39651..b8fdc913d 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -181,7 +181,6 @@ void PeersHandler::handleGetStateString(Request& req, Response& resp) { { RS_STACK_MUTEX(mMtx); - resp.mStateToken = mStateToken; } std::string state_string; @@ -210,7 +209,6 @@ void PeersHandler::handleSetStateString(Request& req, Response& resp) { { RS_STACK_MUTEX(mMtx); - resp.mStateToken = mStateToken; } std::string state_string; @@ -232,7 +230,6 @@ void PeersHandler::handleGetCustomStateString(Request& req, Response& resp) { { RS_STACK_MUTEX(mMtx); - resp.mStateToken = mStateToken; } std::string custom_state_string = rsMsgs->getCustomStateString(); @@ -244,7 +241,6 @@ void PeersHandler::handleSetCustomStateString(Request& req, Response& resp) { { RS_STACK_MUTEX(mMtx); - resp.mStateToken = mStateToken; } std::string custom_state_string; From 569458a1c1847f42dca8556e92a9275af1a13a4b Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 28 Mar 2017 11:18:27 +0200 Subject: [PATCH 024/118] Changed: Qt dependecies are optional --- libresapi/src/api/ApiServer.cpp | 15 +++++++-- libresapi/src/libresapi.pro | 55 ++++++++++++++++++--------------- retroshare.pri | 6 ++++ 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/libresapi/src/api/ApiServer.cpp b/libresapi/src/api/ApiServer.cpp index 6efadeaf6..327dd6260 100644 --- a/libresapi/src/api/ApiServer.cpp +++ b/libresapi/src/api/ApiServer.cpp @@ -17,7 +17,9 @@ #include "ChannelsHandler.h" #include "StatsHandler.h" -#include "SettingsHandler.h" +#ifdef LIBRESAPI_QT + #include "SettingsHandler.h" +#endif /* data types in json http://json.org/ @@ -238,8 +240,10 @@ public: mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler), mApiPluginHandler(sts, ifaces), mChannelsHandler(ifaces.mGxsChannels), - mStatsHandler(), - mSettingsHandler(sts) + mStatsHandler() +#ifdef LIBRESAPI_QT + ,mSettingsHandler(sts) +#endif { // the dynamic cast is to not confuse the addResourceHandler template like this: // addResourceHandler(derived class, parent class) @@ -265,8 +269,10 @@ public: &ChannelsHandler::handleRequest); router.addResourceHandler("stats", dynamic_cast(&mStatsHandler), &StatsHandler::handleRequest); +#ifdef LIBRESAPI_QT router.addResourceHandler("settings", dynamic_cast(&mSettingsHandler), &SettingsHandler::handleRequest); +#endif } PeersHandler mPeersHandler; @@ -279,7 +285,10 @@ public: ApiPluginHandler mApiPluginHandler; ChannelsHandler mChannelsHandler; StatsHandler mStatsHandler; + +#ifdef LIBRESAPI_QT SettingsHandler mSettingsHandler; +#endif }; ApiServer::ApiServer(): diff --git a/libresapi/src/libresapi.pro b/libresapi/src/libresapi.pro index 33c4f726c..e548ea9d0 100644 --- a/libresapi/src/libresapi.pro +++ b/libresapi/src/libresapi.pro @@ -3,8 +3,7 @@ TEMPLATE = lib CONFIG += staticlib CONFIG += create_prl -CONFIG += qt -QT += core +CONFIG -= qt TARGET = resapi TARGET_PRL = libresapi DESTDIR = lib @@ -13,32 +12,32 @@ INCLUDEPATH += ../../libretroshare/src retroshare_android_service { win32 { - OBJECTS_DIR = temp/obj + OBJECTS_DIR = temp/obj - LIBS_DIR = $$PWD/../../libs/lib - LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a - LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a + LIBS_DIR = $$PWD/../../libs/lib + LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a + LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a - for(lib, LIB_DIR):LIBS += -L"$$lib" - for(bin, BIN_DIR):LIBS += -L"$$bin" + for(lib, LIB_DIR):LIBS += -L"$$lib" + for(bin, BIN_DIR):LIBS += -L"$$bin" - LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32 - LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 - LIBS += -lwinmm + LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32 + LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 + LIBS += -lwinmm - DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T + DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T - DEPENDPATH += . $$INC_DIR - INCLUDEPATH += . $$INC_DIR + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR - greaterThan(QT_MAJOR_VERSION, 4) { - # Qt 5 - RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src - } else { - # Qt 4 - QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src - } + greaterThan(QT_MAJOR_VERSION, 4) { + # Qt 5 + RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src + } else { + # Qt 4 + QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src + } } DEPENDPATH += . ../../libretroshare/src/ @@ -183,8 +182,7 @@ SOURCES += \ util/ContentTypes.cpp \ api/ApiPluginHandler.cpp \ api/ChannelsHandler.cpp \ - api/StatsHandler.cpp \ - api/SettingsHandler.cpp + api/StatsHandler.cpp HEADERS += \ api/ApiServer.h \ @@ -211,8 +209,7 @@ HEADERS += \ util/ContentTypes.h \ api/ApiPluginHandler.h \ api/ChannelsHandler.h \ - api/StatsHandler.h \ - api/SettingsHandler.h + api/StatsHandler.h libresapilocalserver { CONFIG *= qt @@ -220,3 +217,11 @@ libresapilocalserver { SOURCES *= api/ApiServerLocal.cpp HEADERS *= api/ApiServerLocal.h } + +qt_dependencies { + CONFIG *= qt + QT *= core + + SOURCES += api/SettingsHandler.cpp + HEADERS += api/SettingsHandler.h +} diff --git a/retroshare.pri b/retroshare.pri index 498131aea..e27348311 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -29,6 +29,11 @@ retroshare_qml_app:CONFIG -= no_retroshare_qml_app CONFIG *= no_libresapilocalserver libresapilocalserver:CONFIG -= no_libresapilocalserver +# To enable Qt dependencies in libresapi append the following +# assignation to qmake command line "CONFIG+=qt_dependencies" +CONFIG *= no_qt_dependencies +qt_dependencies:CONFIG -= no_qt_dependencies + # To disable libresapi via HTTP (based on libmicrohttpd) append the following # assignation to qmake command line "CONFIG+=no_libresapihttpserver" CONFIG *= libresapihttpserver @@ -155,6 +160,7 @@ unfinished { wikipoos:DEFINES *= RS_USE_WIKI rs_gxs:DEFINES *= RS_ENABLE_GXS libresapilocalserver:DEFINES *= LIBRESAPI_LOCAL_SERVER +qt_dependencies:DEFINES *= LIBRESAPI_QT libresapihttpserver:DEFINES *= ENABLE_WEBUI sqlcipher:DEFINES -= NO_SQLCIPHER no_sqlcipher:DEFINES *= NO_SQLCIPHER From efd6ce3ed518af7462689ed467fda66cdf6c0831 Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 28 Mar 2017 11:19:50 +0200 Subject: [PATCH 025/118] Changed: Simplified asking for deferred self signature --- libresapi/src/api/RsControlModule.cpp | 115 ++------------------------ libresapi/src/api/RsControlModule.h | 5 -- 2 files changed, 6 insertions(+), 114 deletions(-) diff --git a/libresapi/src/api/RsControlModule.cpp b/libresapi/src/api/RsControlModule.cpp index 228bb691a..595509f09 100644 --- a/libresapi/src/api/RsControlModule.cpp +++ b/libresapi/src/api/RsControlModule.cpp @@ -458,120 +458,17 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp) resp.setFail("could not create a new location. Error: "+err_string); } -class SignatureEventData -{ - public: - SignatureEventData(const void *_data,int32_t _len,unsigned int _signlen, std::string _reason) - { - // We need a new memory chnk because there's no guarranty _sign nor _signlen are not in the stack - - sign = (unsigned char *)rs_malloc(_signlen); - - if(!sign) - { - signlen = NULL; - signature_result = SELF_SIGNATURE_RESULT_FAILED; - return; - } - - signlen = new unsigned int; - *signlen = _signlen; - signature_result = SELF_SIGNATURE_RESULT_PENDING; - data = rs_malloc(_len); - - if(!data) - { - len = 0; - return; - } - len = _len; - memcpy(data,_data,len); - reason = _reason; - } - - ~SignatureEventData() - { - free(sign); - delete signlen; - free(data); - } - - void performSignature() - { - if(rsPeers->gpgSignData(data,len,sign,signlen,reason)) - signature_result = SELF_SIGNATURE_RESULT_SUCCESS; - else - signature_result = SELF_SIGNATURE_RESULT_FAILED; - } - - void *data; - uint32_t len; - unsigned char *sign; - unsigned int *signlen; - int signature_result; // 0=pending, 1=done, 2=failed/cancelled. - std::string reason; -}; - bool RsControlModule::askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason /*=""*/) { - + if(rsPeers->gpgSignData(data,len,sign,signlen,reason)) { - RsStackMutex stack(mDataMtx); - std::cerr << "NotifyTxt:: deferred signature event requeted. " << std::endl; - - // Look into the queue - - Sha1CheckSum chksum = RsDirUtil::sha1sum((uint8_t*)data,len); - - std::map::iterator it = _deferred_signature_queue.find(chksum.toStdString()); - signature_result = SELF_SIGNATURE_RESULT_PENDING; - - if(it != _deferred_signature_queue.end()) - { - signature_result = it->second->signature_result; - - if(it->second->signature_result != SELF_SIGNATURE_RESULT_PENDING) // found it. Copy the result, and remove from the queue. - { - // We should check for the exact data match, for the sake of being totally secure. - // - std::cerr << "Found into queue: returning it" << std::endl; - - memcpy(sign,it->second->sign,*it->second->signlen); - *signlen = *(it->second->signlen); - - delete it->second; - _deferred_signature_queue.erase(it); - } - - return true; // already registered, but not done yet. - } - - // Not found. Store in the queue and emit a signal. - // - std::cerr << "NotifyTxt:: deferred signature event requeted. Pushing into queue" << std::endl; - - SignatureEventData *edta = new SignatureEventData(data,len,*signlen, reason); - - _deferred_signature_queue[chksum.toStdString()] = edta; + signature_result = SELF_SIGNATURE_RESULT_SUCCESS; + return true; } - handleSignatureEvent(); - return true; -} - -void RsControlModule::handleSignatureEvent() -{ - std::cerr << "NotifyTxt:: performing a deferred signature in the main GUI thread." << std::endl; - - static bool working = false ; - - if(!working) + else { - working = true ; - - for(std::map::const_iterator it(_deferred_signature_queue.begin());it!=_deferred_signature_queue.end();++it) - it->second->performSignature() ; - - working = false ; + signature_result = SELF_SIGNATURE_RESULT_FAILED; + return false; } } diff --git a/libresapi/src/api/RsControlModule.h b/libresapi/src/api/RsControlModule.h index 338027e15..1323651fc 100644 --- a/libresapi/src/api/RsControlModule.h +++ b/libresapi/src/api/RsControlModule.h @@ -9,8 +9,6 @@ namespace resource_api{ class StateTokenServer; class ApiServer; -class SignatureEventData; - // resource api module to control accounts, startup and shutdown of retroshare // - this module handles everything, no things are required from outside // - exception: users of this module have to create an api server and register this module @@ -87,9 +85,6 @@ private: // we store the password in this variable, it has higher priority than the normal password variable // it is also to avoid a lock, when we make a synchronous call into librs, like in ssl cert generation std::string mFixedPassword; - - void handleSignatureEvent(); - std::map _deferred_signature_queue ; }; } // namespace resource_api From 6e530027f8fec09479446316a1bbce92ac749e9d Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 28 Mar 2017 11:20:51 +0200 Subject: [PATCH 026/118] Added: tokens in PeersHandler --- libresapi/src/api/PeersHandler.cpp | 37 +++++++++++++++++++++--------- libresapi/src/api/PeersHandler.h | 5 ++++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index b8fdc913d..f48beb2f6 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -116,9 +116,9 @@ PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *pee mStateTokenServer->registerTickClient(this); addResourceHandler("*", this, &PeersHandler::handleWildcard); addResourceHandler("get_state_string", this, &PeersHandler::handleGetStateString); - addResourceHandler("set_state_string", this, &PeersHandler::handleSetStateString); - addResourceHandler("get_custom_state_string", this, &PeersHandler::handleGetCustomStateString); - addResourceHandler("set_custom_state_string", this, &PeersHandler::handleSetCustomStateString); + addResourceHandler("set_state_string", this, &PeersHandler::handleSetStateString); + addResourceHandler("get_custom_state_string", this, &PeersHandler::handleGetCustomStateString); + addResourceHandler("set_custom_state_string", this, &PeersHandler::handleSetCustomStateString); addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert); } @@ -156,6 +156,27 @@ void PeersHandler::tick() mStateTokenServer->discardToken(mStateToken); mStateToken = mStateTokenServer->getNewToken(); } + + StatusInfo statusInfo; + rsStatus->getOwnStatus(statusInfo); + if(statusInfo.status != status) + { + status = statusInfo.status; + + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->discardToken(mStringStateToken); + mStringStateToken = mStateTokenServer->getNewToken(); + } + + std::string custom_state = rsMsgs->getCustomStateString(); + if(custom_state != custom_state_string) + { + custom_state_string = custom_state; + + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->discardToken(mCustomStateToken); + mCustomStateToken = mStateTokenServer->getNewToken(); + } } void PeersHandler::notifyUnreadMsgCountChanged(const RsPeerId &peer, uint32_t count) @@ -181,6 +202,7 @@ void PeersHandler::handleGetStateString(Request& req, Response& resp) { { RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStringStateToken; } std::string state_string; @@ -207,10 +229,6 @@ void PeersHandler::handleGetStateString(Request& req, Response& resp) void PeersHandler::handleSetStateString(Request& req, Response& resp) { - { - RS_STACK_MUTEX(mMtx); - } - std::string state_string; req.mStream << makeKeyValueReference("state_string", state_string); @@ -230,6 +248,7 @@ void PeersHandler::handleGetCustomStateString(Request& req, Response& resp) { { RS_STACK_MUTEX(mMtx); + resp.mStateToken = mCustomStateToken; } std::string custom_state_string = rsMsgs->getCustomStateString(); @@ -239,10 +258,6 @@ void PeersHandler::handleGetCustomStateString(Request& req, Response& resp) void PeersHandler::handleSetCustomStateString(Request& req, Response& resp) { - { - RS_STACK_MUTEX(mMtx); - } - std::string custom_state_string; req.mStream << makeKeyValueReference("custom_state_string", custom_state_string); diff --git a/libresapi/src/api/PeersHandler.h b/libresapi/src/api/PeersHandler.h index a2eab706b..15d231c10 100644 --- a/libresapi/src/api/PeersHandler.h +++ b/libresapi/src/api/PeersHandler.h @@ -50,9 +50,14 @@ private: RsMsgs* mRsMsgs; // required for avatar data std::list mOnlinePeers; + uint32_t status; + std::string custom_state_string; RsMutex mMtx; StateToken mStateToken; // mutex protected + StateToken mStringStateToken; // mutex protected + StateToken mCustomStateToken; // mutex protected + std::map mUnreadMsgsCounts; }; } // namespace resource_api From 22956be00f1fd9a79dd6b95295eeda762847df51 Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 28 Mar 2017 11:24:16 +0200 Subject: [PATCH 027/118] Deleted: functions for hadling particular lobbies types in ChatHandler --- libresapi/src/api/ChatHandler.cpp | 88 ------------------------------- libresapi/src/api/ChatHandler.h | 4 -- 2 files changed, 92 deletions(-) diff --git a/libresapi/src/api/ChatHandler.cpp b/libresapi/src/api/ChatHandler.cpp index 68f0bd356..511993a29 100644 --- a/libresapi/src/api/ChatHandler.cpp +++ b/libresapi/src/api/ChatHandler.cpp @@ -159,10 +159,6 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs, addResourceHandler("initiate_distant_chat", this, &ChatHandler::handleInitiateDistantChatConnexion); addResourceHandler("distant_chat_status", this, &ChatHandler::handleDistantChatStatus); addResourceHandler("close_distant_chat", this, &ChatHandler::handleCloseDistantChatConnexion); - - addResourceHandler("private_lobbies", this, &ChatHandler::handlePrivateLobbies); - addResourceHandler("subscribed_public_lobbies", this, &ChatHandler::handleSubscribedPublicLobbies); - addResourceHandler("unsubscribed_public_lobbies", this, &ChatHandler::handleUnsubscribedPublicLobbies); } ChatHandler::~ChatHandler() @@ -1204,88 +1200,4 @@ void ChatHandler::handleCloseDistantChatConnexion(Request& req, Response& resp) else resp.setFail("Failed to close distant chat"); } -void ChatHandler::handlePrivateLobbies(Request &req, Response &resp) -{ - tick(); - - { - RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ - resp.mDataStream.getStreamToMember(); - for(std::vector::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit) - { - if(!vit->is_private) - continue; - uint32_t unread_msgs = 0; - ChatId chat_id(vit->id); - std::map >::iterator mit = mMsgs.find(chat_id); - if(mit != mMsgs.end()) - { - std::list& msgs = mit->second; - for(std::list::iterator lit = msgs.begin(); lit != msgs.end(); ++lit) - if(!lit->read) - unread_msgs++; - } - resp.mDataStream.getStreamToMember() << *vit << makeKeyValueReference("unread_msg_count", unread_msgs); - } - resp.mStateToken = mLobbiesStateToken; - } - resp.setOk(); -} - -void ChatHandler::handleSubscribedPublicLobbies(Request &req, Response &resp) -{ - tick(); - - { - RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ - resp.mDataStream.getStreamToMember(); - for(std::vector::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit) - { - if(!vit->subscribed || vit->is_private || vit->is_broadcast) - continue; - uint32_t unread_msgs = 0; - ChatId chat_id(vit->id); - std::map >::iterator mit = mMsgs.find(chat_id); - if(mit != mMsgs.end()) - { - std::list& msgs = mit->second; - for(std::list::iterator lit = msgs.begin(); lit != msgs.end(); ++lit) - if(!lit->read) - unread_msgs++; - } - resp.mDataStream.getStreamToMember() << *vit << makeKeyValueReference("unread_msg_count", unread_msgs); - } - resp.mStateToken = mLobbiesStateToken; - } - resp.setOk(); -} - -void ChatHandler::handleUnsubscribedPublicLobbies(Request &req, Response &resp) -{ - tick(); - - { - RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ - resp.mDataStream.getStreamToMember(); - for(std::vector::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit) - { - if(vit->subscribed || vit->is_private) - continue; - uint32_t unread_msgs = 0; - ChatId chat_id(vit->id); - std::map >::iterator mit = mMsgs.find(chat_id); - if(mit != mMsgs.end()) - { - std::list& msgs = mit->second; - for(std::list::iterator lit = msgs.begin(); lit != msgs.end(); ++lit) - if(!lit->read) - unread_msgs++; - } - resp.mDataStream.getStreamToMember() << *vit << makeKeyValueReference("unread_msg_count", unread_msgs); - } - resp.mStateToken = mLobbiesStateToken; - } - resp.setOk(); -} - } // namespace resource_api diff --git a/libresapi/src/api/ChatHandler.h b/libresapi/src/api/ChatHandler.h index 056629c06..dc075c77f 100644 --- a/libresapi/src/api/ChatHandler.h +++ b/libresapi/src/api/ChatHandler.h @@ -133,10 +133,6 @@ private: void handleDistantChatStatus(Request& req, Response& resp); void handleCloseDistantChatConnexion(Request& req, Response& resp); - void handlePrivateLobbies(Request &req, Response &resp); - void handleSubscribedPublicLobbies(Request &req, Response &resp); - void handleUnsubscribedPublicLobbies(Request &req, Response &resp); - void getPlainText(const std::string& in, std::string &out, std::vector &links); // last parameter is only used for lobbies! void locked_storeTypingInfo(const ChatId& chat_id, std::string status, RsGxsId lobby_gxs_id = RsGxsId()); From fbc1bb4e823209ad534f75552f06264fd4b69a9d Mon Sep 17 00:00:00 2001 From: Konrad Date: Wed, 29 Mar 2017 16:06:39 +0200 Subject: [PATCH 028/118] Added: function for handling autosubscribing lobbies --- libresapi/src/api/ChatHandler.cpp | 10 ++++++++++ libresapi/src/api/ChatHandler.h | 1 + 2 files changed, 11 insertions(+) diff --git a/libresapi/src/api/ChatHandler.cpp b/libresapi/src/api/ChatHandler.cpp index 511993a29..f576f8601 100644 --- a/libresapi/src/api/ChatHandler.cpp +++ b/libresapi/src/api/ChatHandler.cpp @@ -147,6 +147,7 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs, addResourceHandler("lobbies", this, &ChatHandler::handleLobbies); addResourceHandler("subscribe_lobby", this, &ChatHandler::handleSubscribeLobby); addResourceHandler("unsubscribe_lobby", this, &ChatHandler::handleUnsubscribeLobby); + addResourceHandler("autosubscribe_lobby", this, &ChatHandler::handleAutoSubsribeLobby); addResourceHandler("clear_lobby", this, &ChatHandler::handleClearLobby); addResourceHandler("lobby_participants", this, &ChatHandler::handleLobbyParticipants); addResourceHandler("messages", this, &ChatHandler::handleMessages); @@ -890,6 +891,15 @@ void ChatHandler::handleUnsubscribeLobby(Request &req, Response &resp) resp.setOk(); } +void ChatHandler::handleAutoSubsribeLobby(Request& req, Response& resp) +{ + ChatLobbyId chatId = 0; + bool autosubsribe; + req.mStream << makeKeyValueReference("chatid", chatId) << makeKeyValueReference("autosubsribe", autosubsribe); + mRsMsgs->setLobbyAutoSubscribe(chatId, autosubsribe); + resp.setOk(); +} + void ChatHandler::handleClearLobby(Request &req, Response &resp) { ChatLobbyId id = 0; diff --git a/libresapi/src/api/ChatHandler.h b/libresapi/src/api/ChatHandler.h index dc075c77f..3463cee57 100644 --- a/libresapi/src/api/ChatHandler.h +++ b/libresapi/src/api/ChatHandler.h @@ -120,6 +120,7 @@ private: void handleLobbies(Request& req, Response& resp); void handleSubscribeLobby(Request& req, Response& resp); void handleUnsubscribeLobby(Request& req, Response& resp); + void handleAutoSubsribeLobby(Request& req, Response& resp); void handleClearLobby(Request& req, Response& resp); ResponseTask* handleLobbyParticipants(Request& req, Response& resp); void handleMessages(Request& req, Response& resp); From 8543525c77f6c54f44ef58221c0f07b3c6cee69c Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 1 Apr 2017 14:28:55 +0200 Subject: [PATCH 029/118] Fixed: Linker problem --- .../src/retroshare-android-service.pro | 20 +++++++++---------- retroshare-android-service/src/service.cpp | 2 -- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/retroshare-android-service/src/retroshare-android-service.pro b/retroshare-android-service/src/retroshare-android-service.pro index e45067f81..54843d34f 100644 --- a/retroshare-android-service/src/retroshare-android-service.pro +++ b/retroshare-android-service/src/retroshare-android-service.pro @@ -11,6 +11,16 @@ android-g++:CONFIG += dll android-g++:TEMPLATE = lib !android-g++:TEMPLATE = app +DEPENDPATH *= ../../libresapi/src +INCLUDEPATH *= ../../libresapi/src +PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a +LIBS *= ../../libresapi/src/lib/libresapi.a + +DEPENDPATH *= ../../libretroshare/src +INCLUDEPATH *= ../../libretroshare/src +PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a +LIBS *= ../../libretroshare/src/lib/libretroshare.a + win32 { OBJECTS_DIR = temp/obj @@ -41,13 +51,3 @@ win32 { } SOURCES += service.cpp - -DEPENDPATH *= ../../libresapi/src -INCLUDEPATH *= ../../libresapi/src -PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a -LIBS *= ../../libresapi/src/lib/libresapi.a - -DEPENDPATH *= ../../libretroshare/src -INCLUDEPATH *= ../../libretroshare/src -PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a -LIBS *= ../../libretroshare/src/lib/libretroshare.a diff --git a/retroshare-android-service/src/service.cpp b/retroshare-android-service/src/service.cpp index afe73bfc3..c822e8718 100644 --- a/retroshare-android-service/src/service.cpp +++ b/retroshare-android-service/src/service.cpp @@ -40,8 +40,6 @@ int main(int argc, char *argv[]) QCoreApplication a(argc, argv); - RsInit::InitRsConfig(); - ApiServer api; RsControlModule ctrl_mod(argc, argv, api.getStateTokenServer(), &api, true); api.addResourceHandler("control", dynamic_cast(&ctrl_mod), &resource_api::RsControlModule::handleRequest); From 6e65fcd6acf95e32a2ecde450abe67248888a660 Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 1 Apr 2017 14:32:49 +0200 Subject: [PATCH 030/118] Removed: Unused #include statement --- retroshare-android-service/src/service.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/retroshare-android-service/src/service.cpp b/retroshare-android-service/src/service.cpp index c822e8718..84ec62301 100644 --- a/retroshare-android-service/src/service.cpp +++ b/retroshare-android-service/src/service.cpp @@ -24,12 +24,10 @@ # include "util/androiddebug.h" #endif -#include "retroshare/rsinit.h" #include "api/ApiServer.h" #include "api/ApiServerLocal.h" #include "api/RsControlModule.h" - using namespace resource_api; int main(int argc, char *argv[]) From f175533d8df9f7952fc7284718c7aa63cc6e6689 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 8 Apr 2017 14:06:47 +0200 Subject: [PATCH 031/118] Fix comment view when they have line return. Before, they grow row height but only show 2 lines. Now, height stay at one line, but tooltip show the correct message. --- retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp | 5 +++++ retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index 2fa1f3b1e..a99e815c7 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -25,6 +25,7 @@ #include #include +#include "gui/common/RSElidedItemDelegate.h" #include "gui/gxs/GxsCommentTreeWidget.h" #include "gui/gxs/GxsCreateCommentDialog.h" #include "gui/gxs/GxsIdTreeWidgetItem.h" @@ -57,6 +58,10 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) // QTreeWidget* widget = this; setContextMenuPolicy(Qt::CustomContextMenu); + RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); + itemDelegate->setSpacing(QSize(0, 2)); + setItemDelegate(itemDelegate); + setWordWrap(true); // QFont font = QFont("ARIAL", 10); // font.setBold(true); diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp index a1e20e37c..500693df0 100644 --- a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp @@ -25,6 +25,8 @@ #include "GxsCreateCommentDialog.h" #include "ui_GxsCreateCommentDialog.h" +#include "util/HandleRichText.h" + #include #include @@ -45,7 +47,11 @@ void GxsCreateCommentDialog::createComment() { RsGxsComment comment; - comment.mComment = std::string(ui->commentTextEdit->document()->toPlainText().toUtf8()); + QString text = ui->commentTextEdit->toHtml(); + RsHtml::optimizeHtml(text); + std::string msg = text.toUtf8().constData(); + + comment.mComment = msg; comment.mMeta.mParentId = mParentId.second; comment.mMeta.mGroupId = mParentId.first; comment.mMeta.mThreadId = mThreadId; From 4f5da86acaa8f1602c8f95cc25a176653322db5b Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 8 Apr 2017 19:07:33 +0200 Subject: [PATCH 032/118] added method to serialise/deserialise groups to/from memory and export of GxsIdentities to memory chunk in radix format --- libretroshare/src/gxs/rsgenexchange.cc | 52 ++++++++++++ libretroshare/src/gxs/rsgenexchange.h | 14 ++++ libretroshare/src/retroshare/rsidentity.h | 3 + libretroshare/src/services/p3idservice.cc | 96 +++++++++++++++++++++-- libretroshare/src/services/p3idservice.h | 17 ++++ 5 files changed, 175 insertions(+), 7 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index a334f7e3d..4d70ee409 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -1273,6 +1273,58 @@ bool RsGenExchange::getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMa return ok; } +bool RsGenExchange::getSerializedGroupData(const uint32_t &token, RsGxsGroupId& id,unsigned char *& data,uint32_t& size) +{ + RS_STACK_MUTEX(mGenMtx) ; + + std::list nxsGrps; + + if(!mDataAccess->getGroupData(token, nxsGrps)) + return false ; + + if(nxsGrps.size() != 1) + { + std::cerr << "(EE) getSerializedGroupData() got multiple groups in single request. This is unexpected." << std::endl; + + for(std::list::const_iterator it(nxsGrps.begin());it!=nxsGrps.end();++it) + delete *it ; + + return false ; + } + RsNxsGrp *nxs_grp = *(nxsGrps.begin()); + + size = nxs_grp->serial_size() ; + id = nxs_grp->metaData->mGroupId ; + + if(size > 1024*1024 || NULL==(data = (unsigned char *)rs_malloc(size))) + { + std::cerr << "(EE) getSerializedGroupData() cannot allocate mem chunk of size " << size << ". Too big, or no room." << std::endl; + delete nxs_grp ; + return false ; + } + + return nxs_grp->serialise(data,size) ; +} + +bool RsGenExchange::deserializeGroupData(unsigned char *data,uint32_t size) +{ + RS_STACK_MUTEX(mGenMtx) ; + + RsItem *item = mSerialiser->deserialise(data, &size); + + RsNxsGrp *nxs_grp = dynamic_cast(item) ; + + if(item == NULL) + { + std::cerr << "(EE) RsGenExchange::deserializeGroupData(): cannot deserialise this data. Something's wrong." << std::endl; + delete item ; + return false ; + } + + mReceivedGrps.push_back( GxsPendingItem(nxs_grp, nxs_grp->metaData->mGroupId,time(NULL)) ); + + return true ; +} bool RsGenExchange::getGroupData(const uint32_t &token, std::vector& grpItem) { diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 21ea4365c..ec9c0d3f0 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -288,6 +288,20 @@ protected: */ bool getGroupData(const uint32_t &token, std::vector& grpItem); + /*! + * \brief getSerializedGroupData + * Retrieves the complete group data serialized into a chunk of memory. This can be useful to + * transfer a full group from one machine to another. + * + * \param token token previously obtained from cache request + * \param data memory chunk allocated (using malloc) + * \param size size of the memory chunk. + * \return + */ + + bool getSerializedGroupData(const uint32_t &token, RsGxsGroupId &id, unsigned char *& data, uint32_t& size); + bool deserializeGroupData(unsigned char *data, uint32_t size); + template bool getGroupDataT(const uint32_t &token, std::vector& grpItem) { diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 82f4932a3..53704961d 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -305,6 +305,9 @@ public: virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) = 0 ; virtual bool isARegularContact(const RsGxsId& id) = 0 ; + virtual bool serialiseIdentityToMemory(const RsGxsId& id,std::string& radix_string)=0; + virtual bool deserialiseIdentityFromMemory(const std::string& radix_string)=0; + /*! * \brief overallReputationLevel * Returns the overall reputation level of the supplied identity. See rsreputations.h diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 53b922327..9aeec2aea 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -70,6 +70,8 @@ static const time_t MAX_KEEP_KEYS_SIGNED_KNOWN = 30 * 86400 ; // signed ident static const uint32_t MAX_DELAY_BEFORE_CLEANING= 1800 ; // clean old keys every 30 mins +static const uint32_t MAX_SERIALISED_IDENTITY_AGE = 600 ; // after 10 mins, a serialised identity record must be renewed. + RsIdentity *rsIdentity = NULL; /****** @@ -97,13 +99,12 @@ RsIdentity *rsIdentity = NULL; #define BG_REPUTATION 3 -#define GXSIDREQ_CACHELOAD 0x0001 -#define GXSIDREQ_CACHEOWNIDS 0x0002 - -#define GXSIDREQ_PGPHASH 0x0010 -#define GXSIDREQ_RECOGN 0x0020 - -#define GXSIDREQ_OPINION 0x0030 +#define GXSIDREQ_CACHELOAD 0x0001 +#define GXSIDREQ_CACHEOWNIDS 0x0002 +#define GXSIDREQ_PGPHASH 0x0010 +#define GXSIDREQ_RECOGN 0x0020 +#define GXSIDREQ_OPINION 0x0030 +#define GXSIDREQ_SERIALIZE_TO_MEMORY 0x0040 #define GXSIDREQ_CACHETEST 0x1000 @@ -697,6 +698,84 @@ bool p3IdService::getOwnIds(std::list &ownIds) return true ; } +bool p3IdService::serialiseIdentityToMemory(const RsGxsId& id,std::string& radix_string) +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + // look into cache. If available, return the data. If not, request it. + + std::map::const_iterator it = mSerialisedIdentities.find(id); + + if(it != mSerialisedIdentities.end()) + { + Radix64::encode(it->second.mMem,it->second.mSize,radix_string) ; + + if(it->second.mLastUsageTS + MAX_SERIALISED_IDENTITY_AGE > time(NULL)) + return true ; + + std::cerr << "Identity " << id << " will be re-serialised, because the last record is too old." << std::endl; + } + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token = 0; + std::list groupIds; + + groupIds.push_back(RsGxsGroupId(id)) ; + + RsGenExchange::getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); + GxsTokenQueue::queueRequest(token, GXSIDREQ_SERIALIZE_TO_MEMORY); + + return false; +} + +void p3IdService::handle_get_serialized_grp(uint32_t token) +{ + // store the serialized data in cache. + + unsigned char *mem = NULL; + uint32_t size; + RsGxsGroupId id ; + + if(!RsGenExchange::getSerializedGroupData(token,id, mem,size)) + { + std::cerr << "(EE) call to RsGenExchage::getSerializedGroupData() failed." << std::endl; + return ; + } + + std::cerr << "Received serialised group from RsGenExchange." << std::endl; + + std::map::const_iterator it = mSerialisedIdentities.find(RsGxsId(id)); + + if(it != mSerialisedIdentities.end()) + free(it->second.mMem) ; + + SerialisedIdentityStruct s ; + s.mMem = mem ; + s.mSize = size ; + s.mLastUsageTS = time(NULL) ; + + mSerialisedIdentities[RsGxsId(id)] = s ; +} + +bool p3IdService::deserialiseIdentityFromMemory(const std::string& radix_string) +{ + std::vector mem = Radix64::decode(radix_string) ; + + if(mem.empty()) + { + std::cerr << "Cannot decode radix string \"" << radix_string << "\"" << std::endl; + return false ; + } + + if(!RsGenExchange::deserializeGroupData(mem.data(),mem.size())) + { + std::cerr << "Cannot load identity from radix string \"" << radix_string << "\"" << std::endl; + return false ; + } + + return true ; +} bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) { @@ -4117,6 +4196,9 @@ void p3IdService::handleResponse(uint32_t token, uint32_t req_type) case GXSIDREQ_OPINION: opinion_handlerequest(token); break; + case GXSIDREQ_SERIALIZE_TO_MEMORY: + handle_get_serialized_grp(token) ; + default: /* error */ std::cerr << "p3IdService::handleResponse() Unknown Request Type: " << req_type; diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index addff0d1b..6e4585eb6 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -212,6 +212,13 @@ private: void init(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pub_key, const RsTlvPrivateRSAKey& in_priv_key,const std::list &tagList); }; +struct SerialisedIdentityStruct +{ + unsigned char *mMem ; + uint32_t mSize ; + time_t mLastUsageTS; +}; + // Not sure exactly what should be inherited here? // Chris - please correct as necessary. @@ -302,6 +309,8 @@ public: virtual bool requestKey(const RsGxsId &id, const std::list &peers, const RsIdentityUsage &use_info); virtual bool requestPrivateKey(const RsGxsId &id); + virtual bool serialiseIdentityToMemory(const RsGxsId& id,std::string& radix_string); + virtual bool deserialiseIdentityFromMemory(const std::string& radix_string); /**************** RsGixsReputation Implementation ****************/ @@ -394,6 +403,12 @@ private: bool mBgSchedule_Active; uint32_t mBgSchedule_Mode; + /***********************************8 + * Fonction to receive and handle group serialisation to memory + */ + + virtual void handle_get_serialized_grp(uint32_t token); + /************************************************************************ * pgphash processing. * @@ -524,6 +539,8 @@ private: std::map > mIdsNotPresent; std::map mKeysTS ; + std::map mSerialisedIdentities ; + // keep a list of regular contacts. This is useful to sort IDs, and allow some services to priviledged ids only. std::set mContacts; RsNetworkExchangeService* mNes; From 6d290389f029e89e96fbfd46b3971f075457e484 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 8 Apr 2017 21:12:48 +0200 Subject: [PATCH 033/118] added RSLink for GXS identities --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 335 ++++++++++--------- retroshare-gui/src/gui/Identity/IdDialog.h | 1 + retroshare-gui/src/gui/RetroShareLink.cpp | 59 +++- retroshare-gui/src/gui/RetroShareLink.h | 28 +- 4 files changed, 259 insertions(+), 164 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 25db8896d..4b28a1b09 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -2240,165 +2240,202 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req) void IdDialog::IdListCustomPopupMenu( QPoint ) { - QMenu *contextMenu = new QMenu(this); + QMenu *contextMenu = new QMenu(this); - std::list own_identities ; - rsIdentity->getOwnIds(own_identities) ; + std::list own_identities ; + rsIdentity->getOwnIds(own_identities) ; - // make some stats about what's selected. If the same value is used for all selected items, it can be switched. + // make some stats about what's selected. If the same value is used for all selected items, it can be switched. - QList selected_items = ui->idTreeWidget->selectedItems(); + QList selected_items = ui->idTreeWidget->selectedItems(); - bool root_node_present = false ; - bool one_item_owned_by_you = false ; - uint32_t n_positive_reputations = 0 ; - uint32_t n_negative_reputations = 0 ; - uint32_t n_neutral_reputations = 0 ; - uint32_t n_is_a_contact = 0 ; - uint32_t n_is_not_a_contact = 0 ; - uint32_t n_selected_items =0 ; + bool root_node_present = false ; + bool one_item_owned_by_you = false ; + uint32_t n_positive_reputations = 0 ; + uint32_t n_negative_reputations = 0 ; + uint32_t n_neutral_reputations = 0 ; + uint32_t n_is_a_contact = 0 ; + uint32_t n_is_not_a_contact = 0 ; + uint32_t n_selected_items =0 ; - for(QList::const_iterator it(selected_items.begin());it!=selected_items.end();++it) - { - if(*it == allItem || *it == contactsItem || *it == ownItem) - { - root_node_present = true ; - continue ; - } - - uint32_t item_flags = (*it)->data(RSID_COL_KEYID,Qt::UserRole).toUInt() ; - - if(item_flags & RSID_FILTER_OWNED_BY_YOU) - one_item_owned_by_you = true ; - -#ifdef ID_DEBUG - std::cerr << " item flags = " << item_flags << std::endl; -#endif - RsGxsId keyId((*it)->text(RSID_COL_KEYID).toStdString()); - - RsIdentityDetails det ; - rsIdentity->getIdDetails(keyId,det) ; - - switch(det.mReputation.mOwnOpinion) - { - case RsReputations::OPINION_NEGATIVE: ++n_negative_reputations ; - break ; - - case RsReputations::OPINION_POSITIVE: ++n_positive_reputations ; - break ; - - case RsReputations::OPINION_NEUTRAL: ++n_neutral_reputations ; - break ; - } - - ++n_selected_items ; - - if(rsIdentity->isARegularContact(keyId)) - ++n_is_a_contact ; - else - ++n_is_not_a_contact ; - } - - if(!root_node_present) // don't show menu if some of the root nodes are present + for(QList::const_iterator it(selected_items.begin());it!=selected_items.end();++it) + { + if(*it == allItem || *it == contactsItem || *it == ownItem) { - - if(!one_item_owned_by_you) - { - QWidget *widget = new QWidget(contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); - - // create menu header - QHBoxLayout *hbox = new QHBoxLayout(widget); - hbox->setMargin(0); - hbox->setSpacing(6); - - QLabel *iconLabel = new QLabel(widget); - QPixmap pix = QPixmap(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); - iconLabel->setPixmap(pix); - iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); - hbox->addWidget(iconLabel); - - QLabel *textLabel = new QLabel("" + ui->titleBarLabel->text() + "", widget); - hbox->addWidget(textLabel); - - QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - hbox->addItem(spacerItem); - - widget->setLayout(hbox); - - QWidgetAction *widgetAction = new QWidgetAction(this); - widgetAction->setDefaultWidget(widget); - contextMenu->addAction(widgetAction); - - if(n_selected_items == 1) // if only one item is selected, allow to chat with this item - { - if(own_identities.size() <= 1) - { - QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"), tr("Chat with this person"), this, SLOT(chatIdentity())); - - if(own_identities.empty()) - action->setEnabled(false) ; - else - action->setData(QString::fromStdString((own_identities.front()).toStdString())) ; - } - else - { - QMenu *mnu = contextMenu->addMenu(QIcon(":/images/chat_24.png"),tr("Chat with this person as...")) ; - - for(std::list::const_iterator it=own_identities.begin();it!=own_identities.end();++it) - { - RsIdentityDetails idd ; - rsIdentity->getIdDetails(*it,idd) ; - - QPixmap pixmap ; - - if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG")) - pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(*it)) ; - - QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity())); - action->setData(QString::fromStdString((*it).toStdString())) ; - } - } - } - - // always allow to send messages - contextMenu->addAction(QIcon(":/images/mail_new.png"), tr("Send message"), this, SLOT(sendMsg())); - - contextMenu->addSeparator(); - - if(n_is_a_contact == 0) - contextMenu->addAction(QIcon(), tr("Add to Contacts"), this, SLOT(addtoContacts())); - - if(n_is_not_a_contact == 0) - contextMenu->addAction(QIcon(":/images/cancel.png"), tr("Remove from Contacts"), this, SLOT(removefromContacts())); - - contextMenu->addSeparator(); - - if(n_positive_reputations == 0) // only unban when all items are banned - contextMenu->addAction(QIcon(":/icons/png/thumbs-up.png"), tr("Set positive opinion"), this, SLOT(positivePerson())); - - if(n_neutral_reputations == 0) // only unban when all items are banned - contextMenu->addAction(QIcon(":/icons/png/thumbs-neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson())); - - if(n_negative_reputations == 0) - contextMenu->addAction(QIcon(":/icons/png/thumbs-down.png"), tr("Set negative opinion"), this, SLOT(negativePerson())); - } - - if(one_item_owned_by_you && n_selected_items==1) - { - contextMenu->addSeparator(); - - contextMenu->addAction(ui->editIdentity); - contextMenu->addAction(ui->removeIdentity); - } - + root_node_present = true ; + continue ; } - contextMenu = ui->idTreeWidget->createStandardContextMenu(contextMenu); + uint32_t item_flags = (*it)->data(RSID_COL_KEYID,Qt::UserRole).toUInt() ; - contextMenu->exec(QCursor::pos()); - delete contextMenu; + if(item_flags & RSID_FILTER_OWNED_BY_YOU) + one_item_owned_by_you = true ; + +#ifdef ID_DEBUG + std::cerr << " item flags = " << item_flags << std::endl; +#endif + RsGxsId keyId((*it)->text(RSID_COL_KEYID).toStdString()); + + RsIdentityDetails det ; + rsIdentity->getIdDetails(keyId,det) ; + + switch(det.mReputation.mOwnOpinion) + { + case RsReputations::OPINION_NEGATIVE: ++n_negative_reputations ; + break ; + + case RsReputations::OPINION_POSITIVE: ++n_positive_reputations ; + break ; + + case RsReputations::OPINION_NEUTRAL: ++n_neutral_reputations ; + break ; + } + + ++n_selected_items ; + + if(rsIdentity->isARegularContact(keyId)) + ++n_is_a_contact ; + else + ++n_is_not_a_contact ; + } + + if(!root_node_present) // don't show menu if some of the root nodes are present + { + + if(!one_item_owned_by_you) + { + QWidget *widget = new QWidget(contextMenu); + widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + + // create menu header + QHBoxLayout *hbox = new QHBoxLayout(widget); + hbox->setMargin(0); + hbox->setSpacing(6); + + QLabel *iconLabel = new QLabel(widget); + QPixmap pix = QPixmap(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); + iconLabel->setPixmap(pix); + iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); + hbox->addWidget(iconLabel); + + QLabel *textLabel = new QLabel("" + ui->titleBarLabel->text() + "", widget); + hbox->addWidget(textLabel); + + QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + hbox->addItem(spacerItem); + + widget->setLayout(hbox); + + QWidgetAction *widgetAction = new QWidgetAction(this); + widgetAction->setDefaultWidget(widget); + contextMenu->addAction(widgetAction); + + if(n_selected_items == 1) // if only one item is selected, allow to chat with this item + { + if(own_identities.size() <= 1) + { + QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"), tr("Chat with this person"), this, SLOT(chatIdentity())); + + if(own_identities.empty()) + action->setEnabled(false) ; + else + action->setData(QString::fromStdString((own_identities.front()).toStdString())) ; + } + else + { + QMenu *mnu = contextMenu->addMenu(QIcon(":/images/chat_24.png"),tr("Chat with this person as...")) ; + + for(std::list::const_iterator it=own_identities.begin();it!=own_identities.end();++it) + { + RsIdentityDetails idd ; + rsIdentity->getIdDetails(*it,idd) ; + + QPixmap pixmap ; + + if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG")) + pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(*it)) ; + + QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity())); + action->setData(QString::fromStdString((*it).toStdString())) ; + } + } + } + + if(n_selected_items==1) + QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy retroshare link"),this,SLOT(copyRetroshareLink())) ; + + // always allow to send messages + contextMenu->addAction(QIcon(":/images/mail_new.png"), tr("Send message"), this, SLOT(sendMsg())); + + contextMenu->addSeparator(); + + if(n_is_a_contact == 0) + contextMenu->addAction(QIcon(), tr("Add to Contacts"), this, SLOT(addtoContacts())); + + if(n_is_not_a_contact == 0) + contextMenu->addAction(QIcon(":/images/cancel.png"), tr("Remove from Contacts"), this, SLOT(removefromContacts())); + + contextMenu->addSeparator(); + + if(n_positive_reputations == 0) // only unban when all items are banned + contextMenu->addAction(QIcon(":/icons/png/thumbs-up.png"), tr("Set positive opinion"), this, SLOT(positivePerson())); + + if(n_neutral_reputations == 0) // only unban when all items are banned + contextMenu->addAction(QIcon(":/icons/png/thumbs-neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson())); + + if(n_negative_reputations == 0) + contextMenu->addAction(QIcon(":/icons/png/thumbs-down.png"), tr("Set negative opinion"), this, SLOT(negativePerson())); + } + + if(one_item_owned_by_you && n_selected_items==1) + { + contextMenu->addSeparator(); + + contextMenu->addAction(ui->editIdentity); + contextMenu->addAction(ui->removeIdentity); + } + + } + + contextMenu = ui->idTreeWidget->createStandardContextMenu(contextMenu); + + contextMenu->exec(QCursor::pos()); + delete contextMenu; +} + +void IdDialog::copyRetroshareLink() +{ + QTreeWidgetItem *item = ui->idTreeWidget->currentItem(); + + if (!item) + { + std::cerr << "IdDialog::editIdentity() Invalid item"; + std::cerr << std::endl; + return; + } + + std::string keyId = item->text(RSID_COL_KEYID).toStdString(); + + RsIdentityDetails details ; + + if(! rsIdentity->getIdDetails(RsGxsId(keyId),details)) + return ; + + std::string radix ; + if(!rsIdentity->serialiseIdentityToMemory(details.mId,radix)) + { + std::cerr << "(EE) Cannot get radix data for key " << keyId << std::endl; + return; + } + QList urls ; + + RetroShareLink link ; + link.createIdentity(RsGxsId(keyId),QString::fromUtf8(details.mNickname.c_str()),QString::fromStdString(radix)) ; + + RSLinkClipboard::copyLinks(urls) ; + + QMessageBox::information(NULL,tr("information"),tr("This identity link was copied to your clipboard. Paste it in a mail, or a message to transmit the identity to someone.")) ; } void IdDialog::chatIdentity() diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index a44d83677..64ab756af 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -93,6 +93,7 @@ private slots: void editIdentity(); void chatIdentity(); void sendMsg(); + void copyRetroshareLink(); void on_closeInfoFrameButton_clicked(); void updateSelection(); diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index 957b61f7f..a2075aa24 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -67,7 +67,8 @@ #define HOST_SEARCH "search" #define HOST_CERTIFICATE "certificate" #define HOST_PUBLIC_MSG "public_msg" -#define HOST_REGEXP "file|extra|person|forum|channel|posted|search|message|certificate|private_chat|public_msg" +#define HOST_IDENTITY "identity" +#define HOST_REGEXP "file|extra|person|forum|channel|posted|search|message|certificate|private_chat|public_msg|identity" #define FILE_NAME "name" #define FILE_SIZE "size" @@ -89,6 +90,9 @@ #define POSTED_ID "id" #define POSTED_MSGID "msgid" +#define IDENTITY_NAME "name" +#define IDENTITY_ID "gxsid" +#define IDENTITY_GROUP "groupdata" #define MESSAGE_ID "id" #define MESSAGE_SUBJECT "subject" @@ -333,6 +337,21 @@ RetroShareLink::RetroShareLink() clear(); } +bool RetroShareLink::createIdentity(const RsGxsId& id, const QString& name, const QString& radix_data) +{ + clear(); + + _name = name; + _hash = QString::fromStdString(id.toStdString()); + _radix_group_data = radix_data ; + + _type = TYPE_IDENTITY; + + check(); + + return valid(); +} + bool RetroShareLink::createExtraFile(const QString& name, uint64_t size, const QString& hash,const QString& ssl_id) { clear(); @@ -534,6 +553,7 @@ void RetroShareLink::clear() _GPGid = "" ; _time_stamp = 0 ; _encrypted_chat_info = "" ; + _radix_group_data = "" ; } void RetroShareLink::check() @@ -565,6 +585,17 @@ void RetroShareLink::check() if(!checkPGPId(_GPGid)) _valid = false ; break ; + case TYPE_IDENTITY: + if(_name.isNull()) + _valid = false ; + + if(_radix_group_data.isNull()) + _valid = false ; + + if(_hash.isNull()) + _valid = false ; + break ; + case TYPE_PERSON: if(_size != 0) _valid = false; @@ -651,6 +682,9 @@ QString RetroShareLink::title() const return QObject::tr("%1 (%2, Extra - Source included)").arg(hash()).arg(misc::friendlyUnit(size())); case TYPE_FILE: return QString("%1 (%2)").arg(hash()).arg(misc::friendlyUnit(size())); + case TYPE_IDENTITY: + return _name ; + case TYPE_PERSON: return PeerDefs::rsidFromId(RsPgpId(hash().toStdString())); case TYPE_FORUM: @@ -711,6 +745,14 @@ QString RetroShareLink::toString() const break; + case TYPE_IDENTITY: + url.setScheme(RSLINK_SCHEME) ; + url.setHost(HOST_IDENTITY) ; + urlQuery.addQueryItem(IDENTITY_ID,_hash) ; + urlQuery.addQueryItem(IDENTITY_NAME,encodeItem(_name)) ; + urlQuery.addQueryItem(IDENTITY_GROUP,_radix_group_data) ; + break ; + case TYPE_EXTRAFILE: url.setScheme(RSLINK_SCHEME); url.setHost(HOST_EXTRAFILE); @@ -798,9 +840,11 @@ QString RetroShareLink::toString() const QString RetroShareLink::niceName() const { - if (type() == TYPE_PERSON) { + if (type() == TYPE_PERSON) return PeerDefs::rsid(name().toUtf8().constData(), RsPgpId(hash().toStdString())); - } + + if(type() == TYPE_IDENTITY) + return QObject::tr("Click this link to add this person (name=%1, ID=%2) to your People tab.").arg(_name).arg(_hash) ; if(type() == TYPE_PUBLIC_MSG) { RsPeerDetails detail; @@ -1156,6 +1200,15 @@ static void processList(const QStringList &list, const QString &textSingular, co } break ; + case TYPE_IDENTITY: + { + if(rsIdentity->deserialiseIdentityFromMemory(link.radixGroupData().toStdString())) + QMessageBox::information(NULL,QObject::tr("Identity added to People"),QObject::tr("The identity was added to people. You can now chat with it, send messages to it, etc.")) ; + else + QMessageBox::warning(NULL,QObject::tr("Identity cannot be added to People"),QObject::tr("The identity was not added to people. Some error occured. The link is probably corrupted.")) ; + } + break; + case TYPE_FILE: case TYPE_EXTRAFILE: { diff --git a/retroshare-gui/src/gui/RetroShareLink.h b/retroshare-gui/src/gui/RetroShareLink.h index d1390d18d..b272f3416 100644 --- a/retroshare-gui/src/gui/RetroShareLink.h +++ b/retroshare-gui/src/gui/RetroShareLink.h @@ -68,7 +68,8 @@ class RetroShareLink TYPE_EXTRAFILE = 0x08, TYPE_PRIVATE_CHAT = 0x09, TYPE_PUBLIC_MSG = 0x0a, - TYPE_POSTED = 0x0b + TYPE_POSTED = 0x0b, + TYPE_IDENTITY = 0x0c }; public: @@ -85,6 +86,7 @@ class RetroShareLink bool createSearch(const QString& keywords); bool createMessage(const RsPeerId &peerId, const QString& subject); bool createMessage(const RsGxsId &peerId, const QString& subject); + bool createIdentity(const RsGxsId& gxs_id,const QString& name,const QString& radix_data) ; bool createCertificate(const RsPeerId &ssl_id) ; bool createPublicMsgInvite(time_t time_stamp,const QString& pgp_id,const QString& hash) ; bool createUnknwonSslCertificate(const RsPeerId &sslId, const RsPgpId &gpgId = RsPgpId()) ; @@ -101,12 +103,13 @@ class RetroShareLink const QString& SSLId() const { return _SSLid ; } const QString& GPGId() const { return _GPGid ; } const QString& localIPAndPort() const { return _loc_ip_port ; } - const QString& externalIPAndPort() const { return _ext_ip_port ; } - const QString& dyndns() const { return _dyndns_name ; } - const QString& location() const { return _location ; } - const QString& radix() const { return _radix ; } - time_t timeStamp() const { return _time_stamp ; } - QString title() const; + const QString& externalIPAndPort() const { return _ext_ip_port ; } + const QString& dyndns() const { return _dyndns_name ; } + const QString& location() const { return _location ; } + const QString& radix() const { return _radix ; } + time_t timeStamp() const { return _time_stamp ; } + QString title() const; + QString radixGroupData() const { return _radix_group_data ;} unsigned int subType() const { return _subType; } void setSubType(unsigned int subType) { _subType = subType; } @@ -158,12 +161,13 @@ class RetroShareLink QString _GPGBase64String ; // GPG Cert QString _GPGBase64CheckSum ; // GPG Cert QString _location ; // location - QString _ext_ip_port ; - QString _loc_ip_port ; - QString _dyndns_name ; + QString _ext_ip_port ; + QString _loc_ip_port ; + QString _dyndns_name ; QString _radix ; - QString _encrypted_chat_info ; // encrypted data string for the recipient of a chat invite - time_t _time_stamp ; // time stamp at which the link will expire. + QString _encrypted_chat_info ; // encrypted data string for the recipient of a chat invite + time_t _time_stamp ; // time stamp at which the link will expire. + QString _radix_group_data; unsigned int _subType; // for general use as sub type for _type (RSLINK_SUBTYPE_...) }; From 54cd402f1c8c6175501782178507cf2168b3371d Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 8 Apr 2017 21:43:07 +0200 Subject: [PATCH 034/118] fixed a few bugs in latest identity link code --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 1 + retroshare-gui/src/gui/RetroShareLink.cpp | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 4b28a1b09..050785db1 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -2432,6 +2432,7 @@ void IdDialog::copyRetroshareLink() RetroShareLink link ; link.createIdentity(RsGxsId(keyId),QString::fromUtf8(details.mNickname.c_str()),QString::fromStdString(radix)) ; + urls.push_back(link); RSLinkClipboard::copyLinks(urls) ; diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index a2075aa24..4d32930aa 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -307,6 +307,21 @@ void RetroShareLink::fromUrl(const QUrl& url) return; } + if(url.host() == HOST_IDENTITY) { + _type = TYPE_IDENTITY ; + QString name = urlQuery.queryItemValue(IDENTITY_NAME) ; + QString radix= urlQuery.queryItemValue(IDENTITY_GROUP) ; + QString gxsid= urlQuery.queryItemValue(IDENTITY_ID) ; + + RsGxsId id(gxsid.toStdString()) ; + + if(!id.isNull()) + createIdentity(id,name,radix) ; + else + std::cerr << "(EE) identity link is not valid." << std::endl; + return ; + } + if (url.host() == HOST_MESSAGE) { _type = TYPE_MESSAGE; std::string id = urlQuery.queryItemValue(MESSAGE_ID).toStdString(); @@ -844,7 +859,7 @@ QString RetroShareLink::niceName() const return PeerDefs::rsid(name().toUtf8().constData(), RsPgpId(hash().toStdString())); if(type() == TYPE_IDENTITY) - return QObject::tr("Click this link to add this person (name=%1, ID=%2) to your People tab.").arg(_name).arg(_hash) ; + return QObject::tr("Identity link (name=%1, ID=%2)").arg(_name).arg(_hash) ; if(type() == TYPE_PUBLIC_MSG) { RsPeerDetails detail; @@ -1055,6 +1070,7 @@ static void processList(const QStringList &list, const QString &textSingular, co case TYPE_POSTED: case TYPE_SEARCH: case TYPE_MESSAGE: + case TYPE_IDENTITY: case TYPE_CERTIFICATE: case TYPE_PUBLIC_MSG: case TYPE_PRIVATE_CHAT: From d66e653204423622bd9adb2bfa22c8bf1d2a24f1 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 8 Apr 2017 23:39:05 +0200 Subject: [PATCH 035/118] fixed bug in deserialisation of group informaiton --- libretroshare/src/gxs/rsgenexchange.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 4d70ee409..571489212 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -1310,7 +1310,7 @@ bool RsGenExchange::deserializeGroupData(unsigned char *data,uint32_t size) { RS_STACK_MUTEX(mGenMtx) ; - RsItem *item = mSerialiser->deserialise(data, &size); + RsItem *item = RsNxsSerialiser(mServType).deserialise(data, &size); RsNxsGrp *nxs_grp = dynamic_cast(item) ; @@ -1321,7 +1321,7 @@ bool RsGenExchange::deserializeGroupData(unsigned char *data,uint32_t size) return false ; } - mReceivedGrps.push_back( GxsPendingItem(nxs_grp, nxs_grp->metaData->mGroupId,time(NULL)) ); + mReceivedGrps.push_back( GxsPendingItem(nxs_grp, nxs_grp->grpId,time(NULL)) ); return true ; } From 7f12ca266bd5e3ff217f16bd087ad393b27a3536 Mon Sep 17 00:00:00 2001 From: electron128 Date: Sun, 9 Apr 2017 09:57:48 +0200 Subject: [PATCH 036/118] fixed name of local socket where RS waits for rslinks etc. --- retroshare-gui/src/retroshare-gui.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 9e2951f87..6c4fdeb67 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -5,7 +5,7 @@ QT += network xml CONFIG += qt gui uic qrc resources idle bitdht CONFIG += link_prl TARGET = RetroShare06 -DEFINES += TARGET=\\\"$TARGET\\\" +DEFINES += TARGET=\\\"$${TARGET}\\\" # Plz never commit the .pro with these flags enabled. # Use this flag when developping new features only. From 4c9b62070f3d58799293bf0a5bfdb4947351f2ff Mon Sep 17 00:00:00 2001 From: electron128 Date: Sun, 9 Apr 2017 10:26:18 +0200 Subject: [PATCH 037/118] fixed --base-dir command line argument in rs-gui when running multiple instances. Only forward "link" and "rsfile" arguments to a running instance. Start a new instance if other arguments are present. --- retroshare-gui/src/rshare.cpp | 86 +++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/retroshare-gui/src/rshare.cpp b/retroshare-gui/src/rshare.cpp index a2de0840a..040992afe 100644 --- a/retroshare-gui/src/rshare.cpp +++ b/retroshare-gui/src/rshare.cpp @@ -68,6 +68,17 @@ #define ARG_RSFILE_L "rsfile" /**< Open RsFile with or without arg */ //Other defined for server in /libretroshare/src/rsserver/rsinit.cc:351 +// The arguments here can be send to a running instance. +// If the command line contains arguments not listed here, we have to start a new instance. +// For exmample, the user wants to start a second instance using --base-dir arg of libretroshare. +static const char* const forwardableArgs[] = { + ARG_RSLINK_S, + ARG_RSLINK_L, + ARG_RSFILE_S, + ARG_RSFILE_L, + NULL, +}; + /* Static member variables */ QMap Rshare::_args; /**< List of command-line arguments. */ QString Rshare::_style; /**< The current GUI style. */ @@ -115,6 +126,27 @@ void qt_msg_handler(QtMsgType type, const char *msg) } } +static bool notifyRunningInstance() +{ + // Connect to the Local Server of the main process to notify it + // that a new process had been started + QLocalSocket localSocket; + localSocket.connectToServer(QString(TARGET)); + + std::cerr << "Rshare::Rshare waitForConnected to other instance." << std::endl; + if( localSocket.waitForConnected(100) ) + { + std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl; + localSocket.waitForDisconnected(1000); + return true; + } + else + { + std::cerr << "Rshare::Rshare failed to connect to other instance." << std::endl; + return false; + } +} + /** Constructor. Parses the command-line arguments, resets Rshare's * configuration (if requested), and sets up the GUI style and language * translation. */ @@ -128,7 +160,32 @@ Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir) { QString serverName = QString(TARGET); - if (!args.isEmpty()) { + // check if another instance is running + bool haveRunningInstance = notifyRunningInstance(); + + bool sendArgsToRunningInstance = haveRunningInstance; + if(args.empty()) + sendArgsToRunningInstance = false; + // if we find non-forwardable args, start a new instance + for(int i = 0; i < args.size(); ++i) + { + const char* const* argit = forwardableArgs; + bool found = false; + while(*argit && i < args.size()) + { + if(args.value(i) == "-"+QString(*argit) || args.value(i) == "--"+QString(*argit)) + { + found = true; + if(argNeedsValue(*argit)) + i++; + } + argit++; + } + if(!found) + sendArgsToRunningInstance = false; + } + + if (sendArgsToRunningInstance) { // load into shared memory QBuffer buffer; buffer.open(QBuffer::ReadWrite); @@ -156,30 +213,29 @@ Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir) memcpy(to, from, qMin(newArgs.size(), size)); newArgs.unlock(); - // Connect to the Local Server of the main process to notify it - // that a new process had been started - QLocalSocket localSocket; - localSocket.connectToServer(QString(TARGET)); - std::cerr << "Rshare::Rshare waitForConnected to other instance." << std::endl; - if( localSocket.waitForConnected(100) ) + if(notifyRunningInstance()) { - std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl; - localSocket.waitForDisconnected(1000); newArgs.detach(); std::cerr << "Rshare::Rshare Arguments was sended." << std::endl << " To disable it, in Options - General - Misc," << std::endl << " uncheck \"Use Local Server to get new Arguments\"." << std::endl; ::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function } + else + std::cerr << "Rshare::Rshare failed to connect to other instance." << std::endl; newArgs.detach(); } - // No main process exists - // Or started without arguments - // So we start a Local Server to listen for connections from new process - localServer= new QLocalServer(); - QObject::connect(localServer, SIGNAL(newConnection()), this, SLOT(slotConnectionEstablished())); - updateLocalServer(); + + if(!haveRunningInstance) + { + // No main process exists + // Or started without arguments + // So we start a Local Server to listen for connections from new process + localServer= new QLocalServer(); + QObject::connect(localServer, SIGNAL(newConnection()), this, SLOT(slotConnectionEstablished())); + updateLocalServer(); + } } #if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) From 3130ec90412b29ce7df65528389b1237a9865b47 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 10 Apr 2017 20:02:14 +0200 Subject: [PATCH 038/118] added GUI async call to ID serialised data. Allows to copy+paste identities. --- libretroshare/src/gxs/rsgxsdataaccess.cc | 77 +++++++++++----- libretroshare/src/gxs/rsgxsdataaccess.h | 7 ++ libretroshare/src/gxs/rsgxsrequesttypes.h | 6 ++ libretroshare/src/retroshare/rsidentity.h | 1 + libretroshare/src/retroshare/rstokenservice.h | 1 + libretroshare/src/services/p3idservice.cc | 22 +++++ libretroshare/src/services/p3idservice.h | 2 + retroshare-gui/src/gui/Identity/IdDialog.cpp | 91 +++++++++++++++---- retroshare-gui/src/gui/Identity/IdDialog.h | 1 + 9 files changed, 168 insertions(+), 40 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 8fcbbde5d..56899d4ce 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -75,6 +75,12 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const gir->mGroupIds = groupIds; req = gir; } + else if(reqType & GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA) + { + GroupSerializedDataReq* gir = new GroupSerializedDataReq(); + gir->mGroupIds = groupIds; + req = gir; + } if(req == NULL) { @@ -103,34 +109,25 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const uint32_t reqType = opts.mReqType; if(reqType & GXS_REQUEST_TYPE_GROUP_META) - { - GroupMetaReq* gmr = new GroupMetaReq(); - req = gmr; - } + req = new GroupMetaReq(); else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) - { - GroupDataReq* gdr = new GroupDataReq(); - req = gdr; - } + req = new GroupDataReq(); else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) - { - GroupIdReq* gir = new GroupIdReq(); - req = gir; - } - - if(req == NULL) + req = new GroupIdReq(); + else if(reqType & GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA) + req = new GroupSerializedDataReq(); + else { std::cerr << "RsGxsDataAccess::requestGroupInfo() request type not recognised, type " << reqType << std::endl; return false; - }else - { - generateToken(token); -#ifdef DATA_DEBUG - std::cerr << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl; -#endif } + generateToken(token); +#ifdef DATA_DEBUG + std::cerr << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl; +#endif + setReq(req, token, ansType, opts); storeRequest(req); @@ -430,7 +427,16 @@ bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list& else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE) { GroupDataReq* gmreq = dynamic_cast(req); - if(gmreq) + GroupSerializedDataReq* gsreq = dynamic_cast(req); + + if(gsreq) + { + grpData.swap(gsreq->mGroupData); + gsreq->mGroupData.clear(); + + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + } + else if(gmreq) { grpData.swap(gmreq->mGroupData); gmreq->mGroupData.clear(); @@ -804,6 +810,7 @@ void RsGxsDataAccess::processRequests() MsgIdReq* mir; MsgRelatedInfoReq* mri; GroupStatisticRequest* gsr; + GroupSerializedDataReq* grr; ServiceStatisticRequest* ssr; #ifdef DATA_DEBUG @@ -851,6 +858,11 @@ void RsGxsDataAccess::processRequests() { ok = getServiceStatistic(ssr); } + else if((grr = dynamic_cast(req)) != NULL) + { + ok = getGroupSerializedData(grr); + } + else { std::cerr << "RsGxsDataAccess::processRequests() Failed to process request, token: " @@ -929,7 +941,30 @@ bool RsGxsDataAccess::getServiceStatistic(const uint32_t &token, GxsServiceStati return true; } +bool RsGxsDataAccess::getGroupSerializedData(GroupSerializedDataReq* req) +{ + std::map grpData; + std::list grpIdsOut; + getGroupList(req->mGroupIds, req->Options, grpIdsOut); + + if(grpIdsOut.empty()) + return true; + + + for(std::list::iterator lit = grpIdsOut.begin();lit != grpIdsOut.end();++lit) + grpData[*lit] = NULL; + + bool ok = mDataStore->retrieveNxsGrps(grpData, true, true); + req->mGroupData.clear(); + + std::map::iterator mit = grpData.begin(); + + for(; mit != grpData.end(); ++mit) + req->mGroupData.push_back(mit->second) ; + + return ok; +} bool RsGxsDataAccess::getGroupData(GroupDataReq* req) { std::map grpData; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index ac21f4c41..d39823f81 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -418,6 +418,13 @@ private: */ bool getGroupStatistic(GroupStatisticRequest* req); + /*! + * + * Attempts to retrieve group data in serialized format + * @param req Request object to satisfy + */ + bool getGroupSerializedData(GroupSerializedDataReq* req); + /*! * * Attempts to service statistic diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.h b/libretroshare/src/gxs/rsgxsrequesttypes.h index a344a55e7..8009f294b 100644 --- a/libretroshare/src/gxs/rsgxsrequesttypes.h +++ b/libretroshare/src/gxs/rsgxsrequesttypes.h @@ -61,6 +61,12 @@ public: std::list mGroupIds; std::list mGroupIdResult; }; +class GroupSerializedDataReq : public GxsRequest +{ +public: + std::list mGroupIds; + std::list mGroupData; +}; class GroupDataReq : public GxsRequest { diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 53704961d..6be124e93 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -322,6 +322,7 @@ public: */ virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; + virtual bool getGroupSerializedData(const uint32_t &token, std::map& serialized_groups)=0; //virtual bool getMsgData(const uint32_t &token, std::vector &opinions) = 0; }; diff --git a/libretroshare/src/retroshare/rstokenservice.h b/libretroshare/src/retroshare/rstokenservice.h index c55213965..5e74a527f 100644 --- a/libretroshare/src/retroshare/rstokenservice.h +++ b/libretroshare/src/retroshare/rstokenservice.h @@ -47,6 +47,7 @@ #define GXS_REQUEST_TYPE_GROUP_STATS 0x01600000 #define GXS_REQUEST_TYPE_SERVICE_STATS 0x03200000 +#define GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA 0x04000000 // TODO CLEANUP: RS_TOKREQOPT_MSG_* should be an inner enum of RsTokReqOptions diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 9aeec2aea..dcc45af65 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1474,6 +1474,28 @@ bool p3IdService::getGroupData(const uint32_t &token, std::vector return ok; } +bool p3IdService::getGroupSerializedData(const uint32_t &token, std::map& serialized_groups) +{ + unsigned char *mem = NULL; + uint32_t size; + RsGxsGroupId id ; + + serialized_groups.clear() ; + + if(!RsGenExchange::getSerializedGroupData(token,id, mem,size)) + { + std::cerr << "(EE) call to RsGenExchage::getSerializedGroupData() failed." << std::endl; + return false; + } + + std::string radix ; + + Radix64::encode(mem,size,radix) ; + + serialized_groups[RsGxsId(id)] = radix ; + + return true; +} /********************************************************************************/ /********************************************************************************/ diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 6e4585eb6..91e55fe6d 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -245,6 +245,8 @@ public: // These are exposed via RsIdentity. virtual bool getGroupData(const uint32_t &token, std::vector &groups); + virtual bool getGroupSerializedData(const uint32_t &token, std::map& serialized_groups); + //virtual bool getMsgData(const uint32_t &token, std::vector &opinions); // These are local - and not exposed via RsIdentity. diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 050785db1..b7923dc49 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -55,10 +55,11 @@ *****/ // Data Requests. -#define IDDIALOG_IDLIST 1 -#define IDDIALOG_IDDETAILS 2 -#define IDDIALOG_REPLIST 3 -#define IDDIALOG_REFRESH 4 +#define IDDIALOG_IDLIST 1 +#define IDDIALOG_IDDETAILS 2 +#define IDDIALOG_REPLIST 3 +#define IDDIALOG_REFRESH 4 +#define IDDIALOG_SERIALIZED_GROUP 5 #define CIRCLEGROUP_CIRCLE_COL_GROUPNAME 0 #define CIRCLEGROUP_CIRCLE_COL_GROUPID 1 @@ -814,7 +815,7 @@ void IdDialog::loadCircleGroupData(const uint32_t& token) #ifdef ID_DEBUG std::cerr << "Loading circle info" << std::endl; #endif - + std::vector circle_grp_v ; rsGxsCircles->getGroupData(token, circle_grp_v); @@ -1385,6 +1386,8 @@ void IdDialog::updateSelection() } } + + void IdDialog::requestIdList() { //Disable by default, will be enable by insertIdDetails() @@ -2174,6 +2177,45 @@ void IdDialog::insertRepList(uint32_t token) mStateHelper->setActive(IDDIALOG_REPLIST, true); } +void IdDialog::handleSerializedGroupData(uint32_t token) +{ + std::map serialized_group_map ; + + rsIdentity->getGroupSerializedData(token, serialized_group_map); + + if(serialized_group_map.size() < 1) + { + std::cerr << "(EE) Cannot get radix data " << std::endl; + return; + } + if(serialized_group_map.size() > 1) + { + std::cerr << "(EE) Too many results for serialized data" << std::endl; + return; + } + + RsGxsId gxs_id = serialized_group_map.begin()->first ; + std::string radix = serialized_group_map.begin()->second ; + + RsIdentityDetails details ; + + if(!rsIdentity->getIdDetails(gxs_id,details)) + { + std::cerr << "(EE) Cannot get id details for key " << gxs_id << std::endl; + return; + } + + QList urls ; + + RetroShareLink link ; + link.createIdentity(gxs_id,QString::fromUtf8(details.mNickname.c_str()),QString::fromStdString(radix)) ; + urls.push_back(link); + + RSLinkClipboard::copyLinks(urls) ; + + QMessageBox::information(NULL,tr("information"),tr("This identity link was copied to your clipboard. Paste it in a mail, or a message to transmit the identity to someone.")) ; +} + void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req) { #ifdef ID_DEBUG @@ -2197,6 +2239,10 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req) insertRepList(req.mToken); break; + case IDDIALOG_SERIALIZED_GROUP: + handleSerializedGroupData(req.mToken); + break; + case IDDIALOG_REFRESH: // replaced by RsGxsUpdateBroadcastPage // updateDisplay(true); @@ -2415,28 +2461,35 @@ void IdDialog::copyRetroshareLink() return; } - std::string keyId = item->text(RSID_COL_KEYID).toStdString(); + RsGxsId gxs_id(item->text(RSID_COL_KEYID).toStdString()); + + if(gxs_id.isNull()) + { + std::cerr << "Null GXS id. Something went wrong." << std::endl; + return ; + } RsIdentityDetails details ; - if(! rsIdentity->getIdDetails(RsGxsId(keyId),details)) + if(! rsIdentity->getIdDetails(gxs_id,details)) return ; - std::string radix ; - if(!rsIdentity->serialiseIdentityToMemory(details.mId,radix)) - { - std::cerr << "(EE) Cannot get radix data for key " << keyId << std::endl; - return; - } - QList urls ; + if (!mIdQueue) + return; - RetroShareLink link ; - link.createIdentity(RsGxsId(keyId),QString::fromUtf8(details.mNickname.c_str()),QString::fromStdString(radix)) ; - urls.push_back(link); + mStateHelper->setLoading(IDDIALOG_SERIALIZED_GROUP, true); - RSLinkClipboard::copyLinks(urls) ; + mIdQueue->cancelActiveRequestTokens(IDDIALOG_SERIALIZED_GROUP); - QMessageBox::information(NULL,tr("information"),tr("This identity link was copied to your clipboard. Paste it in a mail, or a message to transmit the identity to someone.")) ; + std::list ids ; + ids.push_back(RsGxsGroupId(gxs_id)) ; + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA; + + uint32_t token; + + mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, IDDIALOG_SERIALIZED_GROUP); } void IdDialog::chatIdentity() diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index 64ab756af..1eaae935d 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -133,6 +133,7 @@ private: void requestRepList(); void insertRepList(uint32_t token); + void handleSerializedGroupData(uint32_t token); void requestIdEdit(std::string &id); void showIdEdit(uint32_t token); From e1350a0b34be63b63d566c639c55b5ead635d7f0 Mon Sep 17 00:00:00 2001 From: Konrad Date: Mon, 10 Apr 2017 22:58:23 +0200 Subject: [PATCH 039/118] Fixed: Re-selecting accounts via RsControlModule; Added: Sending feedback about incorrect password --- libresapi/src/api/RsControlModule.cpp | 38 ++++++++++++++++++++------- libresapi/src/api/RsControlModule.h | 1 + 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/libresapi/src/api/RsControlModule.cpp b/libresapi/src/api/RsControlModule.cpp index 595509f09..f65c6058c 100644 --- a/libresapi/src/api/RsControlModule.cpp +++ b/libresapi/src/api/RsControlModule.cpp @@ -24,7 +24,9 @@ RsControlModule::RsControlModule(int argc, char **argv, StateTokenServer* sts, A mDataMtx("RsControlModule::mDataMtx"), mRunState(WAITING_INIT), mAutoLoginNextTime(false), - mWantPassword(false) + mWantPassword(false), + mPassword(""), + mPrevIsBad(false) { mStateToken = sts->getNewToken(); this->argc = argc; @@ -56,11 +58,14 @@ bool RsControlModule::processShouldExit() return mProcessShouldExit; } -bool RsControlModule::askForPassword(const std::string &title, const std::string &key_details, bool /* prev_is_bad */, std::string &password, bool& cancelled) +bool RsControlModule::askForPassword(const std::string &title, const std::string &key_details, bool prev_is_bad, std::string &password, bool& cancelled) { cancelled = false ; { RS_STACK_MUTEX(mDataMtx); // ********** LOCKED ********** + + mPrevIsBad = prev_is_bad; + if(mFixedPassword != "") { password = mFixedPassword; @@ -70,18 +75,25 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string mWantPassword = true; mTitle = title; mKeyName = key_details; - mPassword = ""; + + if(mPassword != "") + { + password = mPassword; + mWantPassword = false; + mPassword = ""; + return true; + } + mStateTokenServer->replaceToken(mStateToken); } - bool wait = true; - while(wait) + int i = 0; + while(i<100) { usleep(5*1000); - RS_STACK_MUTEX(mDataMtx); // ********** LOCKED ********** - wait = mWantPassword; - if(!wait && mPassword != "") + + if(mPassword != "") { password = mPassword; mPassword = ""; @@ -89,6 +101,7 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string mStateTokenServer->replaceToken(mStateToken); return true; } + i++; } return false; } @@ -175,8 +188,13 @@ void RsControlModule::run() std::cerr << "RsControlModule::run() LockAndLoadCertificates failed. Unexpected switch value: " << retVal << std::endl; break; } + + mLoadPeerId.clear(); + mPassword = ""; } + mFixedPassword = mPassword; + setRunState(WAITING_STARTUP); std::cerr << "RsControlModule: login ok, starting Retroshare worker threads..." << std::endl; @@ -302,12 +320,12 @@ void RsControlModule::handlePassword(Request &req, Response &resp) mPassword = passwd; mWantPassword = false; mStateTokenServer->replaceToken(mStateToken); - mFixedPassword = passwd; } resp.mDataStream << makeKeyValueReference("want_password", mWantPassword) - << makeKeyValueReference("key_name", mKeyName); + << makeKeyValueReference("key_name", mKeyName) + << makeKeyValueReference("prev_is_bad", mPrevIsBad); resp.mStateToken = mStateToken; resp.setOk(); } diff --git a/libresapi/src/api/RsControlModule.h b/libresapi/src/api/RsControlModule.h index 1323651fc..7e306405c 100644 --- a/libresapi/src/api/RsControlModule.h +++ b/libresapi/src/api/RsControlModule.h @@ -77,6 +77,7 @@ private: // to notify that a password callback is waiting // to answer the request, clear the flag and set the password bool mWantPassword; + bool mPrevIsBad; std::string mTitle; std::string mKeyName; std::string mPassword; From 9402b8e239a77b11c39a3df6aa9ed3be9433bd09 Mon Sep 17 00:00:00 2001 From: Konrad Date: Mon, 10 Apr 2017 23:42:22 +0200 Subject: [PATCH 040/118] Fixed: mFixedPassword remained empty after logging --- libresapi/src/api/RsControlModule.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libresapi/src/api/RsControlModule.cpp b/libresapi/src/api/RsControlModule.cpp index f65c6058c..f8e2d7e1e 100644 --- a/libresapi/src/api/RsControlModule.cpp +++ b/libresapi/src/api/RsControlModule.cpp @@ -67,7 +67,7 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string mPrevIsBad = prev_is_bad; if(mFixedPassword != "") - { + { password = mFixedPassword; return true; } @@ -80,7 +80,6 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string { password = mPassword; mWantPassword = false; - mPassword = ""; return true; } @@ -95,8 +94,7 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string if(mPassword != "") { - password = mPassword; - mPassword = ""; + password = mPassword; mWantPassword = false; mStateTokenServer->replaceToken(mStateToken); return true; @@ -138,6 +136,7 @@ void RsControlModule::run() bool login_ok = false; while(!login_ok) { + mPassword = ""; // skip account selection if autologin is available if(initResult != RS_INIT_HAVE_ACCOUNT) setRunState(WAITING_ACCOUNT_SELECT); @@ -190,10 +189,10 @@ void RsControlModule::run() } mLoadPeerId.clear(); - mPassword = ""; } mFixedPassword = mPassword; + mPassword = ""; setRunState(WAITING_STARTUP); From aa81cc16d0ba49d7aa151fa766ae179cd1076f2a Mon Sep 17 00:00:00 2001 From: Konrad Date: Wed, 12 Apr 2017 20:24:18 +0200 Subject: [PATCH 041/118] Added: Functions for handling PGP account details requests --- libresapi/src/api/PeersHandler.cpp | 116 +++++++++++++++++++++++++++++ libresapi/src/api/PeersHandler.h | 3 + 2 files changed, 119 insertions(+) diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index f48beb2f6..14cd1b7c6 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -119,6 +119,8 @@ PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *pee addResourceHandler("set_state_string", this, &PeersHandler::handleSetStateString); addResourceHandler("get_custom_state_string", this, &PeersHandler::handleGetCustomStateString); addResourceHandler("set_custom_state_string", this, &PeersHandler::handleSetCustomStateString); + addResourceHandler("get_pgp_options", this, &PeersHandler::handleGetPGPOptions); + addResourceHandler("set_pgp_options", this, &PeersHandler::handleSetPGPOptions); addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert); } @@ -529,6 +531,120 @@ void PeersHandler::handleExamineCert(Request &req, Response &resp) } } +void PeersHandler::handleGetPGPOptions(Request& req, Response& resp) +{ + std::string pgp_id; + req.mStream << makeKeyValueReference("pgp_id", pgp_id); + + RsPgpId pgp(pgp_id); + RsPeerDetails detail; + + if(!rsPeers->getGPGDetails(pgp, detail)) + { + resp.setFail(); + return; + } + + std::string pgp_key = rsPeers->getPGPKey(detail.gpg_id, false); + + resp.mDataStream << makeKeyValue("pgp_fingerprint", detail.fpr.toStdString()); + resp.mDataStream << makeKeyValueReference("pgp_key", pgp_key); + + resp.mDataStream << makeKeyValue("direct_transfer", detail.service_perm_flags & RS_NODE_PERM_DIRECT_DL); + resp.mDataStream << makeKeyValue("allow_push", detail.service_perm_flags & RS_NODE_PERM_ALLOW_PUSH); + resp.mDataStream << makeKeyValue("require_WL", detail.service_perm_flags & RS_NODE_PERM_REQUIRE_WL); + + resp.mDataStream << makeKeyValue("own_sign", detail.ownsign); + resp.mDataStream << makeKeyValue("trustLvl", detail.trustLvl); + + uint32_t max_upload_speed = 0; + uint32_t max_download_speed = 0; + + rsPeers->getPeerMaximumRates(pgp, max_upload_speed, max_download_speed); + + resp.mDataStream << makeKeyValueReference("maxUploadSpeed", max_upload_speed); + resp.mDataStream << makeKeyValueReference("maxDownloadSpeed", max_download_speed); + + StreamBase& signersStream = resp.mDataStream.getStreamToMember("gpg_signers"); + + // mark as list (in case list is empty) + signersStream.getStreamToMember(); + + for(std::list::const_iterator it(detail.gpgSigners.begin()); it != detail.gpgSigners.end(); ++it) + { + RsPeerDetails detail; + if(!rsPeers->getGPGDetails(*it, detail)) + continue; + + std::string pgp_id = (*it).toStdString(); + std::string name = detail.name; + + signersStream.getStreamToMember() + << makeKeyValueReference("pgp_id", pgp_id) + << makeKeyValueReference("name", name); + } + + resp.setOk(); +} + +void PeersHandler::handleSetPGPOptions(Request& req, Response& resp) +{ + std::string pgp_id; + req.mStream << makeKeyValueReference("pgp_id", pgp_id); + + RsPgpId pgp(pgp_id); + RsPeerDetails detail; + + if(!rsPeers->getGPGDetails(pgp, detail)) + { + resp.setFail(); + return; + } + + int trustLvl; + req.mStream << makeKeyValueReference("trustLvl", trustLvl); + + if(trustLvl != (int)detail.trustLvl) + rsPeers->trustGPGCertificate(pgp, trustLvl); + + int max_upload_speed; + int max_download_speed; + + req.mStream << makeKeyValueReference("max_upload_speed", max_upload_speed); + req.mStream << makeKeyValueReference("max_download_speed", max_download_speed); + + rsPeers->setPeerMaximumRates(pgp, (uint32_t)max_upload_speed, (uint32_t)max_download_speed); + + bool direct_transfer; + bool allow_push; + bool require_WL; + + req.mStream << makeKeyValueReference("direct_transfer", direct_transfer); + req.mStream << makeKeyValueReference("allow_push", allow_push); + req.mStream << makeKeyValueReference("require_WL", require_WL); + + ServicePermissionFlags flags(0); + + if(direct_transfer) + flags = flags | RS_NODE_PERM_DIRECT_DL; + if(allow_push) + flags = flags | RS_NODE_PERM_ALLOW_PUSH; + if(require_WL) + flags = flags | RS_NODE_PERM_REQUIRE_WL; + + rsPeers->setServicePermissionFlags(pgp, flags); + + bool own_sign; + req.mStream << makeKeyValueReference("own_sign", own_sign); + + if(own_sign) + rsPeers->signGPGCertificate(pgp); + + resp.mStateToken = getCurrentStateToken(); + + resp.setOk(); +} + StateToken PeersHandler::getCurrentStateToken() { RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ diff --git a/libresapi/src/api/PeersHandler.h b/libresapi/src/api/PeersHandler.h index 15d231c10..5ae393b2f 100644 --- a/libresapi/src/api/PeersHandler.h +++ b/libresapi/src/api/PeersHandler.h @@ -41,6 +41,9 @@ private: void handleGetCustomStateString(Request& req, Response& resp); void handleSetCustomStateString(Request& req, Response& resp); + void handleGetPGPOptions(Request& req, Response& resp); + void handleSetPGPOptions(Request& req, Response& resp); + // a helper which ensures proper mutex locking StateToken getCurrentStateToken(); From dcc8c6e4c35a35c5f8a775781ecc92a9b3e35cb9 Mon Sep 17 00:00:00 2001 From: Konrad Date: Thu, 13 Apr 2017 13:31:32 +0200 Subject: [PATCH 042/118] Changed: Using PeersHandler::mRsPeers instead of rsPeers --- libresapi/src/api/PeersHandler.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index 14cd1b7c6..8473bce04 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -539,13 +539,13 @@ void PeersHandler::handleGetPGPOptions(Request& req, Response& resp) RsPgpId pgp(pgp_id); RsPeerDetails detail; - if(!rsPeers->getGPGDetails(pgp, detail)) + if(!mRsPeers->getGPGDetails(pgp, detail)) { resp.setFail(); return; } - std::string pgp_key = rsPeers->getPGPKey(detail.gpg_id, false); + std::string pgp_key = mRsPeers->getPGPKey(detail.gpg_id, false); resp.mDataStream << makeKeyValue("pgp_fingerprint", detail.fpr.toStdString()); resp.mDataStream << makeKeyValueReference("pgp_key", pgp_key); @@ -560,7 +560,7 @@ void PeersHandler::handleGetPGPOptions(Request& req, Response& resp) uint32_t max_upload_speed = 0; uint32_t max_download_speed = 0; - rsPeers->getPeerMaximumRates(pgp, max_upload_speed, max_download_speed); + mRsPeers->getPeerMaximumRates(pgp, max_upload_speed, max_download_speed); resp.mDataStream << makeKeyValueReference("maxUploadSpeed", max_upload_speed); resp.mDataStream << makeKeyValueReference("maxDownloadSpeed", max_download_speed); @@ -573,7 +573,7 @@ void PeersHandler::handleGetPGPOptions(Request& req, Response& resp) for(std::list::const_iterator it(detail.gpgSigners.begin()); it != detail.gpgSigners.end(); ++it) { RsPeerDetails detail; - if(!rsPeers->getGPGDetails(*it, detail)) + if(!mRsPeers->getGPGDetails(*it, detail)) continue; std::string pgp_id = (*it).toStdString(); @@ -595,7 +595,7 @@ void PeersHandler::handleSetPGPOptions(Request& req, Response& resp) RsPgpId pgp(pgp_id); RsPeerDetails detail; - if(!rsPeers->getGPGDetails(pgp, detail)) + if(!mRsPeers->getGPGDetails(pgp, detail)) { resp.setFail(); return; @@ -605,7 +605,7 @@ void PeersHandler::handleSetPGPOptions(Request& req, Response& resp) req.mStream << makeKeyValueReference("trustLvl", trustLvl); if(trustLvl != (int)detail.trustLvl) - rsPeers->trustGPGCertificate(pgp, trustLvl); + mRsPeers->trustGPGCertificate(pgp, trustLvl); int max_upload_speed; int max_download_speed; @@ -613,7 +613,7 @@ void PeersHandler::handleSetPGPOptions(Request& req, Response& resp) req.mStream << makeKeyValueReference("max_upload_speed", max_upload_speed); req.mStream << makeKeyValueReference("max_download_speed", max_download_speed); - rsPeers->setPeerMaximumRates(pgp, (uint32_t)max_upload_speed, (uint32_t)max_download_speed); + mRsPeers->setPeerMaximumRates(pgp, (uint32_t)max_upload_speed, (uint32_t)max_download_speed); bool direct_transfer; bool allow_push; @@ -632,13 +632,13 @@ void PeersHandler::handleSetPGPOptions(Request& req, Response& resp) if(require_WL) flags = flags | RS_NODE_PERM_REQUIRE_WL; - rsPeers->setServicePermissionFlags(pgp, flags); + mRsPeers->setServicePermissionFlags(pgp, flags); bool own_sign; req.mStream << makeKeyValueReference("own_sign", own_sign); if(own_sign) - rsPeers->signGPGCertificate(pgp); + mRsPeers->signGPGCertificate(pgp); resp.mStateToken = getCurrentStateToken(); From 144d57047c1d084304142ab8785aedb2d03987e1 Mon Sep 17 00:00:00 2001 From: Konrad Date: Thu, 13 Apr 2017 13:40:30 +0200 Subject: [PATCH 043/118] Fixed: Thread safe access to RsControlModule member variables --- libresapi/src/api/RsControlModule.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libresapi/src/api/RsControlModule.cpp b/libresapi/src/api/RsControlModule.cpp index f8e2d7e1e..2910bc443 100644 --- a/libresapi/src/api/RsControlModule.cpp +++ b/libresapi/src/api/RsControlModule.cpp @@ -136,7 +136,11 @@ void RsControlModule::run() bool login_ok = false; while(!login_ok) { - mPassword = ""; + { + RsStackMutex stack(mDataMtx); // ********** LOCKED ********** + mPassword = ""; + } + // skip account selection if autologin is available if(initResult != RS_INIT_HAVE_ACCOUNT) setRunState(WAITING_ACCOUNT_SELECT); @@ -188,11 +192,17 @@ void RsControlModule::run() break; } - mLoadPeerId.clear(); + { + RsStackMutex stack(mDataMtx); // ********** LOCKED ********** + mLoadPeerId.clear(); + } } - mFixedPassword = mPassword; - mPassword = ""; + { + RsStackMutex stack(mDataMtx); // ********** LOCKED ********** + mFixedPassword = mPassword; + mPassword = ""; + } setRunState(WAITING_STARTUP); From 93aeae0f59963dc895ef0a5cae2fba8036a4a703 Mon Sep 17 00:00:00 2001 From: Konrad Date: Fri, 14 Apr 2017 17:41:35 +0200 Subject: [PATCH 044/118] Added: Handling requests to delete identity --- libresapi/src/api/IdentityHandler.cpp | 39 ++++++++++++++++++++++++++- libresapi/src/api/IdentityHandler.h | 1 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 1a43211ea..bf1c65911 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -95,6 +95,37 @@ protected: } }; +class DeleteIdentityTask : public GxsResponseTask +{ +public: + DeleteIdentityTask(RsIdentity* idservice) : + GxsResponseTask(idservice, idservice->getTokenService()), + mToken(0), + mRsIdentity(idservice) + {} + +protected: + virtual void gxsDoWork(Request &req, Response &resp) + { + RsGxsIdGroup group; + std::string gxs_id; + + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + group.mMeta.mGroupId = RsGxsGroupId(gxs_id); + + mRsIdentity->deleteIdentity(mToken, group); + addWaitingToken(mToken); + + done(); + return; + } + +private: + uint32_t mToken; + RsIdentity* mRsIdentity; + RsGxsId mId; +}; + IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIdentity *identity): mStateTokenServer(sts), mNotify(notify), mRsIdentity(identity), mMtx("IdentityHandler Mtx"), mStateToken(sts->getNewToken()) @@ -107,7 +138,8 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden addResourceHandler("own_ids", this, &IdentityHandler::handleOwnIdsRequest); addResourceHandler("notown_ids", this, &IdentityHandler::handleNotOwnIdsRequest); - addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity); + addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity); + addResourceHandler("delete_identity", this, &IdentityHandler::handleDeleteIdentity); } IdentityHandler::~IdentityHandler() @@ -302,4 +334,9 @@ ResponseTask* IdentityHandler::handleCreateIdentity(Request & /* req */, Respons return new CreateIdentityTask(mRsIdentity); } +ResponseTask* IdentityHandler::handleDeleteIdentity(Request& req, Response& resp) +{ + return new DeleteIdentityTask(mRsIdentity); +} + } // namespace resource_api diff --git a/libresapi/src/api/IdentityHandler.h b/libresapi/src/api/IdentityHandler.h index 1b54f5438..17f7cb37d 100644 --- a/libresapi/src/api/IdentityHandler.h +++ b/libresapi/src/api/IdentityHandler.h @@ -28,6 +28,7 @@ private: ResponseTask *handleOwn(Request& req, Response& resp); ResponseTask *handleCreateIdentity(Request& req, Response& resp); + ResponseTask *handleDeleteIdentity(Request& req, Response& resp); StateTokenServer* mStateTokenServer; RsNotify* mNotify; From fd33315146d86bca139c8a0fb5ccd9ec39d57e38 Mon Sep 17 00:00:00 2001 From: Konrad Date: Fri, 14 Apr 2017 17:44:17 +0200 Subject: [PATCH 045/118] Added: Handling requests to create lobby --- libresapi/src/api/ChatHandler.cpp | 34 +++++++++++++++++++++++++++++++ libresapi/src/api/ChatHandler.h | 1 + 2 files changed, 35 insertions(+) diff --git a/libresapi/src/api/ChatHandler.cpp b/libresapi/src/api/ChatHandler.cpp index f576f8601..6e7fa07fe 100644 --- a/libresapi/src/api/ChatHandler.cpp +++ b/libresapi/src/api/ChatHandler.cpp @@ -145,6 +145,7 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs, addResourceHandler("*", this, &ChatHandler::handleWildcard); addResourceHandler("lobbies", this, &ChatHandler::handleLobbies); + addResourceHandler("create_lobby", this, &ChatHandler::handleCreateLobby); addResourceHandler("subscribe_lobby", this, &ChatHandler::handleSubscribeLobby); addResourceHandler("unsubscribe_lobby", this, &ChatHandler::handleUnsubscribeLobby); addResourceHandler("autosubscribe_lobby", this, &ChatHandler::handleAutoSubsribeLobby); @@ -1210,4 +1211,37 @@ void ChatHandler::handleCloseDistantChatConnexion(Request& req, Response& resp) else resp.setFail("Failed to close distant chat"); } +void ChatHandler::handleCreateLobby(Request& req, Response& resp) +{ + std::set invited_identites; + std::string lobby_name; + std::string lobby_topic; + std::string gxs_id; + + req.mStream << makeKeyValueReference("lobby_name", lobby_name); + req.mStream << makeKeyValueReference("lobby_topic", lobby_topic); + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + + RsGxsId gxsId(gxs_id); + + bool lobby_public; + bool pgp_signed; + + req.mStream << makeKeyValueReference("lobby_public", lobby_public); + req.mStream << makeKeyValueReference("pgp_signed", pgp_signed); + + ChatLobbyFlags lobby_flags; + + if(lobby_public) + lobby_flags |= RS_CHAT_LOBBY_FLAGS_PUBLIC; + + if(pgp_signed) + lobby_flags |= RS_CHAT_LOBBY_FLAGS_PGP_SIGNED; + + mRsMsgs->createChatLobby(lobby_name, gxsId, lobby_topic, invited_identites, lobby_flags); + + tick(); + resp.setOk(); +} + } // namespace resource_api diff --git a/libresapi/src/api/ChatHandler.h b/libresapi/src/api/ChatHandler.h index 3463cee57..9cda3e551 100644 --- a/libresapi/src/api/ChatHandler.h +++ b/libresapi/src/api/ChatHandler.h @@ -118,6 +118,7 @@ public: private: void handleWildcard(Request& req, Response& resp); void handleLobbies(Request& req, Response& resp); + void handleCreateLobby(Request& req, Response& resp); void handleSubscribeLobby(Request& req, Response& resp); void handleUnsubscribeLobby(Request& req, Response& resp); void handleAutoSubsribeLobby(Request& req, Response& resp); From 273aae7cc1aad7ae0f9e41d3343b66ab2f1bbd62 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 15 Apr 2017 19:01:13 +0200 Subject: [PATCH 046/118] fixed sharing of own identity --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index b7923dc49..96b943d15 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -2409,7 +2409,7 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) } if(n_selected_items==1) - QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy retroshare link"),this,SLOT(copyRetroshareLink())) ; + QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ; // always allow to send messages contextMenu->addAction(QIcon(":/images/mail_new.png"), tr("Send message"), this, SLOT(sendMsg())); @@ -2438,6 +2438,7 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) { contextMenu->addSeparator(); + contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ; contextMenu->addAction(ui->editIdentity); contextMenu->addAction(ui->removeIdentity); } From cbc264f5a3f9f90afdd83831691e63291244a69f Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 15 Mar 2017 18:53:30 +0100 Subject: [PATCH 047/118] Fix clang warning:Implicit conversion from enumeration warning: implicit conversion from enumeration type 'ops_s2k_usage_t' to different enumeration type 'ops_symmetric_algorithm_t' [-Wenum- conversion] C.secret_key.algorithm=C.secret_key.s2k_usage; ~~~~~~~~~~~~~~^~~~~~~~~ --- openpgpsdk/src/openpgpsdk/packet-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpgpsdk/src/openpgpsdk/packet-parse.c b/openpgpsdk/src/openpgpsdk/packet-parse.c index b80cf4ef8..a4596a55c 100644 --- a/openpgpsdk/src/openpgpsdk/packet-parse.c +++ b/openpgpsdk/src/openpgpsdk/packet-parse.c @@ -2394,7 +2394,7 @@ static int parse_secret_key(ops_region_t *region,ops_parse_info_t *pinfo) else if(C.secret_key.s2k_usage != OPS_S2KU_NONE) { // this is V3 style, looks just like a V4 simple hash - C.secret_key.algorithm=C.secret_key.s2k_usage; + C.secret_key.algorithm=(ops_symmetric_algorithm_t)C.secret_key.s2k_usage; C.secret_key.s2k_usage=OPS_S2KU_ENCRYPTED; C.secret_key.s2k_specifier=OPS_S2KS_SIMPLE; C.secret_key.hash_algorithm=OPS_HASH_MD5; From da4b168a04ddeb797e2db9f47cf9707da01aa63c Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 15 Mar 2017 18:55:24 +0100 Subject: [PATCH 048/118] Fix Clang warnings: mFns is not used warning: private field 'mFns' is not used [-Wunused-private-field] bdDhtFunctions *mFns; ^ --- libbitdht/src/udp/udpbitdht.cc | 2 +- libbitdht/src/udp/udpbitdht.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libbitdht/src/udp/udpbitdht.cc b/libbitdht/src/udp/udpbitdht.cc index 5410d50e0..39c13e182 100644 --- a/libbitdht/src/udp/udpbitdht.cc +++ b/libbitdht/src/udp/udpbitdht.cc @@ -58,7 +58,7 @@ /*************************************/ UdpBitDht::UdpBitDht(UdpPublisher *pub, bdNodeId *id, std::string appVersion, std::string bootstrapfile, const std::string& filteredipfile, bdDhtFunctions *fns) - :UdpSubReceiver(pub), dhtMtx(true), mFns(fns) + :UdpSubReceiver(pub), dhtMtx(true)//, mFns(fns) { std::string usedVersion; diff --git a/libbitdht/src/udp/udpbitdht.h b/libbitdht/src/udp/udpbitdht.h index 36946877e..f1e167abf 100644 --- a/libbitdht/src/udp/udpbitdht.h +++ b/libbitdht/src/udp/udpbitdht.h @@ -119,7 +119,7 @@ void clearDataTransferred(); bdMutex dhtMtx; /* for all class data (below) */ bdNodeManager *mBitDhtManager; - bdDhtFunctions *mFns; + //bdDhtFunctions *mFns; uint32_t mReadBytes; From 105840ab982cb8442f111c49fcba0776abcfd249 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 15 Mar 2017 19:03:39 +0100 Subject: [PATCH 049/118] Fix Clang Warning: Overloaded vf hide warning: 'pqiConnectCbDummy::peerConnectRequest' hides overloaded virtual function [-Woverloaded-virtual] virtual void peerConnectRequest(const RsPeerId& id, ^ --- libretroshare/src/pqi/pqimonitor.cc | 12 +++++++++--- libretroshare/src/pqi/pqimonitor.h | 5 +++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/pqi/pqimonitor.cc b/libretroshare/src/pqi/pqimonitor.cc index 03894a66d..fac7a50f9 100644 --- a/libretroshare/src/pqi/pqimonitor.cc +++ b/libretroshare/src/pqi/pqimonitor.cc @@ -61,14 +61,20 @@ void pqiConnectCbDummy::peerStatus(const RsPeerId& id, const pqiIpAddrSet &ad std::cerr << out << std::endl; } -void pqiConnectCbDummy::peerConnectRequest(const RsPeerId& id, - const struct sockaddr_storage &raddr, uint32_t source) +void pqiConnectCbDummy::peerConnectRequest(const RsPeerId &id, const sockaddr_storage &raddr + , const sockaddr_storage &proxyaddr, const sockaddr_storage &srcaddr + , uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) { std::cerr << "pqiConnectCbDummy::peerConnectRequest()"; std::cerr << " id: " << id; std::cerr << " raddr: " << sockaddr_storage_tostring(raddr); + std::cerr << " proxyaddr: " << sockaddr_storage_tostring(proxyaddr); + std::cerr << " srcaddr: " << sockaddr_storage_tostring(srcaddr); std::cerr << " source: " << source; - std::cerr << std::endl; + std::cerr << " flags: " << flags; + std::cerr << " delay: " << delay; + std::cerr << " bandwidth: " << bandwidth; + std::cerr << std::endl; } void pqiMonitor::disconnectPeer(const RsPeerId &/*peer*/) diff --git a/libretroshare/src/pqi/pqimonitor.h b/libretroshare/src/pqi/pqimonitor.h index 34d998e75..94e9bdf05 100644 --- a/libretroshare/src/pqi/pqimonitor.h +++ b/libretroshare/src/pqi/pqimonitor.h @@ -179,8 +179,9 @@ virtual ~pqiConnectCbDummy(); virtual void peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs, uint32_t type, uint32_t mode, uint32_t source); -virtual void peerConnectRequest(const RsPeerId& id, - const struct sockaddr_storage &raddr, uint32_t source); + virtual void peerConnectRequest(const RsPeerId& id, const struct sockaddr_storage &raddr, + const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr, + uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth); //virtual void stunStatus(std::string id, const struct sockaddr_storage &raddr, uint32_t type, uint32_t flags); }; From cf963c0c7359697c9874df64e4b86ff3671ed54f Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 15 Mar 2017 20:41:39 +0100 Subject: [PATCH 050/118] Fix Clang warnings: struct declared as class warning: 'RsMsgMetaData' defined as a struct here but previously declared as a class [-Wmismatched-tags] struct RsMsgMetaData ^ --- libretroshare/src/gxs/rsgxsdata.h | 24 +++++++++---------- .../src/retroshare/rsgxsifacetypes.h | 2 +- libretroshare/src/retroshare/rsgxsservice.h | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 21fbe1445..2b2e9f14d 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -34,8 +34,8 @@ #include "serialiser/rstlvkeys.h" #include "serialiser/rsgxsitems.h" -class RsGroupMetaData; -class RsMsgMetaData; +struct RsGroupMetaData; +struct RsMsgMetaData; static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0001 = 0x0000 ; // change this, and keep old values if the content changes static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0002 = 0xaf01 ; // current API @@ -56,22 +56,22 @@ public: void clear(); void operator =(const RsGroupMetaData& rMeta); - //Sort data in same order than serialiser and deserializer + //Sort data in same order than serialiser and deserializer RsGxsGroupId mGroupId; RsGxsGroupId mOrigGrpId; - RsGxsGroupId mParentGrpId; + RsGxsGroupId mParentGrpId; std::string mGroupName; uint32_t mGroupFlags; // GXS_SERV::FLAG_PRIVACY_RESTRICTED | GXS_SERV::FLAG_PRIVACY_PRIVATE | GXS_SERV::FLAG_PRIVACY_PUBLIC uint32_t mPublishTs; - uint32_t mCircleType; - uint32_t mAuthenFlags; + uint32_t mCircleType; + uint32_t mAuthenFlags; RsGxsId mAuthorId; - std::string mServiceString; + std::string mServiceString; RsGxsCircleId mCircleId; RsTlvKeySignatureSet signSet; RsTlvSecurityKeySet keys; - uint32_t mSignFlags; + uint32_t mSignFlags; // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. @@ -103,9 +103,9 @@ public: void clear(); void operator =(const RsMsgMetaData& rMeta); - static int refcount; - - //Sort data in same order than serialiser and deserializer + static int refcount; + + //Sort data in same order than serialiser and deserializer RsGxsGroupId mGroupId; RsGxsMessageId mMsgId; RsGxsMessageId mThreadId; @@ -121,7 +121,7 @@ public: // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. // normally READ / UNREAD flags. LOCAL Data. - std::string mServiceString; + std::string mServiceString; uint32_t mMsgStatus; uint32_t mMsgSize; time_t mChildTs; diff --git a/libretroshare/src/retroshare/rsgxsifacetypes.h b/libretroshare/src/retroshare/rsgxsifacetypes.h index 6fd907898..1bc17b5e0 100644 --- a/libretroshare/src/retroshare/rsgxsifacetypes.h +++ b/libretroshare/src/retroshare/rsgxsifacetypes.h @@ -25,7 +25,7 @@ typedef std::pair RsGxsGrpMsgIdPair; typedef std::map > MsgRelatedIdResult; typedef std::map > GxsMsgReq; -class RsMsgMetaData; +struct RsMsgMetaData; typedef std::map > MsgMetaResult; diff --git a/libretroshare/src/retroshare/rsgxsservice.h b/libretroshare/src/retroshare/rsgxsservice.h index 8f26e5262..6afed31c6 100644 --- a/libretroshare/src/retroshare/rsgxsservice.h +++ b/libretroshare/src/retroshare/rsgxsservice.h @@ -5,7 +5,7 @@ #include "retroshare/rsgxsifacetypes.h" #include "retroshare/rstokenservice.h" -class RsMsgMetaData ; +struct RsMsgMetaData ; typedef std::map > GxsMsgMetaMap; typedef std::map > GxsMsgRelatedMetaMap; From 6fecac5f7beee4c66cd45f3c0f77c7e7fe8bca63 Mon Sep 17 00:00:00 2001 From: Phenom Date: Thu, 16 Mar 2017 17:50:25 +0100 Subject: [PATCH 051/118] Fix Clang warnings: Overloaded vf hide warning: 'pqiconnect::connect_parameter' hides overloaded virtual function [-Woverloaded-virtual] virtual bool connect_parameter(uint32_t type, std::string value) { return ni->connect_parameter(type, value);} ^ --- libretroshare/src/pqi/pqiperson.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/pqi/pqiperson.h b/libretroshare/src/pqi/pqiperson.h index f3ff940e1..afd2213d5 100644 --- a/libretroshare/src/pqi/pqiperson.h +++ b/libretroshare/src/pqi/pqiperson.h @@ -29,6 +29,7 @@ #define MRK_PQI_PERSON_HEADER +#include #include "pqi/pqi.h" #include "util/rsnet.h" @@ -66,7 +67,7 @@ public: virtual int reset() { pqistreamer::reset(); return ni->reset(); } virtual int disconnect() { return reset() ; } virtual bool connect_parameter(uint32_t type, uint32_t value) { return ni->connect_parameter(type, value);} - virtual bool connect_parameter(uint32_t type, std::string value) { return ni->connect_parameter(type, value);} + virtual bool connect_parameter(uint32_t type, const std::string &value) { return ni->connect_parameter(type, value);} virtual bool connect_additional_address(uint32_t type, const struct sockaddr_storage &addr) { return ni->connect_additional_address(type, addr); } virtual int getConnectAddress(struct sockaddr_storage &raddr){ return ni->getConnectAddress(raddr); } From 5bc6558567fba0f9f5f30d64d0e72ace1187dd07 Mon Sep 17 00:00:00 2001 From: Phenom Date: Thu, 16 Mar 2017 18:28:48 +0100 Subject: [PATCH 052/118] Fix Clang warnings: explicitly assigning value to itself /home/phenom/GIT/RetroShare/trunk/libretroshare/src/util/radix64.h:96: warning: explicitly assigning value of variable of type 'int' to itself [-Wself-assign] idx = idx; ~~~ ^ ~~~ --- libretroshare/src/util/radix64.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/util/radix64.h b/libretroshare/src/util/radix64.h index dc7f8528c..9ee80f2dd 100644 --- a/libretroshare/src/util/radix64.h +++ b/libretroshare/src/util/radix64.h @@ -93,9 +93,9 @@ again: idx = (idx + 1) % 4; } - idx = idx; + //idx = idx; - return buf; + return buf ; } /**************** From 65321501e48787930da7cde70b92496f1f2d084b Mon Sep 17 00:00:00 2001 From: Phenom Date: Thu, 16 Mar 2017 21:04:38 +0100 Subject: [PATCH 053/118] Fix Clang warnings: Overloaded vf hide in p3dhtmgr warning: 'p3DhtMgr::findPeer' hides overloaded virtual function [- Woverloaded-virtual] virtual bool findPeer(std::string id); warning: 'p3DhtMgr::dropPeer' hides overloaded virtual function [- Woverloaded-virtual] virtual bool dropPeer(std::string id); warning: 'p3DhtMgr::getPeerStatus' hides overloaded virtual function [- Woverloaded-virtual] virtual bool getPeerStatus(std::string id, --- libretroshare/src/pqi/p3dhtmgr.cc | 46 +++++++++++++++---------------- libretroshare/src/pqi/p3dhtmgr.h | 24 ++++++++-------- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/libretroshare/src/pqi/p3dhtmgr.cc b/libretroshare/src/pqi/p3dhtmgr.cc index a93577581..c1d929c94 100644 --- a/libretroshare/src/pqi/p3dhtmgr.cc +++ b/libretroshare/src/pqi/p3dhtmgr.cc @@ -92,7 +92,7 @@ dhtPeerEntry::dhtPeerEntry() return; } -p3DhtMgr::p3DhtMgr(std::string id, pqiConnectCb *cb) +p3DhtMgr::p3DhtMgr(RsPeerId id, pqiConnectCb *cb) :pqiNetAssistConnect(id, cb), dhtMtx("p3DhtMgr"), mStunRequired(true) { /* setup own entry */ @@ -237,13 +237,13 @@ bool p3DhtMgr::setExternalInterface( /* add / remove peers */ -bool p3DhtMgr::findPeer(std::string id) +bool p3DhtMgr::findPeer(const RsPeerId& id) { RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/ mDhtModifications = true; - std::map::iterator it; + std::map::iterator it; it = peers.find(id); if (it != peers.end()) { @@ -281,14 +281,14 @@ bool p3DhtMgr::findPeer(std::string id) return true; } -bool p3DhtMgr::dropPeer(std::string id) +bool p3DhtMgr::dropPeer(const RsPeerId& id) { RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/ mDhtModifications = true; /* once we are connected ... don't worry about them anymore */ - std::map::iterator it; + std::map::iterator it; it = peers.find(id); if (it == peers.end()) { @@ -302,14 +302,14 @@ bool p3DhtMgr::dropPeer(std::string id) } /* post DHT key saying we should connect */ -bool p3DhtMgr::notifyPeer(std::string id) +bool p3DhtMgr::notifyPeer(const RsPeerId& id) { RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/ #ifdef DHT_DEBUG - std::cerr << "p3DhtMgr::notifyPeer() " << id << std::endl; + std::cerr << "p3DhtMgr::notifyPeer() " << id.toStdString() << std::endl; #endif - std::map::iterator it; + std::map::iterator it; it = peers.find(id); if (it == peers.end()) { @@ -333,7 +333,7 @@ bool p3DhtMgr::notifyPeer(std::string id) #ifdef DHT_LOGS { /* Log */ - rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id + " TO SOON - DROPPING"); + rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id.toStdString() + " TO SOON - DROPPING"); } #endif @@ -352,7 +352,7 @@ bool p3DhtMgr::notifyPeer(std::string id) #ifdef DHT_LOGS { /* Log */ - rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id + " PEER NOT FOUND - Trigger Search"); + rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id.toStdString() + " PEER NOT FOUND - Trigger Search"); } #endif it->second.lastTS = 0; @@ -364,14 +364,14 @@ bool p3DhtMgr::notifyPeer(std::string id) } /* extract current peer status */ -bool p3DhtMgr::getPeerStatus(std::string id, - struct sockaddr_in &laddr, - struct sockaddr_in &raddr, +bool p3DhtMgr::getPeerStatus(const RsPeerId &id, + struct sockaddr_in &laddr, + struct sockaddr_in &raddr, uint32_t &type, uint32_t &state) { RsStackMutex stack(dhtMtx); /* LOCK MUTEX */ - std::map::iterator it; + std::map::iterator it; it = peers.find(id); /* ignore OFF peers */ @@ -776,7 +776,7 @@ int p3DhtMgr::checkPeerDHTKeys() dhtMtx.lock(); /* LOCK MUTEX */ /* iterate through and find min time and suitable candidate */ - std::map::iterator it,pit; + std::map::iterator it,pit; time_t now = time(NULL); uint32_t period = 0; uint32_t repeatPeriod = 6000; @@ -802,7 +802,7 @@ int p3DhtMgr::checkPeerDHTKeys() period = DHT_CHECK_PERIOD; } #ifdef DHT_DEBUG - std::cerr << "p3DhtMgr::checkPeerDHTKeys() Peer: " << it->second.id; + std::cerr << "p3DhtMgr::checkPeerDHTKeys() Peer: " << it->second.id.toStdString(); std::cerr << " Period: " << period; std::cerr << " Delta: " << delta; std::cerr << std::endl; @@ -865,7 +865,7 @@ int p3DhtMgr::checkNotifyDHT() RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/ /* iterate through and find min time and suitable candidate */ - std::map::iterator it; + std::map::iterator it; time_t now = time(NULL); int repeatPeriod = DHT_DEFAULT_PERIOD; @@ -1015,7 +1015,7 @@ int p3DhtMgr::checkStunState() if (mDhtState == DHT_STATE_CHECK_PEERS) { /* check that they have all be searched for */ - std::map::iterator it; + std::map::iterator it; for(it = peers.begin(); it != peers.end(); it++) { if (it->second.state == DHT_PEER_INIT) @@ -1287,7 +1287,7 @@ int p3DhtMgr::status(std::ostream &out) out << "OWN DETAILS END----------------------------------------" << std::endl; /* now peers states */ - std::map::iterator it; + std::map::iterator it; out << "PEER DETAILS ------------------------------------------" << std::endl; for(it = peers.begin(); it != peers.end(); it++) { @@ -1622,15 +1622,13 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash) std::cerr << "p3DhtMgr::dhtResultNotify() from idhash: "; std::cerr << RsUtil::BinToHex(idhash) << std::endl; #endif - std::map::iterator it; + std::map::iterator it; time_t now = time(NULL); /* if notify - we must match on the second hash */ for(it = peers.begin(); (it != peers.end()) && ((it->second).hash2 != idhash); it++) ; /* update data */ - std::string peerid; - /* ignore OFF peers */ if ((it != peers.end()) && (it->second.state != DHT_PEER_OFF)) { @@ -1677,7 +1675,7 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash, std::cerr << "p3DhtMgr::dhtResultSearch() for idhash: "; std::cerr << RsUtil::BinToHex(idhash) << std::endl; #endif - std::map::iterator it; + std::map::iterator it; bool doCb = false; bool doStun = false; uint32_t stunFlags = 0; @@ -1780,7 +1778,7 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash, void printDhtPeerEntry(dhtPeerEntry *ent, std::ostream &out) { - out << "DhtEntry: ID: " << ent->id; + out << "DhtEntry: ID: " << ent->id.toStdString(); out << " State: " << ent->state; out << " lastTS: " << ent->lastTS; out << " notifyPending: " << ent->notifyPending; diff --git a/libretroshare/src/pqi/p3dhtmgr.h b/libretroshare/src/pqi/p3dhtmgr.h index f08c2bc96..86d6b5424 100644 --- a/libretroshare/src/pqi/p3dhtmgr.h +++ b/libretroshare/src/pqi/p3dhtmgr.h @@ -78,7 +78,7 @@ class dhtPeerEntry public: dhtPeerEntry(); - std::string id; + RsPeerId id; uint32_t state; time_t lastTS; @@ -97,7 +97,7 @@ class p3DhtMgr: public pqiNetAssistConnect, public RsThread /* */ public: - p3DhtMgr(std::string id, pqiConnectCb *cb); + p3DhtMgr(RsPeerId id, pqiConnectCb *cb); /********** External DHT Interface ************************ * These Functions are the external interface @@ -121,15 +121,15 @@ virtual bool setExternalInterface(struct sockaddr_in laddr, struct sockaddr_in raddr, uint32_t type); /* add / remove peers */ -virtual bool findPeer(std::string id); -virtual bool dropPeer(std::string id); +virtual bool findPeer(const RsPeerId& id); +virtual bool dropPeer(const RsPeerId& id); /* post DHT key saying we should connect (callback when done) */ -virtual bool notifyPeer(std::string id); +virtual bool notifyPeer(const RsPeerId& id); /* extract current peer status */ -virtual bool getPeerStatus(std::string id, - struct sockaddr_in &laddr, struct sockaddr_in &raddr, +virtual bool getPeerStatus(const RsPeerId& id, + struct sockaddr_in &laddr, struct sockaddr_in &raddr, uint32_t &type, uint32_t &mode); /* stun */ @@ -154,17 +154,17 @@ virtual bool dhtResultBootstrap(std::string idhash); protected: /* can block briefly (called only from thread) */ -virtual bool dhtPublish(std::string id, +virtual bool dhtPublish(std::string idhash, struct sockaddr_in &laddr, struct sockaddr_in &raddr, uint32_t type, std::string sign); -virtual bool dhtNotify(std::string peerid, std::string ownId, +virtual bool dhtNotify(std::string idhash, std::string ownIdHash, std::string sign); -virtual bool dhtSearch(std::string id, uint32_t mode); +virtual bool dhtSearch(std::string idhash, uint32_t mode); -virtual bool dhtBootstrap(std::string storehash, std::string ownIdHash, +virtual bool dhtBootstrap(std::string idhash, std::string ownIdHash, std::string sign); /* to publish bootstrap */ @@ -232,7 +232,7 @@ std::string randomBootstrapId(); dhtPeerEntry ownEntry; time_t ownNotifyTS; - std::map peers; + std::map peers; std::list stunIds; bool mStunRequired; From dc533b1346ce1f7fa4f8137ee8133fc65cb285e9 Mon Sep 17 00:00:00 2001 From: Phenom Date: Thu, 16 Mar 2017 22:01:22 +0100 Subject: [PATCH 054/118] Fix Clang warnings: private field not used warning: private field 'lastGroupId' is not used [-Wunused-private- field] uint32_t lastGroupId; warning: private field 'waittimes' is not used [-Wunused-private-field] int waittimes; warning: private field 'listen_checktime' is not used [-Wunused-private- field] long listen_checktime; --- libretroshare/src/pqi/p3peermgr.h | 2 +- libretroshare/src/pqi/pqiperson.cc | 2 +- libretroshare/src/pqi/pqiperson.h | 2 +- libretroshare/src/pqi/pqissludp.cc | 2 +- libretroshare/src/pqi/pqissludp.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/pqi/p3peermgr.h b/libretroshare/src/pqi/p3peermgr.h index ee581b275..f0a9a44cb 100644 --- a/libretroshare/src/pqi/p3peermgr.h +++ b/libretroshare/src/pqi/p3peermgr.h @@ -397,7 +397,7 @@ private: std::map mReportedOwnAddresses ; std::map groupList; - uint32_t lastGroupId; + //uint32_t lastGroupId; std::list saveCleanupList; /* TEMPORARY LIST WHEN SAVING */ diff --git a/libretroshare/src/pqi/pqiperson.cc b/libretroshare/src/pqi/pqiperson.cc index cade0c39e..e7d1cf18b 100644 --- a/libretroshare/src/pqi/pqiperson.cc +++ b/libretroshare/src/pqi/pqiperson.cc @@ -40,7 +40,7 @@ static struct RsLog::logInfo pqipersonzoneInfo = {RsLog::Default, "pqiperson"}; pqiperson::pqiperson(const RsPeerId& id, pqipersongrp *pg) : PQInterface(id), mNotifyMtx("pqiperson-notify"), mPersonMtx("pqiperson"), - active(false), activepqi(NULL), inConnectAttempt(false), waittimes(0), + active(false), activepqi(NULL), inConnectAttempt(false),// waittimes(0), pqipg(pg) {} // TODO: must check id! pqiperson::~pqiperson() diff --git a/libretroshare/src/pqi/pqiperson.h b/libretroshare/src/pqi/pqiperson.h index afd2213d5..69faec48c 100644 --- a/libretroshare/src/pqi/pqiperson.h +++ b/libretroshare/src/pqi/pqiperson.h @@ -172,7 +172,7 @@ private: bool active; pqiconnect *activepqi; bool inConnectAttempt; - int waittimes; + //int waittimes; time_t lastHeartbeatReceived; // use to track connection failure pqipersongrp *pqipg; /* parent for callback */ }; diff --git a/libretroshare/src/pqi/pqissludp.cc b/libretroshare/src/pqi/pqissludp.cc index 9519e2af3..29bd228c9 100644 --- a/libretroshare/src/pqi/pqissludp.cc +++ b/libretroshare/src/pqi/pqissludp.cc @@ -53,7 +53,7 @@ static const uint32_t PQI_SSLUDP_DEF_CONN_PERIOD = 300; /* 5 minutes? */ /********** PQI SSL UDP STUFF **************************************/ pqissludp::pqissludp(PQInterface *parent, p3LinkMgr *lm) : - pqissl(NULL, parent, lm), tou_bio(NULL), listen_checktime(0), + pqissl(NULL, parent, lm), tou_bio(NULL),// listen_checktime(0), mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD), mConnectFlags(0), mConnectBandwidth(0) { diff --git a/libretroshare/src/pqi/pqissludp.h b/libretroshare/src/pqi/pqissludp.h index 848717bbd..195e9e604 100644 --- a/libretroshare/src/pqi/pqissludp.h +++ b/libretroshare/src/pqi/pqissludp.h @@ -95,7 +95,7 @@ private: BIO *tou_bio; // specific to ssludp. - long listen_checktime; + //long listen_checktime; uint32_t mConnectPeriod; uint32_t mConnectFlags; From 22043094b5d269a92db3816468b2312f98e7e374 Mon Sep 17 00:00:00 2001 From: Phenom Date: Thu, 16 Mar 2017 22:11:33 +0100 Subject: [PATCH 055/118] Fix Clang warnings: extraneous parentheses warning: equality comparison with extraneous parentheses [-Wparentheses- equality] else if ((err == ECONNREFUSED)) ~~~~^~~~~~~~~~~~~~~ --- libretroshare/src/pqi/pqissl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index b7709bb82..bcc49cbbc 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1009,7 +1009,7 @@ int pqissl::Basic_Connection_Complete() return -1; } - else if ((err == ECONNREFUSED)) + else if (err == ECONNREFUSED) { rslog(RSL_WARNING, pqisslzone, "pqissl::Basic_Connection_Complete() ECONNREFUSED: cert: " + PeerId().toStdString()); From 872f42bcefe4b6fc6c0b84d04b4484dff177b549 Mon Sep 17 00:00:00 2001 From: Phenom Date: Thu, 16 Mar 2017 22:55:18 +0100 Subject: [PATCH 056/118] Fix Clang warnings: Overloaded vf hide in pluginmanager warning: 'RsPluginManager::loadConfiguration' hides overloaded virtual function [-Woverloaded-virtual] virtual void loadConfiguration() ; --- libretroshare/src/plugins/pluginmanager.cc | 7 ++++++- libretroshare/src/plugins/pluginmanager.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/plugins/pluginmanager.cc b/libretroshare/src/plugins/pluginmanager.cc index 431b6c2f8..259004300 100644 --- a/libretroshare/src/plugins/pluginmanager.cc +++ b/libretroshare/src/plugins/pluginmanager.cc @@ -51,9 +51,14 @@ RsPluginManager::RsPluginManager(const RsFileHash &hash) _allow_all_plugins = false ; } +bool RsPluginManager::loadConfiguration(RsFileHash &loadHash) +{ + return p3Config::loadConfiguration(loadHash); +} + void RsPluginManager::loadConfiguration() { - RsFileHash dummyHash ; + RsFileHash dummyHash; p3Config::loadConfiguration(dummyHash); } diff --git a/libretroshare/src/plugins/pluginmanager.h b/libretroshare/src/plugins/pluginmanager.h index 5f2a8c3b7..27a74f870 100644 --- a/libretroshare/src/plugins/pluginmanager.h +++ b/libretroshare/src/plugins/pluginmanager.h @@ -74,6 +74,7 @@ class RsPluginManager: public RsPluginHandler, public p3Config // -------------------- Own members -------------------------// // virtual void addConfigurations(p3ConfigMgr *cfgMgr) ; + virtual bool loadConfiguration(RsFileHash &loadHash) ; virtual void loadConfiguration() ; /*! From 039908b2c634d1a8c9355b5bb2574de8812b83e2 Mon Sep 17 00:00:00 2001 From: Phenom Date: Thu, 16 Mar 2017 22:58:06 +0100 Subject: [PATCH 057/118] Fix Clang warnings: private field not used warning: private field 'mNetMgr' is not used [-Wunused-private-field] p3NetMgr *mNetMgr; --- libretroshare/src/services/p3banlist.cc | 4 ++-- libretroshare/src/services/p3banlist.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/services/p3banlist.cc b/libretroshare/src/services/p3banlist.cc index 157cc23f8..65d56987b 100644 --- a/libretroshare/src/services/p3banlist.cc +++ b/libretroshare/src/services/p3banlist.cc @@ -66,8 +66,8 @@ */ RsBanList *rsBanList = NULL ; -p3BanList::p3BanList(p3ServiceControl *sc, p3NetMgr *nm) - :p3Service(), mBanMtx("p3BanList"), mServiceCtrl(sc), mNetMgr(nm) +p3BanList::p3BanList(p3ServiceControl *sc, p3NetMgr */*nm*/) + :p3Service(), mBanMtx("p3BanList"), mServiceCtrl(sc)//, mNetMgr(nm) { addSerialType(new RsBanListSerialiser()); diff --git a/libretroshare/src/services/p3banlist.h b/libretroshare/src/services/p3banlist.h index 87bb7104a..86456d6ae 100644 --- a/libretroshare/src/services/p3banlist.h +++ b/libretroshare/src/services/p3banlist.h @@ -148,7 +148,7 @@ private: std::map mWhiteListedRanges; p3ServiceControl *mServiceCtrl; - p3NetMgr *mNetMgr; + //p3NetMgr *mNetMgr; time_t mLastDhtInfoRequest ; bool mIPFilteringEnabled ; From e83104ee0fc520cc9115be3fa1bd335130cb5630 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 18 Mar 2017 10:19:31 +0100 Subject: [PATCH 058/118] Fix Clang warnings: Add author and date to #warning --- libretroshare/src/gxs/rsgxsnetservice.cc | 4 ++-- libretroshare/src/gxs/rsgxsnetutils.cc | 2 +- libretroshare/src/pqi/sslfns.cc | 2 +- libretroshare/src/services/p3gxsreputation.cc | 2 +- libretroshare/src/services/p3idservice.cc | 2 +- retroshare-gui/src/gui/Identity/IdDialog.cpp | 2 +- retroshare-gui/src/gui/RetroShareLink.h | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 259d01135..3811ddd0c 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -1972,7 +1972,7 @@ void RsGxsNetService::updateServerSyncTS() #endif // I keep the creation, but the data is not used yet. -#warning disabled this, but do we need it? +#warning csoler 2016-12-12: Disabled this, but do we need it? // RsGxsServerMsgUpdate& msui(mServerMsgUpdateMap[grpId]) ; // (cyril) I'm removing this, because the msgUpdateTS is updated when new messages are received by calling locked_stampMsgServerUpdateTS(). @@ -3000,7 +3000,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr) } // FIXTESTS global variable rsReputations not available in unittests! -#warning Update the code below to correctly send/recv dependign on reputation +#warning csoler 2016-12-23: Update the code below to correctly send/recv dependign on reputation if(!grpSyncItem->authorId.isNull() && mReputations->overallReputationLevel(grpSyncItem->authorId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE) { #ifdef NXS_NET_DEBUG_0 diff --git a/libretroshare/src/gxs/rsgxsnetutils.cc b/libretroshare/src/gxs/rsgxsnetutils.cc index 4d54ce117..7454ba58a 100644 --- a/libretroshare/src/gxs/rsgxsnetutils.cc +++ b/libretroshare/src/gxs/rsgxsnetutils.cc @@ -45,7 +45,7 @@ bool AuthorPending::getAuthorRep(GixsReputation& rep, const RsGxsId& authorId, c rep.id = authorId ; rep.reputation_level = mRep->overallReputationLevel(authorId); -#warning can it happen that reputations do not have the info yet? +#warning csoler 2017-01-10: Can it happen that reputations do not have the info yet? return true ; #ifdef TO_BE_REMOVED { diff --git a/libretroshare/src/pqi/sslfns.cc b/libretroshare/src/pqi/sslfns.cc index 7cf742956..ba5a9e6a3 100644 --- a/libretroshare/src/pqi/sslfns.cc +++ b/libretroshare/src/pqi/sslfns.cc @@ -627,7 +627,7 @@ bool getX509id(X509 *x509, RsPeerId& xid) * more randomness */ -#warning this is cryptographically horrible. We should do a hash of the public key here!!! +#warning csoler 2017-02-19: This is cryptographically horrible. We should do a hash of the public key here!!! xid = RsPeerId(&signdata[signlen - CERTSIGNLEN]) ; diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index 45fd95898..c60f54f0c 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -1035,7 +1035,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O if (rit == mReputations.end()) { -#warning we should set the owner node id here. +#warning csoler 2017-01-05: We should set the owner node id here. mReputations[gxsid] = Reputation(gxsid); rit = mReputations.find(gxsid); } diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index dcc45af65..78abe7d2b 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -788,7 +788,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if (params.isPgpLinked) { -#warning Backward compatibility issue to fix here in v0.7.0 +#warning csoler 2017-02-07: Backward compatibility issue to fix here in v0.7.0 // This is a hack, because a bad decision led to having RSGXSID_GROUPFLAG_REALID be equal to GXS_SERV::FLAG_PRIVACY_PRIVATE. // In order to keep backward compatibility, we'll also add the new value diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 96b943d15..1cf93055b 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -1993,7 +1993,7 @@ QString IdDialog::createUsageString(const RsIdentityUsage& u) const return tr("Membership verification in circle %1.").arg(QString::fromStdString(u.mGrpId.toStdString())); } -#warning TODO! Add the different strings and translations here. +#warning TODO! csoler 2017-01-03: Add the different strings and translations here. default: return QString("Undone yet"); } diff --git a/retroshare-gui/src/gui/RetroShareLink.h b/retroshare-gui/src/gui/RetroShareLink.h index b272f3416..241d56740 100644 --- a/retroshare-gui/src/gui/RetroShareLink.h +++ b/retroshare-gui/src/gui/RetroShareLink.h @@ -77,7 +77,7 @@ class RetroShareLink RetroShareLink(const QUrl& url); RetroShareLink(const QString& url); -#warning these methods should be static and return a created link +#warning csoler 2017-01-04: These methods should be static and return a created link bool createFile(const QString& name, uint64_t size, const QString& hash); bool createExtraFile(const QString& name, uint64_t size, const QString& hash, const QString& ssl_id); bool createPerson(const RsPgpId &id); From 4ac3b3f5bfd2d156e3c16fbc1d29f3c8d013d8ea Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 18 Mar 2017 10:20:57 +0100 Subject: [PATCH 059/118] Fix Clang warnings: implicit conversion of NULL to bool warning: implicit conversion of NULL constant to 'bool' [-Wnull- conversion] return NULL ; ~~~~~~ ^~~~ false --- libretroshare/src/gxstunnel/p3gxstunnel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index 3ad4198a9..871a5cd49 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -1193,7 +1193,7 @@ bool p3GxsTunnelService::locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem * if(gitem->data_bytes == NULL) { delete gitem ; - return NULL ; + return false ; } // by convention, we use a IV of 0 for unencrypted data. memset(gitem->data_bytes,0,8) ; From 32eeb957b247f72603fcb98f5f52cf2e58e89fc7 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 18 Mar 2017 10:25:23 +0100 Subject: [PATCH 060/118] Fix Clang warnings: unused private field warning: private field 'mAutoBanIdentitiesLimit' is not used [-Wunused- private-field] float mAutoBanIdentitiesLimit ; warning: private field 'mFiles' is not used [-Wunused-private-field] RsFiles* mFiles; --- libresapi/src/api/FileSearchHandler.cpp | 4 ++-- libresapi/src/api/FileSearchHandler.h | 2 +- libretroshare/src/services/p3gxsreputation.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libresapi/src/api/FileSearchHandler.cpp b/libresapi/src/api/FileSearchHandler.cpp index 2b56317ad..c159ad913 100644 --- a/libresapi/src/api/FileSearchHandler.cpp +++ b/libresapi/src/api/FileSearchHandler.cpp @@ -10,8 +10,8 @@ namespace resource_api { -FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle *turtle, RsFiles *files): - mStateTokenServer(sts), mNotify(notify), mTurtle(turtle), mFiles(files), +FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle *turtle, RsFiles */*files*/): + mStateTokenServer(sts), mNotify(notify), mTurtle(turtle),// mFiles(files), mMtx("FileSearchHandler") { mNotify->registerNotifyClient(this); diff --git a/libresapi/src/api/FileSearchHandler.h b/libresapi/src/api/FileSearchHandler.h index 1cab730a4..a049c2207 100644 --- a/libresapi/src/api/FileSearchHandler.h +++ b/libresapi/src/api/FileSearchHandler.h @@ -24,7 +24,7 @@ private: StateTokenServer* mStateTokenServer; RsNotify* mNotify; RsTurtle* mTurtle; - RsFiles* mFiles; + //RsFiles* mFiles; class Search{ public: diff --git a/libretroshare/src/services/p3gxsreputation.h b/libretroshare/src/services/p3gxsreputation.h index baabdaa43..890092237 100644 --- a/libretroshare/src/services/p3gxsreputation.h +++ b/libretroshare/src/services/p3gxsreputation.h @@ -174,7 +174,7 @@ private: time_t mLastIdentityFlagsUpdate ; bool mReputationsUpdated; - float mAutoBanIdentitiesLimit ; + //float mAutoBanIdentitiesLimit ; bool mAutoSetPositiveOptionToContacts; p3LinkMgr *mLinkMgr; From de4f6c06dd951f5b6f18005cbb06cd3e892e1920 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 18 Mar 2017 10:42:38 +0100 Subject: [PATCH 061/118] Fix Clang warnings: Z-order assignment to spacer warning: Z-order assignment: 'verticalSpacer_2' is not a valid widget. --- retroshare-gui/src/gui/Identity/IdDialog.ui | 36 ++++++++++----------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index 016ff28e1..1c52802ef 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -287,7 +287,7 @@ 692 - + @@ -296,12 +296,12 @@ QFrame::Raised - + 12 - + @@ -397,7 +397,7 @@ QFrame::Box - + 6 @@ -514,7 +514,7 @@ border-image: url(:/images/closepressed.png) Identity info - + @@ -526,7 +526,7 @@ border-image: url(:/images/closepressed.png) - + Your opinion: @@ -540,7 +540,7 @@ border-image: url(:/images/closepressed.png) - + Qt::Horizontal @@ -728,7 +728,7 @@ p, li { white-space: pre-wrap; } - + @@ -774,12 +774,12 @@ p, li { white-space: pre-wrap; } - + 6 - + 34 @@ -813,14 +813,14 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical - + 34 @@ -856,7 +856,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -874,11 +874,11 @@ p, li { white-space: pre-wrap; } - + Usage statistics - + @@ -886,7 +886,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -900,10 +900,8 @@ p, li { white-space: pre-wrap; } detailsGroupBox - detailsGroupBox - groupBox + usageStatisticsGBox headerFramePerson - verticalSpacer_2 From e0225efef35068800241d02ff4cee25c1a9e8a9e Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 18 Mar 2017 11:19:42 +0100 Subject: [PATCH 062/118] Fix Clang warnings: 'ChatLobbyDialog::init' hides overloaded virtual function warning: 'ChatLobbyDialog::init' hides overloaded virtual function [- Woverloaded-virtual] virtual void init(); ^ /retroshare-gui/src/gui/chat/ChatDialog.h:87: hidden overloaded virtual function 'ChatDialog::init' declared here: different number of parameters (2 vs 0) virtual void init(ChatId id, const QString &title); ^ --- retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp | 5 +++++ retroshare-gui/src/gui/chat/ChatLobbyDialog.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp index 4056156bb..c5dec3a67 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp @@ -304,6 +304,11 @@ void ChatLobbyDialog::showInPeopleTab() idDialog->navigate(nickname); } +void ChatLobbyDialog::init(ChatId /*id*/, const QString &/*title*/) +{ + init(); +} + void ChatLobbyDialog::init() { ChatLobbyInfo linfo ; diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h index 40fb44014..2dd66a554 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h @@ -71,7 +71,8 @@ protected: virtual ~ChatLobbyDialog(); void processSettings(bool load); - virtual void init(); + virtual void init(ChatId id, const QString &title); + void init(); virtual bool canClose(); virtual void addChatMsg(const ChatMessage &msg); From 13c8f7d342418c2f52943238fc630ba89aa6f601 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 18 Mar 2017 11:28:29 +0100 Subject: [PATCH 063/118] Fix Clang warnings: Infinite recursion warning: all paths through this function will call itself [-Winfinite- recursion] { ^ --- retroshare-gui/src/gui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index 4fecfa620..8e8534345 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -1207,7 +1207,7 @@ void MainWindow::showHelpDialog(const QString &topic) void MainWindow::retranslateUi() { - retranslateUi(); + //retranslateUi(); foreach (MainPage *page, ui->stackPages->pages()) { page->retranslateUi(); } From 9319caffc77dfcf4427baacc86349d71b520a26c Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 18 Mar 2017 11:32:56 +0100 Subject: [PATCH 064/118] Fix Clang warnings: 'Node::advance' hides overloaded virtual function warning: 'Node::advance' hides overloaded virtual function [- Woverloaded-virtual] bool advance(); ^ /usr/include/qt4/QtGui/qgraphicsitem.h:323: hidden overloaded virtual function 'QGraphicsItem::advance' declared here: different number of parameters (1 vs 0) virtual void advance(int phase); ^ --- retroshare-gui/src/gui/elastic/graphwidget.cpp | 2 +- retroshare-gui/src/gui/elastic/node.cpp | 2 +- retroshare-gui/src/gui/elastic/node.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/gui/elastic/graphwidget.cpp b/retroshare-gui/src/gui/elastic/graphwidget.cpp index bb1f9ffb8..a2c69c80d 100644 --- a/retroshare-gui/src/gui/elastic/graphwidget.cpp +++ b/retroshare-gui/src/gui/elastic/graphwidget.cpp @@ -362,7 +362,7 @@ void GraphWidget::timerEvent(QTimerEvent *event) bool itemsMoved = false; foreach (Node *node, _nodes) - if(node->advance()) + if(node->progress()) itemsMoved = true; if (!itemsMoved) { diff --git a/retroshare-gui/src/gui/elastic/node.cpp b/retroshare-gui/src/gui/elastic/node.cpp index bc33151df..6a3020b21 100644 --- a/retroshare-gui/src/gui/elastic/node.cpp +++ b/retroshare-gui/src/gui/elastic/node.cpp @@ -215,7 +215,7 @@ void Node::calculateForces(const double *map,int width,int height,int W,int H,fl newPos.setY(qMin(qMax(newPos.y(), sceneRect.top()) , sceneRect.bottom())); } -bool Node::advance() +bool Node::progress() { if(_type == GraphWidget::ELASTIC_NODE_TYPE_OWN) return false; diff --git a/retroshare-gui/src/gui/elastic/node.h b/retroshare-gui/src/gui/elastic/node.h index 13c717b0b..e43fa3521 100644 --- a/retroshare-gui/src/gui/elastic/node.h +++ b/retroshare-gui/src/gui/elastic/node.h @@ -77,7 +77,7 @@ public: std::string descString() const { return _desc_string ; } void calculateForces(const double *data,int width,int height,int W,int H,float x,float y,float speedf); - bool advance(); + bool progress(); QRectF boundingRect() const; QPainterPath shape() const; From eea49d96bfb58914ef031d7139571c1cc6f36d80 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 18 Mar 2017 11:56:11 +0100 Subject: [PATCH 065/118] Fix Clang warnings: change ChatDialog::init definition warning: 'PopupChatDialog::init' hides overloaded virtual function [- Woverloaded-virtual] virtual void init(const ChatId &chat_id, const QString &title); ^ /retroshare-gui/src/gui/chat/ChatDialog.h:87: hidden overloaded virtual function 'ChatDialog::init' declared here: type mismatch at 1st parameter ('ChatId' vs 'const ChatId &') virtual void init(ChatId id, const QString &title); ^ --- retroshare-gui/src/gui/chat/ChatDialog.cpp | 4 ++-- retroshare-gui/src/gui/chat/ChatDialog.h | 2 +- retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp | 7 +------ retroshare-gui/src/gui/chat/ChatLobbyDialog.h | 3 +-- retroshare-gui/src/gui/chat/PopupChatDialog.h | 2 +- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/retroshare-gui/src/gui/chat/ChatDialog.cpp b/retroshare-gui/src/gui/chat/ChatDialog.cpp index 2ab8b8e90..2a52ccf35 100644 --- a/retroshare-gui/src/gui/chat/ChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatDialog.cpp @@ -63,7 +63,7 @@ void ChatDialog::closeEvent(QCloseEvent *event) emit dialogClose(this); } -void ChatDialog::init(ChatId id, const QString &title) +void ChatDialog::init(const ChatId &id, const QString &title) { mChatId = id; ChatWidget *cw = getChatWidget(); @@ -102,7 +102,7 @@ void ChatDialog::init(ChatId id, const QString &title) if (chatflags & RS_CHAT_OPEN) { if (id.isLobbyId()) { ChatLobbyDialog* cld = new ChatLobbyDialog(id.toLobbyId()); - cld->init(); + cld->init(ChatId(), ""); cd = cld; } else if(id.isDistantChatId()) diff --git a/retroshare-gui/src/gui/chat/ChatDialog.h b/retroshare-gui/src/gui/chat/ChatDialog.h index f6b4ae57e..a5c6a0bc3 100644 --- a/retroshare-gui/src/gui/chat/ChatDialog.h +++ b/retroshare-gui/src/gui/chat/ChatDialog.h @@ -84,7 +84,7 @@ protected: virtual QString getPeerName(const ChatId &sslid) const ; // can be overloaded for chat dialogs that have specific peers virtual QString getOwnName() const; - virtual void init(ChatId id, const QString &title); + virtual void init(const ChatId &id, const QString &title); virtual void addChatMsg(const ChatMessage& msg) = 0; ChatId mChatId; diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp index c5dec3a67..20352b888 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp @@ -304,12 +304,7 @@ void ChatLobbyDialog::showInPeopleTab() idDialog->navigate(nickname); } -void ChatLobbyDialog::init(ChatId /*id*/, const QString &/*title*/) -{ - init(); -} - -void ChatLobbyDialog::init() +void ChatLobbyDialog::init(const ChatId &/*id*/, const QString &/*title*/) { ChatLobbyInfo linfo ; diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h index 2dd66a554..420524f93 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h @@ -71,8 +71,7 @@ protected: virtual ~ChatLobbyDialog(); void processSettings(bool load); - virtual void init(ChatId id, const QString &title); - void init(); + virtual void init(const ChatId &id, const QString &title); virtual bool canClose(); virtual void addChatMsg(const ChatMessage &msg); diff --git a/retroshare-gui/src/gui/chat/PopupChatDialog.h b/retroshare-gui/src/gui/chat/PopupChatDialog.h index 0a304b14c..49e3036b3 100644 --- a/retroshare-gui/src/gui/chat/PopupChatDialog.h +++ b/retroshare-gui/src/gui/chat/PopupChatDialog.h @@ -46,7 +46,7 @@ protected: /** Default destructor */ virtual ~PopupChatDialog(); - virtual void init(const ChatId &chat_id, const QString &title); + virtual void init(const ChatId &chat_id, const QString &title); virtual void showDialog(uint chatflags); virtual ChatWidget *getChatWidget(); virtual bool hasPeerStatus() { return true; } From 07b67e9cc90bea746d92711289a212de50ad2fcf Mon Sep 17 00:00:00 2001 From: Phenom Date: Sun, 19 Mar 2017 10:40:34 +0100 Subject: [PATCH 066/118] Fix Clang warnings: 'PopupDistantChatDialog::init' hides overloaded virtual function warning: 'PopupDistantChatDialog::init' hides overloaded virtual function [-Woverloaded-virtual] virtual void init(const DistantChatPeerId& peer_id); /retroshare-gui/src/gui/chat/PopupChatDialog.h:49: hidden overloaded virtual function 'PopupChatDialog::init' declared here: different number of parameters (2 vs 1) virtual void init(const ChatId &chat_id, const QString &title); --- retroshare-gui/src/gui/chat/ChatDialog.cpp | 2 +- .../src/gui/chat/PopupDistantChatDialog.cpp | 13 ++++++++----- .../src/gui/chat/PopupDistantChatDialog.h | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/retroshare-gui/src/gui/chat/ChatDialog.cpp b/retroshare-gui/src/gui/chat/ChatDialog.cpp index 2a52ccf35..9fe8220ab 100644 --- a/retroshare-gui/src/gui/chat/ChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatDialog.cpp @@ -109,7 +109,7 @@ void ChatDialog::init(const ChatId &id, const QString &title) { PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toDistantChatId()); - pdcd->init(id.toDistantChatId()); + pdcd->init(id, ""); cd = pdcd; } else diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp index 4992b5ff5..dea397310 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp @@ -63,9 +63,12 @@ PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_i updateDisplay() ; } -void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id) +void PopupDistantChatDialog::init(const ChatId &chat_id, const QString &/*title*/) { - _tunnel_id = peer_id; + if (!chat_id.isDistantChatId()) + return; + + _tunnel_id = chat_id.toDistantChatId(); DistantChatPeerInfo tinfo; if(!rsMsgs->getDistantChatStatus(_tunnel_id,tinfo)) @@ -74,15 +77,15 @@ void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id) RsIdentityDetails iddetails ; if(rsIdentity->getIdDetails(tinfo.to_id,iddetails)) - PopupChatDialog::init(ChatId(peer_id), QString::fromUtf8(iddetails.mNickname.c_str())) ; + PopupChatDialog::init(chat_id, QString::fromUtf8(iddetails.mNickname.c_str())) ; else - PopupChatDialog::init(ChatId(peer_id), QString::fromStdString(tinfo.to_id.toStdString())) ; + PopupChatDialog::init(chat_id, QString::fromStdString(tinfo.to_id.toStdString())) ; // Do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window // it will not be transmitted. ui.ownAvatarWidget->setOwnId() ; // sets the flag - ui.ownAvatarWidget->setId(ChatId(peer_id)) ; // sets the actual Id + ui.ownAvatarWidget->setId(chat_id) ; // sets the actual Id } void PopupDistantChatDialog::updateDisplay() diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h index dfe75b9de..ff05f70c0 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h @@ -38,7 +38,7 @@ class PopupDistantChatDialog: public PopupChatDialog /** Default destructor */ virtual ~PopupDistantChatDialog(); - virtual void init(const DistantChatPeerId& peer_id); + virtual void init(const ChatId& chat_id, const QString &title); virtual void closeEvent(QCloseEvent *e) ; virtual QString getPeerName(const ChatId &id) const ; From 6f2d7bbca040448b9ad906e4f816543ee3c924f0 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sun, 19 Mar 2017 10:51:48 +0100 Subject: [PATCH 067/118] Fix Clang warnings: implicit conversion from 'double' to 'int' warning: implicit conversion from 'double' to 'int' changes value from 2.5 to 2 [-Wliteral-conversion] QSize buttonSize = QSize(iconSize + QSize(FMM,FMM)); --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 2ea4ba348..37e2b589e 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -76,7 +76,7 @@ ChatWidget::ChatWidget(QWidget *parent) : int iconHeight = FMM*QFontMetricsF(font()).height() ; QSize iconSize = QSize(iconHeight,iconHeight); - QSize buttonSize = QSize(iconSize + QSize(FMM,FMM)); + QSize buttonSize = QSize(iconSize + QSize((int)FMM,(int)FMM)); newMessages = false; typing = false; @@ -258,7 +258,7 @@ void ChatWidget::addChatBarWidget(QWidget *w) { int iconHeight = FMM*QFontMetricsF(font()).height() ; QSize iconSize = QSize(iconHeight,iconHeight); - QSize buttonSize = QSize(iconSize + QSize(FMM,FMM)); + QSize buttonSize = QSize(iconSize + QSize((int)FMM,(int)FMM)); w->setFixedSize(buttonSize); ui->pluginButtonFrame->layout()->addWidget(w) ; } From 8d85cf558b0f5f2167185a4b56ce5f968fec8efd Mon Sep 17 00:00:00 2001 From: Phenom Date: Tue, 28 Mar 2017 21:16:05 +0200 Subject: [PATCH 068/118] Fix Clang warnings: 'xxxWidget::sizeHint' hides overloaded vf warning: 'IdentityWidget::sizeHint' hides overloaded virtual function [- Woverloaded-virtual] QSize sizeHint(); warning: 'CircleWidget::sizeHint' hides overloaded virtual function [- Woverloaded-virtual] QSize sizeHint(); /usr/include/qt4/QtGui/qwidget.h:537: hidden overloaded virtual function 'QWidget::sizeHint' declared here: different qualifiers (const vs none) virtual QSize sizeHint() const; --- retroshare-gui/src/gui/People/CircleWidget.cpp | 2 +- retroshare-gui/src/gui/People/CircleWidget.h | 2 +- retroshare-gui/src/gui/People/IdentityWidget.cpp | 2 +- retroshare-gui/src/gui/People/IdentityWidget.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/retroshare-gui/src/gui/People/CircleWidget.cpp b/retroshare-gui/src/gui/People/CircleWidget.cpp index 3a192f97a..b36a3fa56 100644 --- a/retroshare-gui/src/gui/People/CircleWidget.cpp +++ b/retroshare-gui/src/gui/People/CircleWidget.cpp @@ -96,7 +96,7 @@ void CircleWidget::updateData(const RsGroupMetaData& gxs_group_info } } -QSize CircleWidget::sizeHint() +QSize CircleWidget::sizeHint() const { QSize size; size.setHeight(ui->graphicsView->size().height() + ui->label->size().height()); diff --git a/retroshare-gui/src/gui/People/CircleWidget.h b/retroshare-gui/src/gui/People/CircleWidget.h index 08b6ad6dc..75d6899ba 100644 --- a/retroshare-gui/src/gui/People/CircleWidget.h +++ b/retroshare-gui/src/gui/People/CircleWidget.h @@ -24,7 +24,7 @@ public: , const RsGxsCircleDetails& details); //Start QWidget Properties - QSize sizeHint(); + QSize sizeHint() const; //Start FlowLayoutItem Properties virtual const QPixmap getImage(); virtual const QPixmap getDragImage(); diff --git a/retroshare-gui/src/gui/People/IdentityWidget.cpp b/retroshare-gui/src/gui/People/IdentityWidget.cpp index 902a4dc18..0fcfbc127 100644 --- a/retroshare-gui/src/gui/People/IdentityWidget.cpp +++ b/retroshare-gui/src/gui/People/IdentityWidget.cpp @@ -148,7 +148,7 @@ void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info, const RsPeer updateData(pgp_details); } -QSize IdentityWidget::sizeHint() +QSize IdentityWidget::sizeHint() const { QSize size; size.setHeight(ui->graphicsView->size().height() + ui->labelName->size().height()); diff --git a/retroshare-gui/src/gui/People/IdentityWidget.h b/retroshare-gui/src/gui/People/IdentityWidget.h index c9ade98e3..7f5dcd97f 100644 --- a/retroshare-gui/src/gui/People/IdentityWidget.h +++ b/retroshare-gui/src/gui/People/IdentityWidget.h @@ -26,7 +26,7 @@ public: , const RsPeerDetails& pgp_details); //Start QWidget Properties - QSize sizeHint(); + QSize sizeHint() const; //Start FlowLayoutItem Properties virtual const QPixmap getImage(); virtual const QPixmap getDragImage(); From fd92bca688e07ade46aec892a23a323e6a3bed1c Mon Sep 17 00:00:00 2001 From: Phenom Date: Tue, 28 Mar 2017 21:18:25 +0200 Subject: [PATCH 069/118] Fix Clang warnings: variable 'layout' is used uninitialized warning: variable 'layout' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] if (wid) layout = --- retroshare-gui/src/gui/People/PeopleDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/People/PeopleDialog.cpp b/retroshare-gui/src/gui/People/PeopleDialog.cpp index 5098da953..bdf247a4f 100644 --- a/retroshare-gui/src/gui/People/PeopleDialog.cpp +++ b/retroshare-gui/src/gui/People/PeopleDialog.cpp @@ -901,7 +901,7 @@ void PeopleDialog::pf_dropEventOccursExt(QDropEvent *event) QWidget *wid = qobject_cast(event->source());//QT5 return QObject - FlowLayout *layout; + FlowLayout *layout = NULL; if (wid) layout = qobject_cast(wid->layout()); if (layout) { @@ -991,7 +991,7 @@ void PeopleDialog::pf_dropEventOccursInt(QDropEvent *event) QWidget *wid = qobject_cast(event->source());//QT5 return QObject - FlowLayout *layout; + FlowLayout *layout = NULL; if (wid) layout = qobject_cast(wid->layout()); if (layout) { From 94ac8216f7c2b7725ddd6607f5717adac1b5cd31 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 29 Mar 2017 18:13:17 +0200 Subject: [PATCH 070/118] Fix Clang warnings: Unused variable Pi warning: unused variable 'Pi' [-Wunused-const-variable] static const double Pi = 3.14159265358979323846264338327950288419717; --- retroshare-gui/src/gui/elastic/edge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/elastic/edge.cpp b/retroshare-gui/src/gui/elastic/edge.cpp index 4fec24fe7..e9e60f06b 100644 --- a/retroshare-gui/src/gui/elastic/edge.cpp +++ b/retroshare-gui/src/gui/elastic/edge.cpp @@ -46,7 +46,7 @@ #include -static const double Pi = 3.14159265358979323846264338327950288419717; +//static const double Pi = 3.14159265358979323846264338327950288419717; Edge::Edge(Node *sourceNode, Node *destNode) : arrowSize(10) From a3a53b970dadc3c11c1c35b5ddff56cd1572a1e5 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 7 Apr 2017 18:19:42 +0200 Subject: [PATCH 071/118] Fix Clang warnings: unused parameter 'req' warning: unused parameter 'req' [-Wunused-parameter] void PeersHandler::handleGetStateString(Request& req, Response& resp) --- libresapi/src/api/PeersHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index 8473bce04..1c4129a38 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -200,7 +200,7 @@ static bool have_avatar(RsMsgs* msgs, const RsPeerId& id) return size != 0; } -void PeersHandler::handleGetStateString(Request& req, Response& resp) +void PeersHandler::handleGetStateString(Request& /*req*/, Response& resp) { { RS_STACK_MUTEX(mMtx); @@ -246,7 +246,7 @@ void PeersHandler::handleSetStateString(Request& req, Response& resp) resp.setOk(); } -void PeersHandler::handleGetCustomStateString(Request& req, Response& resp) +void PeersHandler::handleGetCustomStateString(Request& /*req*/, Response& resp) { { RS_STACK_MUTEX(mMtx); From 19196e2cb05dfb451d9ca15305042404fc3425c8 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 7 Apr 2017 18:21:49 +0200 Subject: [PATCH 072/118] Fix Clang warnings: ariable 'status' is used uninitialized warning: variable 'status' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] else if(state_string == "away") ^~~~~~~~~~~~~~~~~~~~~~ --- libresapi/src/api/PeersHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index 1c4129a38..88e9bc445 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -234,7 +234,7 @@ void PeersHandler::handleSetStateString(Request& req, Response& resp) std::string state_string; req.mStream << makeKeyValueReference("state_string", state_string); - uint32_t status; + uint32_t status = RS_STATUS_OFFLINE; if(state_string == "online") status = RS_STATUS_ONLINE; else if(state_string == "busy") From d8a73132c11bab531cbb8b31ad9583fe09a88532 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 7 Apr 2017 18:32:55 +0200 Subject: [PATCH 073/118] Fix Clang warnings: implicit conversion from 'double' to 'int' warning: implicit conversion from 'double' to 'int' changes value from 0.5 to 0 [-Wliteral-conversion] painter.setPen(QColor::fromRgb(0.5,0.5,0.5)); --- retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp index a309717b8..a8e830624 100644 --- a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp +++ b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp @@ -379,7 +379,7 @@ void GlobalRouterStatisticsWidget::updateContent() painter.setPen(QColor::fromRgb(0,0,0)) ; - painter.setPen(QColor::fromRgb(0.5,0.5,0.5)); + painter.setPen(QColor::fromRgb(127,127,127)); painter.drawRect(ox+2*cellx,current_oy+0.15*celly,fm_monospace.width(ids)+cellx*matrix_info.friend_ids.size()- 2*cellx,celly) ; float total_length = (matrix_info.friend_ids.size()+2)*cellx ; From a476a8138cb410e7b00090e6c371461398365900 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 7 Apr 2017 18:40:02 +0200 Subject: [PATCH 074/118] Fix Clang warnings: function 'update_children_background' is not needed warning: function 'update_children_background' is not needed and will not be emitted [-Wunneeded-internal-declaration] static void update_children_background(QTreeWidgetItem *item, uint32_t type) ^ --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 1cf93055b..3b097b986 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -1233,6 +1233,7 @@ static void set_item_background(QTreeWidgetItem *item, uint32_t type) item->setBackground (0, brush); } +#ifdef SUSPENDED static void update_children_background(QTreeWidgetItem *item, uint32_t type) { int count = item->childCount(); @@ -1248,7 +1249,6 @@ static void update_children_background(QTreeWidgetItem *item, uint32_t type) } } -#ifdef SUSPENDED static void set_tree_background(QTreeWidget *tree, uint32_t type) { std::cerr << "CirclesDialog set_tree_background()"; From 0bbd1499d4a57f235032068f6d5824b745d1fbbd Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 7 Apr 2017 18:42:22 +0200 Subject: [PATCH 075/118] Fix Clang warnings: comparison of integers of different signs warning: comparison of integers of different signs: 'uint32_t' (aka 'unsigned int') and 'int' [-Wsign-compare] for(uint32_t i=0;i<(*it).size();++i) ~^~~~~~~~~~~~~ --- retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 4254af49e..5c479005c 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -1607,7 +1607,7 @@ void GxsForumThreadWidget::insertMessage() int current_index = 0 ; - for(uint32_t i=0;i<(*it).size();++i) + for(int i=0;i<(*it).size();++i) { ui->versions_CB->insertItem(i, ((i==0)?tr("(Latest) "):tr("(Old) "))+" "+DateTime::formatLongDateTime( (*it)[i].first)); ui->versions_CB->setItemData(i,QString::fromStdString((*it)[i].second.toStdString())); From 76f75736598c1e1ce7fca9741bc7b34ccef0185b Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 7 Apr 2017 18:48:40 +0200 Subject: [PATCH 076/118] Fix Clang warnings: comparison of array != a null pointer is always true warning: comparison of array 'known_zones[i].tzName' not equal to a null pointer is always true [-Wtautological-pointer-compare] for (int i=0; known_zones[i].tzName != 0; i++) { --- plugins/FeedReader/services/p3FeedReaderThread.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index c638304f4..9ec1106ef 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -651,7 +651,7 @@ static time_t parseRFC822Date(const std::string &pubDate) offset = abs(offset); offset = ((offset / 100)*60 + (offset % 100))*sgn; } else { - for (int i=0; known_zones[i].tzName != 0; i++) { + for (int i=0; known_zones[i].tzName[0] != 0; i++) { if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) { offset = known_zones[i].tzOffset; break; From 4f939b2b760ae0257cb49db19d9da610a11b1ac3 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 7 Apr 2017 19:29:27 +0200 Subject: [PATCH 077/118] Fix Clang warnings: unused function 'set_item_background' warning: unused function 'set_item_background' [-Wunused-function] static void set_item_background(QTreeWidgetItem *item, uint32_t type) --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 3b097b986..aac7e3ba5 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -1208,6 +1208,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint ) contextMnu.exec(QCursor::pos()); } +#ifdef SUSPENDED static void set_item_background(QTreeWidgetItem *item, uint32_t type) { QBrush brush; @@ -1233,7 +1234,6 @@ static void set_item_background(QTreeWidgetItem *item, uint32_t type) item->setBackground (0, brush); } -#ifdef SUSPENDED static void update_children_background(QTreeWidgetItem *item, uint32_t type) { int count = item->childCount(); From 87dd6140885771e9534782b438b1ad9fb31691c6 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 7 Apr 2017 19:32:19 +0200 Subject: [PATCH 078/118] Fix Clang Warnings: private field 'encoding_debug_file' is not used warning: private field 'encoding_debug_file' is not used [-Wunused- private-field] FILE *encoding_debug_file ; --- plugins/VOIP/gui/VideoProcessor.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/VOIP/gui/VideoProcessor.h b/plugins/VOIP/gui/VideoProcessor.h index 4e47b2c29..4946c4342 100644 --- a/plugins/VOIP/gui/VideoProcessor.h +++ b/plugins/VOIP/gui/VideoProcessor.h @@ -66,7 +66,9 @@ private: AVPacket decoding_buffer; uint64_t encoding_frame_count ; +#ifdef DEBUG_MPEG_VIDEO FILE *encoding_debug_file ; +#endif }; // This class decodes video from a stream. It keeps a queue of From 7d9a80326dc3b14b1a04362eb18e635d9d41a27e Mon Sep 17 00:00:00 2001 From: Phenom Date: Tue, 18 Apr 2017 11:18:10 +0200 Subject: [PATCH 079/118] Fix Clang warnings: bdnet_inet_ntoa C-linkage /libbitdht/src/util/bdnet.h:107: warning: 'bdnet_inet_ntoa' has C- linkage specified, but returns user-defined type 'std::string' (aka 'basic_string') which is incompatible with C [-Wreturn-type-c- linkage] std::string bdnet_inet_ntoa(struct in_addr in); ^ --- libbitdht/src/util/bdnet.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libbitdht/src/util/bdnet.h b/libbitdht/src/util/bdnet.h index 9b9d36f48..7e3e24644 100644 --- a/libbitdht/src/util/bdnet.h +++ b/libbitdht/src/util/bdnet.h @@ -103,8 +103,6 @@ int bdnet_inet_aton(const char *name, struct in_addr *addr); int bdnet_checkTTL(int fd); void bdsockaddr_clear(struct sockaddr_in *addr); -/* thread-safe version of inet_ntoa */ -std::string bdnet_inet_ntoa(struct in_addr in); /* Extra stuff to declare for windows error handling (mimics unix errno) */ @@ -175,4 +173,7 @@ int usleep(unsigned int usec); } /* C Interface */ #endif +/* thread-safe version of inet_ntoa */ +std::string bdnet_inet_ntoa(struct in_addr in); + #endif /* BITDHT_UNIVERSAL_NETWORK_HEADER */ From 37331372c145d24291d5e53ac45acd426ef4ee4d Mon Sep 17 00:00:00 2001 From: Phenom Date: Tue, 18 Apr 2017 11:25:41 +0200 Subject: [PATCH 080/118] Fix Clang warnings: implicit conversion warning: implicit conversion from 'int' to 'char' changes value from 255 to -1 [-Wconstant-conversion] asctobin()[i] = 255; /* used to detect invalid characters */ --- libretroshare/src/util/radix64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/util/radix64.h b/libretroshare/src/util/radix64.h index 9ee80f2dd..7776995f9 100644 --- a/libretroshare/src/util/radix64.h +++ b/libretroshare/src/util/radix64.h @@ -147,7 +147,7 @@ again: private: static inline char *bintoasc() { static char bta[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; return bta ; } - static inline char *asctobin() { static char s[256]; return s ; } /* runtime radix64_initd */ + static inline uint8_t *asctobin() { static uint8_t s[256]; return s ; } /* runtime radix64_initd */ static int& is_radix64_initd() { static int is_inited = false ; return is_inited ; } /* hey, guess what: this is a read-only table. From 4a99000f1624b0ef9f3a46cb7a4ad7d7f6791104 Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 18 Apr 2017 14:00:30 +0200 Subject: [PATCH 081/118] Added: Handling requests to get and set node options --- libresapi/src/api/PeersHandler.cpp | 198 +++++++++++++++++++++++++++++ libresapi/src/api/PeersHandler.h | 3 + 2 files changed, 201 insertions(+) diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index 8473bce04..3ba827a33 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -106,6 +107,84 @@ bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers return ok; } +std::string peerStateString(int peerState) +{ + if (peerState & RS_PEER_STATE_CONNECTED) { + return "Connected"; + } else if (peerState & RS_PEER_STATE_UNREACHABLE) { + return "Unreachable"; + } else if (peerState & RS_PEER_STATE_ONLINE) { + return "Available"; + } else if (peerState & RS_PEER_STATE_FRIEND) { + return "Offline"; + } + + return "Neighbor"; +} + +std::string connectStateString(RsPeerDetails &details) +{ + std::string stateString; + bool isConnected = false; + + switch (details.connectState) { + case 0: + stateString = peerStateString(details.state); + break; + case RS_PEER_CONNECTSTATE_TRYING_TCP: + stateString = "Trying TCP"; + break; + case RS_PEER_CONNECTSTATE_TRYING_UDP: + stateString = "Trying UDP"; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_TCP: + stateString = "Connected: TCP"; + isConnected = true; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_UDP: + stateString = "Connected: UDP"; + isConnected = true; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_TOR: + stateString = "Connected: Tor"; + isConnected = true; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_I2P: + stateString = "Connected: I2P"; + isConnected = true; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN: + stateString = "Connected: Unknown"; + isConnected = true; + break; + } + + if(isConnected) { + stateString += " "; + if(details.actAsServer) + stateString += "inbound connection"; + else + stateString += "outbound connection"; + } + + if (details.connectStateString.empty() == false) { + if (stateString.empty() == false) { + stateString += ": "; + } + stateString += details.connectStateString; + } + + /* HACK to display DHT Status info too */ + if (details.foundDHT) { + if (stateString.empty() == false) { + stateString += ", "; + } + stateString += "DHT: Contact"; + } + + return stateString; +} + PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *peers, RsMsgs* msgs): mStateTokenServer(sts), mNotify(notify), @@ -121,6 +200,8 @@ PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *pee addResourceHandler("set_custom_state_string", this, &PeersHandler::handleSetCustomStateString); addResourceHandler("get_pgp_options", this, &PeersHandler::handleGetPGPOptions); addResourceHandler("set_pgp_options", this, &PeersHandler::handleSetPGPOptions); + addResourceHandler("get_node_options", this, &PeersHandler::handleGetNodeOptions); + addResourceHandler("set_node_options", this, &PeersHandler::handleSetNodeOptions); addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert); } @@ -645,6 +726,123 @@ void PeersHandler::handleSetPGPOptions(Request& req, Response& resp) resp.setOk(); } +void PeersHandler::handleGetNodeOptions(Request& req, Response& resp) +{ + std::string peer_id; + req.mStream << makeKeyValueReference("peer_id", peer_id); + + RsPeerId peerId(peer_id); + RsPeerDetails detail; + if(!mRsPeers->getPeerDetails(peerId, detail)) + { + resp.setFail(); + return; + } + + resp.mDataStream << makeKeyValue("peer_id", detail.id.toStdString()); + resp.mDataStream << makeKeyValue("name", detail.name); + resp.mDataStream << makeKeyValue("location", detail.location); + resp.mDataStream << makeKeyValue("pgp_id", detail.gpg_id.toStdString()); + resp.mDataStream << makeKeyValue("last_contact", detail.lastConnect); + + std::string status_message = mRsMsgs->getCustomStateString(detail.id); + resp.mDataStream << makeKeyValueReference("status_message", status_message); + + std::string encryption; + RsPeerCryptoParams cdet; + if(RsControl::instance()->getPeerCryptoDetails(detail.id, cdet) && cdet.connexion_state != 0) + { + encryption = cdet.cipher_version; + encryption += ": "; + encryption += cdet.cipher_name; + + if(cdet.cipher_version != "TLSv1.2") + encryption += cdet.cipher_bits_1; + } + else + encryption = "Not connected"; + + resp.mDataStream << makeKeyValueReference("encryption", encryption); + + resp.mDataStream << makeKeyValue("is_hidden_node", detail.isHiddenNode); + if (detail.isHiddenNode) + { + resp.mDataStream << makeKeyValue("local_address", detail.hiddenNodeAddress); + resp.mDataStream << makeKeyValue("local_port", (int)detail.hiddenNodePort); + resp.mDataStream << makeKeyValue("ext_address", std::string("none")); + resp.mDataStream << makeKeyValue("ext_port", 0); + resp.mDataStream << makeKeyValue("dyn_dns", std::string("none")); + } + else + { + resp.mDataStream << makeKeyValue("local_address", detail.localAddr); + resp.mDataStream << makeKeyValue("local_port", (int)detail.localPort); + resp.mDataStream << makeKeyValue("ext_address", detail.extAddr); + resp.mDataStream << makeKeyValue("ext_port", (int)detail.extPort); + resp.mDataStream << makeKeyValue("dyn_dns", detail.dyndns); + } + + resp.mDataStream << makeKeyValue("connection_status", connectStateString(detail)); + + StreamBase& addressesStream = resp.mDataStream.getStreamToMember("ip_addresses"); + + // mark as list (in case list is empty) + addressesStream.getStreamToMember(); + + for(std::list::const_iterator it(detail.ipAddressList.begin()); it != detail.ipAddressList.end(); ++it) + { + addressesStream.getStreamToMember() << makeKeyValue("ip_address", (*it)); + } + + std::string certificate = mRsPeers->GetRetroshareInvite(detail.id, false); + resp.mDataStream << makeKeyValueReference("certificate", certificate); + + resp.setOk(); +} + +void PeersHandler::handleSetNodeOptions(Request& req, Response& resp) +{ + std::string peer_id; + req.mStream << makeKeyValueReference("peer_id", peer_id); + + RsPeerId peerId(peer_id); + RsPeerDetails detail; + if(!mRsPeers->getPeerDetails(peerId, detail)) + { + resp.setFail(); + return; + } + + std::string local_address; + std::string ext_address; + std::string dyn_dns; + int local_port; + int ext_port; + + req.mStream << makeKeyValueReference("local_address", local_address); + req.mStream << makeKeyValueReference("local_port", local_port); + req.mStream << makeKeyValueReference("ext_address", ext_address); + req.mStream << makeKeyValueReference("ext_port", ext_port); + req.mStream << makeKeyValueReference("dyn_dns", dyn_dns); + + if(!detail.isHiddenNode) + { + if(detail.localAddr != local_address || (int)detail.localPort != local_port) + mRsPeers->setLocalAddress(peerId, local_address, local_port); + if(detail.extAddr != ext_address || (int)detail.extPort != ext_port) + mRsPeers->setExtAddress(peerId, ext_address, ext_port); + if(detail.dyndns != dyn_dns) + mRsPeers->setDynDNS(peerId, dyn_dns); + } + else + { + if(detail.hiddenNodeAddress != local_address || detail.hiddenNodePort != local_port) + rsPeers->setHiddenNode(peerId, local_address, local_port); + } + + resp.setOk(); +} + StateToken PeersHandler::getCurrentStateToken() { RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ diff --git a/libresapi/src/api/PeersHandler.h b/libresapi/src/api/PeersHandler.h index 5ae393b2f..a7386d8c9 100644 --- a/libresapi/src/api/PeersHandler.h +++ b/libresapi/src/api/PeersHandler.h @@ -44,6 +44,9 @@ private: void handleGetPGPOptions(Request& req, Response& resp); void handleSetPGPOptions(Request& req, Response& resp); + void handleGetNodeOptions(Request& req, Response& resp); + void handleSetNodeOptions(Request& req, Response& resp); + // a helper which ensures proper mutex locking StateToken getCurrentStateToken(); From 76dd7fe47fce9d91065894503013e00f6e5d29a0 Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 18 Apr 2017 14:02:14 +0200 Subject: [PATCH 082/118] Added: Handling requests to add and remove contact --- libresapi/src/api/IdentityHandler.cpp | 33 +++++++++++++++++++++++++++ libresapi/src/api/IdentityHandler.h | 3 +++ 2 files changed, 36 insertions(+) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index bf1c65911..529188087 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -138,6 +138,9 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden addResourceHandler("own_ids", this, &IdentityHandler::handleOwnIdsRequest); addResourceHandler("notown_ids", this, &IdentityHandler::handleNotOwnIdsRequest); + addResourceHandler("add_contact", this, &IdentityHandler::handleAddContact); + addResourceHandler("remove_contact", this, &IdentityHandler::handleRemoveContact); + addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity); addResourceHandler("delete_identity", this, &IdentityHandler::handleDeleteIdentity); } @@ -314,6 +317,36 @@ void IdentityHandler::handleOwnIdsRequest(Request & /*req*/, Response &resp) else resp.setFail(); } +void IdentityHandler::handleAddContact(Request& req, Response& resp) +{ + std::string gxs_id; + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + + mRsIdentity->setAsRegularContact(RsGxsId(gxs_id), true); + + { + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->replaceToken(mStateToken); + } + + resp.setOk(); +} + +void IdentityHandler::handleRemoveContact(Request& req, Response& resp) +{ + std::string gxs_id; + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + + mRsIdentity->setAsRegularContact(RsGxsId(gxs_id), false); + + { + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->replaceToken(mStateToken); + } + + resp.setOk(); +} + ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp) { StateToken state; diff --git a/libresapi/src/api/IdentityHandler.h b/libresapi/src/api/IdentityHandler.h index 17f7cb37d..a164af365 100644 --- a/libresapi/src/api/IdentityHandler.h +++ b/libresapi/src/api/IdentityHandler.h @@ -26,6 +26,9 @@ private: void handleNotOwnIdsRequest(Request& req, Response& resp); void handleOwnIdsRequest(Request& req, Response& resp); + void handleAddContact(Request& req, Response& resp); + void handleRemoveContact(Request& req, Response& resp); + ResponseTask *handleOwn(Request& req, Response& resp); ResponseTask *handleCreateIdentity(Request& req, Response& resp); ResponseTask *handleDeleteIdentity(Request& req, Response& resp); From 3c5e61a297d548683e97d5e16568333dc29204ca Mon Sep 17 00:00:00 2001 From: Phenom Date: Tue, 18 Apr 2017 17:36:43 +0200 Subject: [PATCH 083/118] Encode Radix in RSLinks. Because it can contains special characters like '+', '/'. But this is not backward compatible. --- retroshare-gui/src/gui/RetroShareLink.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index 4d32930aa..28a2d09c6 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -309,8 +309,8 @@ void RetroShareLink::fromUrl(const QUrl& url) if(url.host() == HOST_IDENTITY) { _type = TYPE_IDENTITY ; - QString name = urlQuery.queryItemValue(IDENTITY_NAME) ; - QString radix= urlQuery.queryItemValue(IDENTITY_GROUP) ; + QString name = decodedQueryItemValue(urlQuery, IDENTITY_NAME) ; + QString radix= decodedQueryItemValue(urlQuery, IDENTITY_GROUP) ; QString gxsid= urlQuery.queryItemValue(IDENTITY_ID) ; RsGxsId id(gxsid.toStdString()) ; @@ -331,7 +331,7 @@ void RetroShareLink::fromUrl(const QUrl& url) if (url.host() == HOST_CERTIFICATE) { _type = TYPE_CERTIFICATE; - _radix = urlQuery.queryItemValue(CERTIFICATE_RADIX); + _radix = decodedQueryItemValue(urlQuery, CERTIFICATE_RADIX); #ifdef DEBUG_RSLINK std::cerr << "Got a certificate link!!" << std::endl; @@ -765,7 +765,7 @@ QString RetroShareLink::toString() const url.setHost(HOST_IDENTITY) ; urlQuery.addQueryItem(IDENTITY_ID,_hash) ; urlQuery.addQueryItem(IDENTITY_NAME,encodeItem(_name)) ; - urlQuery.addQueryItem(IDENTITY_GROUP,_radix_group_data) ; + urlQuery.addQueryItem(IDENTITY_GROUP,encodeItem(_radix_group_data)) ; break ; case TYPE_EXTRAFILE: @@ -839,9 +839,9 @@ QString RetroShareLink::toString() const case TYPE_CERTIFICATE: url.setScheme(RSLINK_SCHEME); url.setHost(HOST_CERTIFICATE) ; - urlQuery.addQueryItem(CERTIFICATE_RADIX, _radix); - urlQuery.addQueryItem(CERTIFICATE_NAME, _name); - urlQuery.addQueryItem(CERTIFICATE_LOCATION, _location); + urlQuery.addQueryItem(CERTIFICATE_RADIX, encodeItem(_radix)); + urlQuery.addQueryItem(CERTIFICATE_NAME, encodeItem(_name)); + urlQuery.addQueryItem(CERTIFICATE_LOCATION, encodeItem(_location)); break; } From 3f54568d7fd324cc50c8bc4bdbefd56f943ca12a Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 18 Apr 2017 22:56:35 +0200 Subject: [PATCH 084/118] Added: Handling requests to get details about identity --- libresapi/src/api/IdentityHandler.cpp | 125 ++++++++++++++++++++++++++ libresapi/src/api/IdentityHandler.h | 2 + 2 files changed, 127 insertions(+) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 529188087..097a04ef7 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -1,6 +1,7 @@ #include "IdentityHandler.h" #include +#include #include #include "Operators.h" @@ -143,6 +144,8 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity); addResourceHandler("delete_identity", this, &IdentityHandler::handleDeleteIdentity); + + addResourceHandler("get_identity_details", this, &IdentityHandler::handleGetIdentityDetails); } IdentityHandler::~IdentityHandler() @@ -347,6 +350,128 @@ void IdentityHandler::handleRemoveContact(Request& req, Response& resp) resp.setOk(); } +void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) +{ + std::string gxs_id; + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + + std::list groupIds; + groupIds.push_back(RsGxsGroupId(gxs_id)); + mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); + + time_t start = time(NULL); + while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + &&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + &&((time(NULL) < (start+10))) + ) + { +#ifdef WINDOWS_SYS + Sleep(500); +#else + usleep(500*1000); +#endif + } + + RsGxsIdGroup data; + std::vector datavector; + if (!mRsIdentity->getGroupData(token, datavector)) + { + resp.setFail(); + return; + } + + data = datavector[0]; + + resp.mDataStream << makeKeyValue("gxs_name", data.mMeta.mGroupName); + resp.mDataStream << makeKeyValue("gxs_id", data.mMeta.mGroupId.toStdString()); + + resp.mDataStream << makeKeyValue("pgp_id_known", data.mPgpKnown); + resp.mDataStream << makeKeyValue("pgp_id", data.mPgpId.toStdString()); + + std::string pgp_name; + if (data.mPgpKnown) + { + RsPeerDetails details; + rsPeers->getGPGDetails(data.mPgpId, details); + pgp_name = details.name; + } + else + { + if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) + pgp_name = "[Unknown node]"; + else + pgp_name = "Anonymous Id"; + } + resp.mDataStream << makeKeyValue("pgp_name", pgp_name); + + time_t now = time(NULL); + resp.mDataStream << makeKeyValue("last_usage", std::to_string(now - data.mLastUsageTS)); + + bool isAnonymous = false; + if(!data.mPgpKnown) + { + if (!(data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)) + isAnonymous = true; + } + resp.mDataStream << makeKeyValue("anonymous", isAnonymous); + + + bool isOwnId = (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN); + resp.mDataStream << makeKeyValue("own", isOwnId); + + std::string type; + if(isOwnId) + { + if (data.mPgpKnown && !data.mPgpId.isNull()) + type = "Identity owned by you, linked to your Retroshare node"; + else + type = "Anonymous identity, owned by you"; + } + else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) + { + if (data.mPgpKnown) + { + if (rsPeers->isGPGAccepted(data.mPgpId)) + type = "Linked to a friend Retroshare node"; + else + type = "Linked to a known Retroshare node"; + } + else + type = "Linked to unknown Retroshare node"; + } + else + type = "Anonymous identity"; + + resp.mDataStream << makeKeyValue("type", type); + + resp.mDataStream << makeKeyValue("bannned_node", rsReputations->isNodeBanned(data.mPgpId)); + + RsReputations::ReputationInfo info; + rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId), data.mPgpId, info); + resp.mDataStream << makeKeyValue("friends_positive_votes", info.mFriendsPositiveVotes); + resp.mDataStream << makeKeyValue("friends_negative_votes", info.mFriendsNegativeVotes); + resp.mDataStream << makeKeyValue("overall_reputation_level", (int)info.mOverallReputationLevel); + resp.mDataStream << makeKeyValue("own_opinion", (int)info.mOwnOpinion); + + RsIdentityDetails details; + mRsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId), details); + StreamBase& usagesStream = resp.mDataStream.getStreamToMember("usages"); + usagesStream.getStreamToMember(); + + for(std::map::const_iterator it(details.mUseCases.begin()); it != details.mUseCases.end(); ++it) + { + usagesStream.getStreamToMember() << makeKeyValue("usage_time", std::to_string(now - it->second)); + usagesStream.getStreamToMember() << makeKeyValue("usage_service", (int)(it->first.mServiceId)); + usagesStream.getStreamToMember() << makeKeyValue("usage_case", (int)(it->first.mUsageCode)); + } + + resp.setOk(); +} + ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp) { StateToken state; diff --git a/libresapi/src/api/IdentityHandler.h b/libresapi/src/api/IdentityHandler.h index a164af365..0780585e8 100644 --- a/libresapi/src/api/IdentityHandler.h +++ b/libresapi/src/api/IdentityHandler.h @@ -29,6 +29,8 @@ private: void handleAddContact(Request& req, Response& resp); void handleRemoveContact(Request& req, Response& resp); + void handleGetIdentityDetails(Request& req, Response& resp); + ResponseTask *handleOwn(Request& req, Response& resp); ResponseTask *handleCreateIdentity(Request& req, Response& resp); ResponseTask *handleDeleteIdentity(Request& req, Response& resp); From 120ca9d0783d3dbbd8a7491b8fed3254a880c71f Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 18 Apr 2017 22:58:15 +0200 Subject: [PATCH 085/118] Added: Handling requests to set opinion about identity --- libresapi/src/api/IdentityHandler.cpp | 15 +++++++++++++++ libresapi/src/api/IdentityHandler.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 097a04ef7..1b298467d 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -146,6 +146,8 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden addResourceHandler("delete_identity", this, &IdentityHandler::handleDeleteIdentity); addResourceHandler("get_identity_details", this, &IdentityHandler::handleGetIdentityDetails); + + addResourceHandler("set_ban_node", this, &IdentityHandler::handleSetBanNode); } IdentityHandler::~IdentityHandler() @@ -472,6 +474,19 @@ void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) resp.setOk(); } +void IdentityHandler::handleSetBanNode(Request& req, Response& resp) +{ + std::string pgp_id; + req.mStream << makeKeyValueReference("pgp_id", pgp_id); + RsPgpId pgpId(pgp_id); + + bool banned_node; + req.mStream << makeKeyValueReference("banned_node", banned_node); + rsReputations->banNode(pgpId, banned_node); + + resp.setOk(); +} + ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp) { StateToken state; diff --git a/libresapi/src/api/IdentityHandler.h b/libresapi/src/api/IdentityHandler.h index 0780585e8..3824d483d 100644 --- a/libresapi/src/api/IdentityHandler.h +++ b/libresapi/src/api/IdentityHandler.h @@ -31,6 +31,8 @@ private: void handleGetIdentityDetails(Request& req, Response& resp); + void handleSetBanNode(Request& req, Response& resp); + ResponseTask *handleOwn(Request& req, Response& resp); ResponseTask *handleCreateIdentity(Request& req, Response& resp); ResponseTask *handleDeleteIdentity(Request& req, Response& resp); From b43bedf66948e1a5ff59b12d6af70c2a2b87617f Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 18 Apr 2017 23:00:59 +0200 Subject: [PATCH 086/118] Added: Handling requests to set opinion about identity --- libresapi/src/api/IdentityHandler.cpp | 31 +++++++++++++++++++++++++++ libresapi/src/api/IdentityHandler.h | 1 + 2 files changed, 32 insertions(+) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 1b298467d..420d310a5 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -148,6 +148,7 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden addResourceHandler("get_identity_details", this, &IdentityHandler::handleGetIdentityDetails); addResourceHandler("set_ban_node", this, &IdentityHandler::handleSetBanNode); + addResourceHandler("set_opinion", this, &IdentityHandler::handleSetOpinion); } IdentityHandler::~IdentityHandler() @@ -487,6 +488,36 @@ void IdentityHandler::handleSetBanNode(Request& req, Response& resp) resp.setOk(); } +void IdentityHandler::handleSetOpinion(Request& req, Response& resp) +{ + std::string gxs_id; + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + RsGxsId gxsId(gxs_id); + + int own_opinion; + req.mStream << makeKeyValueReference("own_opinion", own_opinion); + + RsReputations::Opinion opinion; + switch(own_opinion) + { + case 0: + opinion = RsReputations::OPINION_NEGATIVE; + break; + case 1: opinion = + RsReputations::OPINION_NEUTRAL; + break; + case 2: + opinion = RsReputations::OPINION_POSITIVE; + break; + default: + resp.setFail(); + return; + } + rsReputations->setOwnOpinion(gxsId, opinion); + + resp.setOk(); +} + ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp) { StateToken state; diff --git a/libresapi/src/api/IdentityHandler.h b/libresapi/src/api/IdentityHandler.h index 3824d483d..bac61f574 100644 --- a/libresapi/src/api/IdentityHandler.h +++ b/libresapi/src/api/IdentityHandler.h @@ -32,6 +32,7 @@ private: void handleGetIdentityDetails(Request& req, Response& resp); void handleSetBanNode(Request& req, Response& resp); + void handleSetOpinion(Request& req, Response& resp); ResponseTask *handleOwn(Request& req, Response& resp); ResponseTask *handleCreateIdentity(Request& req, Response& resp); From 1da89dd70d6532d9d661ff630f7caaeca5a84ac0 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 19 Apr 2017 17:16:30 +0200 Subject: [PATCH 087/118] changed FFT code in graph widget into a more efficient one, with free licence --- retroshare-gui/src/gui/elastic/fft.h | 827 ++++++++++++++++++ .../src/gui/elastic/graphwidget.cpp | 64 +- 2 files changed, 872 insertions(+), 19 deletions(-) create mode 100644 retroshare-gui/src/gui/elastic/fft.h diff --git a/retroshare-gui/src/gui/elastic/fft.h b/retroshare-gui/src/gui/elastic/fft.h new file mode 100644 index 000000000..12d460c24 --- /dev/null +++ b/retroshare-gui/src/gui/elastic/fft.h @@ -0,0 +1,827 @@ +/****************************************************************** + + Original FFT code Credits: + Copyright Takuya OOURA, 1996-2001 + http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html + +******************************************************************/ + +/* +Fast Fourier/Cosine/Sine Transform + dimension :two + data length :power of 2 + decimation :frequency + radix :4, 2, row-column + data :inplace + table :use +functions + cdft2d: Complex Discrete Fourier Transform + rdft2d: Real Discrete Fourier Transform + ddct2d: Discrete Cosine Transform + ddst2d: Discrete Sine Transform +function prototypes + void cdft2d(int, int, int, double **, int *, double *); + void rdft2d(int, int, int, double **, int *, double *); + void ddct2d(int, int, int, double **, double **, int *, double *); + void ddst2d(int, int, int, double **, double **, int *, double *); + + +-------- Complex DFT (Discrete Fourier Transform) -------- + [definition] + + X[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 x[j1][j2] * + exp(2*pi*i*j1*k1/n1) * + exp(2*pi*i*j2*k2/n2), 0<=k1 + X[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 x[j1][j2] * + exp(-2*pi*i*j1*k1/n1) * + exp(-2*pi*i*j2*k2/n2), 0<=k1 + ip[0] = 0; // first time only + cdft2d(n1, 2*n2, 1, a, ip, w); + + ip[0] = 0; // first time only + cdft2d(n1, 2*n2, -1, a, ip, w); + [parameters] + n1 :data length (int) + n1 >= 1, n1 = power of 2 + 2*n2 :data length (int) + n2 >= 1, n2 = power of 2 + a[0...n1-1][0...2*n2-1] + :input/output data (double **) + input data + a[j1][2*j2] = Re(x[j1][j2]), + a[j1][2*j2+1] = Im(x[j1][j2]), + 0<=j1= 2+sqrt(n) + (n = max(n1, n2)) + ip[0],ip[1] are pointers of the cos/sin table. + w[0...*] + :cos/sin table (double *) + length of w >= max(n1/2, n2/2) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + cdft2d(n1, 2*n2, -1, a, ip, w); + is + cdft2d(n1, 2*n2, 1, a, ip, w); + for (j1 = 0; j1 <= n1 - 1; j1++) { + for (j2 = 0; j2 <= 2 * n2 - 1; j2++) { + a[j1][j2] *= 1.0 / (n1 * n2); + } + } +*/ + + +/* -------- initializing routines -------- */ + +#pragma once +#include + +class fft +{ +public: + static void makewt(int nw, int *ip, double *w) + { + int nwh, j; + double delta, x, y; + + ip[0] = nw; + ip[1] = 1; + if (nw > 2) { + nwh = nw >> 1; + delta = atan(1.0) / nwh; + w[0] = 1; + w[1] = 0; + w[nwh] = cos(delta * nwh); + w[nwh + 1] = w[nwh]; + for (j = 2; j <= nwh - 2; j += 2) { + sincos(delta*j,&y,&x) ; + //x = cos(delta * j); + //y = sin(delta * j); + w[j] = x; + w[j + 1] = y; + w[nw - j] = y; + w[nw - j + 1] = x; + } + bitrv2(nw, ip + 2, w); + } + } + + + /* -------- child routines -------- */ + + + static void bitrv2(int n, int *ip, double *a) + { + int j, j1, k, k1, l, m, m2; + double xr, xi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 2) < l) { + l >>= 1; + for (j = 0; j <= m - 1; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + if ((m << 2) > l) { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + a[j1] = a[k1]; + a[j1 + 1] = a[k1 + 1]; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + } else { + m2 = m << 1; + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + a[j1] = a[k1]; + a[j1 + 1] = a[k1 + 1]; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += m2; + xr = a[j1]; + xi = a[j1 + 1]; + a[j1] = a[k1]; + a[j1 + 1] = a[k1 + 1]; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + } + } + + + static void bitrv2col(int n1, int n, int *ip, double **a) + { + int i, j, j1, k, k1, l, m, m2; + double xr, xi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 2) < l) { + l >>= 1; + for (j = 0; j <= m - 1; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + if ((m << 2) > l) { + for (i = 0; i <= n1 - 1; i++) { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[i][j1]; + xi = a[i][j1 + 1]; + a[i][j1] = a[i][k1]; + a[i][j1 + 1] = a[i][k1 + 1]; + a[i][k1] = xr; + a[i][k1 + 1] = xi; + } + } + } + } else { + m2 = m << 1; + for (i = 0; i <= n1 - 1; i++) { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[i][j1]; + xi = a[i][j1 + 1]; + a[i][j1] = a[i][k1]; + a[i][j1 + 1] = a[i][k1 + 1]; + a[i][k1] = xr; + a[i][k1 + 1] = xi; + j1 += m2; + k1 += m2; + xr = a[i][j1]; + xi = a[i][j1 + 1]; + a[i][j1] = a[i][k1]; + a[i][j1 + 1] = a[i][k1 + 1]; + a[i][k1] = xr; + a[i][k1 + 1] = xi; + } + } + } + } + } + + + static void bitrv2row(int n, int n2, int *ip, double **a) + { + int i, j, j1, k, k1, l, m; + double xr, xi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 1) < l) { + l >>= 1; + for (j = 0; j <= m - 1; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + if ((m << 1) > l) { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = j + ip[k]; + k1 = k + ip[j]; + for (i = 0; i <= n2 - 2; i += 2) { + xr = a[j1][i]; + xi = a[j1][i + 1]; + a[j1][i] = a[k1][i]; + a[j1][i + 1] = a[k1][i + 1]; + a[k1][i] = xr; + a[k1][i + 1] = xi; + } + } + } + } else { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = j + ip[k]; + k1 = k + ip[j]; + for (i = 0; i <= n2 - 2; i += 2) { + xr = a[j1][i]; + xi = a[j1][i + 1]; + a[j1][i] = a[k1][i]; + a[j1][i + 1] = a[k1][i + 1]; + a[k1][i] = xr; + a[k1][i + 1] = xi; + } + j1 += m; + k1 += m; + for (i = 0; i <= n2 - 2; i += 2) { + xr = a[j1][i]; + xi = a[j1][i + 1]; + a[j1][i] = a[k1][i]; + a[j1][i + 1] = a[k1][i + 1]; + a[k1][i] = xr; + a[k1][i + 1] = xi; + } + } + } + } + } + + + static void cftbcol(int n1, int n, double **a, double *w) + { + int i, j, j1, j2, j3, k, k1, ks, l, m; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + for (i = 0; i <= n1 - 1; i++) { + l = 2; + while ((l << 1) < n) { + m = l << 2; + for (j = 0; j <= l - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + a[i][j2] = x0r - x2r; + a[i][j2 + 1] = x0i - x2i; + a[i][j1] = x1r - x3i; + a[i][j1 + 1] = x1i + x3r; + a[i][j3] = x1r + x3i; + a[i][j3 + 1] = x1i - x3r; + } + if (m < n) { + wk1r = w[2]; + for (j = m; j <= l + m - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + a[i][j2] = x2i - x0i; + a[i][j2 + 1] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[i][j1] = wk1r * (x0r - x0i); + a[i][j1 + 1] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[i][j3] = wk1r * (x0i - x0r); + a[i][j3 + 1] = wk1r * (x0i + x0r); + } + k1 = 1; + ks = -1; + for (k = (m << 1); k <= n - m; k += m) { + k1++; + ks = -ks; + wk1r = w[k1 << 1]; + wk1i = w[(k1 << 1) + 1]; + wk2r = ks * w[k1]; + wk2i = w[k1 + ks]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j <= l + k - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[i][j2] = wk2r * x0r - wk2i * x0i; + a[i][j2 + 1] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[i][j1] = wk1r * x0r - wk1i * x0i; + a[i][j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[i][j3] = wk3r * x0r - wk3i * x0i; + a[i][j3 + 1] = wk3r * x0i + wk3i * x0r; + } + } + } + l = m; + } + if (l < n) { + for (j = 0; j <= l - 2; j += 2) { + j1 = j + l; + x0r = a[i][j] - a[i][j1]; + x0i = a[i][j + 1] - a[i][j1 + 1]; + a[i][j] += a[i][j1]; + a[i][j + 1] += a[i][j1 + 1]; + a[i][j1] = x0r; + a[i][j1 + 1] = x0i; + } + } + } + } + + + static void cftbrow(int n, int n2, double **a, double *w) + { + int i, j, j1, j2, j3, k, k1, ks, l, m; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 1; + while ((l << 1) < n) { + m = l << 2; + for (j = 0; j <= l - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + a[j2][i] = x0r - x2r; + a[j2][i + 1] = x0i - x2i; + a[j1][i] = x1r - x3i; + a[j1][i + 1] = x1i + x3r; + a[j3][i] = x1r + x3i; + a[j3][i + 1] = x1i - x3r; + } + } + if (m < n) { + wk1r = w[2]; + for (j = m; j <= l + m - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + a[j2][i] = x2i - x0i; + a[j2][i + 1] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1][i] = wk1r * (x0r - x0i); + a[j1][i + 1] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[j3][i] = wk1r * (x0i - x0r); + a[j3][i + 1] = wk1r * (x0i + x0r); + } + } + k1 = 1; + ks = -1; + for (k = (m << 1); k <= n - m; k += m) { + k1++; + ks = -ks; + wk1r = w[k1 << 1]; + wk1i = w[(k1 << 1) + 1]; + wk2r = ks * w[k1]; + wk2i = w[k1 + ks]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j <= l + k - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2][i] = wk2r * x0r - wk2i * x0i; + a[j2][i + 1] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1][i] = wk1r * x0r - wk1i * x0i; + a[j1][i + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3][i] = wk3r * x0r - wk3i * x0i; + a[j3][i + 1] = wk3r * x0i + wk3i * x0r; + } + } + } + } + l = m; + } + if (l < n) { + for (j = 0; j <= l - 1; j++) { + j1 = j + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] - a[j1][i]; + x0i = a[j][i + 1] - a[j1][i + 1]; + a[j][i] += a[j1][i]; + a[j][i + 1] += a[j1][i + 1]; + a[j1][i] = x0r; + a[j1][i + 1] = x0i; + } + } + } + } + + + static void cftfcol(int n1, int n, double **a, double *w) + { + int i, j, j1, j2, j3, k, k1, ks, l, m; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + for (i = 0; i <= n1 - 1; i++) { + l = 2; + while ((l << 1) < n) { + m = l << 2; + for (j = 0; j <= l - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + a[i][j2] = x0r - x2r; + a[i][j2 + 1] = x0i - x2i; + a[i][j1] = x1r + x3i; + a[i][j1 + 1] = x1i - x3r; + a[i][j3] = x1r - x3i; + a[i][j3 + 1] = x1i + x3r; + } + if (m < n) { + wk1r = w[2]; + for (j = m; j <= l + m - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + a[i][j2] = x0i - x2i; + a[i][j2 + 1] = x2r - x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[i][j1] = wk1r * (x0i + x0r); + a[i][j1 + 1] = wk1r * (x0i - x0r); + x0r = x3i - x1r; + x0i = x3r + x1i; + a[i][j3] = wk1r * (x0r + x0i); + a[i][j3 + 1] = wk1r * (x0r - x0i); + } + k1 = 1; + ks = -1; + for (k = (m << 1); k <= n - m; k += m) { + k1++; + ks = -ks; + wk1r = w[k1 << 1]; + wk1i = w[(k1 << 1) + 1]; + wk2r = ks * w[k1]; + wk2i = w[k1 + ks]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j <= l + k - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[i][j2] = wk2r * x0r + wk2i * x0i; + a[i][j2 + 1] = wk2r * x0i - wk2i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[i][j1] = wk1r * x0r + wk1i * x0i; + a[i][j1 + 1] = wk1r * x0i - wk1i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[i][j3] = wk3r * x0r + wk3i * x0i; + a[i][j3 + 1] = wk3r * x0i - wk3i * x0r; + } + } + } + l = m; + } + if (l < n) { + for (j = 0; j <= l - 2; j += 2) { + j1 = j + l; + x0r = a[i][j] - a[i][j1]; + x0i = a[i][j + 1] - a[i][j1 + 1]; + a[i][j] += a[i][j1]; + a[i][j + 1] += a[i][j1 + 1]; + a[i][j1] = x0r; + a[i][j1 + 1] = x0i; + } + } + } + } + + + static void cftfrow(int n, int n2, double **a, double *w) + { + int i, j, j1, j2, j3, k, k1, ks, l, m; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 1; + while ((l << 1) < n) { + m = l << 2; + for (j = 0; j <= l - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + a[j2][i] = x0r - x2r; + a[j2][i + 1] = x0i - x2i; + a[j1][i] = x1r + x3i; + a[j1][i + 1] = x1i - x3r; + a[j3][i] = x1r - x3i; + a[j3][i + 1] = x1i + x3r; + } + } + if (m < n) { + wk1r = w[2]; + for (j = m; j <= l + m - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + a[j2][i] = x0i - x2i; + a[j2][i + 1] = x2r - x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j1][i] = wk1r * (x0i + x0r); + a[j1][i + 1] = wk1r * (x0i - x0r); + x0r = x3i - x1r; + x0i = x3r + x1i; + a[j3][i] = wk1r * (x0r + x0i); + a[j3][i + 1] = wk1r * (x0r - x0i); + } + } + k1 = 1; + ks = -1; + for (k = (m << 1); k <= n - m; k += m) { + k1++; + ks = -ks; + wk1r = w[k1 << 1]; + wk1i = w[(k1 << 1) + 1]; + wk2r = ks * w[k1]; + wk2i = w[k1 + ks]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j <= l + k - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2][i] = wk2r * x0r + wk2i * x0i; + a[j2][i + 1] = wk2r * x0i - wk2i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j1][i] = wk1r * x0r + wk1i * x0i; + a[j1][i + 1] = wk1r * x0i - wk1i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j3][i] = wk3r * x0r + wk3i * x0i; + a[j3][i + 1] = wk3r * x0i - wk3i * x0r; + } + } + } + } + l = m; + } + if (l < n) { + for (j = 0; j <= l - 1; j++) { + j1 = j + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] - a[j1][i]; + x0i = a[j][i + 1] - a[j1][i + 1]; + a[j][i] += a[j1][i]; + a[j][i + 1] += a[j1][i + 1]; + a[j1][i] = x0r; + a[j1][i + 1] = x0i; + } + } + } + } + static int *alloc_1d_int(int n1) + { + int *i; + + i = (int *) malloc(sizeof(int) * n1); + return i; + } + + static void free_1d_int(int *i) { free(i); } + + static double *alloc_1d_double(int n1) + { + double *d; + + d = (double *) malloc(sizeof(double) * n1); + return d; + } + + + static void free_1d_double(double *d) { free(d); } + static double **alloc_2d_double(int n1, int n2) + { + double **dd, *d; + int j; + + dd = (double **) malloc(sizeof(double *) * n1); + d = (double *) malloc(sizeof(double) * n1 * n2); + + dd[0] = d; + for (j = 1; j < n1; j++) { + dd[j] = dd[j - 1] + n2; + } + return dd; + } + + static void free_2d_double(double **dd) { free(dd[0]); free(dd); } + + + static void cdft2d(int n1, int n2, int isgn, double **a, int *ip, double *w) + { + int n; + + n = n1 << 1; + if (n < n2) { + n = n2; + } + if (n > (ip[0] << 2)) { + makewt(n >> 2, ip, w); + } + if (n2 > 4) { + bitrv2col(n1, n2, ip + 2, a); + } + if (n1 > 2) { + bitrv2row(n1, n2, ip + 2, a); + } + if (isgn < 0) { + cftfcol(n1, n2, a, w); + cftfrow(n1, n2, a, w); + } else { + cftbcol(n1, n2, a, w); + cftbrow(n1, n2, a, w); + } + } +}; diff --git a/retroshare-gui/src/gui/elastic/graphwidget.cpp b/retroshare-gui/src/gui/elastic/graphwidget.cpp index a2c69c80d..099ca3d7d 100644 --- a/retroshare-gui/src/gui/elastic/graphwidget.cpp +++ b/retroshare-gui/src/gui/elastic/graphwidget.cpp @@ -42,6 +42,7 @@ #include "graphwidget.h" #include "edge.h" #include "node.h" +#include "fft.h" #include #include @@ -259,45 +260,70 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) } } -static void convolveWithGaussian(double *forceMap,unsigned int S,int /*s*/) +static void convolveWithForce(double *forceMap,unsigned int S,int /*s*/) { - static double *bf = NULL ; + static double **bf = NULL ; + static double **tmp = NULL ; + static int *ip = NULL ; + static double *w = NULL ; + static uint32_t last_S = 0 ; if(bf == NULL) { - bf = new double[S*S*2] ; + bf = fft::alloc_2d_double(S, 2*S); for(unsigned int i=0;i derivative is constant - bf[2*(i+S*j)+1] = 0 ; + + bf[i][j*2+0] = log(sqrtf(0.1 + x*x+y*y)); // linear -> derivative is constant + bf[i][j*2+1] = 0 ; } - unsigned long nn[2] = {S,S}; - fourn(&bf[-1],&nn[-1],2,1) ; + //unsigned long nn[2] = {S,S}; + //fourn(&bf[-1],&nn[-1],2,1) ; + + ip = fft::alloc_1d_int(2 + (int) sqrt(S + 0.5)); + w = fft::alloc_1d_double(S/2+S); + ip[0] = 0; + + fft::cdft2d(S, 2*S, 1, bf, ip, w); } - unsigned long nn[2] = {S,S}; - fourn(&forceMap[-1],&nn[-1],2,1) ; + if(last_S != S) + { + if(tmp) + fft::free_2d_double(tmp) ; + + tmp = fft::alloc_2d_double(S, 2*S); + last_S = S ; + } + memcpy(tmp[0],forceMap,S*S*2*sizeof(double)) ; + + fft::cdft2d(S, 2*S, 1, tmp, ip, w); + + //fourn(&forceMap[-1],&nn[-1],2,1) ; for (unsigned int i=0;isceneRect()) ; - if( (hit++ & 7) == 0) + if( (hit++ & 3) == 0) { memset(forceMap,0,2*S*S*sizeof(double)) ; @@ -348,7 +374,7 @@ void GraphWidget::timerEvent(QTimerEvent *event) } // compute convolution with 1/omega kernel. - convolveWithGaussian(forceMap,S,20) ; + convolveWithForce(forceMap,S,20) ; } foreach (Node *node, _nodes) From f406b8123867240479ea35dee168c58957f51cbb Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 19 Apr 2017 18:46:58 +0200 Subject: [PATCH 088/118] removed all FFT code and cleaned up deleted code in graphwidget.cpp --- .../src/gui/elastic/graphwidget.cpp | 145 ------------------ 1 file changed, 145 deletions(-) diff --git a/retroshare-gui/src/gui/elastic/graphwidget.cpp b/retroshare-gui/src/gui/elastic/graphwidget.cpp index 099ca3d7d..9aeebbeda 100644 --- a/retroshare-gui/src/gui/elastic/graphwidget.cpp +++ b/retroshare-gui/src/gui/elastic/graphwidget.cpp @@ -51,86 +51,9 @@ #include -#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr - -void fourn(double data[],unsigned long nn[],unsigned long ndim,int isign) -{ - int i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2; - int ibit,idim,k1,k2,n,nprev,nrem,ntot; - double tempi,tempr; - double theta,wi,wpi,wpr,wr,wtemp; - - ntot=1; - for (idim=1;idim<=(long)ndim;++idim) - ntot *= nn[idim]; - nprev=1; - for (idim=ndim;idim>=1;idim--) { - n=nn[idim]; - nrem=ntot/(n*nprev); - ip1=nprev << 1; - ip2=ip1*n; - ip3=ip2*nrem; - i2rev=1; - for (i2=1;i2<=ip2;i2+=ip1) { - if (i2 < i2rev) { - for (i1=i2;i1<=i2+ip1-2;i1+=2) { - for (i3=i1;i3<=ip3;i3+=ip2) { - i3rev=i2rev+i3-i2; - SWAP(data[i3],data[i3rev]); - SWAP(data[i3+1],data[i3rev+1]); - } - } - } - ibit=ip2 >> 1; - while (ibit >= ip1 && i2rev > ibit) { - i2rev -= ibit; - ibit >>= 1; - } - i2rev += ibit; - } - ifp1=ip1; - while (ifp1 < ip2) { - ifp2=ifp1 << 1; - theta=isign*6.28318530717959/(ifp2/ip1); - wtemp=sin(0.5*theta); - wpr = -2.0*wtemp*wtemp; - wpi=sin(theta); - wr=1.0; - wi=0.0; - for (i3=1;i3<=ifp1;i3+=ip1) { - for (i1=i3;i1<=i3+ip1-2;i1+=2) { - for (i2=i1;i2<=ip3;i2+=ifp2) { - k1=i2; - k2=k1+ifp1; - tempr=wr*data[k2]-wi*data[k2+1]; - tempi=wr*data[k2+1]+wi*data[k2]; - data[k2]=data[k1]-tempr; - data[k2+1]=data[k1+1]-tempi; - data[k1] += tempr; - data[k1+1] += tempi; - } - } - wr=(wtemp=wr)*wpr-wi*wpi+wr; - wi=wi*wpr+wtemp*wpi+wi; - } - ifp1=ifp2; - } - nprev *= n; - } -} - -#undef SWAP - GraphWidget::GraphWidget(QWidget *) : timerId(0), mIsFrozen(false) { -// QGraphicsScene *scene = new QGraphicsScene(QRectF(0,0,500,500),this); -// scene->setItemIndexMethod(QGraphicsScene::NoIndex); -// scene->clear() ; -// setScene(scene); - -// scene()->setSceneRect(0, 0, width(), height()); - setCacheMode(CacheBackground); setViewportUpdateMode(BoundingRectViewportUpdate); setRenderHint(QPainter::Antialiasing); @@ -143,18 +66,6 @@ GraphWidget::GraphWidget(QWidget *) void GraphWidget::clearGraph() { -// QGraphicsScene *scene = new QGraphicsScene(this); -// scene->setItemIndexMethod(QGraphicsScene::NoIndex); -// setScene(scene); - -// scene->addItem(centerNode); -// centerNode->setPos(0, 0); - -// if (oldscene != NULL) -// { -// delete oldscene; -// } - scene()->clear(); scene()->setSceneRect(0, 0, width(), height()); @@ -230,18 +141,6 @@ void GraphWidget::itemMoved() void GraphWidget::keyPressEvent(QKeyEvent *event) { switch (event->key()) { -// case Qt::Key_Up: -// centerNode->moveBy(0, -20); -// break; -// case Qt::Key_Down: -// centerNode->moveBy(0, 20); -// break; -// case Qt::Key_Left: -// centerNode->moveBy(-20, 0); -// break; -// case Qt::Key_Right: -// centerNode->moveBy(20, 0); -// break; case Qt::Key_Plus: scaleView(qreal(1.2)); break; @@ -282,9 +181,6 @@ static void convolveWithForce(double *forceMap,unsigned int S,int /*s*/) bf[i][j*2+1] = 0 ; } - //unsigned long nn[2] = {S,S}; - //fourn(&bf[-1],&nn[-1],2,1) ; - ip = fft::alloc_1d_int(2 + (int) sqrt(S + 0.5)); w = fft::alloc_1d_double(S/2+S); ip[0] = 0; @@ -304,8 +200,6 @@ static void convolveWithForce(double *forceMap,unsigned int S,int /*s*/) fft::cdft2d(S, 2*S, 1, tmp, ip, w); - //fourn(&forceMap[-1],&nn[-1],2,1) ; - for (unsigned int i=0;idelta() / 240.0)); } -//void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect) -//{ -// Q_UNUSED(rect); -// -// // Shadow -// QRectF sceneRect = this->sceneRect(); -// QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height()); -// QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5); -// if (rightShadow.intersects(rect) || rightShadow.contains(rect)) -// painter->fillRect(rightShadow, Qt::darkGray); -// if (bottomShadow.intersects(rect) || bottomShadow.contains(rect)) -// painter->fillRect(bottomShadow, Qt::darkGray); -// -// // Fill -// QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight()); -// gradient.setColorAt(0, Qt::white); -// gradient.setColorAt(1, Qt::lightGray); -// painter->fillRect(rect.intersected(sceneRect), gradient); -// painter->setBrush(Qt::NoBrush); -// painter->drawRect(sceneRect); -// -// // Text -// QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4, -// sceneRect.width() - 4, sceneRect.height() - 4); -// QString message(tr("Click and drag the nodes around, and zoom with the mouse " -// "wheel or the '+' and '-' keys")); -// -// QFont font = painter->font(); -// font.setBold(true); -// font.setPointSize(14); -// painter->setFont(font); -// painter->setPen(Qt::lightGray); -// painter->drawText(textRect.translated(2, 2), message); -// painter->setPen(Qt::black); -// painter->drawText(textRect, message); -//} - void GraphWidget::scaleView(qreal scaleFactor) { qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); From 4a0b51ce2d853c3466940f19f642854225e238d2 Mon Sep 17 00:00:00 2001 From: Konrad Date: Wed, 19 Apr 2017 22:03:24 +0200 Subject: [PATCH 089/118] Added: to response information whether the identity is a contact --- libresapi/src/api/IdentityHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 420d310a5..67e5cb4c6 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -207,6 +207,7 @@ void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp) << makeKeyValueReference("gxs_id", grp.mMeta.mGroupId) << makeKeyValueReference("pgp_id",grp.mPgpId ) << makeKeyValueReference("name", grp.mMeta.mGroupName) + << makeKeyValueReference("contact", grp.mIsAContact) << makeKeyValueReference("own", own) << makeKeyValueReference("pgp_linked", pgp_linked); } From 9600359bdb62cc05e553f846dbf243bde5830f37 Mon Sep 17 00:00:00 2001 From: Konrad Date: Thu, 20 Apr 2017 18:09:19 +0200 Subject: [PATCH 090/118] Fixed: Password was not stored after creating a new location --- libresapi/src/api/RsControlModule.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libresapi/src/api/RsControlModule.cpp b/libresapi/src/api/RsControlModule.cpp index 2910bc443..cb3cdcdf2 100644 --- a/libresapi/src/api/RsControlModule.cpp +++ b/libresapi/src/api/RsControlModule.cpp @@ -456,6 +456,7 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp) // give the password to the password callback { RsStackMutex stack(mDataMtx); // ********** LOCKED ********** + mPassword = pgp_password; mFixedPassword = pgp_password; } bool ssl_ok = RsAccounts::GenerateSSLCertificate(pgp_id, "", ssl_name, "", hidden_port!=0, ssl_password, ssl_id, err_string); From c9f618ddf602f1623fcb3a99741bde3015476b10 Mon Sep 17 00:00:00 2001 From: Konrad Date: Thu, 20 Apr 2017 19:09:57 +0200 Subject: [PATCH 091/118] Added: Notification about changed peer status --- libresapi/src/api/PeersHandler.cpp | 6 ++++++ libresapi/src/api/PeersHandler.h | 1 + 2 files changed, 7 insertions(+) diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index 3ba827a33..6649acdcb 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -221,6 +221,12 @@ void PeersHandler::notifyListChange(int list, int /* type */) } } +void PeersHandler::notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/) +{ + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->replaceToken(mStateToken); +} + void PeersHandler::notifyPeerHasNewAvatar(std::string /*peer_id*/) { RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ diff --git a/libresapi/src/api/PeersHandler.h b/libresapi/src/api/PeersHandler.h index a7386d8c9..c4e0ddc3d 100644 --- a/libresapi/src/api/PeersHandler.h +++ b/libresapi/src/api/PeersHandler.h @@ -21,6 +21,7 @@ public: // from NotifyClient // note: this may get called from foreign threads virtual void notifyListChange(int list, int type); // friends list change + virtual void notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/); virtual void notifyPeerHasNewAvatar(std::string /*peer_id*/); // from Tickable From 5f8bf03dfea7570473cd8960b91e1db82bd12eaa Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 20 Apr 2017 20:54:51 +0200 Subject: [PATCH 092/118] added mechanism to allow services to document the names of their items, and improved bandwidth graph to show names for GXS services. Other services still need to supply their own names --- libretroshare/src/gxs/rsgxsnetservice.cc | 17 +++++ libretroshare/src/gxs/rsgxsnetservice.h | 1 + libretroshare/src/pqi/p3servicecontrol.cc | 67 +++++++++++-------- libretroshare/src/pqi/p3servicecontrol.h | 8 +++ libretroshare/src/pqi/pqiservice.cc | 17 ++++- libretroshare/src/pqi/pqiservice.h | 44 ++++++------ .../src/retroshare/rsservicecontrol.h | 1 + libretroshare/src/rsserver/rsinit.cc | 2 + .../src/gui/common/RSGraphWidget.cpp | 52 +++++++++++--- retroshare-gui/src/gui/common/RSGraphWidget.h | 12 +++- retroshare-gui/src/gui/statistics/BWGraph.cpp | 62 ++++++++++++++--- retroshare-gui/src/gui/statistics/BWGraph.h | 13 +++- .../gui/statistics/BandwidthStatsWidget.cpp | 28 ++++++-- .../src/gui/statistics/BandwidthStatsWidget.h | 3 +- .../gui/statistics/BandwidthStatsWidget.ui | 34 +++++++++- 15 files changed, 280 insertions(+), 81 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 3811ddd0c..7258ae775 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -328,6 +328,23 @@ RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds, mUpdateCounter = 0; } +void RsGxsNetService::getItemNames(std::map& names) const +{ + names.clear(); + + names[RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM ] = "Group Sync Request" ; + names[RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM ] = "Group Sync" ; + names[RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM ] = "Group Stats" ; + names[RS_PKT_SUBTYPE_NXS_GRP_ITEM ] = "Group Data" ; + names[RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM ] = "Encrypted data" ; + names[RS_PKT_SUBTYPE_NXS_SESSION_KEY_ITEM ] = "Session Key" ; + names[RS_PKT_SUBTYPE_NXS_SYNC_MSG_ITEM ] = "Message Sync" ; + names[RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM ] = "Message Sync Request" ; + names[RS_PKT_SUBTYPE_NXS_MSG_ITEM ] = "Message Data" ; + names[RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM ] = "Transaction" ; + names[RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM ] = "Publish key" ; +} + RsGxsNetService::~RsGxsNetService() { RS_STACK_MUTEX(mNxsMutex) ; diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index b14d55058..fba79ebc9 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -99,6 +99,7 @@ public: virtual RsServiceInfo getServiceInfo() { return mServiceInfo; } + virtual void getItemNames(std::map& names) const ; public: diff --git a/libretroshare/src/pqi/p3servicecontrol.cc b/libretroshare/src/pqi/p3servicecontrol.cc index a397a4e1c..799093d29 100644 --- a/libretroshare/src/pqi/p3servicecontrol.cc +++ b/libretroshare/src/pqi/p3servicecontrol.cc @@ -29,7 +29,9 @@ #include "serialiser/rsserviceids.h" #include "serialiser/rsserial.h" #include "serialiser/rsbaseserial.h" +#include "serialiser/rsnxsitems.h" #include "pqi/p3cfgmgr.h" +#include "pqi/pqiservice.h" /*******************************/ // #define SERVICECONTROL_DEBUG 1 @@ -138,7 +140,7 @@ public: std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; return NULL ; } - + /* add mandatory parts first */ ok &= getRawUInt32(data, rssize, &offset, &item->mServiceId); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, item->mServiceName); @@ -248,6 +250,13 @@ const RsPeerId& p3ServiceControl::getOwnId() return mOwnPeerId; } +bool p3ServiceControl::getServiceItemNames(uint32_t serviceId,std::map& names) +{ + if(mServiceServer != NULL) + return mServiceServer->getServiceItemNames(serviceId,names) ; + + return false ; +} /* Interface for Services */ bool p3ServiceControl::registerService(const RsServiceInfo &info, bool defaultOn) @@ -537,7 +546,7 @@ bool p3ServiceControl::updateServicePermissions(uint32_t serviceId, const RsServ { for(pit = onlinePeers.begin(); pit != onlinePeers.end(); ++pit) { - if (it->second.peerHasPermission(*pit) != + if (it->second.peerHasPermission(*pit) != permissions.peerHasPermission(*pit)) { mUpdatedSet.insert(*pit); @@ -597,7 +606,7 @@ bool p3ServiceControl::checkFilter(uint32_t serviceId, const RsPeerId &peerId) #endif // must allow ServiceInfo through, or we have nothing! -#define FULLID_SERVICEINFO ((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + ((RS_SERVICE_TYPE_SERVICEINFO) << 8)) +#define FULLID_SERVICEINFO ((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + ((RS_SERVICE_TYPE_SERVICEINFO) << 8)) //if (serviceId == RS_SERVICE_TYPE_SERVICEINFO) if (serviceId == FULLID_SERVICEINFO) @@ -691,21 +700,21 @@ bool ServiceInfoCompatible(const RsServiceInfo &info1, const RsServiceInfo &info } // ensure that info1 meets minimum requirements for info2 - if (!versionOkay(info1.mVersionMajor, info1.mVersionMinor, + if (!versionOkay(info1.mVersionMajor, info1.mVersionMinor, info2.mMinVersionMajor, info2.mMinVersionMinor)) { return false; } // ensure that info2 meets minimum requirements for info1 - if (!versionOkay(info2.mVersionMajor, info2.mVersionMinor, + if (!versionOkay(info2.mVersionMajor, info2.mVersionMinor, info1.mMinVersionMajor, info1.mMinVersionMinor)) { return false; } return true; } - + bool p3ServiceControl::updateFilterByPeer(const RsPeerId &peerId) { @@ -790,8 +799,8 @@ bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId) std::cerr << "p3ServiceControl::updateFilterByPeer_locked() Empty ... Clearing"; std::cerr << std::endl; #endif - - // empty, remove... + + // empty, remove... recordFilterChanges_locked(peerId, originalFilter, peerFilter); if (fit != mPeerFilterMap.end()) { @@ -882,7 +891,7 @@ bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId) std::cerr << "p3ServiceControl::updateFilterByPeer_locked() Empty(2) ... Clearing"; std::cerr << std::endl; #endif - + if (fit != mPeerFilterMap.end()) { mPeerFilterMap.erase(fit); @@ -900,7 +909,7 @@ bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId) return true; } -void p3ServiceControl::recordFilterChanges_locked(const RsPeerId &peerId, +void p3ServiceControl::recordFilterChanges_locked(const RsPeerId &peerId, ServicePeerFilter &originalFilter, ServicePeerFilter &updatedFilter) { #ifdef SERVICECONTROL_DEBUG @@ -1202,7 +1211,7 @@ bool p3ServiceControl::loadList(std::list& loadList) if(item != NULL) mServicePermissionMap[item->mServiceId] = *item ; - + delete *it ; } @@ -1396,49 +1405,49 @@ void p3ServiceControl::notifyServices() std::cerr << "p3ServiceControl::notifyServices(): Noone Monitoring ... skipping"; std::cerr << std::endl; #endif - + continue; } - + std::list peers; std::set::const_iterator pit; - for(pit = it->second.mAdded.begin(); + for(pit = it->second.mAdded.begin(); pit != it->second.mAdded.end(); ++pit) { pqiServicePeer peer; peer.id = *pit; peer.actions = RS_SERVICE_PEER_CONNECTED; - + peers.push_back(peer); - + #ifdef SERVICECONTROL_DEBUG std::cerr << "p3ServiceControl::notifyServices(): Peer: " << *pit << " CONNECTED"; std::cerr << std::endl; #endif } - - for(pit = it->second.mRemoved.begin(); + + for(pit = it->second.mRemoved.begin(); pit != it->second.mRemoved.end(); ++pit) { pqiServicePeer peer; peer.id = *pit; peer.actions = RS_SERVICE_PEER_DISCONNECTED; - + peers.push_back(peer); - + #ifdef SERVICECONTROL_DEBUG std::cerr << "p3ServiceControl::notifyServices(): Peer: " << *pit << " DISCONNECTED"; std::cerr << std::endl; #endif } - + for(; sit != eit; ++sit) { #ifdef SERVICECONTROL_DEBUG std::cerr << "p3ServiceControl::notifyServices(): Sending to Monitoring Service"; std::cerr << std::endl; #endif - + sit->second->statusChange(peers); } } @@ -1500,17 +1509,17 @@ void RsServicePermissions::resetPermission(const RsPeerId& peerId) } RsServiceInfo::RsServiceInfo( - const uint16_t service_type, - const std::string service_name, + const uint16_t service_type, + const std::string service_name, const uint16_t version_major, const uint16_t version_minor, const uint16_t min_version_major, const uint16_t min_version_minor) - :mServiceName(service_name), - mServiceType((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + (((uint32_t) service_type) << 8)), - mVersionMajor(version_major), + :mServiceName(service_name), + mServiceType((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + (((uint32_t) service_type) << 8)), + mVersionMajor(version_major), mVersionMinor(version_minor), - mMinVersionMajor(min_version_major), + mMinVersionMajor(min_version_major), mMinVersionMinor(min_version_minor) { return; @@ -1518,7 +1527,7 @@ RsServiceInfo::RsServiceInfo( RsServiceInfo::RsServiceInfo() - :mServiceName("unknown"), + :mServiceName("unknown"), mServiceType(0), mVersionMajor(0), mVersionMinor(0), diff --git a/libretroshare/src/pqi/p3servicecontrol.h b/libretroshare/src/pqi/p3servicecontrol.h index 948481a2b..9c9724347 100644 --- a/libretroshare/src/pqi/p3servicecontrol.h +++ b/libretroshare/src/pqi/p3servicecontrol.h @@ -36,6 +36,8 @@ #include "pqi/pqiservicemonitor.h" #include "pqi/p3linkmgr.h" +class p3ServiceServer ; + class ServiceNotifications { public: @@ -101,6 +103,9 @@ virtual bool updateServicePermissions(uint32_t serviceId, const RsServicePermiss virtual void getPeersConnected(const uint32_t serviceId, std::set &peerSet); virtual bool isPeerConnected(const uint32_t serviceId, const RsPeerId &peerId); + // Gets the list of items used by that service +virtual bool getServiceItemNames(uint32_t serviceId,std::map& names) ; + /** * Registration for all Services. */ @@ -132,6 +137,8 @@ virtual bool updateServicesProvided(const RsPeerId &peerId, const RsPeerServiceI // pqiMonitor. virtual void statusChange(const std::list &plist); + virtual void setServiceServer(p3ServiceServer *p) { mServiceServer = p ; } + protected: // configuration. virtual bool saveList(bool &cleanup, std::list&); @@ -196,6 +203,7 @@ bool peerHasPermissionForService_locked(const RsPeerId &peerId, uint32_t service // Below here is saved in Configuration. std::map mServicePermissionMap; + p3ServiceServer *mServiceServer ; }; diff --git a/libretroshare/src/pqi/pqiservice.cc b/libretroshare/src/pqi/pqiservice.cc index 4ba249c69..d9c93cc18 100644 --- a/libretroshare/src/pqi/pqiservice.cc +++ b/libretroshare/src/pqi/pqiservice.cc @@ -79,11 +79,26 @@ int p3ServiceServer::addService(pqiService *ts, bool defaultOn) services[info.mServiceType] = ts; // This doesn't need to be in Mutex. - mServiceControl->registerService(info, defaultOn); + mServiceControl->registerService(info,defaultOn); return 1; } +bool p3ServiceServer::getServiceItemNames(uint32_t service_type,std::map& names) +{ + RsStackMutex stack(srvMtx); /********* LOCKED *********/ + + std::map::iterator it=services.find(service_type) ; + + if(it != services.end()) + { + it->second->getItemNames(names) ; + return true ; + } + else + return false ; +} + int p3ServiceServer::removeService(pqiService *ts) { RsStackMutex stack(srvMtx); /********* LOCKED *********/ diff --git a/libretroshare/src/pqi/pqiservice.h b/libretroshare/src/pqi/pqiservice.h index c293cc005..b22a34aac 100644 --- a/libretroshare/src/pqi/pqiservice.h +++ b/libretroshare/src/pqi/pqiservice.h @@ -60,24 +60,26 @@ class p3ServiceServerIface; class pqiService { - protected: +protected: pqiService() // our type of packets. - :mServiceServer(NULL) { return; } + :mServiceServer(NULL) { return; } -virtual ~pqiService() { return; } + virtual ~pqiService() { return; } - public: -void setServiceServer(p3ServiceServerIface *server); - // -virtual bool recv(RsRawItem *) = 0; -virtual bool send(RsRawItem *item); +public: + void setServiceServer(p3ServiceServerIface *server); + // + virtual bool recv(RsRawItem *) = 0; + virtual bool send(RsRawItem *item); -virtual RsServiceInfo getServiceInfo() = 0; + virtual RsServiceInfo getServiceInfo() = 0; -virtual int tick() { return 0; } + virtual int tick() { return 0; } - private: + virtual void getItemNames(std::map& names) const {} // This does nothing by default. Service should derive it in order to give info for the UI + +private: p3ServiceServerIface *mServiceServer; // const, no need for mutex. }; @@ -97,10 +99,10 @@ public: virtual ~p3ServiceServerIface() {} -virtual bool recvItem(RsRawItem *) = 0; -virtual bool sendItem(RsRawItem *) = 0; - + virtual bool recvItem(RsRawItem *) = 0; + virtual bool sendItem(RsRawItem *) = 0; + virtual bool getServiceItemNames(uint32_t service_type,std::map& names) =0; }; class p3ServiceServer : public p3ServiceServerIface @@ -108,13 +110,15 @@ class p3ServiceServer : public p3ServiceServerIface public: p3ServiceServer(pqiPublisher *pub, p3ServiceControl *ctrl); -int addService(pqiService *, bool defaultOn); -int removeService(pqiService *); + int addService(pqiService *, bool defaultOn); + int removeService(pqiService *); -bool recvItem(RsRawItem *); -bool sendItem(RsRawItem *); + bool recvItem(RsRawItem *); + bool sendItem(RsRawItem *); -int tick(); + bool getServiceItemNames(uint32_t service_type, std::map& names) ; + + int tick(); public: private: @@ -122,7 +126,7 @@ private: pqiPublisher *mPublisher; // constant no need for mutex. p3ServiceControl *mServiceControl; - RsMutex srvMtx; + RsMutex srvMtx; std::map services; }; diff --git a/libretroshare/src/retroshare/rsservicecontrol.h b/libretroshare/src/retroshare/rsservicecontrol.h index a6d8fde7c..7558764e7 100644 --- a/libretroshare/src/retroshare/rsservicecontrol.h +++ b/libretroshare/src/retroshare/rsservicecontrol.h @@ -109,6 +109,7 @@ virtual ~RsServiceControl() { return; } virtual bool getOwnServices(RsPeerServiceInfo &info) = 0; virtual std::string getServiceName(uint32_t service_id) = 0; +virtual bool getServiceItemNames(uint32_t service_id,std::map& names) = 0; virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0; virtual bool getServicesProvided(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 47036b691..fd378b286 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1243,6 +1243,8 @@ int RsServer::StartupRetroShare() pqih = new pqisslpersongrp(serviceCtrl, flags, mPeerMgr); //pqih = new pqipersongrpDummy(none, flags); + serviceCtrl->setServiceServer(pqih) ; + /****** New Ft Server **** !!! */ ftServer *ftserver = new ftServer(mPeerMgr, serviceCtrl); ftserver->setConfigDirectory(rsAccounts->PathAccountDirectory()); diff --git a/retroshare-gui/src/gui/common/RSGraphWidget.cpp b/retroshare-gui/src/gui/common/RSGraphWidget.cpp index 90cf069c2..b7759d846 100644 --- a/retroshare-gui/src/gui/common/RSGraphWidget.cpp +++ b/retroshare-gui/src/gui/common/RSGraphWidget.cpp @@ -99,6 +99,11 @@ QString RSGraphSource::displayValue(float v) const return QString::number(v,'f',_digits) + " " + unitName() ; } +void RSGraphSource::getCumulatedValues(std::vector& vals) const +{ + for(std::map::const_iterator it = _totals.begin();it!=_totals.end();++it) + vals.push_back(it->second) ; +} void RSGraphSource::getCurrentValues(std::vector& vals) const { std::map > >::const_iterator it = _points.begin(); @@ -108,9 +113,9 @@ void RSGraphSource::getCurrentValues(std::vector& vals) const vals.push_back(QPointF( (now - it->second.back().first)/1000.0f,it->second.back().second)) ; } -QString RSGraphSource::legend(int i,float v) const +QString RSGraphSource::legend(int i,float v,bool show_value) const { - return displayName(i) + " (" + displayValue(v) + " )"; + return displayName(i) + (show_value?(" (" + displayValue(v) + ")"):""); } void RSGraphSource::getDataPoints(int index,std::vector& pts,float filter_factor) const @@ -209,11 +214,30 @@ void RSGraphSource::update() } else ++it ; + + updateTotals(); +} + +void RSGraphSource::updateTotals() +{ + // now compute totals + + _totals.clear(); + + for(std::map > >::const_iterator it(_points.begin());it!=_points.end();++it) + { + float& f = _totals[it->first] ; + + f = 0.0f ; + for(std::list >::const_iterator it2=it->second.begin();it2!=it->second.end();++it2) + f += (*it2).second ; + } } void RSGraphSource::reset() { - _points.clear() ; + _points.clear(); + _totals.clear(); } void RSGraphSource::setCollectionTimeLimit(qint64 s) { _time_limit_msecs = s ; } @@ -630,8 +654,19 @@ void RSGraphWidget::paintLegend() { //int bottom = _rec.height(); - std::vector vals ; - _source->getCurrentValues(vals) ; + std::vector vals ; + + if(_flags & RSGRAPH_FLAGS_LEGEND_CUMULATED) + _source->getCumulatedValues(vals) ; + else + { + std::vector cvals ; + _source->getCurrentValues(cvals) ; + + for(uint32_t i=0;idisplayName(i).toStdString()) == _masked_entries.end() ) { - if( _rec.width() - (vals[i].x()-0)*_time_scale < SCALE_WIDTH*fact ) - continue ; +// if( _rec.width() - (vals[i].x()-0)*_time_scale < SCALE_WIDTH*fact ) +// continue ; qreal paintStep = 4*fact+FS; qreal pos = 15*fact+j*paintStep; - QString text = _source->legend(i,vals[i].y()) ; + + QString text = _source->legend(i,vals[i]) ; QPen oldPen = _painter->pen(); _painter->setPen(QPen(getColor(i), Qt::SolidLine)); diff --git a/retroshare-gui/src/gui/common/RSGraphWidget.h b/retroshare-gui/src/gui/common/RSGraphWidget.h index 84a4ee3be..2159ba0dc 100644 --- a/retroshare-gui/src/gui/common/RSGraphWidget.h +++ b/retroshare-gui/src/gui/common/RSGraphWidget.h @@ -69,8 +69,11 @@ public: // return the vector of last values up to date virtual void getCurrentValues(std::vector& vals) const ; + // return the vector of cumulated values up to date + virtual void getCumulatedValues(std::vector& vals) const; + // returns what to display in the legend. Derive this to show additional info. - virtual QString legend(int i,float v) const ; + virtual QString legend(int i, float v, bool show_value=true) const ; // Returns the n^th interpolated value at the given time in floating point seconds backward. virtual void getDataPoints(int index, std::vector& pts, float filter_factor=0.0f) const ; @@ -95,11 +98,13 @@ protected slots: protected: virtual void getValues(std::map& values) const = 0 ;// overload this in your own class to fill in the values you want to display. + void updateTotals(); qint64 getTime() const ; // returns time in ms since RS has started // Storage of collected events. The string is any string used to represent the collected data. std::map > > _points ; + std::map _totals ; QTimer *_timer ; @@ -118,8 +123,9 @@ public: static const uint32_t RSGRAPH_FLAGS_LOG_SCALE_Y = 0x0002 ;// log scale in Y static const uint32_t RSGRAPH_FLAGS_ALWAYS_COLLECT = 0x0004 ;// keep collecting while not displayed static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_PLAIN = 0x0008 ;// use plain / line drawing style - static const uint32_t RSGRAPH_FLAGS_SHOW_LEGEND = 0x0010 ;// show legend in the graph - static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes + static const uint32_t RSGRAPH_FLAGS_SHOW_LEGEND = 0x0010 ;// show legend in the graph + static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes + static const uint32_t RSGRAPH_FLAGS_LEGEND_CUMULATED = 0x0040 ;// show the total in the legend rather than current values /** Bandwidth graph style. */ enum GraphStyle diff --git a/retroshare-gui/src/gui/statistics/BWGraph.cpp b/retroshare-gui/src/gui/statistics/BWGraph.cpp index 08c208868..a7451c560 100644 --- a/retroshare-gui/src/gui/statistics/BWGraph.cpp +++ b/retroshare-gui/src/gui/statistics/BWGraph.cpp @@ -107,16 +107,25 @@ void BWGraphSource::update() // remove empty lists + float duration = 0.0f; + for(std::map > >::iterator it=_points.begin();it!=_points.end();) if(it->second.empty()) - { - std::map > >::iterator tmp(it) ; - ++tmp; - _points.erase(it) ; - it=tmp ; - } + { + std::map > >::iterator tmp(it) ; + ++tmp; + _points.erase(it) ; + it=tmp ; + } else + { + float d = it->second.back().first - it->second.front().first; + + if(duration < d) + duration = d ; + ++it ; + } // also clears history @@ -138,11 +147,36 @@ void BWGraphSource::update() break ; } + // now update the totals, and possibly convert into an average if the unit requires it. + + updateTotals(); + + if(_current_unit == UNIT_KILOBYTES) + for(std::map::iterator it(_totals.begin());it!=_totals.end();++it) + it->second /= (duration/1000.0) ; + #ifdef BWGRAPH_DEBUG std::cerr << "Traffic history has size " << mTrafficHistory.size() << std::endl; #endif } +std::string BWGraphSource::makeSubItemName(uint16_t service_id,uint8_t sub_item_type) const +{ + RsServiceInfoWithNames& s(mServiceInfoMap[service_id]) ; + + if(s.item_names.empty()) + return "item #"+QString("%1").arg(sub_item_type,2,16,QChar('0')).toStdString() ; + else + { + std::map::const_iterator it = s.item_names.find(sub_item_type) ; + + if(it == s.item_names.end()) + return "item #"+QString("%1").arg(sub_item_type,2,16,QChar('0')).toStdString() + " (undocumented)"; + + return QString("%1").arg(sub_item_type,2,16,QChar('0')).toStdString()+": " + it->second ; + } +} + void BWGraphSource::convertTrafficClueToValues(const std::list& lst,std::map& vals) const { vals.clear() ; @@ -162,7 +196,7 @@ void BWGraphSource::convertTrafficClueToValues(const std::list& l for(uint32_t i=0;i<256;++i) if(clue_per_sub_id[i].count > 0) - vals["item #"+QString::number(i,16).toStdString()] = (_current_unit == UNIT_KILOBYTES)?(clue_per_sub_id[i].size):(clue_per_sub_id[i].count) ; + vals[makeSubItemName(clue_per_sub_id[i].service_id,i)] = (_current_unit == UNIT_KILOBYTES)?(clue_per_sub_id[i].size):(clue_per_sub_id[i].count) ; } break ; @@ -233,11 +267,14 @@ void BWGraphSource::convertTrafficClueToValues(const std::list& l for(std::list::const_iterator it(lst.begin());it!=lst.end();++it) if(it->service_id == _current_selected_service) + { clue_per_sub_id[it->service_sub_id] += *it ; + clue_per_sub_id[it->service_sub_id].service_id = it->service_id ; + } for(uint32_t i=0;i<256;++i) if(clue_per_sub_id[i].count > 0) - vals["item #"+QString::number(i,16).toStdString()] = (_current_unit == UNIT_KILOBYTES)?(clue_per_sub_id[i].size):(clue_per_sub_id[i].count) ; + vals[makeSubItemName(clue_per_sub_id[i].service_id,i)] = (_current_unit == UNIT_KILOBYTES)?(clue_per_sub_id[i].size):(clue_per_sub_id[i].count) ; } break ; @@ -297,7 +334,11 @@ BWGraphSource::BWGraphSource() rsServiceControl->getOwnServices(rspsi) ; for(std::map::const_iterator it(rspsi.mServiceList.begin());it!=rspsi.mServiceList.end();++it) + { mServiceInfoMap[ (it->first >> 8) & 0xffff ] = it->second ; + + rsServiceControl->getServiceItemNames(it->first,mServiceInfoMap[(it->first >> 8) & 0xffff].item_names) ; + } } void BWGraphSource::getValues(std::map& values) const @@ -359,9 +400,9 @@ QString BWGraphSource::displayValue(float v) const return QString() ; } -QString BWGraphSource::legend(int i,float v) const +QString BWGraphSource::legend(int i,float v,bool show_value) const { - return RSGraphSource::legend(i,v) ;//+ " Total: " + niceNumber(_total_recv) ; + return RSGraphSource::legend(i,v,show_value) ; } QString BWGraphSource::niceNumber(float v) const { @@ -446,6 +487,7 @@ void BWGraphSource::setUnit(int unit) recomputeCurrentCurves() ; } + void BWGraphSource::setDirection(int dir) { if(dir == _current_direction) diff --git a/retroshare-gui/src/gui/statistics/BWGraph.h b/retroshare-gui/src/gui/statistics/BWGraph.h index 865893473..3e2c4b8b2 100644 --- a/retroshare-gui/src/gui/statistics/BWGraph.h +++ b/retroshare-gui/src/gui/statistics/BWGraph.h @@ -13,6 +13,14 @@ public: std::list out_rstcl ; std::list in_rstcl ; }; + class RsServiceInfoWithNames: public RsServiceInfo + { + public: + RsServiceInfoWithNames(const RsServiceInfo& s) : RsServiceInfo(s) {} + RsServiceInfoWithNames(){} + + std::map item_names ; + }; BWGraphSource() ; @@ -25,7 +33,7 @@ public: virtual void getValues(std::map& values) const; virtual QString displayValue(float v) const; - virtual QString legend(int i,float v) const; + virtual QString legend(int i,float v,bool show_value=true) const; virtual void update(); QString unitName() const ; @@ -45,6 +53,7 @@ public: protected: void convertTrafficClueToValues(const std::list &lst, std::map &vals) const; + std::string makeSubItemName(uint16_t service_id,uint8_t sub_item_type) const; void recomputeCurrentCurves() ; std::string visibleFriendName(const RsPeerId &pid) const ; @@ -67,7 +76,7 @@ private: std::map mVisibleFriends ; std::set mVisibleServices ; - mutable std::map mServiceInfoMap ; + mutable std::map mServiceInfoMap ; }; class BWGraph: public RSGraphWidget diff --git a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.cpp b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.cpp index b3fd9a063..6ae112803 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.cpp +++ b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.cpp @@ -28,13 +28,18 @@ BandwidthStatsWidget::BandwidthStatsWidget(QWidget *parent) ui.bwgraph_BW->setSelector(BWGraphSource::SELECTOR_TYPE_SERVICE,BWGraphSource::GRAPH_TYPE_SUM) ; ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_KILOBYTES) ; + ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_CUMULATED) ; + + updateUnitSelection(0); + // Setup connections - QObject::connect(ui.friend_CB ,SIGNAL(currentIndexChanged(int)),this, SLOT( updateFriendSelection(int))) ; - QObject::connect(ui.updn_CB ,SIGNAL(currentIndexChanged(int)),this, SLOT( updateUpDownSelection(int))) ; - QObject::connect(ui.unit_CB ,SIGNAL(currentIndexChanged(int)),this, SLOT( updateUnitSelection(int))) ; - QObject::connect(ui.service_CB,SIGNAL(currentIndexChanged(int)),this, SLOT(updateServiceSelection(int))) ; - QObject::connect(ui.logScale_CB,SIGNAL(toggled(bool)),this, SLOT(toggleLogScale(bool))) ; + QObject::connect(ui.friend_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateFriendSelection(int ))) ; + QObject::connect(ui.updn_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateUpDownSelection(int ))) ; + QObject::connect(ui.unit_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateUnitSelection(int ))) ; + QObject::connect(ui.service_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT(updateServiceSelection(int ))) ; + QObject::connect(ui.legend_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateLegendType(int ))) ; + QObject::connect(ui.logScale_CB,SIGNAL( toggled(bool)),this, SLOT( toggleLogScale(bool))) ; // setup one timer for auto-update @@ -156,6 +161,13 @@ void BandwidthStatsWidget::updateFriendSelection(int n) ui.bwgraph_BW->setSelector(BWGraphSource::SELECTOR_TYPE_FRIEND,BWGraphSource::GRAPH_TYPE_SINGLE,ui.friend_CB->itemData(ci,Qt::UserRole).toString().toStdString()) ; } } +void BandwidthStatsWidget::updateLegendType(int n) +{ + if(n==0) + ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_CUMULATED) ; + else + ui.bwgraph_BW->setFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_CUMULATED) ; +} void BandwidthStatsWidget::updateServiceSelection(int n) { if(n == 0) @@ -187,7 +199,13 @@ void BandwidthStatsWidget::updateUpDownSelection(int n) void BandwidthStatsWidget::updateUnitSelection(int n) { if(n==0) + { ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_KILOBYTES) ; + ui.legend_CB->setItemText(1,tr("Average")); + } else + { ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_COUNT) ; + ui.legend_CB->setItemText(1,tr("Total")); + } } diff --git a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h index 9a835fc57..055555f73 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h +++ b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h @@ -15,7 +15,8 @@ protected slots: void updateUpDownSelection(int n); void updateUnitSelection(int n); void toggleLogScale(bool b); - + void updateLegendType(int n); + private: Ui::BwStatsWidget ui; diff --git a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui index e99058ac3..fdfefb99b 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui +++ b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui @@ -6,7 +6,7 @@ 0 0 - 1128 + 1148 385 @@ -14,7 +14,16 @@ Form - + + 0 + + + 0 + + + 0 + + 0 @@ -103,6 +112,27 @@ + + + + Legend: + + + + + + + + Current + + + + + Total + + + + From 969b5ce1f1260160e0bfc0be2f59253777c27b8c Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 21 Apr 2017 15:57:57 +0200 Subject: [PATCH 093/118] Fix MacOSX compilation. --- retroshare-gui/src/gui/elastic/fft.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/retroshare-gui/src/gui/elastic/fft.h b/retroshare-gui/src/gui/elastic/fft.h index 12d460c24..0b5c48ad7 100644 --- a/retroshare-gui/src/gui/elastic/fft.h +++ b/retroshare-gui/src/gui/elastic/fft.h @@ -104,7 +104,11 @@ public: w[nwh] = cos(delta * nwh); w[nwh + 1] = w[nwh]; for (j = 2; j <= nwh - 2; j += 2) { +#ifdef __APPLE__ + __sincos(delta*j,&y,&x); +#else sincos(delta*j,&y,&x) ; +#endif //x = cos(delta * j); //y = sin(delta * j); w[j] = x; From 936dcbabb344e46b95c396fb596fc41febe63d98 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 21 Apr 2017 18:50:36 +0200 Subject: [PATCH 094/118] Fix UnitTest compilation. --- tests/unittests/libretroshare/gxs/nxs_test/nxstesthub.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unittests/libretroshare/gxs/nxs_test/nxstesthub.cc b/tests/unittests/libretroshare/gxs/nxs_test/nxstesthub.cc index 216f971c1..36b288341 100644 --- a/tests/unittests/libretroshare/gxs/nxs_test/nxstesthub.cc +++ b/tests/unittests/libretroshare/gxs/nxs_test/nxstesthub.cc @@ -53,6 +53,7 @@ public: { return recvItem(i); } + bool getServiceItemNames(uint32_t /*service_type*/, std::map& /*names*/) { return false; } private: RsPeerId mPeerId; RecvPeerItemIface* mRecvIface; From 8c0b7ce776bfc77f4d03ec269d3f3ffbec250d90 Mon Sep 17 00:00:00 2001 From: Konrad Date: Fri, 21 Apr 2017 23:44:00 +0200 Subject: [PATCH 095/118] Fixed: Responds sends now correct time difference --- libresapi/src/api/IdentityHandler.cpp | 4 ++-- libresapi/src/api/PeersHandler.cpp | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 67e5cb4c6..2990a745c 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -413,7 +413,7 @@ void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) resp.mDataStream << makeKeyValue("pgp_name", pgp_name); time_t now = time(NULL); - resp.mDataStream << makeKeyValue("last_usage", std::to_string(now - data.mLastUsageTS)); + resp.mDataStream << makeKeyValue("last_usage", difftime(now, data.mLastUsageTS)); bool isAnonymous = false; if(!data.mPgpKnown) @@ -468,7 +468,7 @@ void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) for(std::map::const_iterator it(details.mUseCases.begin()); it != details.mUseCases.end(); ++it) { - usagesStream.getStreamToMember() << makeKeyValue("usage_time", std::to_string(now - it->second)); + usagesStream.getStreamToMember() << makeKeyValue("usage_time", difftime(now, data.mLastUsageTS)); usagesStream.getStreamToMember() << makeKeyValue("usage_service", (int)(it->first.mServiceId)); usagesStream.getStreamToMember() << makeKeyValue("usage_case", (int)(it->first.mUsageCode)); } diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index 6649acdcb..dd03f8351 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "Operators.h" #include "ApiTypes.h" @@ -745,11 +746,12 @@ void PeersHandler::handleGetNodeOptions(Request& req, Response& resp) return; } + time_t now = time(NULL); resp.mDataStream << makeKeyValue("peer_id", detail.id.toStdString()); resp.mDataStream << makeKeyValue("name", detail.name); resp.mDataStream << makeKeyValue("location", detail.location); resp.mDataStream << makeKeyValue("pgp_id", detail.gpg_id.toStdString()); - resp.mDataStream << makeKeyValue("last_contact", detail.lastConnect); + resp.mDataStream << makeKeyValue("last_contact", difftime(now, detail.lastConnect)); std::string status_message = mRsMsgs->getCustomStateString(detail.id); resp.mDataStream << makeKeyValueReference("status_message", status_message); From 8b9c447063a13f4b2c567e8be378a8c270487003 Mon Sep 17 00:00:00 2001 From: electron128 Date: Sat, 22 Apr 2017 10:13:23 +0200 Subject: [PATCH 096/118] fixed possible crash and return value in rsGetHostByName(), thanks to Kotyara for reporting this --- libretroshare/src/util/rsnet.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/util/rsnet.cc b/libretroshare/src/util/rsnet.cc index 63501511b..8b8c9ef82 100644 --- a/libretroshare/src/util/rsnet.cc +++ b/libretroshare/src/util/rsnet.cc @@ -81,15 +81,18 @@ bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) addrinfo *info = NULL; int res = getaddrinfo(hostname.c_str(),NULL,NULL,&info) ; + bool ok = true; if(res > 0 || info == NULL || info->ai_addr == NULL) { std::cerr << "(EE) getaddrinfo returned error " << res << " on string \"" << hostname << "\"" << std::endl; returned_addr.s_addr = 0 ; + ok = false; } else returned_addr.s_addr = ((sockaddr_in*)info->ai_addr)->sin_addr.s_addr ; - freeaddrinfo(info) ; + if(info) + freeaddrinfo(info) ; #ifdef DEPRECATED_TO_REMOVE #if defined(WINDOWS_SYS) || defined(__APPLE__) || defined(__HAIKU__) @@ -123,7 +126,7 @@ bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) returned_addr.s_addr = *(unsigned long*) (result->h_addr); #endif - return true ; + return ok; } bool isValidNet(const struct in_addr *addr) From f571b05693e2e886cbb062cdf5636e945e5b607f Mon Sep 17 00:00:00 2001 From: Konrad Date: Sat, 22 Apr 2017 11:06:56 +0200 Subject: [PATCH 097/118] Added: Checking if the vector is empty; Changed: Grouped values into one member --- libresapi/src/api/IdentityHandler.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 2990a745c..1306f9a54 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -388,6 +388,12 @@ void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) return; } + if(datavector.empty()) + { + resp.setFail(); + return; + } + data = datavector[0]; resp.mDataStream << makeKeyValue("gxs_name", data.mMeta.mGroupName); @@ -468,9 +474,10 @@ void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) for(std::map::const_iterator it(details.mUseCases.begin()); it != details.mUseCases.end(); ++it) { - usagesStream.getStreamToMember() << makeKeyValue("usage_time", difftime(now, data.mLastUsageTS)); - usagesStream.getStreamToMember() << makeKeyValue("usage_service", (int)(it->first.mServiceId)); - usagesStream.getStreamToMember() << makeKeyValue("usage_case", (int)(it->first.mUsageCode)); + usagesStream.getStreamToMember() + << makeKeyValue("usage_time", difftime(now, data.mLastUsageTS)) + << makeKeyValue("usage_service", (int)(it->first.mServiceId)) + << makeKeyValue("usage_case", (int)(it->first.mUsageCode)); } resp.setOk(); From 0e087db807dfff94cdab04dfc763e6fe3b26689a Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 22 Apr 2017 17:32:59 +0200 Subject: [PATCH 098/118] Fixed to use right icons for context menu actions --- retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 5c479005c..6afa8dbdd 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -60,6 +60,7 @@ /* Images for context menu icons */ #define IMAGE_MESSAGE ":/images/mail_new.png" #define IMAGE_MESSAGEREPLY ":/images/mail_reply.png" +#define IMAGE_MESSAGEEDIT ":/images/edit_16.png" #define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png" #define IMAGE_DOWNLOAD ":/images/start.png" #define IMAGE_DOWNLOADALL ":/images/startall.png" @@ -485,7 +486,7 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) QMenu contextMnu(this); - QAction *editAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Edit"), &contextMnu); + QAction *editAct = new QAction(QIcon(IMAGE_MESSAGEEDIT), tr("Edit"), &contextMnu); connect(editAct, SIGNAL(triggered()), this, SLOT(editforummessage())); QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu); @@ -531,7 +532,7 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu); connect(markMsgAsUnreadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren())); - QAction *showinpeopleAct = new QAction(QIcon(":/images/message-mail.png"), tr("Show author in people tab"), &contextMnu); + QAction *showinpeopleAct = new QAction(QIcon(":/images/info16.png"), tr("Show author in people tab"), &contextMnu); connect(showinpeopleAct, SIGNAL(triggered()), this, SLOT(showInPeopleTab())); if (IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { From 4c326f5e808f261bb3e4522d6cbaba2927224dc9 Mon Sep 17 00:00:00 2001 From: Phenom Date: Sun, 23 Apr 2017 10:27:18 +0200 Subject: [PATCH 099/118] Fix Relay setting page. --- retroshare-gui/src/gui/settings/RelayPage.cpp | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/retroshare-gui/src/gui/settings/RelayPage.cpp b/retroshare-gui/src/gui/settings/RelayPage.cpp index 258bc05aa..3124f40db 100644 --- a/retroshare-gui/src/gui/settings/RelayPage.cpp +++ b/retroshare-gui/src/gui/settings/RelayPage.cpp @@ -29,6 +29,7 @@ #include #include #include +#include "util/misc.h" #include @@ -127,35 +128,37 @@ void RelayPage::load() uint32_t count; uint32_t bandwidth; rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_FRIENDS, count, bandwidth); - ui.noFriendSpinBox->setValue(count); - ui.bandFriendSpinBox->setValue(bandwidth / 1000); + whileBlocking(ui.noFriendSpinBox)->setValue(count); + whileBlocking(ui.bandFriendSpinBox)->setValue(bandwidth / 1000); rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_FOF, count, bandwidth); - ui.noFOFSpinBox->setValue(count); - ui.bandFOFSpinBox->setValue(bandwidth / 1000); + whileBlocking(ui.noFOFSpinBox)->setValue(count); + whileBlocking(ui.bandFOFSpinBox)->setValue(bandwidth / 1000); rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_GENERAL, count, bandwidth); - ui.noGeneralSpinBox->setValue(count); - ui.bandGeneralSpinBox->setValue(bandwidth / 1000); + whileBlocking(ui.noGeneralSpinBox)->setValue(count); + whileBlocking(ui.bandGeneralSpinBox)->setValue(bandwidth / 1000); + + updateTotals(); uint32_t relayMode = rsDht->getRelayMode(); if (relayMode & RSDHT_RELAY_ENABLED) { - ui.enableCheckBox->setCheckState(Qt::Checked); + whileBlocking(ui.enableCheckBox)->setCheckState(Qt::Checked); if ((relayMode & RSDHT_RELAY_MODE_MASK) == RSDHT_RELAY_MODE_OFF) { - ui.serverCheckBox->setCheckState(Qt::Unchecked); + whileBlocking(ui.serverCheckBox)->setCheckState(Qt::Unchecked); } else { - ui.serverCheckBox->setCheckState(Qt::Checked); + whileBlocking(ui.serverCheckBox)->setCheckState(Qt::Checked); } } else { - ui.enableCheckBox->setCheckState(Qt::Unchecked); - ui.serverCheckBox->setCheckState(Qt::Unchecked); + whileBlocking(ui.enableCheckBox)->setCheckState(Qt::Unchecked); + whileBlocking(ui.serverCheckBox)->setCheckState(Qt::Unchecked); } loadServers(); From 5b3b903603742a7717d7e5f372df8f13140089f7 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 23 Apr 2017 17:33:21 +0200 Subject: [PATCH 100/118] added missing line for ubuntu zesty --- build_scripts/Debian+Ubuntu/makeSourcePackage.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh index 5cbb59f24..2e6f4305a 100755 --- a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh +++ b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh @@ -116,6 +116,8 @@ for i in ${dist}; do if test "${i}" = "lucid" ; then cp ../control.ubuntu_lucid debian/control + elif test "${i}" = "zesty" ; then + cp ../control.zesty debian/control elif test "${i}" = "squeeze" ; then cp ../control.squeeze_bubba3 debian/control elif test "${i}" = "precise" ; then From c738026eb8f874620ecaf174b5477f4d5039eae4 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 23 Apr 2017 17:48:39 +0200 Subject: [PATCH 101/118] updated ubuntu changelog --- build_scripts/Debian+Ubuntu/changelog | 194 ++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) diff --git a/build_scripts/Debian+Ubuntu/changelog b/build_scripts/Debian+Ubuntu/changelog index 15c1216c6..bb6fcd9b7 100644 --- a/build_scripts/Debian+Ubuntu/changelog +++ b/build_scripts/Debian+Ubuntu/changelog @@ -1,5 +1,199 @@ retroshare06 (0.6.2-1.XXXXXX~YYYYYY) YYYYYY; urgency=low + 5b3b903 csoler Sun, 23 Apr 2017 17:33:21 +0200 added missing line for ubuntu zesty + 73bfc27 csoler Sun, 23 Apr 2017 17:33:50 +0200 Merge pull request #784 from PhenomRetroShare/Fix_RelaySettingsPage + 4c326f5 Phenom Sun, 23 Apr 2017 10:27:18 +0200 Fix Relay setting page. + 0e087db defnax Sat, 22 Apr 2017 17:32:59 +0200 Fixed to use right icons for context menu actions + 8b9c447 electr Sat, 22 Apr 2017 10:13:23 +0200 fixed possible crash and return value in rsGetHostByName(), thanks to Kotyara for reporting this + 4ab6021 csoler Fri, 21 Apr 2017 19:45:30 +0200 Merge pull request #782 from PhenomRetroShare/Fix_MacOSX_Compilation + 936dcba Phenom Fri, 21 Apr 2017 18:50:36 +0200 Fix UnitTest compilation. + 969b5ce Phenom Fri, 21 Apr 2017 15:57:57 +0200 Fix MacOSX compilation. + 7400a8d csoler Thu, 20 Apr 2017 20:59:12 +0200 Merge pull request #780 from csoler/v0.6-ImprovedGUI + 5f8bf03 csoler Thu, 20 Apr 2017 20:54:51 +0200 added mechanism to allow services to document the names of their items, and improved bandwidth graph to show names for GXS services. Other services still need to supply their own names + ccfd12b csoler Wed, 19 Apr 2017 18:53:49 +0200 Merge pull request #778 from csoler/v0.6-ImprovedGUI + f406b81 csoler Wed, 19 Apr 2017 18:46:58 +0200 removed all FFT code and cleaned up deleted code in graphwidget.cpp + 1da89dd csoler Wed, 19 Apr 2017 17:16:30 +0200 changed FFT code in graph widget into a more efficient one, with free licence + e95ddb9 csoler Tue, 18 Apr 2017 20:28:36 +0200 Merge pull request #767 from PhenomRetroShare/Fix_CommentWithLineReturn + 5f969e7 csoler Tue, 18 Apr 2017 20:27:20 +0200 Merge pull request #776 from PhenomRetroShare/Fix_ClangWarnings + 3ab39c6 csoler Tue, 18 Apr 2017 20:26:14 +0200 Merge pull request #777 from PhenomRetroShare/Fix_EncodeRadixInRSLinks + 3c5e61a Phenom Tue, 18 Apr 2017 17:36:43 +0200 Encode Radix in RSLinks. + 3733137 Phenom Tue, 18 Apr 2017 11:25:41 +0200 Fix Clang warnings: implicit conversion + 7d9a803 Phenom Tue, 18 Apr 2017 11:18:10 +0200 Fix Clang warnings: bdnet_inet_ntoa C-linkage + 4faaaf7 csoler Mon, 17 Apr 2017 22:03:48 +0200 Merge pull request #775 from csoler/v0.6-PRTest + 87dd614 Phenom Fri, 7 Apr 2017 19:32:19 +0200 Fix Clang Warnings: private field 'encoding_debug_file' is not used + 4f939b2 Phenom Fri, 7 Apr 2017 19:29:27 +0200 Fix Clang warnings: unused function 'set_item_background' + 76f7573 Phenom Fri, 7 Apr 2017 18:48:40 +0200 Fix Clang warnings: comparison of array != a null pointer is always true + 0bbd149 Phenom Fri, 7 Apr 2017 18:42:22 +0200 Fix Clang warnings: comparison of integers of different signs + a476a81 Phenom Fri, 7 Apr 2017 18:40:02 +0200 Fix Clang warnings: function 'update_children_background' is not needed + d8a7313 Phenom Fri, 7 Apr 2017 18:32:55 +0200 Fix Clang warnings: implicit conversion from 'double' to 'int' + 19196e2 Phenom Fri, 7 Apr 2017 18:21:49 +0200 Fix Clang warnings: ariable 'status' is used uninitialized + a3a53b9 Phenom Fri, 7 Apr 2017 18:19:42 +0200 Fix Clang warnings: unused parameter 'req' + 94ac821 Phenom Wed, 29 Mar 2017 18:13:17 +0200 Fix Clang warnings: Unused variable Pi + fd92bca Phenom Tue, 28 Mar 2017 21:18:25 +0200 Fix Clang warnings: variable 'layout' is used uninitialized + 8d85cf5 Phenom Tue, 28 Mar 2017 21:16:05 +0200 Fix Clang warnings: 'xxxWidget::sizeHint' hides overloaded vf + 6f2d7bb Phenom Sun, 19 Mar 2017 10:51:48 +0100 Fix Clang warnings: implicit conversion from 'double' to 'int' + 07b67e9 Phenom Sun, 19 Mar 2017 10:40:34 +0100 Fix Clang warnings: 'PopupDistantChatDialog::init' hides overloaded virtual function + eea49d9 Phenom Sat, 18 Mar 2017 11:56:11 +0100 Fix Clang warnings: change ChatDialog::init definition + 9319caf Phenom Sat, 18 Mar 2017 11:32:56 +0100 Fix Clang warnings: 'Node::advance' hides overloaded virtual function + 13c8f7d Phenom Sat, 18 Mar 2017 11:28:29 +0100 Fix Clang warnings: Infinite recursion + e0225ef Phenom Sat, 18 Mar 2017 11:19:42 +0100 Fix Clang warnings: 'ChatLobbyDialog::init' hides overloaded virtual function + de4f6c0 Phenom Sat, 18 Mar 2017 10:42:38 +0100 Fix Clang warnings: Z-order assignment to spacer + 32eeb95 Phenom Sat, 18 Mar 2017 10:25:23 +0100 Fix Clang warnings: unused private field + 4ac3b3f Phenom Sat, 18 Mar 2017 10:20:57 +0100 Fix Clang warnings: implicit conversion of NULL to bool + e83104e Phenom Sat, 18 Mar 2017 10:19:31 +0100 Fix Clang warnings: Add author and date to #warning + 039908b Phenom Thu, 16 Mar 2017 22:58:06 +0100 Fix Clang warnings: private field not used + 872f42b Phenom Thu, 16 Mar 2017 22:55:18 +0100 Fix Clang warnings: Overloaded vf hide in pluginmanager + 2204309 Phenom Thu, 16 Mar 2017 22:11:33 +0100 Fix Clang warnings: extraneous parentheses + dc533b1 Phenom Thu, 16 Mar 2017 22:01:22 +0100 Fix Clang warnings: private field not used + 6532150 Phenom Thu, 16 Mar 2017 21:04:38 +0100 Fix Clang warnings: Overloaded vf hide in p3dhtmgr + 5bc6558 Phenom Thu, 16 Mar 2017 18:28:48 +0100 Fix Clang warnings: explicitly assigning value to itself + 6fecac5 Phenom Thu, 16 Mar 2017 17:50:25 +0100 Fix Clang warnings: Overloaded vf hide + cf963c0 Phenom Wed, 15 Mar 2017 20:41:39 +0100 Fix Clang warnings: struct declared as class + 105840a Phenom Wed, 15 Mar 2017 19:03:39 +0100 Fix Clang Warning: Overloaded vf hide + da4b168 Phenom Wed, 15 Mar 2017 18:55:24 +0100 Fix Clang warnings: mFns is not used + cbc264f Phenom Wed, 15 Mar 2017 18:53:30 +0100 Fix clang warning:Implicit conversion from enumeration + b2e37fe csoler Sat, 15 Apr 2017 20:24:06 +0200 Merge pull request #773 from csoler/v0.6-Identity + 273aae7 csoler Sat, 15 Apr 2017 19:01:13 +0200 fixed sharing of own identity + 98e1a6d electr Thu, 13 Apr 2017 14:12:46 +0200 Merge pull request #770 from Sonetio/fix_reselecting_accounts + 144d570 Konrad Thu, 13 Apr 2017 13:40:30 +0200 Fixed: Thread safe access to RsControlModule member variables + dcc8c6e Konrad Thu, 13 Apr 2017 13:31:32 +0200 Changed: Using PeersHandler::mRsPeers instead of rsPeers + a382d68 electr Thu, 13 Apr 2017 09:22:19 +0200 Merge pull request #769 from electron128/fix-gui-multiinstance + aa81cc1 Konrad Wed, 12 Apr 2017 20:24:18 +0200 Added: Functions for handling PGP account details requests + 9402b8e Konrad Mon, 10 Apr 2017 23:42:22 +0200 Fixed: mFixedPassword remained empty after logging + e1350a0 Konrad Mon, 10 Apr 2017 22:58:23 +0200 Fixed: Re-selecting accounts via RsControlModule; Added: Sending feedback about incorrect password + 3130ec9 csoler Mon, 10 Apr 2017 20:02:14 +0200 added GUI async call to ID serialised data. Allows to copy+paste identities. + 4c9b620 electr Sun, 9 Apr 2017 10:26:18 +0200 fixed --base-dir command line argument in rs-gui when running multiple instances. Only forward "link" and "rsfile" arguments to a running instance. Start a new instance if other arguments are present. + 7f12ca2 electr Sun, 9 Apr 2017 09:57:48 +0200 fixed name of local socket where RS waits for rslinks etc. + d66e653 csoler Sat, 8 Apr 2017 23:39:05 +0200 fixed bug in deserialisation of group informaiton + 54cd402 csoler Sat, 8 Apr 2017 21:43:07 +0200 fixed a few bugs in latest identity link code + 6d29038 csoler Sat, 8 Apr 2017 21:12:48 +0200 added RSLink for GXS identities + 4f5da86 csoler Sat, 8 Apr 2017 19:07:33 +0200 added method to serialise/deserialise groups to/from memory and export of GxsIdentities to memory chunk in radix format + f175533 Phenom Sat, 8 Apr 2017 14:06:47 +0200 Fix comment view when they have line return. + 4067c95 electr Wed, 5 Apr 2017 18:49:32 +0200 Merge pull request #760 from Sonetio/windows_service + 6e65fcd Konrad Sat, 1 Apr 2017 14:32:49 +0200 Removed: Unused #include statement + 8543525 Konrad Sat, 1 Apr 2017 14:28:55 +0200 Fixed: Linker problem + fbc1bb4 Konrad Wed, 29 Mar 2017 16:06:39 +0200 Added: function for handling autosubscribing lobbies + 22956be Konrad Tue, 28 Mar 2017 11:24:16 +0200 Deleted: functions for hadling particular lobbies types in ChatHandler + 6e53002 Konrad Tue, 28 Mar 2017 11:20:51 +0200 Added: tokens in PeersHandler + efd6ce3 Konrad Tue, 28 Mar 2017 11:19:50 +0200 Changed: Simplified asking for deferred self signature + 5694581 Konrad Tue, 28 Mar 2017 11:18:27 +0200 Changed: Qt dependecies are optional + 4031e49 Konrad Mon, 27 Mar 2017 16:11:04 +0200 Deleted: unused stateTokens + c33107c Konrad Sun, 26 Mar 2017 19:12:04 +0200 Fixed: backward comptiblity + bef7540 Konrad Sun, 26 Mar 2017 15:11:07 +0200 Fixed building on Travis CI + dbcf2d2 csoler Sat, 25 Mar 2017 20:27:18 +0100 Merge pull request #756 from RetroPooh/guistuff + 04af39f csoler Sat, 25 Mar 2017 20:24:40 +0100 Merge pull request #754 from PhenomRetroShare/Fix_WinNoSQLCipherCompil + ccb632a csoler Sat, 25 Mar 2017 19:26:12 +0100 Merge pull request #749 from PhenomRetroShare/Fix_WindowsHeightAtFirstStart + 8624c93 Konrad Sat, 25 Mar 2017 18:33:35 +0100 Added functions for hadling particular lobbies types to ChatHandler + 194878a Konrad Sat, 25 Mar 2017 18:31:13 +0100 Added functions for handling own and not own identities to IdentityHandler + cb32f30 Konrad Sat, 25 Mar 2017 18:28:31 +0100 Added states handling to PeersHandler + 28d37c2 Konrad Sat, 25 Mar 2017 18:25:26 +0100 Added password storing to RsControlModule for GUI benefits + 39967b7 Konrad Sat, 25 Mar 2017 18:23:28 +0100 Added name of requests to be used by GUI + ae95b49 Konrad Sat, 25 Mar 2017 18:20:53 +0100 Added SettingsHandler to handle response to settings requests + cb04134 Konrad Sat, 25 Mar 2017 18:15:47 +0100 Added Windows support to libresapi when working with retroshare_android_service + b0d2249 Konrad Sat, 25 Mar 2017 18:12:39 +0100 Added Windows support to retroshare-android-service + f5e7217 RetroP Tue, 21 Mar 2017 17:24:59 +0300 statistics - router - fix bold marking for tunnel speeds over 1mbs + 85cfda1 RetroP Tue, 21 Mar 2017 16:52:40 +0300 add tree item counters for channels,forums,posted + 50c81d7 RetroP Tue, 21 Mar 2017 16:41:39 +0300 chat lobby list - mark signed lobbies with color + 000dabf RetroP Tue, 21 Mar 2017 15:02:46 +0300 chat lobby list - add tree item counters + 19bd51d RetroP Tue, 21 Mar 2017 14:57:06 +0300 searchdialog - mark current downloads green + 5efa8e3 Phenom Fri, 17 Mar 2017 22:14:14 +0100 Fix Windows Compilation with CONFIG+=no_sqlcipher + ca0521c csoler Thu, 16 Mar 2017 21:01:27 +0100 allowed to edit subject hen editing forum posts. Only the latest subject is visible + 107d48f Phenom Wed, 15 Mar 2017 22:50:51 +0100 Fix windows height at first start. + 2046dbe csoler Wed, 15 Mar 2017 20:53:01 +0100 merged latest fixes from official 0.6.2 release branch + e4fad45 csoler Wed, 15 Mar 2017 20:51:40 +0100 fixed layout in ConfCertDialog, removed overnumerous tabs + 2114374 csoler Wed, 15 Mar 2017 19:26:07 +0100 fixed update of Tor proxy address in hidden nodes server page + 44f2971 csoler Tue, 14 Mar 2017 20:04:22 +0100 Merge pull request #682 from csoler/v0.6-EditPosts + a0d1089 csoler Sat, 11 Mar 2017 18:15:35 +0100 added branch parameter to makeSourcePackage script + fdab480 csoler Sat, 11 Mar 2017 18:10:14 +0100 added minimum version number for debian stretch + 733b114 thunde Fri, 10 Mar 2017 15:57:40 +0100 Updated languages from Transifex + ed5779f csoler Fri, 10 Mar 2017 15:39:22 +0100 Merge pull request #743 from mestaritonttu/patch-22 + 69c3df6 csoler Fri, 10 Mar 2017 15:36:50 +0100 fixed bug in total item size estimation in pqiqosstreamer due to item slicing + c377bf3 csoler Fri, 10 Mar 2017 15:12:10 +0100 fixed debug output for groups with no data + fd84639 csoler Fri, 10 Mar 2017 15:05:41 +0100 removed some debug info + c87de3e csoler Fri, 10 Mar 2017 10:48:40 +0100 fixed mistake in pointer handling + cf2edb5 csoler Thu, 9 Mar 2017 22:47:06 +0100 fixed memory leak in deleteGroup and removed unnecessary pointer in the functions called below + a545481 csoler Thu, 9 Mar 2017 22:05:06 +0100 fixed memory leak when receving multi-chunk file lists + 5b819eb csoler Thu, 9 Mar 2017 20:59:01 +0100 added missing virtual destructor causing a memory leak + 1f8fd95 csoler Thu, 9 Mar 2017 20:48:26 +0100 fixed uninitialised memory read in chacha20 test code + d5f2ae8 csoler Thu, 9 Mar 2017 20:39:12 +0100 fixed memory leak recently introduced with openssl-1.1.0 changes + f76454d csoler Thu, 9 Mar 2017 13:05:03 +0100 updated full pipeline packaging script for debian + 999e845 mestar Wed, 8 Mar 2017 13:17:34 +0200 Fix grammar + e6cf628 csoler Tue, 7 Mar 2017 21:58:59 +0100 Merge pull request #740 from RetroPooh/trstats + 283a2ee csoler Tue, 7 Mar 2017 21:54:56 +0100 Merge pull request #717 from PhenomRetroShare/Fix_SettingListWidth + b3b2a4b csoler Tue, 7 Mar 2017 21:54:10 +0100 Merge pull request #726 from mestaritonttu/patch-8 + bbc27b2 csoler Tue, 7 Mar 2017 21:53:21 +0100 Merge pull request #736 from mestaritonttu/patch-18 + 3d0c28d csoler Tue, 7 Mar 2017 21:52:19 +0100 Merge pull request #724 from mestaritonttu/patch-6 + ed22b48 csoler Tue, 7 Mar 2017 21:51:51 +0100 Merge pull request #738 from mestaritonttu/patch-20 + 376be42 csoler Tue, 7 Mar 2017 21:51:13 +0100 Merge pull request #739 from mestaritonttu/patch-21 + b3578f6 csoler Tue, 7 Mar 2017 21:50:20 +0100 Merge pull request #734 from mestaritonttu/patch-16 + d9c084b csoler Tue, 7 Mar 2017 21:49:52 +0100 Merge pull request #730 from mestaritonttu/patch-12 + 5bad326 csoler Tue, 7 Mar 2017 21:49:14 +0100 Merge pull request #725 from mestaritonttu/patch-7 + ec21698 csoler Tue, 7 Mar 2017 21:48:30 +0100 Merge pull request #727 from mestaritonttu/patch-9 + 7d8e06b csoler Tue, 7 Mar 2017 21:47:43 +0100 Merge pull request #732 from mestaritonttu/patch-14 + f3e29bd csoler Tue, 7 Mar 2017 21:47:00 +0100 Merge pull request #731 from mestaritonttu/patch-13 + 17c44db csoler Tue, 7 Mar 2017 21:46:21 +0100 Merge pull request #733 from mestaritonttu/patch-15 + 5f9f061 csoler Tue, 7 Mar 2017 21:45:50 +0100 Merge pull request #735 from mestaritonttu/patch-17 + 8881a44 csoler Tue, 7 Mar 2017 21:45:11 +0100 Merge pull request #737 from mestaritonttu/patch-19 + 160c289 csoler Tue, 7 Mar 2017 21:44:42 +0100 Merge pull request #728 from mestaritonttu/patch-10 + 22308bc csoler Tue, 7 Mar 2017 21:44:14 +0100 Merge pull request #729 from mestaritonttu/patch-11 + fedffd7 csoler Tue, 7 Mar 2017 21:43:36 +0100 Merge pull request #723 from mestaritonttu/patch-5 + d3f0f9d RetroP Tue, 7 Mar 2017 17:50:13 +0300 router stats - mark active tunnels bold + 87f9dba mestar Tue, 7 Mar 2017 14:05:21 +0200 Improvements and typo fixes in strings + 222cf48 mestar Tue, 7 Mar 2017 14:03:05 +0200 Various improvements and fixes to strings + 83283d9 mestar Tue, 7 Mar 2017 13:58:43 +0200 Remove extra your + 7005126 mestar Tue, 7 Mar 2017 13:57:10 +0200 Added whitespace to strings + 6ec5415 mestar Tue, 7 Mar 2017 13:55:02 +0200 ASCII uppercase + 28d2e27 mestar Tue, 7 Mar 2017 13:53:08 +0200 Remove whitespace from string + 931531b mestar Tue, 7 Mar 2017 13:51:28 +0200 Fix typo + 65c7ca7 mestar Tue, 7 Mar 2017 13:49:57 +0200 Clarify sorting by posts + 21b7861 mestar Tue, 7 Mar 2017 13:48:14 +0200 Fix grammar + ba18fcd mestar Tue, 7 Mar 2017 13:45:31 +0200 Fix grammar + a4c2015 mestar Tue, 7 Mar 2017 13:41:45 +0200 Fix typos + 6b4f7e3 mestar Tue, 7 Mar 2017 13:39:39 +0200 Removed extra "to" + b444567 mestar Tue, 7 Mar 2017 13:34:53 +0200 Added period + 400dde9 mestar Tue, 7 Mar 2017 13:09:04 +0200 Added whitespace + c9a4a55 mestar Tue, 7 Mar 2017 13:06:22 +0200 Fix grammar + 86e7243 mestar Tue, 7 Mar 2017 12:56:25 +0200 Fix typos + d7dc9cc mestar Tue, 7 Mar 2017 12:53:18 +0200 Whitespace inside

+ a518225 csoler Tue, 7 Mar 2017 11:27:17 +0100 Merge pull request #716 from felisucoibi/master + 6a6bcf7 thunde Mon, 6 Mar 2017 21:46:42 +0100 Fixed Windows compile of VOIP + dc65d3f Phenom Sun, 5 Mar 2017 13:22:30 +0100 Fix Setting list width. + 0316c8c thunde Mon, 6 Mar 2017 06:34:06 +0100 Added workaround for crash on Windows 7 for Qt versions with gcc 5.3.0. The call to GetProcAddress in openssl (cryptlib.c) finds an function pointer to the not existing function _OPENSSL_isservice in the executable running on Windows 7. + 313e1b3 csoler Sun, 5 Mar 2017 20:08:53 +0100 updated translation files + 88a5c03 csoler Sun, 5 Mar 2017 20:08:36 +0100 removed some debug info + 94c9c94 thunde Sun, 5 Mar 2017 14:30:45 +0100 updated version number to 0.6.2 in rsversion.in + b71f475 csoler Sun, 5 Mar 2017 14:14:46 +0100 qick fix to allow re-advertising for known forums/channels during the same session. Will be reset at restart (probably best) + fbd72dd csoler Sun, 5 Mar 2017 13:57:49 +0100 fixed settings SoundPage + 15bb0ff felisu Sun, 5 Mar 2017 02:45:37 +0100 Update ChatPage.h + 951820f felisu Sun, 5 Mar 2017 02:45:07 +0100 Update ForumPage.h + 63174aa felisu Sun, 5 Mar 2017 02:44:18 +0100 Update PostedPage.h + ca75515 felisu Sun, 5 Mar 2017 02:43:40 +0100 Update MessagePage.h + d3cdd15 csoler Sat, 4 Mar 2017 21:20:34 +0100 fixed uninitialised memory read in GxsReputation + dec5c5c csoler Sat, 4 Mar 2017 21:13:34 +0100 suppressed uninitialised memory leak in LocalDirectoryStorage + b14e4d5 csoler Sat, 4 Mar 2017 21:08:10 +0100 removed memory leak due to missing delete for BWGraph + 0bd0056 csoler Sat, 4 Mar 2017 20:52:41 +0100 fixed memory leak in RsGxsNetService + 7111579 csoler Sat, 4 Mar 2017 20:52:06 +0100 fixed memory leak in config of msgService + 2302c46 csoler Sat, 4 Mar 2017 16:41:10 +0100 updated version number in changelog + 0024ddf csoler Sat, 4 Mar 2017 16:39:39 +0100 fixed utf8 bug in ShareManager + 3600905 csoler Sat, 4 Mar 2017 12:04:41 +0100 updated packaging files + c715b03 csoler Sat, 4 Mar 2017 11:56:51 +0100 updated version number to 0.6.2 + 5e2a253 csoler Sat, 4 Mar 2017 11:44:31 +0100 updated ubuntu changelog + bd8189c csoler Tue, 28 Feb 2017 18:05:44 +0100 added test to prevent msgs with a different name to be used as different version + 763f227 csoler Sun, 26 Feb 2017 20:39:40 +0100 merged upstream/master into v0.6-EditPosts branch + 22f2edb csoler Sat, 11 Feb 2017 10:45:30 +0100 removed debug info and added comment + ea82d26 csoler Thu, 9 Feb 2017 23:35:59 +0100 fixed signature verification bug for versionned messages + 5bf8376 csoler Thu, 9 Feb 2017 21:49:24 +0100 fixed a few more bugs in post version UI + 8deeec6 csoler Thu, 9 Feb 2017 18:45:55 +0100 fixed UI for post versions + b93130a csoler Thu, 9 Feb 2017 16:15:35 +0100 fixed a few bugs in post version collecting + f8056e5 csoler Thu, 9 Feb 2017 14:49:43 +0100 added collection of older posts versions. + 6681985 csoler Wed, 8 Feb 2017 20:40:47 +0100 merged upstream/master + dfcb66d csoler Fri, 3 Feb 2017 13:02:53 +0100 added spinbox to show older versions + 777a73e csoler Fri, 3 Feb 2017 12:48:51 +0100 added GUI for editing forum messages + + -- Retroshare Dev Team Dim, 23 Apr 2017 16:00:00 +0100 + +retroshare06 (0.6.2-1.931442~trusty) trusty; urgency=low + 931442a csoler Sat, 4 Mar 2017 00:07:51 +0100 fixed compilation b4e0a8f csoler Sat, 4 Mar 2017 00:04:52 +0100 removed unused file DirectoriesPage.{cpp,ui,h} e257563 csoler Sat, 4 Mar 2017 00:01:21 +0100 merged Directories settings page into Transfers and renamed it Files From 06e90e65494d096b8fbe760b6cc1e62935b0cb8d Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 23 Apr 2017 17:49:07 +0200 Subject: [PATCH 102/118] added control file for zesty --- build_scripts/Debian+Ubuntu/control.zesty | 44 +++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 build_scripts/Debian+Ubuntu/control.zesty diff --git a/build_scripts/Debian+Ubuntu/control.zesty b/build_scripts/Debian+Ubuntu/control.zesty new file mode 100644 index 000000000..9b557e3b8 --- /dev/null +++ b/build_scripts/Debian+Ubuntu/control.zesty @@ -0,0 +1,44 @@ +Source: retroshare06 +Section: devel +Priority: standard +Maintainer: Cyril Soler +Build-Depends: debhelper (>= 7), libglib2.0-dev, libupnp-dev, libssl-dev, libxss-dev, libgnome-keyring-dev, libbz2-dev, libspeex-dev, libspeexdsp-dev, libxslt1-dev, cmake, libcurl4-openssl-dev, libopencv-dev, tcl8.6, libsqlcipher-dev, libmicrohttpd-dev, libavcodec-dev, qtmultimedia5-dev, qttools5-dev, libqt5x11extras5-dev, qt5-default +Standards-Version: 3.9.6 +Homepage: http://retroshare.sourceforge.net + +Package: retroshare06-voip-plugin +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, retroshare06, libspeex1, libspeexdsp1, libqt5multimedia5 +Description: RetroShare VOIP plugin + This package provides a plugin for RetroShare, a secured Friend-to-Friend communication + plateform. The plugin adds voice-over-IP functionality to the private chat window. Both + friends chatting together need the plugin installed to be able to talk together. + +Package: retroshare06-feedreader-plugin +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, retroshare06 +Description: RetroShare FeedReader plugin + This package provides a plugin for RetroShare, a secured Friend-to-Friend communication + plateform. The plugin adds a RSS feed reader tab to retroshare. + +Package: retroshare06-nogui +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, gnome-keyring +Conflicts: retroshare06 +Description: Secure communication with friends + This is the command-line client for RetroShare network. This client + can be contacted and talked-to using SSL. Clients exist for portable + devices running e.g. Android. + +Package: retroshare06 +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, gnome-keyring +Conflicts: retroshare06-nogui +Description: Secure communication with friends + RetroShare is a Open Source cross-platform, private and secure decentralised + commmunication platform. It lets you to securely chat and share files with your + friends and family, using a web-of-trust to authenticate peers and OpenSSL to + encrypt all communication. RetroShare provides filesharing, chat, messages, + forums and channels. + + From 190a638cc1076674d53d1d64dc2fef29fd28b125 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 23 Apr 2017 17:53:25 +0200 Subject: [PATCH 103/118] added zesty to ubuntu releases --- build_scripts/Debian+Ubuntu/makeSourcePackage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh index 2e6f4305a..dc5892b07 100755 --- a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh +++ b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh @@ -54,7 +54,7 @@ while [ ${#} -gt 0 ]; do done if test "${dist}" = "" ; then - dist="precise trusty vivid xenial yakkety" + dist="precise trusty vivid xenial yakkety zesty" fi echo Attempting to get revision number... From 6313d89718cffa5133b32034b170078992af350b Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 24 Apr 2017 01:23:05 +0200 Subject: [PATCH 104/118] Improved look n feel of Profile Generation Window. --- retroshare-gui/src/gui/GenCertDialog.cpp | 40 +- retroshare-gui/src/gui/GenCertDialog.ui | 1160 ++++++-------- retroshare-gui/src/gui/images.qrc | 1331 +++++++++-------- retroshare-gui/src/gui/images/cancel.png | Bin 792 -> 640 bytes .../src/gui/images/logo/logo_spash2.png | Bin 0 -> 102946 bytes 5 files changed, 1177 insertions(+), 1354 deletions(-) create mode 100644 retroshare-gui/src/gui/images/logo/logo_spash2.png diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index ff8fbf909..c65c08b89 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,7 @@ #include #define IMAGE_GOOD ":/images/accepted16.png" -#define IMAGE_BAD ":/images/deletemail24.png" +#define IMAGE_BAD ":/images/cancel.png" class EntropyCollectorWidget: public QTextBrowser { @@ -133,8 +134,8 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent) //ui.headerFrame->setHeaderImage(QPixmap(":/icons/svg/profile.svg")); //ui.headerFrame->setHeaderText(tr("Create a new profile")); - connect(ui.reuse_existing_node_CB, SIGNAL(clicked()), this, SLOT(switchReuseExistingNode())); - connect(ui.adv_checkbox, SIGNAL(clicked()), this, SLOT(setupState())); + connect(ui.reuse_existing_node_CB, SIGNAL(triggered()), this, SLOT(switchReuseExistingNode())); + connect(ui.adv_checkbox, SIGNAL(triggered()), this, SLOT(setupState())); connect(ui.nodeType_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(setupState())); connect(ui.genButton, SIGNAL(clicked()), this, SLOT(genPerson())); @@ -172,6 +173,11 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent) /* get all available pgp private certificates.... * mark last one as default. */ + + QMenu *menu = new QMenu(tr("Advanced options")); + menu->addAction(ui.adv_checkbox); + menu->addAction(ui.reuse_existing_node_CB); + ui.optionsButton->setMenu(menu); mAllFieldsOk = false ; mEntropyOk = false ; @@ -246,22 +252,22 @@ void GenCertDialog::setupState() genNewGPGKey = generate_new; - ui.no_node_label->setVisible(false); + //ui.no_node_label->setVisible(false); setWindowTitle(generate_new?tr("Create new profile and new Retroshare node"):tr("Create new Retroshare node")); //ui.headerFrame->setHeaderText(generate_new?tr("Create a new profile and node"):tr("Create a new node")); ui.label_nodeType->setVisible(adv_state) ; ui.nodeType_CB->setVisible(adv_state) ; - ui.reuse_existing_node_CB->setVisible(adv_state) ; + ui.reuse_existing_node_CB->setEnabled(adv_state) ; ui.importIdentity_PB->setVisible(adv_state && !generate_new) ; ui.exportIdentity_PB->setVisible(adv_state && !generate_new) ; ui.genPGPuser->setVisible(adv_state && haveGPGKeys && !generate_new) ; - ui.genprofileinfo_label->setVisible(false); - ui.no_gpg_key_label->setText(tr("Welcome to Retroshare. Before you can proceed you need to create a profile and associate a node with it. To do so please fill out this form.\nAlternatively you can import a (previously exported) profile. Just uncheck \"Create a new profile\"")); - ui.no_gpg_key_label->setVisible(false); + //ui.genprofileinfo_label->setVisible(false); + //ui.no_gpg_key_label->setText(tr("Welcome to Retroshare. Before you can proceed you need to create a profile and associate a node with it. To do so please fill out this form.\nAlternatively you can import a (previously exported) profile. Just uncheck \"Create a new profile\"")); + //no_gpg_key_label->setVisible(false); ui.nickname_label->setVisible(adv_state) ; ui.nickname_input->setVisible(adv_state) ; @@ -269,7 +275,7 @@ void GenCertDialog::setupState() ui.name_label->setVisible(true); ui.name_input->setVisible(generate_new); - ui.header_label->setVisible(false) ; + //ui.header_label->setVisible(false) ; ui.nickname_label->setVisible(adv_state && !mOnlyGenerateIdentity); ui.nickname_input->setVisible(adv_state && !mOnlyGenerateIdentity); @@ -300,14 +306,16 @@ void GenCertDialog::setupState() if(mEntropyOk && mAllFieldsOk) { ui.genButton->setEnabled(true) ; - ui.genButton->setIcon(QIcon(IMAGE_GOOD)) ; + //ui.genButton->setIcon(QIcon(IMAGE_GOOD)) ; ui.genButton->setToolTip(tr("Click to create your node and/or profile")) ; + ui.generate_label->setPixmap(QPixmap(IMAGE_GOOD)) ; } else { ui.genButton->setEnabled(false) ; - ui.genButton->setIcon(QIcon(IMAGE_BAD)) ; + //ui.genButton->setIcon(QIcon(IMAGE_BAD)) ; ui.genButton->setToolTip(tr("Disabled until all fields correctly set and enough randomness collected.")) ; + ui.generate_label->setPixmap(QPixmap(IMAGE_BAD)) ; } } @@ -495,9 +503,9 @@ void GenCertDialog::genPerson() } //generate a new gpg key std::string err_string; - ui.no_gpg_key_label->setText(tr("Generating new node key, please be patient: this process needs generating large prime numbers, and can take some minutes on slow computers. \n\nFill in your password when asked, to sign your new key.")); - ui.no_gpg_key_label->show(); - ui.reuse_existing_node_CB->hide(); + //_key_label->setText(tr("Generating new node key, please be patient: this process needs generating large prime numbers, and can take some minutes on slow computers. \n\nFill in your password when asked, to sign your new key.")); + //ui.no_gpg_key_label->show(); + //ui.reuse_existing_node_CB->hide(); ui.name_label->hide(); ui.name_input->hide(); ui.nickname_label->hide(); @@ -514,9 +522,9 @@ void GenCertDialog::genPerson() ui.node_input->hide(); ui.genButton->hide(); ui.importIdentity_PB->hide(); - ui.genprofileinfo_label->hide(); + //ui.genprofileinfo_label->hide(); ui.nodeType_CB->hide(); - ui.adv_checkbox->hide(); + //ui.adv_checkbox->hide(); ui.keylength_label->hide(); ui.keylength_comboBox->hide(); diff --git a/retroshare-gui/src/gui/GenCertDialog.ui b/retroshare-gui/src/gui/GenCertDialog.ui index 8325ffa3a..468c17693 100644 --- a/retroshare-gui/src/gui/GenCertDialog.ui +++ b/retroshare-gui/src/gui/GenCertDialog.ui @@ -6,8 +6,8 @@ 0 0 - 724 - 667 + 533 + 544 @@ -54,7 +54,10 @@ - :/images/logo/logo_splash.png + :/images/logo/logo_spash2.png + + + false Qt::AlignCenter @@ -77,22 +80,13 @@ - - - - 16777215 - 32 - - - - <html><head/><body><p>Use this if you need to import an existing profile, if you want to generate a new node with an already existing key, or if you want to create a TOR/I2P hidden node.</p></body></html> - + - Advanced options + Options - :/icons/settings/general.svg:/icons/settings/general.svg + :/icons/svg/options.svg:/icons/svg/options.svg @@ -100,667 +94,481 @@ 24 - + false + + true + - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 178 - - - - - - - 255 - 255 - 178 - - - - - - - - true + + + - QFrame::Box + QFrame::StyledPanel - - You can create a new profile with this form. -Alternatively you can use an existing profile. Just uncheck "Create a new profile" - - - true + + QFrame::Raised + + + + + + + + + + + + + + PGP key length + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> + + + + + + 1024 + + + QLineEdit::Password + + + + + + + This password is for PGP + + + Password + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + This password is for PGP + + + Password (check) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Please move your mouse around in order to collect as much randomness as possible. A minimum of 20% is needed to create your node keys.</p></body></html> + + + 24 + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + Standard node + + + + + TOR/I2P Hidden node + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + <html><head/><body><p>Your node name designates the Retroshare instance that</p><p>will run on this computer.</p></body></html> + + + 64 + + + + + + + Node name + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 32 + + + + <html><head/><body><p>The profile name identifies you over the network.</p><p>It is used by your friends to accept connections from you.</p><p>You can create multiple Retroshare nodes with the</p><p>same profile on different computers.</p><p><br/></p></body></html> + + + + + + 64 + + + + + + + + 0 + 0 + + + + Your profile is associated with a PGP key pair. RetroShare currently ignores DSA keys. + + + + + + + + + + + 0 + 0 + + + + Export this profle + + + + + + + + 0 + 0 + + + + Import profile + + + + + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> + + + + + + 1024 + + + QLineEdit::Password + + + + + + + Profile name + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Randomness + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Node type + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + hidden address + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 6 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 32 + + + + <html><head/><body><p>This should be a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion <br/>or an I2P address in the form: [52 characters].b32.i2p </p><p>In order to get one, you must configure either Tor or I2P to create a new hidden service / server tunnel. </p><p>You can also leave this blank now, but your node will only work if you correctly set the Tor/I2P service address in Options-&gt;Network-&gt;Hidden Service configuration panel.</p></body></html> + + + 64 + + + + + + + Port + + + + + + + + 0 + 0 + + + + <html><head/><body><p>This is your connection port.</p><p>Any value between 1024 and 65535 </p><p>should be ok. You can change it later.</p></body></html> + + + 1 + + + 65535 + + + 7812 + + + + + + + + + + + + Chat identity + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Identities are used when you write in chat rooms, forums and channel comments. </p><p>They also receive/send email over the Retroshare network. You can create</p><p>a signed identity now, or do it later on when you get to need it.</p></body></html> + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 12 + + + + + + + Go! + + + + 16 + 16 + + + + + + + + + + + + + + - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 178 - - - - - - - 255 - 255 - 178 - - - - - - - - true - - - QFrame::Box - - - You can create and run Retroshare nodes on different computers using the same profile. To do so just export the selected profile, import it on the other computer and create a new node with it. - - - true - - - - - - - It looks like no profile (PGP keys) exists. Please fill in the form below to create one, or import an existing profile. - - - true - - - - - - - No node exists for this profile. - - - true - - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> - - - - - - 1024 - - - QLineEdit::Password - - - - - - - This password is for PGP - - - Password - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - - - - This password is for PGP - - - Password (check) - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Please move your mouse around in order to collect as much randomness as possible. A minimum of 20% is needed to create your node keys.</p></body></html> - - - 24 - - - - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - - Standard node - - - - - TOR/I2P Hidden node - - - - - - - - PGP key length - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - <html><head/><body><p>Your node name designates the Retroshare instance that</p><p>will run on this computer.</p></body></html> - - - 64 - - - - - - - Node name - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 32 - - - - <html><head/><body><p>The profile name identifies you over the network.</p><p>It is used by your friends to accept connections from you.</p><p>You can create multiple Retroshare nodes with the</p><p>same profile on different computers.</p><p><br/></p></body></html> - - - - - - 64 - - - - - - - - 0 - 0 - - - - Your profile is associated with a PGP key pair. RetroShare currently ignores DSA keys. - - - - - - - - 0 - 0 - - - - Export this profle - - - - - - - - 0 - 0 - - - - Import profile - - - - - - - - 0 - 0 - - - - Re-use an existing profile - - - - - - - - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> - - - - - - 1024 - - - QLineEdit::Password - - - - - - - Profile name - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Randomness - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Node type - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - hidden address - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 6 - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 32 - - - - <html><head/><body><p>This should be a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion <br/>or an I2P address in the form: [52 characters].b32.i2p </p><p>In order to get one, you must configure either Tor or I2P to create a new hidden service / server tunnel. </p><p>You can also leave this blank now, but your node will only work if you correctly set the Tor/I2P service address in Options-&gt;Network-&gt;Hidden Service configuration panel.</p></body></html> - - - 64 - - - - - - - Port - - - - - - - - 0 - 0 - - - - <html><head/><body><p>This is your connection port.</p><p>Any value between 1024 and 65535 </p><p>should be ok. You can change it later.</p></body></html> - - - 1 - - - 65535 - - - 7812 - - - - - - - - - - - - Chat identity - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Identities are used when you write in chat rooms, forums and channel comments. </p><p>They also receive/send email over the Retroshare network. You can create</p><p>a signed identity now, or do it later on when you get to need it.</p></body></html> - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - - - Go! - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - @@ -778,27 +586,33 @@ Alternatively you can use an existing profile. Just uncheck "Create a new p + + + true + + + Advanced options + + + + + true + + + Use existing node + + - - - StyledLabel - QLabel -

gui/common/StyledLabel.h
- - name_input node_input password_input password_input_2 - adv_checkbox keylength_comboBox exportIdentity_PB - reuse_existing_node_CB genPGPuser hiddenaddr_input hiddenport_spinBox - genButton importIdentity_PB diff --git a/retroshare-gui/src/gui/images.qrc b/retroshare-gui/src/gui/images.qrc index adad4c232..fbdb66d3d 100644 --- a/retroshare-gui/src/gui/images.qrc +++ b/retroshare-gui/src/gui/images.qrc @@ -1,667 +1,668 @@ - - images/network_map.png - images/global_switch_on.png - images/global_switch_off.png - images/switch00.png - images/switch01.png - images/switch10.png - images/switch11.png - images/add_chat24.png - images/RSS_004_32.png - images/mail-encrypted-full.png - images/mail-signed-full.png - images/document-edit-sign.png - images/decrypt-mail.png - images/inbox_22.png - images/blue_lock.png - images/blue_lock_open.png - images/d-chat64.png - images/edit_24.png - images/streaming.png - images/white-bubble-64.png - images/orange-bubble-64.png - images/stock_signature_bad.png - images/stock_signature_ok.png - images/stock_signature_missing.png - images/stock_signature_unverified.png - images/anonymous_128_blue.png - images/browsable_128_green.png - images/browsable_128_blue.png - images/blank_128_green.png - images/blank_128_blue.png - images/door_in.png - images/tor-logo.png - images/help/addafriend.png - images/help/addfriendkey.png - images/help/dhtgreen.png - icons/help_64.png - images/help/natgreen.png - images/help/natred.png - images/attach.png - images/pgp.png - images/rs_wizard.png - images/avatar_request.png - images/avatar_refused.png - images/avatar_request_unknown.png - images/backblue.png - images/backchat.png - images/buttonframe.png - images/btn1.png - images/btn2.png - images/btn3.png - images/btn4.png - images/btn_26.png - images/btn_26_hover.png - images/btn_26_pressed.png - images/btn_27.png - images/btn_27_hover.png - images/btn_blue.png - images/btn_blue_hover.png - images/btn_green.png - images/btn_green_hover.png - images/btn_green_pressed.png - images/connect_creating.png - images/dht16.png - images/dht32.png - images/edit-clear-history.png - images/edit_16.png - images/feedback_arrow.png - images/feedback_arrow_hover.png - images/firewall_24.png - images/list_bullet_arrow.png - images/rc_combined.png - images/combobox_arrow.png - images/arrow-left.png - images/arrow-right.png - help/authors.html - help/licence.html - help/thanks.html - images/accepted16.png - images/add_image24.png - images/add_channel64.png - images/add_channel24.png - images/add_channel32.png - images/admin-16.png - images/admin-32.png - images/admin-24.png - images/admin-48.png - images/user/add_group22.png - images/user/add_group256.png - images/user/edit_group64.png - images/avatarstatus-bg-116.png - images/avatarstatus-bg-online-116.png - images/avatarstatus-bg-idle-116.png - images/avatarstatus-bg-away-116.png - images/avatarstatus-bg-busy-116.png - images/avatarstatus-bg-offline-116.png - images/avatarstatus-bg-70.png - images/avatarstatus-bg-online-70.png - images/avatarstatus-bg-idle-70.png - images/avatarstatus-bg-away-70.png - images/avatarstatus-bg-busy-70.png - images/avatarstatus-bg-offline-70.png - images/browse-looking.gif - images/back.png - images/backgroundl.png - images/blockdevice.png - images/blockdevice2.png - images/configure.png - images/channels.png - images/turtle.png - images/channels16.png - images/channels24.png - images/channels32.png - images/channels_new.png - images/channelsred.png - images/channelsyellow.png - images/channelsgreen.png - images/channelsblue.png - images/copyrslink.png - images/contacts24.png - images/contactsclosed24.png - images/connection.png - images/contact_new.png - images/contact_new22.png - images/contact.png - images/contact22.png - images/Client0.png - images/Client1.png - images/Client2.png - images/Client3.png - images/Client4.png - images/closenormal.png - images/closehover.png - images/closepressed.png - images/denied16.png - images/filetype-association.png - images/FileTypeAny.png - images/FileTypeArchive.png - images/FileTypeAudio.png - images/FileTypeCDImage.png - images/FileTypeDocument.png - images/FileTypePicture.png - images/FileTypeProgram.png - images/FileTypeVideo.png - images/fonts.png - images/folder16.png - images/foldermail.png - images/folderopen.png - images/fileopen.png - images/graph-downloaded.png - images/graph-downloading.png - images/graph-notdownload.png - images/graph-checking.png - images/graph-blue.png - images/add-share24.png - images/add_24x24.png - images/advsearch_24x24.png - images/amsn16.png - images/attachment.png - images/avatar_background.png - images/backgroundimage.png - images/button_cancel.png - images/calendar.png - images/chat.png - images/chat_22.png - images/chat_24.png - images/chat_32.png - images/chat_64.png - images/chat_x24.png - images/chat_red24.png - images/cancel.png - images/close-down.png - images/close_normal.png - images/console-small-down.png - images/console-small-hover.png - images/console-small-up.png - images/contact_new128.png - images/copy.png - images/delete.png - images/deleteall.png - images/deletemail-pressed.png - images/deletemail24.png - images/directoryadd_24x24_shadow.png - images/directoryremove_24x24_shadow.png - images/directoryselect_24x24_shadow.png - images/diskSave.png - images/document_save.png - images/down.png - images/down_24x24.png - images/download.png - images/download16.png - images/edit_add24.png - images/edit-bold.png - images/edit-italic.png - images/edit-underline.png - images/edit_remove24.png - images/encrypted16.png - images/encrypted22.png - images/encrypted32.png - images/encrypted48.png - images/disabled_plugin_48.png - images/evolution.png - images/exit_24x24.png - images/exit_32.png - images/expand_frame.png - images/exportpeers_16x16.png - images/extension_32.png - images/filefind.png - images/fileinfo.png - images/filename.png - images/filepriority.png - images/filecomments.png - images/filerating0.png - images/filerating1.png - images/filerating2.png - images/filerating3.png - images/filerating4.png - images/filerating5.png - images/fileshare16.png - images/fileshare24.png - images/fileshare32.png - images/fileshare48.png - images/fileshare64.png - images/find.png - images/find-16.png - images/emoticons/kopete/kopete020.png - images/flags/af.png - images/flags/bg.png - images/flags/zh_CN.png - images/flags/zh_TW.png - images/flags/ca_ES.png - images/flags/cs.png - images/flags/de.png - images/flags/da.png - images/flags/el.png - images/flags/en.png - images/flags/es.png - images/flags/fi.png - images/flags/fr.png - images/flags/hu.png - images/flags/it.png - images/flags/ja_JP.png - images/flags/ko.png - images/flags/nl.png - images/flags/pl.png - images/flags/pt.png - images/flags/ru.png - images/flags/sv.png - images/flags/sl.png - images/flags/tr.png - images/folder-draft.png - images/folder-draft24-pressed.png - images/folder-draft24.png - images/folder_inbox64.png - images/folder-inbox.png - images/folder-inbox-new.png - images/folder-outbox.png - images/folder-sent.png - images/folder-trash.png - images/folder_doments.png - images/folder_green.png - images/folder_red.png - images/folder_grey.png - images/folder_yellow.png - images/folder_open.png - images/folder_video.png - images/folder_blueshared.png - images/forward.png - images/friendsfolder24.png - images/kgames.png - images/go-down.png - images/go-top.png - images/go-up.png - images/go-bottom.png - images/graph-area.png - images/graph-line.png - images/groupchat.png - images/genbackground.png - images/gohome.png - images/gpgp_key_generate.png - images/help.png - images/help24.png - images/hide_toolbox_frame.png - images/hide_frame.png - images/highlight.png - images/hi16-app-ktorrent.png - images/hi24-app-ktorrent.png - images/hot_0.png - images/hot_1.png - images/hot_2.png - images/hot_3.png - images/hot_4.png - images/hot_5.png - images/image16.png - images/imageblocked_24.png - images/info16.png - images/im-user.png - images/im-user-offline.png - images/im-user-away.png - images/im-user-busy.png - images/im-user-inactive.png - images/informations_24x24.png - images/connect_friend.png - images/kalarm.png - images/kbackgammon.png - images/kblogger.png - images/hi48-app-kblogger.png - images/hi64-app-kblogger.png - images/transfers_new.png - images/kcmsystem24.png - images/kdmconfig.png - images/konsole.png - images/newsfeed128.png - images/newsfeed128_notify.png - images/konversation.png - images/konversation16.png - images/konversation128.png - images/konv_message2.png - images/konv_message3.png - images/konv_message64.png - images/konversation64.png - images/forums_new.png - images/ksysguard.png - images/ksysguard32.png - images/ktorrent.png - images/ktorrent32.png - images/knewsticker24.png - images/library.png - images/loadcert16.png - images/ledoff1.png - images/ledon1.png - images/locale.png - images/looknfeel.png - images/lphoto.png - images/lphoto16.png - images/lphoto24.png - images/logo/logo_16.png - images/logo/logo_24.png - images/logo/logo_24_0.png - images/logo/logo_24_1.png - images/logo/logo_24_2.png - images/logo/logo_32.png - images/logo/logo_48.png - images/logo/logo_64.png - images/logo/logo_128.png - images/logo/logo_256.png - images/logo/logo_512.png - images/logo/logo_info.png - images/logo/logo_splash.png - images/logobar/logo_bar_fill.png - images/logobar/logo_bar_start.png - images/logobar/rslogo.png - images/logobar/rslogo2.png - images/mail-message-new.png - images/mail-signed.png - images/mail-signature-unknown.png - images/mail_delete.png - images/mail_get.png - images/mail_reply.png - images/mail_replyall.png - images/mail_forward.png - images/mail_send.png - images/mail_new.png - images/mail_send24.png - images/mailforward24-hover.png - images/message-mail.png - images/message-mail-read.png - images/message-mail-imapdelete.png - images/message-mail-replied-read.png - images/message-mail-forwarded-read.png - images/message-mail-replied.png - images/message-mail-forwarded.png - images/message-mail-replied-forw.png - images/message-mail-replied-forw-read.png - images/message-state-read.png - images/message-state-unread.png - images/message-state-header.png - images/message-state-new.png - images/message-news.png - images/message_new.png - images/message.png - images/messenger.png - images/mute-off-16.png - images/mute-on-16.png - images/my_documents_16.png - images/my_documents_22.png - images/network.png - images/network16.png - images/network32.png - images/new-mail-alert.png - images/new_forum16.png - images/newmsg.png - images/no_avatar_70.png - images/no_avatar_background.png - images/openimage.png - images/office-chart-area-stacked.png - images/office-chart-line.png - images/pasterslink.png - images/package_games1.png - images/pin32.png - images/print24.png - images/priorityauto.png - images/priorityhigh.png - images/prioritylow.png - images/prioritynormal.png - images/pause.png - images/preview.png - images/player_play.png - images/quick_restart24.png - images/quote_24.png - images/redled.png - images/greenled.png - images/grayled.png - images/yellowled.png - images/rate-1.png - images/rate-2.png - images/rate-3.png - images/rate-4.png - images/rate-5.png - images/rating.png - images/records.png - images/replymail-pressed.png - images/replymail24.png - images/replymailall24-hover.png - images/reset.png - images/resume.png - images/security-high-16.png - images/security-high-48.png - images/security-low-48.png - images/security-medium-48.png - images/security-high-off-48.png - images/security-low-off-48.png - images/security-medium-off-48.png - images/save24.png - images/send24.png - images/settings.png - images/settings16.png - images/show_toolbox_frame.png - images/start.png - images/stop.png - images/star-on-16.png - images/star-off-16.png - images/StatsCumulative.png - images/StatisticsDetail.png - images/status_unknown.png - images/startall.png - images/server_24x24.png - images/sort_incr.png - images/sort_decrease.png - images/sound.png - images/tab-dock.png - images/tab-undock.png - images/tab-new.png - images/tag24.png - images/transferupdown.png - images/tools_wizard.png - images/typing.png - images/trustsettings.png - images/uploads.png - images/headerFrame.png - images/loader/indicator-16.gif - images/loader/indicator-32.gif - images/loader/circleball-16.gif - images/loader/progress.gif - images/mimetypes/pdf.png - images/mimetypes/rscollection-16.png - images/mimetypes/patch.png - images/mimetypes/source_c.png - images/mimetypes/source_cpp.png - images/mimetypes/source_h.png - images/view-certificate-copy-32.png - images/view-certificate-export-32.png - images/textedit/textbold.png - images/textedit/textitalic.png - images/textedit/textunder.png - images/textedit/textjustify.png - images/textedit/textcenter.png - images/textedit/textleft.png - images/textedit/textright.png - images/textedit/editcopy.png - images/textedit/editcut.png - images/textedit/editpaste.png - images/textedit/editredo.png - images/textedit/editundo.png - images/textedit/exportpdf.png - images/textedit/filenew.png - images/textedit/fileopen.png - images/textedit/fileprint.png - images/textedit/filesave.png - images/textedit/format-text-color.png - images/textedit/format-list-ordered.png - images/textedit/format-list-unordered.png - images/textedit/zoomin.png - images/textedit/zoomout.png - images/textedit/format_font_size_more.png - images/textedit/format_font_size_less.png - images/textedit/hi22-action-format-text-blockquote.png - images/textedit/hi22-action-format-text-code.png - images/textedit/hi22-action-insert-more-mark.png - images/toaster/chat.png - images/toaster/hangup.png - images/toaster/pickup.png - images/toaster/backgroundtoaster.png - images/thumb-default-video.png - images/user/add_user24.png - images/user/add_user48.png - images/user/remove_user24.png - images/user/deny_user48.png - images/user/friends24.png - images/user/friends32.png - images/user/friends64.png - images/user/friends24_notify.png - images/user/friend_suggestion16.png - images/user/identity16.png - images/user/identity24.png - images/user/identity24_low.png - images/user/identity32.png - images/user/identity48.png - images/user/identityinfo48.png - images/user/identityinfo64.png - images/user/identityoffline24.png - images/user/identity24away.png - images/user/identity24busy.png - images/user/identity24idle.png - images/user/identityavaiblecyan24.png - images/user/invite24.png - images/user/agt_forum24.png - images/user/agt_forum32.png - images/user/identitygray16.png - images/user/add_user16.png - images/user/personal64.png - images/user/personal128.png - images/user/kuser24.png - images/user/agt_forum64.png - images/user/agt_forum128.png - images/user/group16.png - images/user/group24.png - images/user/servicepermissions64.png - images/user/user_request16.png - images/user/user_request48.png - images/user/user_request_unknown48.png - images/up.png - images/up0down0.png - images/up0down1.png - images/up1down1.png - images/up1down0.png - images/underconstruction.png - images/user.png - images/view-certificate-sign-32.png - images/view_calendar_day.png - images/view_calendar_week.png - images/view_calendar_month.png - images/view_calendar_list.png - images/view_split_top_bottom.png - images/vote_up.png - images/vote_down.png - images/vote_neutral.png - images/window_fullscreen.png - images/window_nofullscreen.png - images/identity/identities_32.png - images/identity/identity_64.png - images/identity/identity_create_32.png - images/identity/identity_create_64.png - images/identity/identity_delete_32.png - images/identity/identity_edit_32.png - images/identity/identity_edit_64.png - qss/chat/standard/private/info.xml - qss/chat/standard/private/incoming.htm - qss/chat/standard/private/outgoing.htm - qss/chat/standard/private/hincoming.htm - qss/chat/standard/private/houtgoing.htm - qss/chat/standard/private/ooutgoing.htm - qss/chat/standard/private/system.htm - qss/chat/standard/private/main.css - qss/chat/standard/private/variants/Standard.css - qss/chat/standard/public/info.xml - qss/chat/standard/public/incoming.htm - qss/chat/standard/public/outgoing.htm - qss/chat/standard/public/hincoming.htm - qss/chat/standard/public/houtgoing.htm - qss/chat/standard/public/ooutgoing.htm - qss/chat/standard/public/system.htm - qss/chat/standard/public/main.css - qss/chat/standard/public/variants/Standard.css - qss/chat/standard/history/info.xml - qss/chat/standard/history/incoming.htm - qss/chat/standard/history/outgoing.htm - qss/chat/standard/history/hincoming.htm - qss/chat/standard/history/houtgoing.htm - qss/chat/standard/history/ooutgoing.htm - qss/chat/standard/history/system.htm - qss/chat/standard/history/main.css - qss/chat/standard/history/variants/Standard.css - qss/chat/compact/private/info.xml - qss/chat/compact/private/incoming.htm - qss/chat/compact/private/outgoing.htm - qss/chat/compact/private/hincoming.htm - qss/chat/compact/private/houtgoing.htm - qss/chat/compact/private/ooutgoing.htm - qss/chat/compact/private/system.htm - qss/chat/compact/private/main.css - qss/chat/compact/private/variants/Standard.css - qss/chat/compact/private/variants/Colored.css - qss/chat/compact/public/info.xml - qss/chat/compact/public/incoming.htm - qss/chat/compact/public/outgoing.htm - qss/chat/compact/public/hincoming.htm - qss/chat/compact/public/houtgoing.htm - qss/chat/compact/public/ooutgoing.htm - qss/chat/compact/public/system.htm - qss/chat/compact/public/main.css - qss/chat/compact/public/variants/Standard.css - qss/chat/compact/public/variants/Colored.css - qss/chat/compact/history/info.xml - qss/chat/compact/history/incoming.htm - qss/chat/compact/history/outgoing.htm - qss/chat/compact/history/hincoming.htm - qss/chat/compact/history/houtgoing.htm - qss/chat/compact/history/ooutgoing.htm - qss/chat/compact/history/system.htm - qss/chat/compact/history/main.css - qss/chat/compact/history/variants/Standard.css - qss/chat/compact/history/variants/Colored.css - qss/stylesheet/qss.default - qss/stylesheet/Standard.qss - images/connect/connectFriendWatermark.png - images/connect/connectFriendLogo.png - images/connect/connectFriendBanner.png - images/connect/connectFriendBanner1.png - images/connect/info16.png - images/connect/mail_send.png - images/tags/pgp-known.png - images/tags/pgp-unknown.png - images/tags/anon.png - images/tags/dev-ambassador.png - images/tags/dev-translator.png - images/tags/dev-patcher.png - images/tags/developer.png - images/circles/circles_32.png - images/circles/circles_64.png - images/newsfeed/news-feed-32.png - images/newsfeed/news-feed-notify-32.png - images/share-icon-16.png - help/version.html - images/view-certificate-sign-48.png - images/toasterEnable.png - images/toasterDisable.png - images/library_edit.png - images/library_view.png - images/library_add.png - images/library64.png - images/library16.png - images/btn_red_pressed.png - images/btn_red_hover.png - images/btn_red.png - images/view-feeds.png - images/view-files.png - images/emblem-web.png - images/rsmessenger16.png - images/rsmessenger32.png - images/rsmessenger48.png - images/SmileyText.png - images/SimpleText.png - images/ColoredText.png - + + images/logo/logo_spash2.png + images/network_map.png + images/global_switch_on.png + images/global_switch_off.png + images/switch00.png + images/switch01.png + images/switch10.png + images/switch11.png + images/add_chat24.png + images/RSS_004_32.png + images/mail-encrypted-full.png + images/mail-signed-full.png + images/document-edit-sign.png + images/decrypt-mail.png + images/inbox_22.png + images/blue_lock.png + images/blue_lock_open.png + images/d-chat64.png + images/edit_24.png + images/streaming.png + images/white-bubble-64.png + images/orange-bubble-64.png + images/stock_signature_bad.png + images/stock_signature_ok.png + images/stock_signature_missing.png + images/stock_signature_unverified.png + images/anonymous_128_blue.png + images/browsable_128_green.png + images/browsable_128_blue.png + images/blank_128_green.png + images/blank_128_blue.png + images/door_in.png + images/tor-logo.png + images/help/addafriend.png + images/help/addfriendkey.png + images/help/dhtgreen.png + icons/help_64.png + images/help/natgreen.png + images/help/natred.png + images/attach.png + images/pgp.png + images/rs_wizard.png + images/avatar_request.png + images/avatar_refused.png + images/avatar_request_unknown.png + images/backblue.png + images/backchat.png + images/buttonframe.png + images/btn1.png + images/btn2.png + images/btn3.png + images/btn4.png + images/btn_26.png + images/btn_26_hover.png + images/btn_26_pressed.png + images/btn_27.png + images/btn_27_hover.png + images/btn_blue.png + images/btn_blue_hover.png + images/btn_green.png + images/btn_green_hover.png + images/btn_green_pressed.png + images/connect_creating.png + images/dht16.png + images/dht32.png + images/edit-clear-history.png + images/edit_16.png + images/feedback_arrow.png + images/feedback_arrow_hover.png + images/firewall_24.png + images/list_bullet_arrow.png + images/rc_combined.png + images/combobox_arrow.png + images/arrow-left.png + images/arrow-right.png + help/authors.html + help/licence.html + help/thanks.html + images/accepted16.png + images/add_image24.png + images/add_channel64.png + images/add_channel24.png + images/add_channel32.png + images/admin-16.png + images/admin-32.png + images/admin-24.png + images/admin-48.png + images/user/add_group22.png + images/user/add_group256.png + images/user/edit_group64.png + images/avatarstatus-bg-116.png + images/avatarstatus-bg-online-116.png + images/avatarstatus-bg-idle-116.png + images/avatarstatus-bg-away-116.png + images/avatarstatus-bg-busy-116.png + images/avatarstatus-bg-offline-116.png + images/avatarstatus-bg-70.png + images/avatarstatus-bg-online-70.png + images/avatarstatus-bg-idle-70.png + images/avatarstatus-bg-away-70.png + images/avatarstatus-bg-busy-70.png + images/avatarstatus-bg-offline-70.png + images/browse-looking.gif + images/back.png + images/backgroundl.png + images/blockdevice.png + images/blockdevice2.png + images/configure.png + images/channels.png + images/turtle.png + images/channels16.png + images/channels24.png + images/channels32.png + images/channels_new.png + images/channelsred.png + images/channelsyellow.png + images/channelsgreen.png + images/channelsblue.png + images/copyrslink.png + images/contacts24.png + images/contactsclosed24.png + images/connection.png + images/contact_new.png + images/contact_new22.png + images/contact.png + images/contact22.png + images/Client0.png + images/Client1.png + images/Client2.png + images/Client3.png + images/Client4.png + images/closenormal.png + images/closehover.png + images/closepressed.png + images/denied16.png + images/filetype-association.png + images/FileTypeAny.png + images/FileTypeArchive.png + images/FileTypeAudio.png + images/FileTypeCDImage.png + images/FileTypeDocument.png + images/FileTypePicture.png + images/FileTypeProgram.png + images/FileTypeVideo.png + images/fonts.png + images/folder16.png + images/foldermail.png + images/folderopen.png + images/fileopen.png + images/graph-downloaded.png + images/graph-downloading.png + images/graph-notdownload.png + images/graph-checking.png + images/graph-blue.png + images/add-share24.png + images/add_24x24.png + images/advsearch_24x24.png + images/amsn16.png + images/attachment.png + images/avatar_background.png + images/backgroundimage.png + images/button_cancel.png + images/calendar.png + images/chat.png + images/chat_22.png + images/chat_24.png + images/chat_32.png + images/chat_64.png + images/chat_x24.png + images/chat_red24.png + images/cancel.png + images/close-down.png + images/close_normal.png + images/console-small-down.png + images/console-small-hover.png + images/console-small-up.png + images/contact_new128.png + images/copy.png + images/delete.png + images/deleteall.png + images/deletemail-pressed.png + images/deletemail24.png + images/directoryadd_24x24_shadow.png + images/directoryremove_24x24_shadow.png + images/directoryselect_24x24_shadow.png + images/diskSave.png + images/document_save.png + images/down.png + images/down_24x24.png + images/download.png + images/download16.png + images/edit_add24.png + images/edit-bold.png + images/edit-italic.png + images/edit-underline.png + images/edit_remove24.png + images/encrypted16.png + images/encrypted22.png + images/encrypted32.png + images/encrypted48.png + images/disabled_plugin_48.png + images/evolution.png + images/exit_24x24.png + images/exit_32.png + images/expand_frame.png + images/exportpeers_16x16.png + images/extension_32.png + images/filefind.png + images/fileinfo.png + images/filename.png + images/filepriority.png + images/filecomments.png + images/filerating0.png + images/filerating1.png + images/filerating2.png + images/filerating3.png + images/filerating4.png + images/filerating5.png + images/fileshare16.png + images/fileshare24.png + images/fileshare32.png + images/fileshare48.png + images/fileshare64.png + images/find.png + images/find-16.png + images/emoticons/kopete/kopete020.png + images/flags/af.png + images/flags/bg.png + images/flags/zh_CN.png + images/flags/zh_TW.png + images/flags/ca_ES.png + images/flags/cs.png + images/flags/de.png + images/flags/da.png + images/flags/el.png + images/flags/en.png + images/flags/es.png + images/flags/fi.png + images/flags/fr.png + images/flags/hu.png + images/flags/it.png + images/flags/ja_JP.png + images/flags/ko.png + images/flags/nl.png + images/flags/pl.png + images/flags/pt.png + images/flags/ru.png + images/flags/sv.png + images/flags/sl.png + images/flags/tr.png + images/folder-draft.png + images/folder-draft24-pressed.png + images/folder-draft24.png + images/folder_inbox64.png + images/folder-inbox.png + images/folder-inbox-new.png + images/folder-outbox.png + images/folder-sent.png + images/folder-trash.png + images/folder_doments.png + images/folder_green.png + images/folder_red.png + images/folder_grey.png + images/folder_yellow.png + images/folder_open.png + images/folder_video.png + images/folder_blueshared.png + images/forward.png + images/friendsfolder24.png + images/kgames.png + images/go-down.png + images/go-top.png + images/go-up.png + images/go-bottom.png + images/graph-area.png + images/graph-line.png + images/groupchat.png + images/genbackground.png + images/gohome.png + images/gpgp_key_generate.png + images/help.png + images/help24.png + images/hide_toolbox_frame.png + images/hide_frame.png + images/highlight.png + images/hi16-app-ktorrent.png + images/hi24-app-ktorrent.png + images/hot_0.png + images/hot_1.png + images/hot_2.png + images/hot_3.png + images/hot_4.png + images/hot_5.png + images/image16.png + images/imageblocked_24.png + images/info16.png + images/im-user.png + images/im-user-offline.png + images/im-user-away.png + images/im-user-busy.png + images/im-user-inactive.png + images/informations_24x24.png + images/connect_friend.png + images/kalarm.png + images/kbackgammon.png + images/kblogger.png + images/hi48-app-kblogger.png + images/hi64-app-kblogger.png + images/transfers_new.png + images/kcmsystem24.png + images/kdmconfig.png + images/konsole.png + images/newsfeed128.png + images/newsfeed128_notify.png + images/konversation.png + images/konversation16.png + images/konversation128.png + images/konv_message2.png + images/konv_message3.png + images/konv_message64.png + images/konversation64.png + images/forums_new.png + images/ksysguard.png + images/ksysguard32.png + images/ktorrent.png + images/ktorrent32.png + images/knewsticker24.png + images/library.png + images/loadcert16.png + images/ledoff1.png + images/ledon1.png + images/locale.png + images/looknfeel.png + images/lphoto.png + images/lphoto16.png + images/lphoto24.png + images/logo/logo_16.png + images/logo/logo_24.png + images/logo/logo_24_0.png + images/logo/logo_24_1.png + images/logo/logo_24_2.png + images/logo/logo_32.png + images/logo/logo_48.png + images/logo/logo_64.png + images/logo/logo_128.png + images/logo/logo_256.png + images/logo/logo_512.png + images/logo/logo_info.png + images/logo/logo_splash.png + images/logobar/logo_bar_fill.png + images/logobar/logo_bar_start.png + images/logobar/rslogo.png + images/logobar/rslogo2.png + images/mail-message-new.png + images/mail-signed.png + images/mail-signature-unknown.png + images/mail_delete.png + images/mail_get.png + images/mail_reply.png + images/mail_replyall.png + images/mail_forward.png + images/mail_send.png + images/mail_new.png + images/mail_send24.png + images/mailforward24-hover.png + images/message-mail.png + images/message-mail-read.png + images/message-mail-imapdelete.png + images/message-mail-replied-read.png + images/message-mail-forwarded-read.png + images/message-mail-replied.png + images/message-mail-forwarded.png + images/message-mail-replied-forw.png + images/message-mail-replied-forw-read.png + images/message-state-read.png + images/message-state-unread.png + images/message-state-header.png + images/message-state-new.png + images/message-news.png + images/message_new.png + images/message.png + images/messenger.png + images/mute-off-16.png + images/mute-on-16.png + images/my_documents_16.png + images/my_documents_22.png + images/network.png + images/network16.png + images/network32.png + images/new-mail-alert.png + images/new_forum16.png + images/newmsg.png + images/no_avatar_70.png + images/no_avatar_background.png + images/openimage.png + images/office-chart-area-stacked.png + images/office-chart-line.png + images/pasterslink.png + images/package_games1.png + images/pin32.png + images/print24.png + images/priorityauto.png + images/priorityhigh.png + images/prioritylow.png + images/prioritynormal.png + images/pause.png + images/preview.png + images/player_play.png + images/quick_restart24.png + images/quote_24.png + images/redled.png + images/greenled.png + images/grayled.png + images/yellowled.png + images/rate-1.png + images/rate-2.png + images/rate-3.png + images/rate-4.png + images/rate-5.png + images/rating.png + images/records.png + images/replymail-pressed.png + images/replymail24.png + images/replymailall24-hover.png + images/reset.png + images/resume.png + images/security-high-16.png + images/security-high-48.png + images/security-low-48.png + images/security-medium-48.png + images/security-high-off-48.png + images/security-low-off-48.png + images/security-medium-off-48.png + images/save24.png + images/send24.png + images/settings.png + images/settings16.png + images/show_toolbox_frame.png + images/start.png + images/stop.png + images/star-on-16.png + images/star-off-16.png + images/StatsCumulative.png + images/StatisticsDetail.png + images/status_unknown.png + images/startall.png + images/server_24x24.png + images/sort_incr.png + images/sort_decrease.png + images/sound.png + images/tab-dock.png + images/tab-undock.png + images/tab-new.png + images/tag24.png + images/transferupdown.png + images/tools_wizard.png + images/typing.png + images/trustsettings.png + images/uploads.png + images/headerFrame.png + images/loader/indicator-16.gif + images/loader/indicator-32.gif + images/loader/circleball-16.gif + images/loader/progress.gif + images/mimetypes/pdf.png + images/mimetypes/rscollection-16.png + images/mimetypes/patch.png + images/mimetypes/source_c.png + images/mimetypes/source_cpp.png + images/mimetypes/source_h.png + images/view-certificate-copy-32.png + images/view-certificate-export-32.png + images/textedit/textbold.png + images/textedit/textitalic.png + images/textedit/textunder.png + images/textedit/textjustify.png + images/textedit/textcenter.png + images/textedit/textleft.png + images/textedit/textright.png + images/textedit/editcopy.png + images/textedit/editcut.png + images/textedit/editpaste.png + images/textedit/editredo.png + images/textedit/editundo.png + images/textedit/exportpdf.png + images/textedit/filenew.png + images/textedit/fileopen.png + images/textedit/fileprint.png + images/textedit/filesave.png + images/textedit/format-text-color.png + images/textedit/format-list-ordered.png + images/textedit/format-list-unordered.png + images/textedit/zoomin.png + images/textedit/zoomout.png + images/textedit/format_font_size_more.png + images/textedit/format_font_size_less.png + images/textedit/hi22-action-format-text-blockquote.png + images/textedit/hi22-action-format-text-code.png + images/textedit/hi22-action-insert-more-mark.png + images/toaster/chat.png + images/toaster/hangup.png + images/toaster/pickup.png + images/toaster/backgroundtoaster.png + images/thumb-default-video.png + images/user/add_user24.png + images/user/add_user48.png + images/user/remove_user24.png + images/user/deny_user48.png + images/user/friends24.png + images/user/friends32.png + images/user/friends64.png + images/user/friends24_notify.png + images/user/friend_suggestion16.png + images/user/identity16.png + images/user/identity24.png + images/user/identity24_low.png + images/user/identity32.png + images/user/identity48.png + images/user/identityinfo48.png + images/user/identityinfo64.png + images/user/identityoffline24.png + images/user/identity24away.png + images/user/identity24busy.png + images/user/identity24idle.png + images/user/identityavaiblecyan24.png + images/user/invite24.png + images/user/agt_forum24.png + images/user/agt_forum32.png + images/user/identitygray16.png + images/user/add_user16.png + images/user/personal64.png + images/user/personal128.png + images/user/kuser24.png + images/user/agt_forum64.png + images/user/agt_forum128.png + images/user/group16.png + images/user/group24.png + images/user/servicepermissions64.png + images/user/user_request16.png + images/user/user_request48.png + images/user/user_request_unknown48.png + images/up.png + images/up0down0.png + images/up0down1.png + images/up1down1.png + images/up1down0.png + images/underconstruction.png + images/user.png + images/view-certificate-sign-32.png + images/view_calendar_day.png + images/view_calendar_week.png + images/view_calendar_month.png + images/view_calendar_list.png + images/view_split_top_bottom.png + images/vote_up.png + images/vote_down.png + images/vote_neutral.png + images/window_fullscreen.png + images/window_nofullscreen.png + images/identity/identities_32.png + images/identity/identity_64.png + images/identity/identity_create_32.png + images/identity/identity_create_64.png + images/identity/identity_delete_32.png + images/identity/identity_edit_32.png + images/identity/identity_edit_64.png + qss/chat/standard/private/info.xml + qss/chat/standard/private/incoming.htm + qss/chat/standard/private/outgoing.htm + qss/chat/standard/private/hincoming.htm + qss/chat/standard/private/houtgoing.htm + qss/chat/standard/private/ooutgoing.htm + qss/chat/standard/private/system.htm + qss/chat/standard/private/main.css + qss/chat/standard/private/variants/Standard.css + qss/chat/standard/public/info.xml + qss/chat/standard/public/incoming.htm + qss/chat/standard/public/outgoing.htm + qss/chat/standard/public/hincoming.htm + qss/chat/standard/public/houtgoing.htm + qss/chat/standard/public/ooutgoing.htm + qss/chat/standard/public/system.htm + qss/chat/standard/public/main.css + qss/chat/standard/public/variants/Standard.css + qss/chat/standard/history/info.xml + qss/chat/standard/history/incoming.htm + qss/chat/standard/history/outgoing.htm + qss/chat/standard/history/hincoming.htm + qss/chat/standard/history/houtgoing.htm + qss/chat/standard/history/ooutgoing.htm + qss/chat/standard/history/system.htm + qss/chat/standard/history/main.css + qss/chat/standard/history/variants/Standard.css + qss/chat/compact/private/info.xml + qss/chat/compact/private/incoming.htm + qss/chat/compact/private/outgoing.htm + qss/chat/compact/private/hincoming.htm + qss/chat/compact/private/houtgoing.htm + qss/chat/compact/private/ooutgoing.htm + qss/chat/compact/private/system.htm + qss/chat/compact/private/main.css + qss/chat/compact/private/variants/Standard.css + qss/chat/compact/private/variants/Colored.css + qss/chat/compact/public/info.xml + qss/chat/compact/public/incoming.htm + qss/chat/compact/public/outgoing.htm + qss/chat/compact/public/hincoming.htm + qss/chat/compact/public/houtgoing.htm + qss/chat/compact/public/ooutgoing.htm + qss/chat/compact/public/system.htm + qss/chat/compact/public/main.css + qss/chat/compact/public/variants/Standard.css + qss/chat/compact/public/variants/Colored.css + qss/chat/compact/history/info.xml + qss/chat/compact/history/incoming.htm + qss/chat/compact/history/outgoing.htm + qss/chat/compact/history/hincoming.htm + qss/chat/compact/history/houtgoing.htm + qss/chat/compact/history/ooutgoing.htm + qss/chat/compact/history/system.htm + qss/chat/compact/history/main.css + qss/chat/compact/history/variants/Standard.css + qss/chat/compact/history/variants/Colored.css + qss/stylesheet/qss.default + qss/stylesheet/Standard.qss + images/connect/connectFriendWatermark.png + images/connect/connectFriendLogo.png + images/connect/connectFriendBanner.png + images/connect/connectFriendBanner1.png + images/connect/info16.png + images/connect/mail_send.png + images/tags/pgp-known.png + images/tags/pgp-unknown.png + images/tags/anon.png + images/tags/dev-ambassador.png + images/tags/dev-translator.png + images/tags/dev-patcher.png + images/tags/developer.png + images/circles/circles_32.png + images/circles/circles_64.png + images/newsfeed/news-feed-32.png + images/newsfeed/news-feed-notify-32.png + images/share-icon-16.png + help/version.html + images/view-certificate-sign-48.png + images/toasterEnable.png + images/toasterDisable.png + images/library_edit.png + images/library_view.png + images/library_add.png + images/library64.png + images/library16.png + images/btn_red_pressed.png + images/btn_red_hover.png + images/btn_red.png + images/view-feeds.png + images/view-files.png + images/emblem-web.png + images/rsmessenger16.png + images/rsmessenger32.png + images/rsmessenger48.png + images/SmileyText.png + images/SimpleText.png + images/ColoredText.png + diff --git a/retroshare-gui/src/gui/images/cancel.png b/retroshare-gui/src/gui/images/cancel.png index e2db55f22d6752e10a57f07e286081ebebacfea5..87cd0b0125d6193c16c59f25b88396493e885f6b 100644 GIT binary patch delta 626 zcmbQi*1$SJvYwfNfk8u;KNv_c7dv@|aBy(ke(3)I$mJ~Xh%9DcVB8JDj8<>t*I;7bhncr0V4trO$q6BL!3~9^ez=`v3p`1_p)|3=C@- z7}^;ax)>NHGBC_wV3@RV8~-&$Yo&2VqjRrz%Wf)yIxML zNk#fnMd@KL&yxwUbLD0Bn`j+%w_hSJyhL7fiK5gJWx1ttLd)a?R;!4wSC`&wsJ2;K zexH~9VK0XhKF+7Yd>WJ$8%}w#rhL&r(*XwlRuSl!;c9-pjzSkAY#orE&d1 zL9Ro_#)o`84qI6rwKO^=#B*GT=cJw8X&3v`eqLwX+%7OMToB^992RytJmhj}!j+`B zYYDN}lM`kPYraQ8tFbY(tBE5_$)W~Sy}1J-p=iu=wVMs0a*6lae66V1{}lBO?zm@bvWb^7ao147zar?!70^UVZxV z^%o5M27y07@b~ZEfB&xL-Ae)*Fx%6`F+@VL_n@m-69WV50e+1eN@eBcN$g4G&;OoZ z_@U%HkI2G1Y&DW|L{gS~pLvn#*O$}oPDyv;)@d%@S+MWUnh6;~!r6rr_0J!v3}TiP zmj2Sd_M*wT2km`jv);P39Gh=-=K8Ceh+g@r^*SZhhb$H}`H087pLX?B)^^UB3LD?w z|E_d;s@(f#UZF$9XErfRx31(k!O_kdKc~AvNZxs~aQ62tX(>Q=GI+ZBxvXf delta 780 zcmV+n1M~cV1(*hq8Gi-<001BJ|6u?C0^dnQK~y-6rIF8XlLZ{cKi{`M*KTWR*LIyV zOM#7*DZ@=SF_3}AQA3P|gNg^^%|8H7{u4T5;)N3sh*3r~9Q0sBM3RX=h7k4($wr!W zUAMOD_O^Z7zVFuqJ$Uy?p2Kr^o;=A%RF(fDF~ob^L^ zH>W3RaM#t*fdMUmmp>n$oF`v` z);GWW<6T{X8-LfagArUWy~x7#3tYQ*U;M!9W0N|Xd56Y>dw6NVP@4PMEslKs#fSj7 z!@bq{RDZ|F(lUi+9ee>|JyA+;y-hurBRMxmp;CdWNzChEEgUAbv5jI00Q-_DfCrBw zQLTgC1pOJbJebx(GO4#fZ-Z7r7eRrwu3!}WegvSSe}9l#c7+(s&31K8ly~>o09XWHdDZnkp~*aF;j$D!ITe-Q6e zE5FW)!hazk*1n$uij^G>npNJ9C-le7yZ~4zM$>Ll2lrGks74{jp2A_CIxsel|JX5} z2U0-MZqivSF%=DI4FWAkF`A7=^pj6NYj&F^B~=F6D9{fS zS`9+mJA8chU9+i9A9v2Y$E}`j{TuWVs0Df@9)HuU&%OLZD8P+yfK`v{&nt;uZGk=p zUFr_%@5x@B5y5a!R7AFc1H);q4G;5bq430pAqPQ4uwiVfm|y%Vo*5 zPy`#n2ALh&&$;PS*vf#Tineh%3bv!^vqJ-Xn?8sGq9QmV{0nAcK6qK?z8e4l002ov KP6b4+LSTX`Yi$Pr diff --git a/retroshare-gui/src/gui/images/logo/logo_spash2.png b/retroshare-gui/src/gui/images/logo/logo_spash2.png new file mode 100644 index 0000000000000000000000000000000000000000..dab5aa9381d067df268a5f8fac5d2811c40d0dbe GIT binary patch literal 102946 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 z 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�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

pLiP5elc| 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 Date: Mon, 24 Apr 2017 16:00:23 +0200 Subject: [PATCH 105/118] Changed: difference time to absolute time. --- libresapi/src/api/IdentityHandler.cpp | 5 ++--- libresapi/src/api/PeersHandler.cpp | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 1306f9a54..be2e28622 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -418,8 +418,7 @@ void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) } resp.mDataStream << makeKeyValue("pgp_name", pgp_name); - time_t now = time(NULL); - resp.mDataStream << makeKeyValue("last_usage", difftime(now, data.mLastUsageTS)); + resp.mDataStream << makeKeyValue("last_usage", (uint32_t)data.mLastUsageTS); bool isAnonymous = false; if(!data.mPgpKnown) @@ -475,7 +474,7 @@ void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) for(std::map::const_iterator it(details.mUseCases.begin()); it != details.mUseCases.end(); ++it) { usagesStream.getStreamToMember() - << makeKeyValue("usage_time", difftime(now, data.mLastUsageTS)) + << makeKeyValue("usage_time", (uint32_t)data.mLastUsageTS) << makeKeyValue("usage_service", (int)(it->first.mServiceId)) << makeKeyValue("usage_case", (int)(it->first.mUsageCode)); } diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index dd03f8351..6649acdcb 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -7,7 +7,6 @@ #include #include -#include #include "Operators.h" #include "ApiTypes.h" @@ -746,12 +745,11 @@ void PeersHandler::handleGetNodeOptions(Request& req, Response& resp) return; } - time_t now = time(NULL); resp.mDataStream << makeKeyValue("peer_id", detail.id.toStdString()); resp.mDataStream << makeKeyValue("name", detail.name); resp.mDataStream << makeKeyValue("location", detail.location); resp.mDataStream << makeKeyValue("pgp_id", detail.gpg_id.toStdString()); - resp.mDataStream << makeKeyValue("last_contact", difftime(now, detail.lastConnect)); + resp.mDataStream << makeKeyValue("last_contact", detail.lastConnect); std::string status_message = mRsMsgs->getCustomStateString(detail.id); resp.mDataStream << makeKeyValueReference("status_message", status_message); From 13275820961a0509a38bc4e028f3bdb5b44041ca Mon Sep 17 00:00:00 2001 From: Phenom Date: Mon, 24 Apr 2017 17:28:25 +0200 Subject: [PATCH 106/118] Fix Relay setting values Was multiply by 1024 then divide by 1000. --- retroshare-gui/src/gui/settings/RelayPage.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/gui/settings/RelayPage.cpp b/retroshare-gui/src/gui/settings/RelayPage.cpp index 3124f40db..d26550c8b 100644 --- a/retroshare-gui/src/gui/settings/RelayPage.cpp +++ b/retroshare-gui/src/gui/settings/RelayPage.cpp @@ -129,15 +129,15 @@ void RelayPage::load() uint32_t bandwidth; rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_FRIENDS, count, bandwidth); whileBlocking(ui.noFriendSpinBox)->setValue(count); - whileBlocking(ui.bandFriendSpinBox)->setValue(bandwidth / 1000); + whileBlocking(ui.bandFriendSpinBox)->setValue(bandwidth / 1024); rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_FOF, count, bandwidth); whileBlocking(ui.noFOFSpinBox)->setValue(count); - whileBlocking(ui.bandFOFSpinBox)->setValue(bandwidth / 1000); + whileBlocking(ui.bandFOFSpinBox)->setValue(bandwidth / 1024); rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_GENERAL, count, bandwidth); whileBlocking(ui.noGeneralSpinBox)->setValue(count); - whileBlocking(ui.bandGeneralSpinBox)->setValue(bandwidth / 1000); + whileBlocking(ui.bandGeneralSpinBox)->setValue(bandwidth / 1024); updateTotals(); From 6e42cf420015a84d45b22050b1ff2dc76abd85a6 Mon Sep 17 00:00:00 2001 From: Phenom Date: Tue, 18 Apr 2017 11:56:25 +0200 Subject: [PATCH 107/118] Fix Clang warnings: field 'mPassword' will be initialized after field 'mPrevIsBad' warning: field 'mPassword' will be initialized after field 'mPrevIsBad' [-Wreorder] --- libresapi/src/api/RsControlModule.cpp | 4 ++-- libresapi/src/api/RsControlModule.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libresapi/src/api/RsControlModule.cpp b/libresapi/src/api/RsControlModule.cpp index cb3cdcdf2..ece94b7af 100644 --- a/libresapi/src/api/RsControlModule.cpp +++ b/libresapi/src/api/RsControlModule.cpp @@ -25,8 +25,8 @@ RsControlModule::RsControlModule(int argc, char **argv, StateTokenServer* sts, A mRunState(WAITING_INIT), mAutoLoginNextTime(false), mWantPassword(false), - mPassword(""), - mPrevIsBad(false) + mPrevIsBad(false), + mPassword("") { mStateToken = sts->getNewToken(); this->argc = argc; diff --git a/libresapi/src/api/RsControlModule.h b/libresapi/src/api/RsControlModule.h index 7e306405c..8b8b1f3f0 100644 --- a/libresapi/src/api/RsControlModule.h +++ b/libresapi/src/api/RsControlModule.h @@ -77,7 +77,7 @@ private: // to notify that a password callback is waiting // to answer the request, clear the flag and set the password bool mWantPassword; - bool mPrevIsBad; + bool mPrevIsBad ; std::string mTitle; std::string mKeyName; std::string mPassword; From 490f8d2f5462b3b4dc639b975a752703077566a3 Mon Sep 17 00:00:00 2001 From: Phenom Date: Tue, 18 Apr 2017 12:00:00 +0200 Subject: [PATCH 108/118] Fix Clang warnings: 'TYPE_IDENTITY' not handled warning: enumeration value 'TYPE_IDENTITY' not handled in switch [- Wswitch] --- retroshare-gui/src/util/HandleRichText.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index 73801bd5b..c5f578d3a 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -230,12 +230,13 @@ bool RsHtml::canReplaceAnchor(QDomDocument &/*doc*/, QDomElement &/*element*/, c case RetroShareLink::TYPE_PERSON: case RetroShareLink::TYPE_FORUM: case RetroShareLink::TYPE_CHANNEL: - case RetroShareLink::TYPE_POSTED: case RetroShareLink::TYPE_SEARCH: case RetroShareLink::TYPE_MESSAGE: case RetroShareLink::TYPE_EXTRAFILE: case RetroShareLink::TYPE_PRIVATE_CHAT: case RetroShareLink::TYPE_PUBLIC_MSG: + case RetroShareLink::TYPE_POSTED: + case RetroShareLink::TYPE_IDENTITY: // not yet implemented break; From f22dc0f0df195524590edc378395130b7d712c8f Mon Sep 17 00:00:00 2001 From: Phenom Date: Tue, 18 Apr 2017 12:02:34 +0200 Subject: [PATCH 109/118] Fix Clang warnings: unused variable 'action' warning: unused variable 'action' [-Wunused-variable] QAction *action = contextMenu- >addAction(QIcon(":/images/chat_24.png"),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ; --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index aac7e3ba5..755dab9c9 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -2408,8 +2408,8 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) } } - if(n_selected_items==1) - QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ; + if (n_selected_items==1) + contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ; // always allow to send messages contextMenu->addAction(QIcon(":/images/mail_new.png"), tr("Send message"), this, SLOT(sendMsg())); From ff1908eda6293d5105fbe1d60d5c41641e1bb0e8 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 19 Apr 2017 11:50:24 +0200 Subject: [PATCH 110/118] Fix Clang Static Analyser: Undefined allocation of 0 bytes Unix API: Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131): Call to 'malloc' has an allocation size of 0 bytes 1: Loop body executed 0 times in /home/phenom/GIT/RetroShare/trunk/ libbitdht/src/util/bdbloom.cc:223 2: Calling 'bloomFilter::getFilter' in /home/phenom/GIT/RetroShare/ trunk/libbitdht/src/util/bdbloom.cc:240 3: 'bytes' initialized to 0 in /home/phenom/GIT/RetroShare/trunk/ libbitdht/src/util/bdbloom.cc:141 4: Call to 'malloc' has an allocation size of 0 bytes in /home/phenom/ GIT/RetroShare/trunk/libbitdht/src/util/bdbloom.cc:148 --- libbitdht/src/util/bdbloom.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libbitdht/src/util/bdbloom.cc b/libbitdht/src/util/bdbloom.cc index 36f3a3bee..016808ea4 100644 --- a/libbitdht/src/util/bdbloom.cc +++ b/libbitdht/src/util/bdbloom.cc @@ -144,6 +144,11 @@ std::string bloomFilter::getFilter() bytes++; } + if (bytes==0) + { + std::cerr << "(EE) Error. Cannot allocate memory for 0 byte in " << __PRETTY_FUNCTION__ << std::endl; + return std::string(); + } // convert to binary array. uint8_t *tmparray = (uint8_t *) malloc(bytes); From b2b7d004cd4204c3ae06f1876329dd4800f38f98 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 19 Apr 2017 14:01:35 +0200 Subject: [PATCH 111/118] Fix CSA warnings: Called C++ object pointer is null Logic error: Called C++ object pointer is null 1: 'di' initialized here in /home/phenom/GIT/RetroShare/trunk/plugins/ VOIP/gui/VOIPGUIHandler.cpp:157 2: Assuming 'di' is null in /home/phenom/GIT/RetroShare/trunk/plugins/ VOIP/gui/VOIPGUIHandler.cpp:158 3: Called C++ object pointer is null in /home/phenom/GIT/RetroShare/ trunk/plugins/VOIP/gui/VOIPGUIHandler.cpp:161 --- plugins/VOIP/gui/VOIPGUIHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/VOIP/gui/VOIPGUIHandler.cpp b/plugins/VOIP/gui/VOIPGUIHandler.cpp index 6a7d7d703..f999ed437 100644 --- a/plugins/VOIP/gui/VOIPGUIHandler.cpp +++ b/plugins/VOIP/gui/VOIPGUIHandler.cpp @@ -155,7 +155,7 @@ void VOIPGUIHandler::ReceivedVoipBandwidthInfo(const RsPeerId &peer_id, int byte #endif ChatDialog *di = ChatDialog::getExistingChat(ChatId(peer_id)) ; - if(!di) + if(di) { ChatWidget *cw = di->getChatWidget(); From 90cd6233d8b3e446984ddc1b68b2e89fbf35995d Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 19 Apr 2017 14:04:50 +0200 Subject: [PATCH 112/118] Fix CAS warnings: Potential leak of memory pointed to by 'toaster' Memory Error: Memory leak: Potential leak of memory pointed to by 'toaster' 1: Memory is allocated in /home/phenom/GIT/RetroShare/trunk/plugins/ VOIP/gui/VOIPToasterNotify.cpp:182 --- plugins/VOIP/gui/VOIPToasterNotify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/VOIP/gui/VOIPToasterNotify.cpp b/plugins/VOIP/gui/VOIPToasterNotify.cpp index d2de3f6bd..eff862467 100644 --- a/plugins/VOIP/gui/VOIPToasterNotify.cpp +++ b/plugins/VOIP/gui/VOIPToasterNotify.cpp @@ -180,7 +180,7 @@ ToasterItem* VOIPToasterNotify::testToasterItem(QString tag) if (tag == "Invitation") toaster = new ToasterItem(new VOIPToasterItem(ownId, tr("Test VOIP Invitation"), VOIPToasterItem::Invitation)); #endif if (tag == "AudioCall") toaster = new ToasterItem(new VOIPToasterItem(ownId, tr("Test VOIP Audio Call"), VOIPToasterItem::AudioCall)); - if (tag == "VideoCall") toaster = new ToasterItem(new VOIPToasterItem(ownId, tr("Test VOIP Video Call"), VOIPToasterItem::VideoCall)); + if (tag == "VideoCall" || toaster == NULL) toaster = new ToasterItem(new VOIPToasterItem(ownId, tr("Test VOIP Video Call"), VOIPToasterItem::VideoCall)); return toaster; } From 30632dcfeb5a065caee5b3b9d610ad50880a65b2 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 19 Apr 2017 14:06:56 +0200 Subject: [PATCH 113/118] Fix CSA warnings: Called C++ object pointer is null Logic error: Called C++ object pointer is null 1: Calling 'MainWindow::createNotifyIcons' in /home/phenom/GIT/ RetroShare/trunk/retroshare-gui/src/gui/MainWindow.cpp:291 2: Loop body executed 0 times in /home/phenom/GIT/RetroShare/trunk/ retroshare-gui/src/gui/MainWindow.cpp:600 3: Calling 'MainWindow::updateTrayCombine' in /home/phenom/GIT/ RetroShare/trunk/retroshare-gui/src/gui/MainWindow.cpp:605 4: Value assigned to field 'notifyMenu' in /home/phenom/GIT/RetroShare/ trunk/retroshare-gui/src/gui/MainWindow.cpp:654 5: Assuming pointer value is null in /home/phenom/GIT/RetroShare/trunk/ retroshare-gui/src/gui/MainWindow.cpp:658 6: Called C++ object pointer is null in /home/phenom/GIT/RetroShare/ trunk/retroshare-gui/src/gui/MainWindow.cpp:679 --- retroshare-gui/src/gui/MainWindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index 8e8534345..af2e10574 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -676,7 +676,8 @@ void MainWindow::updateTrayCombine() } } - notifyMenu->menuAction()->setVisible(visible); + if (notifyMenu) + notifyMenu->menuAction()->setVisible(visible); // update tray icon updateFriends(); From 1f16f46aad3769457561e5a5d0d26fef81beec3c Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 19 Apr 2017 14:15:34 +0200 Subject: [PATCH 114/118] Fix CSA warnings: Called C++ object pointer is null Logic error: Called C++ object pointer is null 1: Assuming pointer value is null in /home/phenom/GIT/RetroShare/trunk/ retroshare-gui/src/gui/common/MimeTextEdit.cpp:65 2: Called C++ object pointer is null in /home/phenom/GIT/RetroShare/ trunk/retroshare-gui/src/gui/common/MimeTextEdit.cpp:83 --- retroshare-gui/src/gui/common/MimeTextEdit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/retroshare-gui/src/gui/common/MimeTextEdit.cpp b/retroshare-gui/src/gui/common/MimeTextEdit.cpp index 5ff657ce3..9c0395ffb 100644 --- a/retroshare-gui/src/gui/common/MimeTextEdit.cpp +++ b/retroshare-gui/src/gui/common/MimeTextEdit.cpp @@ -77,6 +77,7 @@ void MimeTextEdit::insertFromMimeData(const QMimeData* source) } } #endif + if (source == NULL) return; //insert retroshare links QList links; From 90aaace69c9a74509ed11992226c5c0d4c9dbcd6 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 19 Apr 2017 14:18:35 +0200 Subject: [PATCH 115/118] Fix CSA warnings: Called C++ object pointer is null Logic error: Called C++ object pointer is null 1: Value assigned to field 'mMainAction' in /home/phenom/GIT/ RetroShare/trunk/retroshare-gui/src/gui/common/UserNotify.cpp:94 2: Assuming pointer value is null in /home/phenom/GIT/RetroShare/trunk/ retroshare-gui/src/gui/common/UserNotify.cpp:95 3: Called C++ object pointer is null in /home/phenom/GIT/RetroShare/ trunk/retroshare-gui/src/gui/common/UserNotify.cpp:103 --- retroshare-gui/src/gui/common/UserNotify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/common/UserNotify.cpp b/retroshare-gui/src/gui/common/UserNotify.cpp index 96cbf554b..6c70b3c9f 100644 --- a/retroshare-gui/src/gui/common/UserNotify.cpp +++ b/retroshare-gui/src/gui/common/UserNotify.cpp @@ -99,7 +99,7 @@ void UserNotify::initialize(QToolBar *mainToolBar, QAction *mainAction, QListWid } } mListItem = listItem; - if (mListItem && !mMainAction) { + if (mListItem && mMainAction) { mButtonText = mMainAction->text(); } } From 593c0cb7e65b13a2e07d74fdc15d563e93f78e75 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 19 Apr 2017 14:19:54 +0200 Subject: [PATCH 116/118] Fix CSA warnings: Called C++ object pointer is null Logic error: Called C++ object pointer is null 1: Null pointer value stored to field 'mInternalTokenQueue' in /home/ phenom/GIT/RetroShare/trunk/retroshare-gui/src/gui/gxs/ GxsGroupDialog.cpp:70 2: Calling 'GxsGroupDialog::init' in /home/phenom/GIT/RetroShare/trunk/ retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp:72 3: Calling 'GxsGroupDialog::initMode' in /home/phenom/GIT/RetroShare/ trunk/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp:136 4: Calling 'GxsGroupDialog::requestGroup' in /home/phenom/GIT/ RetroShare/trunk/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp:190 5: Called C++ object pointer is null in /home/phenom/GIT/RetroShare/ trunk/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp:866 --- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index b18ab3688..cd792623d 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -863,7 +863,8 @@ void GxsGroupDialog::requestGroup(const RsGxsGroupId &groupId) std::cerr << std::endl; uint32_t token; - mInternalTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, GXSGROUP_INTERNAL_LOADGROUP); + if (mInternalTokenQueue) + mInternalTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, GXSGROUP_INTERNAL_LOADGROUP) ; } void GxsGroupDialog::loadGroup(uint32_t token) From 3592d5bf5d35aee004742d06a949e4508a26bb32 Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 21 Apr 2017 19:55:37 +0200 Subject: [PATCH 117/118] =?UTF-8?q?Fix=20GCC=20warnings:=20unused=20parame?= =?UTF-8?q?ter=20=E2=80=98names=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /libretroshare/src/pqi/pqiservice.h:80: warning: unused parameter ‘names’ [-Wunused-parameter] virtual void getItemNames(std::map& names) const {} // This does nothing by default. Service should derive it in order to give info for the UI ^~~~~ --- libretroshare/src/pqi/pqiservice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/pqi/pqiservice.h b/libretroshare/src/pqi/pqiservice.h index b22a34aac..41c540d4c 100644 --- a/libretroshare/src/pqi/pqiservice.h +++ b/libretroshare/src/pqi/pqiservice.h @@ -77,7 +77,7 @@ public: virtual int tick() { return 0; } - virtual void getItemNames(std::map& names) const {} // This does nothing by default. Service should derive it in order to give info for the UI + virtual void getItemNames(std::map& /*names*/) const {} // This does nothing by default. Service should derive it in order to give info for the UI private: p3ServiceServerIface *mServiceServer; // const, no need for mutex. From 078913f0f34c6246e6f61290a308fb35b7a7886e Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 21 Apr 2017 21:29:20 +0200 Subject: [PATCH 118/118] =?UTF-8?q?Fix=20GCC=20warnings:=20enumeration=20v?= =?UTF-8?q?alue=20=E2=80=98TYPE=5FIDENTITY=E2=80=99=20not=20handled=20in?= =?UTF-8?q?=20switch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit warning: enumeration value ‘TYPE_IDENTITY’ not handled in switch [- Wswitch] switch (link.type()) { ^ --- retroshare-gui/src/util/HandleRichText.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index c5f578d3a..96fd36d73 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -260,12 +260,13 @@ void RsHtml::anchorStylesheetForImg(QDomDocument &/*doc*/, QDomElement &/*elemen case RetroShareLink::TYPE_PERSON: case RetroShareLink::TYPE_FORUM: case RetroShareLink::TYPE_CHANNEL: - case RetroShareLink::TYPE_POSTED: case RetroShareLink::TYPE_SEARCH: case RetroShareLink::TYPE_MESSAGE: case RetroShareLink::TYPE_EXTRAFILE: case RetroShareLink::TYPE_PRIVATE_CHAT: case RetroShareLink::TYPE_PUBLIC_MSG: + case RetroShareLink::TYPE_POSTED: + case RetroShareLink::TYPE_IDENTITY: // not yet implemented break;