2010-03-10 16:38:26 -05:00
/***************************************************************************
* Copyright ( C ) 2009 *
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License for more details . *
* *
* You should have received a copy of the GNU General Public License *
* along with this program ; if not , write to the *
* Free Software Foundation , Inc . , *
* 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <iostream>
2013-10-21 07:00:49 -04:00
# include <time.h>
2010-03-10 16:38:26 -05:00
# include <QStringList>
2010-03-22 15:46:58 -04:00
# include <QRegExp>
# include <QApplication>
# include <QMimeData>
# include <QClipboard>
2010-07-15 07:25:34 -04:00
# include <QDesktopServices>
# include <QMessageBox>
# include <QIcon>
# include <QObject>
2013-09-26 19:53:06 -04:00
# include <time.h>
2010-07-15 07:25:34 -04:00
2013-10-19 16:59:55 -04:00
# if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
# include <QUrlQuery>
# endif
2010-03-10 16:38:26 -05:00
# include "RetroShareLink.h"
2011-04-19 15:42:44 -04:00
# include "MainWindow.h"
2013-09-07 00:21:48 -04:00
//#include "ForumsDialog.h"
//#include "ChannelFeed.h"
2011-05-04 06:22:49 -04:00
# include "SearchDialog.h"
2011-05-07 19:14:09 -04:00
# include "msgs/MessageComposer.h"
2010-08-06 11:31:30 -04:00
# include "util/misc.h"
2010-09-28 16:33:34 -04:00
# include "common/PeerDefs.h"
2011-12-10 16:38:38 -05:00
# include "common/RsCollectionFile.h"
2012-01-18 15:31:30 -05:00
# include "gui/connect/ConnectFriendWizard.h"
2011-05-18 17:23:26 -04:00
# include "gui/connect/ConfCertDialog.h"
2013-06-17 14:53:47 -04:00
# include "gui/chat/ChatDialog.h"
2010-03-10 16:38:26 -05:00
2010-08-06 05:40:23 -04:00
# include <retroshare/rsfiles.h>
2013-04-18 17:41:13 -04:00
# include <retroshare/rsmsgs.h>
2010-08-06 05:40:23 -04:00
# include <retroshare/rspeers.h>
2013-09-07 00:21:48 -04:00
//#include <retroshare/rsforums.h>
//#include <retroshare/rschannels.h>
2010-07-15 07:25:34 -04:00
2013-02-23 09:29:36 -05:00
//#define DEBUG_RSLINK 1
2010-03-10 16:38:26 -05:00
2012-01-18 15:31:30 -05:00
# define HOST_FILE "file"
2012-11-10 17:59:51 -05:00
# define HOST_EXTRAFILE "extra"
2012-01-18 15:31:30 -05:00
# define HOST_PERSON "person"
# define HOST_FORUM "forum"
# define HOST_CHANNEL "channel"
# define HOST_MESSAGE "message"
# define HOST_SEARCH "search"
# define HOST_CERTIFICATE "certificate"
2013-04-13 09:12:13 -04:00
# define HOST_PUBLIC_MSG "public_msg"
# define HOST_PRIVATE_CHAT "private_chat"
# define HOST_REGEXP "file|person|forum|channel|search|message|certificate|private_chat|public_msg"
2010-11-18 11:31:44 -05:00
# define FILE_NAME "name"
# define FILE_SIZE "size"
# define FILE_HASH "hash"
2012-11-10 17:59:51 -05:00
# define FILE_SOURCE "src"
2010-11-18 11:31:44 -05:00
# define PERSON_NAME "name"
# define PERSON_HASH "hash"
2010-03-10 16:38:26 -05:00
2011-04-19 15:42:44 -04:00
# define FORUM_NAME "name"
# define FORUM_ID "id"
# define FORUM_MSGID "msgid"
# define CHANNEL_NAME "name"
# define CHANNEL_ID "id"
# define CHANNEL_MSGID "msgid"
2011-05-07 19:14:09 -04:00
# define MESSAGE_ID "id"
# define MESSAGE_SUBJECT "subject"
2012-01-18 15:31:30 -05:00
# define SEARCH_KEYWORDS "keywords"
# define CERTIFICATE_SSLID "sslid"
# define CERTIFICATE_GPG_ID "gpgid"
# define CERTIFICATE_GPG_BASE64 "gpgbase64"
# define CERTIFICATE_GPG_CHECKSUM "gpgchecksum"
# define CERTIFICATE_LOCATION "location"
# define CERTIFICATE_NAME "name"
2012-02-11 09:49:04 -05:00
# define CERTIFICATE_EXT_IPPORT "extipp"
# define CERTIFICATE_LOC_IPPORT "locipp"
2013-07-06 16:27:29 -04:00
# define CERTIFICATE_DYNDNS "dyndns"
2011-05-04 06:22:49 -04:00
2013-04-13 09:12:13 -04:00
# define PRIVATE_CHAT_TIME_STAMP "time_stamp"
# define PRIVATE_CHAT_STRING "encrypted_data"
2013-04-13 18:40:17 -04:00
# define PRIVATE_CHAT_GPG_ID "gpgid"
2013-04-13 09:12:13 -04:00
# define PUBLIC_MSG_TIME_STAMP "time_stamp"
# define PUBLIC_MSG_SRC_PGP_ID "gpgid"
# define PUBLIC_MSG_HASH "hash"
2010-03-10 18:09:35 -05:00
RetroShareLink : : RetroShareLink ( const QUrl & url )
2010-03-10 16:38:26 -05:00
{
2010-11-18 11:31:44 -05:00
fromUrl ( url ) ;
2010-07-15 07:25:34 -04:00
}
RetroShareLink : : RetroShareLink ( const QString & url )
{
fromString ( url ) ;
}
void RetroShareLink : : fromString ( const QString & url )
{
2010-11-18 11:31:44 -05:00
clear ( ) ;
2010-07-15 07:25:34 -04:00
// parse
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " got new RS link \" " < < url . toStdString ( ) < < " \" " < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-11-18 11:31:44 -05:00
if ( ( url . startsWith ( QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_FILE ) ) & & url . count ( " | " ) = = 3 ) | |
2013-04-13 18:40:17 -04:00
( url . startsWith ( QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_PERSON ) ) & & url . count ( " | " ) = = 2 ) )
{
2010-11-18 11:31:44 -05:00
/* Old link, we try it */
QStringList list = url . split ( " | " ) ;
if ( list . size ( ) > = 1 ) {
if ( list . size ( ) = = 4 & & list [ 0 ] = = QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_FILE ) ) {
bool ok ;
2010-03-10 16:38:26 -05:00
2010-11-18 11:31:44 -05:00
_type = TYPE_FILE ;
_name = list [ 1 ] ;
_size = list [ 2 ] . toULongLong ( & ok ) ;
_hash = list [ 3 ] . left ( 40 ) ; // normally not necessary, but it's a security.
2010-03-10 16:38:26 -05:00
2010-11-18 11:31:44 -05:00
if ( ok ) {
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-11-18 11:31:44 -05:00
std : : cerr < < " New RetroShareLink forged: " < < std : : endl ;
std : : cerr < < " name = \" " < < _name . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " hash = \" " < < _hash . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " size = " < < _size < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-11-18 11:31:44 -05:00
check ( ) ;
return ;
}
} else if ( list . size ( ) = = 3 & & list [ 0 ] = = QString ( RSLINK_SCHEME ) + " :// " + QString ( HOST_PERSON ) ) {
_type = TYPE_PERSON ;
_name = list [ 1 ] ;
_hash = list [ 2 ] . left ( 40 ) ; // normally not necessary, but it's a security.
_size = 0 ;
2010-07-15 07:25:34 -04:00
check ( ) ;
return ;
}
2010-11-18 11:31:44 -05:00
// bad link
}
}
/* Now try QUrl */
2011-10-08 13:49:06 -04:00
fromUrl ( QUrl : : fromEncoded ( url . toUtf8 ( ) . constData ( ) ) ) ;
2010-11-18 11:31:44 -05:00
}
void RetroShareLink : : fromUrl ( const QUrl & url )
{
2013-10-19 16:59:55 -04:00
# if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
const QUrlQuery urlQuery ( url ) ;
# else
const QUrl & urlQuery ( url ) ;
# endif
2010-11-18 11:31:44 -05:00
clear ( ) ;
// parse
# ifdef DEBUG_RSLINK
std : : cerr < < " got new RS link \" " < < url . toString ( ) . toStdString ( ) < < " \" " < < std : : endl ;
# endif
if ( url . scheme ( ) ! = RSLINK_SCHEME ) {
/* No RetroShare-Link */
2013-04-14 17:45:02 -04:00
std : : cerr < < " Not a RS link: scheme= " < < url . scheme ( ) . toStdString ( ) < < std : : endl ;
2010-11-18 11:31:44 -05:00
return ;
}
if ( url . host ( ) = = HOST_FILE ) {
bool ok ;
_type = TYPE_FILE ;
2013-10-19 16:59:55 -04:00
_name = urlQuery . queryItemValue ( FILE_NAME ) ;
_size = urlQuery . queryItemValue ( FILE_SIZE ) . toULongLong ( & ok ) ;
_hash = urlQuery . queryItemValue ( FILE_HASH ) . left ( 40 ) ; // normally not necessary, but it's a security.
2010-11-18 11:31:44 -05:00
if ( ok ) {
# ifdef DEBUG_RSLINK
std : : cerr < < " New RetroShareLink forged: " < < std : : endl ;
std : : cerr < < " name = \" " < < _name . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " hash = \" " < < _hash . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " size = " < < _size < < std : : endl ;
# endif
2010-07-15 07:25:34 -04:00
check ( ) ;
return ;
}
2010-11-18 11:31:44 -05:00
}
2010-07-15 07:25:34 -04:00
2013-04-13 09:12:13 -04:00
if ( url . host ( ) = = HOST_PRIVATE_CHAT )
{
bool ok ;
_type = TYPE_PRIVATE_CHAT ;
2013-10-19 16:59:55 -04:00
_time_stamp = urlQuery . queryItemValue ( PRIVATE_CHAT_TIME_STAMP ) . toUInt ( & ok ) ;
_encrypted_chat_info = urlQuery . queryItemValue ( PRIVATE_CHAT_STRING ) ;
_GPGid = urlQuery . queryItemValue ( PRIVATE_CHAT_GPG_ID ) ;
2013-04-13 09:12:13 -04:00
check ( ) ;
return ;
}
if ( url . host ( ) = = HOST_PUBLIC_MSG )
{
bool ok ;
_type = TYPE_PUBLIC_MSG ;
2013-10-19 16:59:55 -04:00
_hash = urlQuery . queryItemValue ( PUBLIC_MSG_HASH ) ;
_time_stamp = urlQuery . queryItemValue ( PUBLIC_MSG_TIME_STAMP ) . toUInt ( & ok ) ;
_GPGid = urlQuery . queryItemValue ( PUBLIC_MSG_SRC_PGP_ID ) ;
2013-04-13 09:12:13 -04:00
check ( ) ;
return ;
}
2012-11-10 17:59:51 -05:00
if ( url . host ( ) = = HOST_EXTRAFILE ) {
bool ok ;
_type = TYPE_EXTRAFILE ;
2013-10-19 16:59:55 -04:00
_name = urlQuery . queryItemValue ( FILE_NAME ) ;
_size = urlQuery . queryItemValue ( FILE_SIZE ) . toULongLong ( & ok ) ;
_hash = urlQuery . queryItemValue ( FILE_HASH ) . left ( 40 ) ; // normally not necessary, but it's a security.
_SSLid = urlQuery . queryItemValue ( FILE_SOURCE ) ;
2012-11-10 17:59:51 -05:00
if ( ok ) {
# ifdef DEBUG_RSLINK
std : : cerr < < " New RetroShareLink forged: " < < std : : endl ;
std : : cerr < < " name = \" " < < _name . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " hash = \" " < < _hash . toStdString ( ) < < " \" " < < std : : endl ;
std : : cerr < < " size = " < < _size < < std : : endl ;
std : : cerr < < " src = " < < _SSLid . toStdString ( ) < < std : : endl ;
# endif
check ( ) ;
return ;
}
}
2010-11-18 11:31:44 -05:00
if ( url . host ( ) = = HOST_PERSON ) {
_type = TYPE_PERSON ;
2013-10-19 16:59:55 -04:00
_name = urlQuery . queryItemValue ( PERSON_NAME ) ;
_hash = urlQuery . queryItemValue ( PERSON_HASH ) . left ( 40 ) ; // normally not necessary, but it's a security.
2010-11-18 11:31:44 -05:00
check ( ) ;
return ;
2010-07-15 07:25:34 -04:00
}
2010-03-10 16:38:26 -05:00
2011-04-19 15:42:44 -04:00
if ( url . host ( ) = = HOST_FORUM ) {
_type = TYPE_FORUM ;
2013-10-19 16:59:55 -04:00
_name = urlQuery . queryItemValue ( FORUM_NAME ) ;
_hash = urlQuery . queryItemValue ( FORUM_ID ) ;
_msgId = urlQuery . queryItemValue ( FORUM_MSGID ) ;
2011-04-19 15:42:44 -04:00
check ( ) ;
return ;
}
if ( url . host ( ) = = HOST_CHANNEL ) {
_type = TYPE_CHANNEL ;
2013-10-19 16:59:55 -04:00
_name = urlQuery . queryItemValue ( CHANNEL_NAME ) ;
_hash = urlQuery . queryItemValue ( CHANNEL_ID ) ;
_msgId = urlQuery . queryItemValue ( CHANNEL_MSGID ) ;
2011-05-04 06:22:49 -04:00
check ( ) ;
return ;
}
if ( url . host ( ) = = HOST_SEARCH ) {
_type = TYPE_SEARCH ;
2013-10-19 16:59:55 -04:00
_name = urlQuery . queryItemValue ( SEARCH_KEYWORDS ) ;
2011-04-19 15:42:44 -04:00
check ( ) ;
return ;
}
2011-05-07 19:14:09 -04:00
if ( url . host ( ) = = HOST_MESSAGE ) {
_type = TYPE_MESSAGE ;
2013-10-19 16:59:55 -04:00
std : : string id = urlQuery . queryItemValue ( MESSAGE_ID ) . toStdString ( ) ;
2014-03-17 16:56:06 -04:00
createMessage ( RsPeerId ( id ) , urlQuery . queryItemValue ( MESSAGE_SUBJECT ) ) ;
2011-05-07 19:14:09 -04:00
return ;
}
2012-01-18 15:31:30 -05:00
if ( url . host ( ) = = HOST_CERTIFICATE ) {
_type = TYPE_CERTIFICATE ;
2013-10-19 16:59:55 -04:00
_SSLid = urlQuery . queryItemValue ( CERTIFICATE_SSLID ) ;
_name = urlQuery . queryItemValue ( CERTIFICATE_NAME ) ;
_location = urlQuery . queryItemValue ( CERTIFICATE_LOCATION ) ;
_GPGBase64String = urlQuery . queryItemValue ( CERTIFICATE_GPG_BASE64 ) ;
_GPGid = urlQuery . queryItemValue ( CERTIFICATE_GPG_ID ) ;
_GPGBase64CheckSum = urlQuery . queryItemValue ( CERTIFICATE_GPG_CHECKSUM ) ;
_ext_ip_port = urlQuery . queryItemValue ( CERTIFICATE_EXT_IPPORT ) ;
_loc_ip_port = urlQuery . queryItemValue ( CERTIFICATE_LOC_IPPORT ) ;
_dyndns_name = urlQuery . queryItemValue ( CERTIFICATE_DYNDNS ) ;
2012-01-18 15:31:30 -05:00
std : : cerr < < " Got a certificate link!! " < < std : : endl ;
check ( ) ;
return ;
}
2010-11-18 11:31:44 -05:00
// bad link
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " Wrongly formed RS link. Can't process. " < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-11-18 11:31:44 -05:00
clear ( ) ;
2010-03-10 16:38:26 -05:00
}
2011-05-04 06:22:49 -04:00
RetroShareLink : : RetroShareLink ( )
2010-03-10 16:38:26 -05:00
{
2011-05-04 06:22:49 -04:00
clear ( ) ;
}
2012-11-10 17:59:51 -05:00
bool RetroShareLink : : createExtraFile ( const QString & name , uint64_t size , const QString & hash , const QString & ssl_id )
{
clear ( ) ;
_name = name ;
_size = size ;
_hash = hash ;
_SSLid = ssl_id ;
_type = TYPE_EXTRAFILE ;
check ( ) ;
return valid ( ) ;
}
2011-05-04 06:22:49 -04:00
bool RetroShareLink : : createFile ( const QString & name , uint64_t size , const QString & hash )
{
clear ( ) ;
_name = name ;
_size = size ;
_hash = hash ;
2010-07-15 07:25:34 -04:00
_type = TYPE_FILE ;
2011-05-04 06:22:49 -04:00
check ( ) ;
return valid ( ) ;
2010-03-10 16:38:26 -05:00
}
2013-04-13 09:12:13 -04:00
bool RetroShareLink : : createPrivateChatInvite ( time_t time_stamp , const QString & gpg_id , const QString & encrypted_chat_info )
{
clear ( ) ;
2013-04-13 18:40:17 -04:00
_type = TYPE_PRIVATE_CHAT ;
2013-04-13 09:12:13 -04:00
_time_stamp = time_stamp ;
_encrypted_chat_info = encrypted_chat_info ;
2013-04-13 18:40:17 -04:00
_GPGid = gpg_id ;
2013-04-13 09:12:13 -04:00
check ( ) ;
return valid ( ) ;
}
2013-04-29 16:44:48 -04:00
bool RetroShareLink : : createPublicMsgInvite ( time_t time_stamp , const QString & issuer_pgp_id , const QString & hash )
2013-04-13 09:12:13 -04:00
{
clear ( ) ;
2013-04-13 18:40:17 -04:00
_type = TYPE_PUBLIC_MSG ;
2013-04-13 09:12:13 -04:00
_time_stamp = time_stamp ;
_hash = hash ;
2013-04-29 16:44:48 -04:00
_GPGid = issuer_pgp_id ;
2013-04-13 09:12:13 -04:00
check ( ) ;
return valid ( ) ;
}
2014-03-17 16:56:06 -04:00
bool RetroShareLink : : createPerson ( const RsPgpId & id )
2010-03-10 16:38:26 -05:00
{
2011-05-04 06:22:49 -04:00
clear ( ) ;
2011-05-12 15:37:13 -04:00
RsPeerDetails detail ;
2014-03-17 16:56:06 -04:00
if ( rsPeers - > getGPGDetails ( id , detail ) = = false ) {
2011-05-12 15:37:13 -04:00
std : : cerr < < " RetroShareLink::createPerson() Couldn't find peer id " < < id < < std : : endl ;
return false ;
}
2014-03-17 16:56:06 -04:00
_hash = QString : : fromStdString ( id . toStdString ( ) ) ;
2011-05-12 15:37:13 -04:00
_name = QString : : fromUtf8 ( detail . name . c_str ( ) ) ;
2011-05-04 06:22:49 -04:00
2010-07-15 07:25:34 -04:00
_type = TYPE_PERSON ;
2011-05-04 06:22:49 -04:00
check ( ) ;
return valid ( ) ;
2010-07-15 07:25:34 -04:00
}
2010-03-10 16:38:26 -05:00
2014-03-17 16:56:06 -04:00
bool RetroShareLink : : createCertificate ( const RsPeerId & ssl_id )
2012-01-18 15:31:30 -05:00
{
2012-08-14 14:57:45 -04:00
// This is baaaaaad code:
// - we should not need to parse and re-read a cert in old format.
//
2012-01-18 15:31:30 -05:00
RsPeerDetails detail ;
2014-03-17 16:56:06 -04:00
if ( rsPeers - > getPeerDetails ( ssl_id , detail ) = = false ) {
std : : cerr < < " RetroShareLink::createPerson() Couldn't find peer id " < < ssl_id < < std : : endl ;
2012-01-18 15:31:30 -05:00
return false ;
}
2012-08-14 15:31:47 -04:00
std : : string gpg_base_64_str = " " ;
std : : string gpg_base_64_checksum_str = " " ;
2012-01-18 15:31:30 -05:00
2012-08-14 15:31:47 -04:00
if ( ! rsPeers - > GetPGPBase64StringAndCheckSum ( detail . gpg_id , gpg_base_64_str , gpg_base_64_checksum_str ) )
return false ;
_GPGBase64String = QString : : fromStdString ( gpg_base_64_str ) ;
_GPGBase64CheckSum = QString : : fromStdString ( gpg_base_64_checksum_str ) ;
2012-01-18 15:31:30 -05:00
_type = TYPE_CERTIFICATE ;
2014-03-17 16:56:06 -04:00
_GPGid = QString : : fromStdString ( detail . gpg_id . toStdString ( ) ) . right ( 8 ) ;
// if(detail.isOnlyGPGdetail)
// {
// _SSLid.clear();
// _location.clear();
// _ext_ip_port.clear();
// _loc_ip_port.clear();
// }
// else
// {
_SSLid = QString : : fromStdString ( ssl_id . toStdString ( ) ) ;
2012-05-01 05:18:55 -04:00
_location = QString : : fromUtf8 ( detail . location . c_str ( ) ) ;
2012-08-14 15:31:47 -04:00
_ext_ip_port = QString : : fromStdString ( detail . extAddr ) + " : " + QString : : number ( detail . extPort ) + " ; " ;
_loc_ip_port = QString : : fromStdString ( detail . localAddr ) + " : " + QString : : number ( detail . localPort ) + " ; " ;
2013-07-06 16:27:29 -04:00
_dyndns_name = QString : : fromStdString ( detail . dyndns ) ;
2014-03-17 16:56:06 -04:00
//}
2012-02-13 16:09:38 -05:00
_name = QString : : fromUtf8 ( detail . name . c_str ( ) ) ;
2012-01-18 15:31:30 -05:00
std : : cerr < < " Found gpg base 64 string = " < < _GPGBase64String . toStdString ( ) < < std : : endl ;
std : : cerr < < " Found gpg base 64 checksum = " < < _GPGBase64CheckSum . toStdString ( ) < < std : : endl ;
std : : cerr < < " Found SSLId = " < < _SSLid . toStdString ( ) < < std : : endl ;
std : : cerr < < " Found GPGId = " < < _GPGid . toStdString ( ) < < std : : endl ;
2012-02-11 09:49:04 -05:00
std : : cerr < < " Found Local IP+Port = " < < _loc_ip_port . toStdString ( ) < < std : : endl ;
std : : cerr < < " Found External IP+Port = " < < _ext_ip_port . toStdString ( ) < < std : : endl ;
2012-01-18 15:31:30 -05:00
std : : cerr < < " Found Location = " < < _location . toStdString ( ) < < std : : endl ;
2013-07-06 16:27:29 -04:00
std : : cerr < < " Found DNS = " < < _dyndns_name . toStdString ( ) < < std : : endl ;
2012-01-21 16:14:11 -05:00
return true ;
2012-01-18 15:31:30 -05:00
}
2014-03-17 16:56:06 -04:00
bool RetroShareLink : : createUnknwonSslCertificate ( const RsPeerId & sslId , const RsPgpId & gpgId )
2012-05-01 05:18:55 -04:00
{
// first try ssl id
if ( createCertificate ( sslId ) ) {
2014-03-17 16:56:06 -04:00
if ( gpgId . isNull ( ) | | _GPGid . toStdString ( ) = = gpgId . toStdString ( ) ) {
2012-05-01 05:18:55 -04:00
return true ;
}
// wrong gpg id
return false ;
}
// then gpg id
2014-03-17 16:56:06 -04:00
if ( createCertificate ( sslId ) ) {
2012-05-01 05:18:55 -04:00
if ( ! _SSLid . isEmpty ( ) ) {
return false ;
}
2014-03-17 16:56:06 -04:00
if ( sslId . isNull ( ) ) {
2012-05-01 05:18:55 -04:00
return true ;
}
2014-03-17 16:56:06 -04:00
_SSLid = QString : : fromStdString ( sslId . toStdString ( ) ) ;
2012-05-01 05:18:55 -04:00
if ( _location . isEmpty ( ) ) {
_location = _name ;
}
return true ;
}
return false ;
}
2011-05-08 19:11:27 -04:00
bool RetroShareLink : : createForum ( const std : : string & id , const std : : string & msgId )
2011-04-19 15:42:44 -04:00
{
2011-05-08 19:11:27 -04:00
clear ( ) ;
2013-09-07 00:21:48 -04:00
#if 0
2011-05-08 19:11:27 -04:00
if ( ! id . empty ( ) ) {
_hash = QString : : fromStdString ( id ) ;
_msgId = QString : : fromStdString ( msgId ) ;
_type = TYPE_FORUM ;
if ( msgId . empty ( ) ) {
ForumInfo fi ;
if ( rsForums - > getForumInfo ( id , fi ) ) {
_name = QString : : fromStdWString ( fi . forumName ) ;
}
} else {
ForumMsgInfo mi ;
if ( rsForums - > getForumMessage ( id , msgId , mi ) ) {
2012-02-13 15:40:36 -05:00
_name = ForumsDialog : : titleFromInfo ( mi ) ;
2011-05-08 19:11:27 -04:00
}
}
}
2013-09-07 00:21:48 -04:00
# endif
2011-05-08 19:11:27 -04:00
check ( ) ;
return valid ( ) ;
2011-05-04 06:22:49 -04:00
}
2014-03-17 16:56:06 -04:00
bool RetroShareLink : : createChannel ( const std : : string & id , const std : : string & msgId )
2011-05-04 06:22:49 -04:00
{
2011-05-08 19:11:27 -04:00
clear ( ) ;
2013-09-07 00:21:48 -04:00
#if 0
2011-05-08 19:11:27 -04:00
if ( ! id . empty ( ) ) {
_hash = QString : : fromStdString ( id ) ;
_msgId = QString : : fromStdString ( msgId ) ;
_type = TYPE_CHANNEL ;
if ( msgId . empty ( ) ) {
ChannelInfo ci ;
if ( rsChannels - > getChannelInfo ( id , ci ) ) {
_name = QString : : fromStdWString ( ci . channelName ) ;
}
} else {
ChannelMsgInfo mi ;
if ( rsChannels - > getChannelMessage ( id , msgId , mi ) ) {
_name = QString : : fromStdWString ( mi . subject ) ;
}
}
}
2013-09-07 00:21:48 -04:00
# endif
2011-05-08 19:11:27 -04:00
check ( ) ;
return valid ( ) ;
2011-05-04 06:22:49 -04:00
}
bool RetroShareLink : : createSearch ( const QString & keywords )
{
clear ( ) ;
_name = keywords ;
_type = TYPE_SEARCH ;
check ( ) ;
return valid ( ) ;
2011-04-19 15:42:44 -04:00
}
2014-03-17 16:56:06 -04:00
bool RetroShareLink : : createMessage ( const RsPeerId & peerId , const QString & subject )
2011-05-07 19:14:09 -04:00
{
clear ( ) ;
2014-03-17 16:56:06 -04:00
_hash = QString : : fromStdString ( peerId . toStdString ( ) ) ;
2011-05-07 19:14:09 -04:00
PeerDefs : : rsidFromId ( peerId , & _name ) ;
_subject = subject ;
_type = TYPE_MESSAGE ;
check ( ) ;
return valid ( ) ;
}
2010-11-18 11:31:44 -05:00
void RetroShareLink : : clear ( )
{
_valid = false ;
_type = TYPE_UNKNOWN ;
2012-08-16 06:20:34 -04:00
_subType = 0 ;
2010-11-18 11:31:44 -05:00
_hash = " " ;
_size = 0 ;
_name = " " ;
2013-04-13 09:12:13 -04:00
_GPGid = " " ;
_time_stamp = 0 ;
_encrypted_chat_info = " " ;
2010-11-18 11:31:44 -05:00
}
2010-07-15 07:25:34 -04:00
void RetroShareLink : : check ( )
{
2011-05-07 19:14:09 -04:00
_valid = true ;
2010-07-15 07:25:34 -04:00
2013-04-13 09:12:13 -04:00
switch ( _type )
{
case TYPE_UNKNOWN :
2011-05-07 19:14:09 -04:00
_valid = false ;
2013-04-13 09:12:13 -04:00
break ;
case TYPE_EXTRAFILE :
if ( ! checkSSLId ( _SSLid ) )
_valid = false ; // no break! We also test file stuff below.
case TYPE_FILE :
if ( _size > ( ( ( uint64_t ) 1 ) < < 40 ) ) // 1TB. Who has such large files?
_valid = false ;
if ( ! checkName ( _name ) )
_valid = false ;
if ( ! checkHash ( _hash ) )
_valid = false ;
break ;
case TYPE_PRIVATE_CHAT :
if ( ! checkRadix64 ( _encrypted_chat_info ) ) _valid = false ;
2013-04-13 18:40:17 -04:00
if ( ! checkPGPId ( _GPGid ) ) _valid = false ;
2013-04-13 09:12:13 -04:00
break ;
case TYPE_PUBLIC_MSG :
if ( ! checkHash ( _hash ) ) _valid = false ;
if ( ! checkPGPId ( _GPGid ) ) _valid = false ;
break ;
case TYPE_PERSON :
if ( _size ! = 0 )
_valid = false ;
if ( _name . isEmpty ( ) )
_valid = false ;
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_FORUM :
if ( _size ! = 0 )
_valid = false ;
if ( _name . isEmpty ( ) )
_valid = false ;
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_CHANNEL :
if ( _size ! = 0 )
_valid = false ;
if ( _name . isEmpty ( ) )
_valid = false ;
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_SEARCH :
if ( _size ! = 0 )
_valid = false ;
if ( _name . isEmpty ( ) )
_valid = false ;
if ( ! _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_MESSAGE :
if ( _size ! = 0 )
_valid = false ;
if ( _hash . isEmpty ( ) )
_valid = false ;
break ;
case TYPE_CERTIFICATE :
break ;
2011-05-07 19:14:09 -04:00
}
if ( ! _valid ) {
clear ( ) ;
}
2010-03-10 16:38:26 -05:00
}
2011-05-01 18:26:41 -04:00
QString RetroShareLink : : title ( ) const
{
if ( ! valid ( ) ) {
return " " ;
}
switch ( _type ) {
case TYPE_UNKNOWN :
break ;
2013-04-13 09:12:13 -04:00
case TYPE_PUBLIC_MSG :
{
RsPeerDetails detail ;
2014-03-17 16:56:06 -04:00
rsPeers - > getGPGDetails ( RsPgpId ( _GPGid . toStdString ( ) ) , detail ) ;
2013-04-13 09:12:13 -04:00
return QString ( " Click to send a private message to %1 (%2) . " ).arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
}
case TYPE_PRIVATE_CHAT :
{
RsPeerDetails detail ;
2014-03-17 16:56:06 -04:00
rsPeers - > getGPGDetails ( RsPgpId ( _GPGid . toStdString ( ) ) , detail ) ;
2013-04-13 09:12:13 -04:00
2014-03-17 16:56:06 -04:00
if ( _GPGid . toStdString ( ) = = rsPeers - > getGPGOwnId ( ) . toStdString ( ) )
2013-04-13 09:12:13 -04:00
return QString ( " Click to open a private chat canal to %1 (%2) . " ).arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
else
return QString ( " This is a private chat invite for %1 (%2) . You can ' t use it . " ).arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
}
2012-11-10 17:59:51 -05:00
case TYPE_EXTRAFILE :
return QString ( " %1 (%2, Extra - Source included) " ).arg(hash()).arg(misc::friendlyUnit(size())) ;
2011-05-01 18:26:41 -04:00
case TYPE_FILE :
return QString ( " %1 (%2) " ).arg(hash()).arg(misc::friendlyUnit(size())) ;
case TYPE_PERSON :
2014-03-17 16:56:06 -04:00
return PeerDefs : : rsidFromId ( RsPgpId ( hash ( ) . toStdString ( ) ) ) ;
2011-05-01 18:26:41 -04:00
case TYPE_FORUM :
case TYPE_CHANNEL :
2011-05-04 06:22:49 -04:00
case TYPE_SEARCH :
2011-05-01 18:26:41 -04:00
break ;
2011-05-07 19:14:09 -04:00
case TYPE_MESSAGE :
2014-03-17 16:56:06 -04:00
return PeerDefs : : rsidFromId ( RsPeerId ( hash ( ) . toStdString ( ) ) ) ;
2012-01-18 15:31:30 -05:00
case TYPE_CERTIFICATE :
2013-07-06 16:27:29 -04:00
return QObject : : tr ( " Click to add this RetroShare cert to your PGP keyring \n and open the Make Friend Wizard. \n " ) + QString ( " PGP Id = " ) + GPGId ( ) + QString ( " \n SSLId = " ) + SSLId ( ) ;
2011-05-01 18:26:41 -04:00
}
return " " ;
}
2011-10-22 07:15:30 -04:00
static QString encodeItem ( QString item )
{
2013-08-23 16:34:50 -04:00
return item
2013-09-07 08:30:41 -04:00
// .replace("{", "%"+QString::number((int)'{', 16))
// .replace("}", "%"+QString::number((int)'}', 16))
// .replace("[", "%"+QString::number((int)'[', 16))
// .replace("]", "%"+QString::number((int)']', 16))
// .replace("^", "%"+QString::number((int)'^', 16))
// .replace("~", "%"+QString::number((int)'~', 16))
// .replace(";", "%"+QString::number((int)';', 16))
// .replace(":", "%"+QString::number((int)':', 16))
// .replace("=", "%"+QString::number((int)'=', 16))
// .replace("+", "%"+QString::number((int)'+', 16))
// .replace("$", "%"+QString::number((int)'$', 16))
// .replace(",", "%"+QString::number((int)',', 16))
// .replace("\"", "%"+QString::number((int)'\"', 16))
// .replace("|", "%"+QString::number((int)'|', 16))
// .replace("?", "%"+QString::number((int)'?', 16))
// .replace("@", "%"+QString::number((int)'@', 16))
. replace ( " & " , " % " + QString : : number ( ( int ) ' & ' , 16 ) ) //Not necessary: only for text link
. replace ( " / " , " % " + QString : : number ( ( int ) ' / ' , 16 ) )
. replace ( " " , " % " + QString : : number ( ( int ) ' ' , 16 ) )
. replace ( " # " , " % " + QString : : number ( ( int ) ' # ' , 16 ) )
// .replace("£", "%"+QString::number((int)'£', 16))
// .replace("µ", "%"+QString::number((int)'µ', 16))
// .replace("§", "%"+QString::number((int)'§', 16))
// .replace("!", "%"+QString::number((int)'!', 16))
2013-08-23 16:34:50 -04:00
;
2011-10-22 07:15:30 -04:00
}
2011-10-08 13:49:06 -04:00
QString RetroShareLink : : toString ( ) const
2010-03-10 16:38:26 -05:00
{
2013-10-19 16:59:55 -04:00
QUrl url ;
# if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
QUrlQuery urlQuery ;
# else
QUrl & urlQuery ( url ) ;
# endif
2010-07-15 07:25:34 -04:00
switch ( _type ) {
case TYPE_UNKNOWN :
2013-10-19 16:59:55 -04:00
return " " ;
2010-07-15 07:25:34 -04:00
case TYPE_FILE :
2013-10-19 16:59:55 -04:00
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_FILE ) ;
urlQuery . addQueryItem ( FILE_NAME , encodeItem ( _name ) ) ;
urlQuery . addQueryItem ( FILE_SIZE , QString : : number ( _size ) ) ;
urlQuery . addQueryItem ( FILE_HASH , _hash ) ;
break ;
2013-04-13 09:12:13 -04:00
case TYPE_PRIVATE_CHAT :
2013-10-19 16:59:55 -04:00
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_PRIVATE_CHAT ) ;
urlQuery . addQueryItem ( PRIVATE_CHAT_TIME_STAMP , QString : : number ( _time_stamp ) ) ;
urlQuery . addQueryItem ( PRIVATE_CHAT_GPG_ID , _GPGid ) ;
urlQuery . addQueryItem ( PRIVATE_CHAT_STRING , _encrypted_chat_info ) ;
break ;
2013-04-13 09:12:13 -04:00
case TYPE_PUBLIC_MSG :
2013-10-19 16:59:55 -04:00
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_PUBLIC_MSG ) ;
urlQuery . addQueryItem ( PUBLIC_MSG_TIME_STAMP , QString : : number ( _time_stamp ) ) ;
urlQuery . addQueryItem ( PUBLIC_MSG_HASH , _hash ) ;
urlQuery . addQueryItem ( PUBLIC_MSG_SRC_PGP_ID , _GPGid ) ;
break ;
2013-04-13 09:12:13 -04:00
2012-11-10 17:59:51 -05:00
case TYPE_EXTRAFILE :
2013-10-19 16:59:55 -04:00
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_EXTRAFILE ) ;
urlQuery . addQueryItem ( FILE_NAME , encodeItem ( _name ) ) ;
urlQuery . addQueryItem ( FILE_SIZE , QString : : number ( _size ) ) ;
urlQuery . addQueryItem ( FILE_HASH , _hash ) ;
urlQuery . addQueryItem ( FILE_SOURCE , _SSLid ) ;
break ;
2012-11-10 17:59:51 -05:00
2010-07-15 07:25:34 -04:00
case TYPE_PERSON :
2013-10-19 16:59:55 -04:00
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_PERSON ) ;
urlQuery . addQueryItem ( PERSON_NAME , encodeItem ( _name ) ) ;
urlQuery . addQueryItem ( PERSON_HASH , _hash ) ;
break ;
2011-04-19 15:42:44 -04:00
2013-10-19 16:59:55 -04:00
case TYPE_FORUM :
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_FORUM ) ;
urlQuery . addQueryItem ( FORUM_NAME , encodeItem ( _name ) ) ;
urlQuery . addQueryItem ( FORUM_ID , _hash ) ;
if ( ! _msgId . isEmpty ( ) ) {
urlQuery . addQueryItem ( FORUM_MSGID , _msgId ) ;
2011-04-19 15:42:44 -04:00
}
2013-10-19 16:59:55 -04:00
break ;
case TYPE_CHANNEL :
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_CHANNEL ) ;
urlQuery . addQueryItem ( CHANNEL_NAME , encodeItem ( _name ) ) ;
urlQuery . addQueryItem ( CHANNEL_ID , _hash ) ;
if ( ! _msgId . isEmpty ( ) ) {
urlQuery . addQueryItem ( CHANNEL_MSGID , _msgId ) ;
2011-05-04 06:22:49 -04:00
}
2013-10-19 16:59:55 -04:00
break ;
2011-05-04 06:22:49 -04:00
case TYPE_SEARCH :
2013-10-19 16:59:55 -04:00
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_SEARCH ) ;
urlQuery . addQueryItem ( SEARCH_KEYWORDS , encodeItem ( _name ) ) ;
2011-05-04 06:22:49 -04:00
2013-10-19 16:59:55 -04:00
break ;
2011-05-07 19:14:09 -04:00
2013-10-19 16:59:55 -04:00
case TYPE_MESSAGE :
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_MESSAGE ) ;
urlQuery . addQueryItem ( MESSAGE_ID , _hash ) ;
if ( _subject . isEmpty ( ) = = false ) {
urlQuery . addQueryItem ( MESSAGE_SUBJECT , encodeItem ( _subject ) ) ;
2010-11-18 11:31:44 -05:00
}
2013-10-19 16:59:55 -04:00
break ;
2012-01-18 15:31:30 -05:00
case TYPE_CERTIFICATE :
2013-10-19 16:59:55 -04:00
url . setScheme ( RSLINK_SCHEME ) ;
url . setHost ( HOST_CERTIFICATE ) ;
if ( ! _SSLid . isEmpty ( ) ) {
urlQuery . addQueryItem ( CERTIFICATE_SSLID , _SSLid ) ;
}
urlQuery . addQueryItem ( CERTIFICATE_GPG_ID , _GPGid ) ;
urlQuery . addQueryItem ( CERTIFICATE_GPG_BASE64 , _GPGBase64String ) ;
urlQuery . addQueryItem ( CERTIFICATE_GPG_CHECKSUM , _GPGBase64CheckSum ) ;
if ( ! _location . isEmpty ( ) ) {
urlQuery . addQueryItem ( CERTIFICATE_LOCATION , encodeItem ( _location ) ) ;
2012-01-18 15:31:30 -05:00
}
2013-10-19 16:59:55 -04:00
urlQuery . addQueryItem ( CERTIFICATE_NAME , encodeItem ( _name ) ) ;
if ( ! _loc_ip_port . isEmpty ( ) ) {
urlQuery . addQueryItem ( CERTIFICATE_LOC_IPPORT , encodeItem ( _loc_ip_port ) ) ;
}
if ( ! _ext_ip_port . isEmpty ( ) ) {
urlQuery . addQueryItem ( CERTIFICATE_EXT_IPPORT , encodeItem ( _ext_ip_port ) ) ;
}
if ( ! _dyndns_name . isEmpty ( ) ) {
urlQuery . addQueryItem ( CERTIFICATE_DYNDNS , encodeItem ( _dyndns_name ) ) ;
}
break ;
2010-07-15 07:25:34 -04:00
}
2013-10-19 16:59:55 -04:00
# if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
url . setQuery ( urlQuery ) ;
# endif
return url . toString ( ) ;
2010-03-10 16:38:26 -05:00
}
2010-07-15 07:25:34 -04:00
QString RetroShareLink : : niceName ( ) const
{
if ( type ( ) = = TYPE_PERSON ) {
2014-03-17 16:56:06 -04:00
return PeerDefs : : rsid ( name ( ) . toUtf8 ( ) . constData ( ) , RsPgpId ( hash ( ) . toStdString ( ) ) ) ;
2010-07-15 07:25:34 -04:00
}
2013-04-13 18:40:17 -04:00
if ( type ( ) = = TYPE_PRIVATE_CHAT ) {
return QString ( " Private chat invite (Valid only for key %1) " ).arg(_GPGid) ;
}
if ( type ( ) = = TYPE_PUBLIC_MSG ) {
2013-04-29 16:44:48 -04:00
RsPeerDetails detail ;
2014-03-17 16:56:06 -04:00
rsPeers - > getGPGDetails ( RsPgpId ( _GPGid . toStdString ( ) ) , detail ) ;
2013-04-29 16:44:48 -04:00
return QString ( " Click this link to send a private message to %1 (%2) " ).arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
2013-04-13 18:40:17 -04:00
}
2012-05-01 05:18:55 -04:00
if ( type ( ) = = TYPE_CERTIFICATE ) {
if ( _location . isEmpty ( ) ) {
return QString ( " RetroShare Certificate (%1) " ).arg(_name) ;
}
return QString ( " RetroShare Certificate (%1, @%2) " ).arg(_name, _location) ; // should add SSL id there
}
2012-01-18 15:31:30 -05:00
2010-07-15 07:25:34 -04:00
return name ( ) ;
}
2010-03-15 08:57:08 -04:00
QString RetroShareLink : : toHtml ( ) const
2010-03-22 15:46:58 -04:00
{
2011-10-08 13:49:06 -04:00
QString html = " <a href= \" " + toString ( ) + " \" " ;
2011-05-01 18:26:41 -04:00
QString linkTitle = title ( ) ;
if ( ! linkTitle . isEmpty ( ) ) {
html + = " title= \" " + linkTitle + " \" " ;
}
2011-05-06 11:04:35 -04:00
html + = " > " + niceName ( ) + " </a> " ;
2011-05-01 18:26:41 -04:00
return html ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
2010-03-22 15:46:58 -04:00
QString RetroShareLink : : toHtmlFull ( ) const
2010-03-15 08:57:08 -04:00
{
2011-10-08 13:49:06 -04:00
return QString ( " <a href= \" " ) + toString ( ) + " \" > " + toString ( ) + " </a> " ;
2010-03-15 08:57:08 -04:00
}
2010-03-10 16:38:26 -05:00
2010-08-06 11:31:30 -04:00
QString RetroShareLink : : toHtmlSize ( ) const
{
2011-12-10 16:38:38 -05:00
QString size = QString ( " (%1) " ) . arg ( misc : : friendlyUnit ( _size ) ) ;
2012-11-10 17:59:51 -05:00
2011-12-10 16:59:42 -05:00
if ( type ( ) = = TYPE_FILE & & RsCollectionFile : : isCollectionFile ( name ( ) ) ) {
2011-12-10 16:38:38 -05:00
FileInfo finfo ;
2014-03-17 16:56:06 -04:00
if ( rsFiles - > FileDetails ( RsFileHash ( hash ( ) . toStdString ( ) ) , RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL , finfo ) ) {
2011-12-10 16:38:38 -05:00
RsCollectionFile collection ;
if ( collection . load ( QString : : fromUtf8 ( finfo . path . c_str ( ) ) , false ) ) {
size + = QString ( " [%1] " ) . arg ( misc : : friendlyUnit ( collection . size ( ) ) ) ;
}
}
}
QString link = QString ( " <a href= \" %1 \" >%2</a> <font color= \" blue \" >%3</font> " ) . arg ( toString ( ) ) . arg ( name ( ) ) . arg ( size ) ;
return link ;
2010-08-06 11:31:30 -04:00
}
2010-03-10 16:38:26 -05:00
bool RetroShareLink : : checkName ( const QString & name )
{
2010-07-15 07:25:34 -04:00
if ( name = = " " )
return false ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
for ( int i = 0 ; i < name . length ( ) ; + + i )
{
QChar : : Category cat ( name [ i ] . category ( ) ) ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
if ( cat = = QChar : : Separator_Line
| | cat = = QChar : : Other_NotAssigned
)
{
2010-03-10 16:38:26 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " Unwanted category " < < cat < < " at place " < < i < < " in string \" " < < name . toStdString ( ) < < " \" " < < std : : endl ;
2010-03-10 16:38:26 -05:00
# endif
2010-07-15 07:25:34 -04:00
return false ;
}
}
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
return true ;
2010-03-10 16:38:26 -05:00
}
2010-03-10 18:09:35 -05:00
QUrl RetroShareLink : : toUrl ( ) const
{
2011-10-08 13:49:06 -04:00
return QUrl : : fromEncoded ( toString ( ) . toUtf8 ( ) . constData ( ) ) ;
2010-03-10 18:09:35 -05:00
}
2012-11-10 17:59:51 -05:00
bool RetroShareLink : : checkSSLId ( const QString & ssl_id )
{
if ( ssl_id . length ( ) ! = 32 )
return false ;
2013-10-18 17:10:33 -04:00
QByteArray qb ( ssl_id . toLatin1 ( ) ) ;
2012-11-10 17:59:51 -05:00
for ( int i = 0 ; i < qb . length ( ) ; + + i )
{
unsigned char b ( qb [ i ] ) ;
if ( ! ( ( b > 47 & & b < 58 ) | | ( b > 96 & & b < 103 ) ) )
return false ;
}
return true ;
}
2013-04-13 09:12:13 -04:00
bool RetroShareLink : : checkPGPId ( const QString & pgp_id )
{
if ( pgp_id . length ( ) ! = 16 )
return false ;
2013-10-18 17:10:33 -04:00
QByteArray qb ( pgp_id . toLatin1 ( ) ) ;
2013-04-13 09:12:13 -04:00
for ( int i = 0 ; i < qb . length ( ) ; + + i )
{
unsigned char b ( qb [ i ] ) ;
if ( ! ( ( b > 47 & & b < 58 ) | | ( b > 64 & & b < 71 ) ) )
return false ;
}
return true ;
}
bool RetroShareLink : : checkRadix64 ( const QString & s )
{
2013-10-18 17:10:33 -04:00
QByteArray qb ( s . toLatin1 ( ) ) ;
2013-04-13 09:12:13 -04:00
for ( int i = 0 ; i < qb . length ( ) ; + + i )
{
unsigned char b ( qb [ i ] ) ;
2013-04-13 18:40:17 -04:00
if ( ! ( ( b > 46 & & b < 58 ) | | ( b > 64 & & b < 91 ) | | ( b > 96 & & b < 123 ) | | b = = ' + ' | | b = = ' = ' ) )
{
std : : cerr < < " Character not allowed in radix: " < < b < < std : : endl ;
2013-04-13 09:12:13 -04:00
return false ;
2013-04-13 18:40:17 -04:00
}
2013-04-13 09:12:13 -04:00
}
2013-04-13 18:40:17 -04:00
std : : cerr < < " Radix check: passed " < < std : : endl ;
2013-04-13 09:12:13 -04:00
return true ;
}
2010-03-10 16:38:26 -05:00
bool RetroShareLink : : checkHash ( const QString & hash )
{
2010-07-15 07:25:34 -04:00
if ( hash . length ( ) ! = 40 )
return false ;
2013-10-18 17:10:33 -04:00
QByteArray qb ( hash . toLatin1 ( ) ) ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
for ( int i = 0 ; i < qb . length ( ) ; + + i )
{
unsigned char b ( qb [ i ] ) ;
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
if ( ! ( ( b > 47 & & b < 58 ) | | ( b > 96 & & b < 103 ) ) )
return false ;
}
2010-03-10 16:38:26 -05:00
2010-07-15 07:25:34 -04:00
return true ;
}
2010-03-10 16:38:26 -05:00
2012-05-11 20:40:53 -04:00
static void processList ( const QStringList & list , const QString & textSingular , const QString & textPlural , QString & result )
2010-07-15 07:25:34 -04:00
{
2011-09-11 18:07:24 -04:00
if ( list . size ( ) = = 0 ) {
return ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
if ( list . size ( ) = = 1 ) {
result + = " " + textSingular + " : " ;
} else {
result + = " " + textPlural + " : " ;
}
result + = " <p style='margin-left: 5px; margin-top: 0px'> " ;
2012-05-11 20:40:53 -04:00
QStringList : : const_iterator it ;
2011-09-11 18:07:24 -04:00
for ( it = list . begin ( ) ; it ! = list . end ( ) ; + + it ) {
if ( it ! = list . begin ( ) ) {
result + = " , " ;
}
result + = * it ;
}
result + = " </p> " ;
}
2010-07-15 07:25:34 -04:00
2012-05-11 20:40:53 -04:00
/*static*/ int RetroShareLink : : process ( const QList < RetroShareLink > & linksIn , uint flag /* = RSLINK_PROCESS_NOTIFY_ALL*/ )
2011-09-11 18:07:24 -04:00
{
2012-05-11 20:40:53 -04:00
QList < RetroShareLink > : : const_iterator linkIt ;
2012-12-17 15:58:35 -05:00
flag & = ~ RSLINK_PROCESS_NOTIFY_BAD_CHARS ; // this will be set below when needed
2010-07-15 07:25:34 -04:00
2011-09-11 18:07:24 -04:00
/* filter dublicate links */
QList < RetroShareLink > links ;
for ( linkIt = linksIn . begin ( ) ; linkIt ! = linksIn . end ( ) ; linkIt + + ) {
if ( links . contains ( * linkIt ) ) {
continue ;
}
2010-07-15 07:25:34 -04:00
2011-09-11 18:07:24 -04:00
links . append ( * linkIt ) ;
}
2010-09-24 17:01:13 -04:00
2011-09-11 18:07:24 -04:00
if ( flag & RSLINK_PROCESS_NOTIFY_ASK ) {
/* ask for some types of link */
QStringList fileAdd ;
QStringList personAdd ;
for ( linkIt = links . begin ( ) ; linkIt ! = links . end ( ) ; linkIt + + ) {
2012-05-11 20:40:53 -04:00
const RetroShareLink & link = * linkIt ;
2011-09-11 18:07:24 -04:00
if ( link . valid ( ) = = false ) {
continue ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
switch ( link . type ( ) ) {
case TYPE_UNKNOWN :
case TYPE_FORUM :
case TYPE_CHANNEL :
case TYPE_SEARCH :
case TYPE_MESSAGE :
2012-01-21 16:14:11 -05:00
case TYPE_CERTIFICATE :
2013-06-10 09:27:24 -04:00
case TYPE_PRIVATE_CHAT :
case TYPE_PUBLIC_MSG :
2011-09-11 18:07:24 -04:00
// no need to ask
break ;
case TYPE_FILE :
2012-11-10 17:59:51 -05:00
case TYPE_EXTRAFILE :
2011-09-11 18:07:24 -04:00
fileAdd . append ( link . name ( ) ) ;
break ;
case TYPE_PERSON :
2014-03-17 16:56:06 -04:00
personAdd . append ( PeerDefs : : rsid ( link . name ( ) . toUtf8 ( ) . constData ( ) , RsPgpId ( link . hash ( ) . toStdString ( ) ) ) ) ;
2011-09-11 18:07:24 -04:00
break ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
}
2011-05-07 19:14:09 -04:00
2011-09-11 18:07:24 -04:00
QString content ;
if ( fileAdd . size ( ) ) {
processList ( fileAdd , QObject : : tr ( " Add file " ) , QObject : : tr ( " Add files " ) , content ) ;
}
if ( personAdd . size ( ) ) {
processList ( personAdd , QObject : : tr ( " Add friend " ) , QObject : : tr ( " Add friends " ) , content ) ;
}
if ( content . isEmpty ( ) = = false ) {
QString question = " <html><body> " ;
if ( links . size ( ) = = 1 ) {
question + = QObject : : tr ( " Do you want to process the link ? " ) ;
} else {
question + = QObject : : tr ( " Do you want to process %1 links ? " ) . arg ( links . size ( ) ) ;
}
question + = " <br><br> " + content + " </body></html> " ;
QMessageBox mb ( QObject : : tr ( " Confirmation " ) , question , QMessageBox : : Question , QMessageBox : : Yes , QMessageBox : : No , 0 ) ;
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
if ( mb . exec ( ) = = QMessageBox : : No ) {
return 0 ;
2011-05-07 19:14:09 -04:00
}
}
2011-09-11 18:07:24 -04:00
}
2010-07-15 07:25:34 -04:00
2011-09-11 18:07:24 -04:00
int countInvalid = 0 ;
int countUnknown = 0 ;
bool needNotifySuccess = false ;
// file
QStringList fileAdded ;
QStringList fileExist ;
// person
QStringList personAdded ;
QStringList personExist ;
QStringList personFailed ;
QStringList personNotFound ;
// forum
QStringList forumFound ;
QStringList forumMsgFound ;
QStringList forumUnknown ;
QStringList forumMsgUnknown ;
// forum
QStringList channelFound ;
QStringList channelMsgFound ;
QStringList channelUnknown ;
QStringList channelMsgUnknown ;
// search
QStringList searchStarted ;
// message
QStringList messageStarted ;
QStringList messageReceipientNotAccepted ;
QStringList messageReceipientUnknown ;
2012-01-18 15:31:30 -05:00
// Certificate
QStringList GPGBase64Strings ;
QStringList SSLIds ;
2011-09-11 18:07:24 -04:00
// summary
QList < QStringList * > processedList ;
QList < QStringList * > errorList ;
processedList < < & fileAdded < < & personAdded < < & forumFound < < & channelFound < < & searchStarted < < & messageStarted ;
errorList < < & fileExist < < & personExist < < & personFailed < < & personNotFound < < & forumUnknown < < & forumMsgUnknown < < & channelUnknown < < & channelMsgUnknown < < & messageReceipientNotAccepted < < & messageReceipientUnknown ;
// not needed: forumFound, channelFound, messageStarted
for ( linkIt = links . begin ( ) ; linkIt ! = links . end ( ) ; linkIt + + ) {
2012-05-11 20:40:53 -04:00
const RetroShareLink & link = * linkIt ;
2011-09-11 18:07:24 -04:00
if ( link . valid ( ) = = false ) {
std : : cerr < < " RetroShareLink::process invalid request " < < std : : endl ;
countInvalid + + ;
continue ;
}
2012-01-18 15:31:30 -05:00
switch ( link . type ( ) )
{
case TYPE_UNKNOWN :
countUnknown + + ;
break ;
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
case TYPE_CERTIFICATE :
{
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process certificate. " < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2012-01-18 15:31:30 -05:00
needNotifySuccess = true ;
2010-07-15 07:25:34 -04:00
2012-01-18 15:31:30 -05:00
QString RS_Certificate ;
RS_Certificate + = " -----BEGIN PGP PUBLIC KEY BLOCK----- \n " ;
RS_Certificate + = " Version: Retroshare Generated cert. \n " ;
RS_Certificate + = " \n " ;
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
QString radix = link . GPGRadix64Key ( ) ;
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
while ( radix . size ( ) > 64 )
{
RS_Certificate + = radix . left ( 64 ) + " \n " ;
radix = radix . right ( radix . size ( ) - 64 ) ;
}
RS_Certificate + = radix . left ( 64 ) + " \n " ;
RS_Certificate + = " = " + link . GPGBase64CheckSum ( ) + " \n " ;
RS_Certificate + = " -----END PGP PUBLIC KEY BLOCK----- \n " ;
RS_Certificate + = " --SSLID-- " + link . SSLId ( ) + " ;--LOCATION-- " + link . location ( ) + " ; \n " ;
2012-02-11 09:49:04 -05:00
if ( ! link . externalIPAndPort ( ) . isNull ( ) )
RS_Certificate + = " --EXT-- " + link . externalIPAndPort ( ) + " ; " ;
if ( ! link . localIPAndPort ( ) . isNull ( ) )
RS_Certificate + = " --LOCAL-- " + link . localIPAndPort ( ) + " ; " ;
2013-07-06 16:27:29 -04:00
if ( ! link . dyndns ( ) . isNull ( ) )
RS_Certificate + = " --DYNDNS-- " + link . dyndns ( ) + " ; " ;
2012-02-11 09:49:04 -05:00
RS_Certificate + = " \n " ;
2012-01-18 15:31:30 -05:00
std : : cerr < < " Usign this certificate: " < < std : : endl ;
std : : cerr < < RS_Certificate . toStdString ( ) < < std : : endl ;
2011-05-07 19:14:09 -04:00
2012-05-22 18:24:10 -04:00
ConnectFriendWizard connectFriendWizard ;
2012-08-16 06:20:34 -04:00
connectFriendWizard . setCertificate ( RS_Certificate , ( link . subType ( ) = = RSLINK_SUBTYPE_CERTIFICATE_USER_REQUEST ) ? true : false ) ;
2012-05-22 18:24:10 -04:00
connectFriendWizard . exec ( ) ;
2012-01-18 15:31:30 -05:00
needNotifySuccess = false ;
2011-05-07 19:14:09 -04:00
}
2012-01-18 15:31:30 -05:00
break ;
2011-05-07 19:14:09 -04:00
2013-04-13 09:12:13 -04:00
case TYPE_PUBLIC_MSG :
2014-03-17 16:56:06 -04:00
{
std : : cerr < < " (!!) Distant messages from links is disabled for now " < < std : : endl ;
// std::cerr << "Opening a public msg window " << std::endl;
// std::cerr << " time_stamp = " << link._time_stamp << std::endl;
// std::cerr << " hash = " << link._hash.toStdString() << std::endl;
// std::cerr << " Issuer Id = " << link._GPGid.toStdString() << std::endl;
//
// if(link._time_stamp < time(NULL))
// {
// QMessageBox::information(NULL,QObject::tr("Messaging link is expired"),QObject::tr("This Messaging link is expired. The destination peer will not receive it.")) ;
// break ;
// }
//
// MessageComposer::msgDistantPeer(link._hash.toStdString(),link._GPGid.toStdString()) ;
2013-04-13 09:12:13 -04:00
}
break ;
case TYPE_PRIVATE_CHAT :
{
std : : cerr < < " Opening a private chat window " < < std : : endl ;
std : : cerr < < " time_stamp = " < < link . _time_stamp < < std : : endl ;
std : : cerr < < " enc-string = " < < link . _encrypted_chat_info . toStdString ( ) < < std : : endl ;
2013-04-13 18:40:17 -04:00
std : : cerr < < " PGP Id = " < < link . _GPGid . toStdString ( ) < < std : : endl ;
2013-04-16 17:13:42 -04:00
if ( link . _time_stamp < time ( NULL ) )
{
2013-04-18 17:41:13 -04:00
QMessageBox : : information ( NULL , QObject : : tr ( " Chat link is expired " ) , QObject : : tr ( " This chat link is expired. The destination peer will not answer. " ) ) ;
2013-04-16 17:13:42 -04:00
break ;
}
2014-03-17 16:56:06 -04:00
if ( RsPgpId ( link . _GPGid . toStdString ( ) ) ! = rsPeers - > getGPGOwnId ( ) )
2013-04-16 17:13:42 -04:00
{
2013-06-24 17:23:50 -04:00
QMessageBox : : information ( NULL , QObject : : tr ( " Chat link cannot be decrypted " ) , QObject : : tr ( " This chat link is encrypted with a key that is not yours. You can't use it. Key ID = " ) + link . _GPGid ) ;
2013-04-16 17:13:42 -04:00
break ;
}
2014-03-17 16:56:06 -04:00
DistantChatPeerId dpid ;
2013-04-18 17:41:13 -04:00
uint32_t error_code ;
2014-03-17 16:56:06 -04:00
if ( ! rsMsgs - > initiateDistantChatConnexion ( link . _encrypted_chat_info . toStdString ( ) , link . _time_stamp , dpid , error_code ) )
2013-04-18 17:41:13 -04:00
{
QString error_msg ;
switch ( error_code )
{
default :
case RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED : error_msg = QObject : : tr ( " The link could not be decrypted. " ) ; break ;
case RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH : error_msg = QObject : : tr ( " The link signature cannot be checked. " ) ; break ;
case RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY : error_msg = QObject : : tr ( " The link is signed by an unknown key. " ) ; break ;
}
2013-06-24 17:23:50 -04:00
QMessageBox : : information ( NULL , QObject : : tr ( " Chat connection is not possible " ) , error_msg ) ;
2013-04-18 17:41:13 -04:00
}
2013-06-17 14:53:47 -04:00
else
2013-10-07 16:49:02 -04:00
{
if ( error_code = = RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY )
2013-10-22 05:24:29 -04:00
QMessageBox : : information ( NULL , QObject : : tr ( " Chat connection is unauthenticated " ) , QObject : : tr ( " Signature check failed! \n Make sure you know who you're talking to. " ) ) ;
2013-10-07 16:49:02 -04:00
2014-03-17 16:56:06 -04:00
ChatDialog : : chatFriend ( dpid ) ;
2013-10-07 16:49:02 -04:00
}
2013-04-13 09:12:13 -04:00
}
break ;
2012-01-18 15:31:30 -05:00
case TYPE_FILE :
2012-11-10 17:59:51 -05:00
case TYPE_EXTRAFILE :
2012-01-18 15:31:30 -05:00
{
2011-09-11 18:07:24 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process FileRequest : fileName : " < < link . name ( ) . toUtf8 ( ) . constData ( ) < < " . fileHash : " < < link . hash ( ) . toStdString ( ) < < " . fileSize : " < < link . size ( ) < < std : : endl ;
2011-09-11 18:07:24 -04:00
# endif
2012-01-18 15:31:30 -05:00
needNotifySuccess = true ;
2014-03-17 16:56:06 -04:00
std : : list < RsPeerId > srcIds ;
2012-11-10 17:59:51 -05:00
// Add the link built-in source. This is needed for EXTRA files, where the source is specified in the link.
if ( link . type ( ) = = TYPE_EXTRAFILE )
{
# ifdef DEBUG_RSLINK
std : : cerr < < " RetroShareLink::process Adding built-in source " < < link . SSLId ( ) . toStdString ( ) < < std : : endl ;
# endif
2014-03-17 16:56:06 -04:00
srcIds . push_back ( RsPeerId ( link . SSLId ( ) . toStdString ( ) ) ) ;
2012-11-10 17:59:51 -05:00
}
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
// Get a list of available direct sources, in case the file is browsable only.
2012-11-10 17:59:51 -05:00
//
2012-01-18 15:31:30 -05:00
FileInfo finfo ;
2014-03-17 16:56:06 -04:00
rsFiles - > FileDetails ( RsFileHash ( link . hash ( ) . toStdString ( ) ) , RS_FILE_HINTS_REMOTE , finfo ) ;
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
for ( std : : list < TransferInfo > : : const_iterator it ( finfo . peers . begin ( ) ) ; it ! = finfo . peers . end ( ) ; + + it )
{
# ifdef DEBUG_RSLINK
std : : cerr < < " adding peerid " < < ( * it ) . peerId < < std : : endl ;
# endif
2014-03-17 16:56:06 -04:00
srcIds . push_back ( ( * it ) . peerId ) ;
2011-09-11 18:07:24 -04:00
}
2012-12-13 17:13:58 -05:00
QString cleanname = link . name ( ) ;
2012-12-13 17:48:36 -05:00
static const QString bad_chars_str = " / \\ \" *:?<>| " ;
2012-12-13 17:13:58 -05:00
2013-06-10 09:27:24 -04:00
for ( int i = 0 ; i < cleanname . length ( ) ; + + i )
for ( int j = 0 ; j < bad_chars_str . length ( ) ; + + j )
2012-12-13 17:48:36 -05:00
if ( cleanname [ i ] = = bad_chars_str [ j ] )
{
cleanname [ i ] = ' _ ' ;
flag | = RSLINK_PROCESS_NOTIFY_BAD_CHARS ;
}
2012-12-13 17:13:58 -05:00
2014-03-17 16:56:06 -04:00
if ( rsFiles - > FileRequest ( cleanname . toUtf8 ( ) . constData ( ) , RsFileHash ( link . hash ( ) . toStdString ( ) ) , link . size ( ) , " " , RS_FILE_REQ_ANONYMOUS_ROUTING , srcIds ) ) {
2012-01-18 15:31:30 -05:00
fileAdded . append ( link . name ( ) ) ;
} else {
fileExist . append ( link . name ( ) ) ;
2011-05-07 19:14:09 -04:00
}
2014-03-17 16:56:06 -04:00
break ;
2011-05-07 19:14:09 -04:00
}
2012-01-18 15:31:30 -05:00
case TYPE_PERSON :
{
2011-04-19 15:42:44 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process FriendRequest : name : " < < link . name ( ) . toStdString ( ) < < " . id : " < < link . hash ( ) . toStdString ( ) < < std : : endl ;
2011-04-19 15:42:44 -04:00
# endif
2012-01-18 15:31:30 -05:00
needNotifySuccess = true ;
RsPeerDetails detail ;
2014-03-17 16:56:06 -04:00
if ( rsPeers - > getPeerDetails ( RsPeerId ( link . hash ( ) . toStdString ( ) ) , detail ) )
{
if ( RsPgpId ( detail . gpg_id ) = = rsPeers - > getGPGOwnId ( ) ) {
// it's me, do nothing
break ;
}
2012-01-18 15:31:30 -05:00
2014-03-17 16:56:06 -04:00
if ( detail . accept_connection ) {
// peer connection is already accepted
personExist . append ( PeerDefs : : rsid ( detail ) ) ;
break ;
}
2012-01-18 15:31:30 -05:00
2014-03-17 16:56:06 -04:00
if ( rsPeers - > addFriend ( RsPeerId ( ) , RsPgpId ( link . hash ( ) . toStdString ( ) ) ) ) {
ConfCertDialog : : loadAll ( ) ;
personAdded . append ( PeerDefs : : rsid ( detail ) ) ;
break ;
}
2012-01-18 15:31:30 -05:00
2014-03-17 16:56:06 -04:00
personFailed . append ( PeerDefs : : rsid ( link . name ( ) . toUtf8 ( ) . constData ( ) , RsPgpId ( link . hash ( ) . toStdString ( ) ) ) ) ;
break ;
}
2012-01-18 15:31:30 -05:00
2014-03-17 16:56:06 -04:00
personNotFound . append ( PeerDefs : : rsid ( link . name ( ) . toUtf8 ( ) . constData ( ) , RsPgpId ( link . hash ( ) . toStdString ( ) ) ) ) ;
2011-09-11 18:07:24 -04:00
break ;
2011-05-07 19:14:09 -04:00
}
2013-09-07 00:21:48 -04:00
#if 0
2012-01-18 15:31:30 -05:00
case TYPE_FORUM :
{
# ifdef DEBUG_RSLINK
std : : cerr < < " RetroShareLink::process ForumRequest : name : " < < link . name ( ) . toStdString ( ) < < " . id : " < < link . hash ( ) . toStdString ( ) < < " . msgId : " < < link . msgId ( ) . toStdString ( ) < < std : : endl ;
# endif
ForumInfo fi ;
if ( ! rsForums - > getForumInfo ( link . id ( ) . toStdString ( ) , fi ) ) {
if ( link . msgId ( ) . isEmpty ( ) ) {
forumUnknown . append ( link . name ( ) ) ;
} else {
forumMsgUnknown . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
break ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
ForumMsgInfo msg ;
if ( ! link . msgId ( ) . isEmpty ( ) ) {
if ( ! rsForums - > getForumMessage ( fi . forumId , link . msgId ( ) . toStdString ( ) , msg ) ) {
forumMsgUnknown . append ( link . name ( ) ) ;
break ;
}
}
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
MainWindow : : showWindow ( MainWindow : : Forums ) ;
ForumsDialog * forumsDialog = dynamic_cast < ForumsDialog * > ( MainWindow : : getPage ( MainWindow : : Forums ) ) ;
if ( ! forumsDialog ) {
return false ;
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
if ( forumsDialog - > navigate ( fi . forumId , msg . msgId ) ) {
if ( link . msgId ( ) . isEmpty ( ) ) {
forumFound . append ( link . name ( ) ) ;
} else {
forumMsgFound . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
} else {
2012-01-18 15:31:30 -05:00
if ( link . msgId ( ) . isEmpty ( ) ) {
forumUnknown . append ( link . name ( ) ) ;
} else {
forumMsgUnknown . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
break ;
2011-09-11 18:07:24 -04:00
}
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
case TYPE_CHANNEL :
{
2011-04-19 15:42:44 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process ChannelRequest : name : " < < link . name ( ) . toStdString ( ) < < " . id : " < < link . hash ( ) . toStdString ( ) < < " . msgId : " < < link . msgId ( ) . toStdString ( ) < < std : : endl ;
2011-04-19 15:42:44 -04:00
# endif
2012-01-18 15:31:30 -05:00
ChannelInfo ci ;
if ( ! rsChannels - > getChannelInfo ( link . id ( ) . toStdString ( ) , ci ) ) {
if ( link . msgId ( ) . isEmpty ( ) ) {
channelUnknown . append ( link . name ( ) ) ;
} else {
channelMsgUnknown . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
break ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
ChannelMsgInfo msg ;
if ( ! link . msgId ( ) . isEmpty ( ) ) {
if ( ! rsChannels - > getChannelMessage ( ci . channelId , link . msgId ( ) . toStdString ( ) , msg ) ) {
channelMsgUnknown . append ( link . name ( ) ) ;
break ;
}
}
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
MainWindow : : showWindow ( MainWindow : : Channels ) ;
ChannelFeed * channelFeed = dynamic_cast < ChannelFeed * > ( MainWindow : : getPage ( MainWindow : : Channels ) ) ;
if ( ! channelFeed ) {
return false ;
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
if ( channelFeed - > navigate ( ci . channelId , msg . msgId ) ) {
if ( link . msgId ( ) . isEmpty ( ) ) {
channelFound . append ( link . name ( ) ) ;
} else {
channelMsgFound . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
} else {
2012-01-18 15:31:30 -05:00
if ( link . msgId ( ) . isEmpty ( ) ) {
channelUnknown . append ( link . name ( ) ) ;
} else {
channelMsgUnknown . append ( link . name ( ) ) ;
}
2011-09-11 18:07:24 -04:00
}
2012-01-18 15:31:30 -05:00
break ;
2011-09-11 18:07:24 -04:00
}
2013-09-07 00:21:48 -04:00
# endif
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
case TYPE_SEARCH :
{
2011-05-07 19:14:09 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process SearchRequest : string : " < < link . name ( ) . toStdString ( ) < < std : : endl ;
2011-05-07 19:14:09 -04:00
# endif
2012-01-18 15:31:30 -05:00
SearchDialog * searchDialog = dynamic_cast < SearchDialog * > ( MainWindow : : getPage ( MainWindow : : Search ) ) ;
2013-02-23 08:24:16 -05:00
if ( ! searchDialog )
{
std : : cerr < < " Retrieve of search dialog failed. Please debug! " < < std : : endl ;
2012-01-18 15:31:30 -05:00
break ;
}
2013-02-23 09:29:36 -05:00
MainWindow : : showWindow ( MainWindow : : Search ) ;
2012-01-18 15:31:30 -05:00
searchDialog - > searchKeywords ( link . name ( ) ) ;
searchStarted . append ( link . name ( ) ) ;
2011-09-11 18:07:24 -04:00
break ;
}
2011-04-19 15:42:44 -04:00
2012-01-18 15:31:30 -05:00
case TYPE_MESSAGE :
{
2011-05-04 06:22:49 -04:00
# ifdef DEBUG_RSLINK
2012-01-18 15:31:30 -05:00
std : : cerr < < " RetroShareLink::process MessageRequest : id : " < < link . hash ( ) . toStdString ( ) < < " , subject : " < < link . name ( ) . toStdString ( ) < < std : : endl ;
2011-05-04 06:22:49 -04:00
# endif
2012-01-18 15:31:30 -05:00
RsPeerDetails detail ;
2014-03-17 16:56:06 -04:00
DistantMsgPeerId dm_pid ;
// This is awful, but apparently the hash can be multiple different types. Let's check!
RsPgpId pgp_id ( link . hash ( ) . toStdString ( ) ) ;
RsPeerId ssl_id ( link . hash ( ) . toStdString ( ) ) ;
2013-08-30 16:40:28 -04:00
2014-03-17 16:56:06 -04:00
if ( ! pgp_id . isNull ( ) & & rsPeers - > getGPGDetails ( pgp_id , detail )
| | ! ssl_id . isNull ( ) & & rsPeers - > getPeerDetails ( ssl_id , detail ) )
2013-08-30 16:40:28 -04:00
{
2014-03-17 16:56:06 -04:00
if ( detail . accept_connection | | RsPeerId ( detail . id ) = = rsPeers - > getOwnId ( ) | | RsPgpId ( detail . gpg_id ) = = rsPeers - > getGPGOwnId ( ) ) {
2012-01-18 15:31:30 -05:00
MessageComposer * msg = MessageComposer : : newMsg ( ) ;
msg - > addRecipient ( MessageComposer : : TO , detail . id , false ) ;
if ( link . subject ( ) . isEmpty ( ) = = false ) {
2012-05-04 19:39:36 -04:00
msg - > setTitleText ( link . subject ( ) ) ;
2012-01-18 15:31:30 -05:00
}
msg - > show ( ) ;
messageStarted . append ( PeerDefs : : nameWithLocation ( detail ) ) ;
2013-08-30 16:40:28 -04:00
}
2014-03-17 16:56:06 -04:00
else if ( rsMsgs - > getDistantMessagePeerId ( detail . gpg_id , dm_pid ) )
2013-08-30 16:40:28 -04:00
{
MessageComposer * msg = MessageComposer : : newMsg ( ) ;
2014-03-17 16:56:06 -04:00
msg - > addRecipient ( MessageComposer : : TO , dm_pid , detail . gpg_id ) ;
2013-08-30 16:40:28 -04:00
if ( link . subject ( ) . isEmpty ( ) = = false ) {
msg - > setTitleText ( link . subject ( ) ) ;
}
msg - > show ( ) ;
messageStarted . append ( PeerDefs : : nameWithLocation ( detail ) ) ;
}
else
{
2012-01-18 15:31:30 -05:00
messageReceipientNotAccepted . append ( PeerDefs : : nameWithLocation ( detail ) ) ;
2011-09-11 18:07:24 -04:00
}
} else {
2014-03-17 16:56:06 -04:00
messageReceipientUnknown . append ( PeerDefs : : rsidFromId ( RsPeerId ( link . hash ( ) . toStdString ( ) ) ) ) ;
2011-05-07 19:14:09 -04:00
}
2011-09-11 18:07:24 -04:00
2012-01-18 15:31:30 -05:00
break ;
}
2011-05-07 19:14:09 -04:00
2012-01-18 15:31:30 -05:00
default :
std : : cerr < < " RetroShareLink::process unknown type: " < < link . type ( ) < < std : : endl ;
countUnknown + + ;
2011-05-07 19:14:09 -04:00
}
}
2011-05-04 06:22:49 -04:00
2011-09-11 18:07:24 -04:00
int countProcessed = 0 ;
int countError = 0 ;
2010-07-15 07:25:34 -04:00
2011-09-11 18:07:24 -04:00
QList < QStringList * > : : iterator listIt ;
for ( listIt = processedList . begin ( ) ; listIt ! = processedList . end ( ) ; + + listIt ) {
countProcessed + = ( * listIt ) - > size ( ) ;
}
for ( listIt = errorList . begin ( ) ; listIt ! = errorList . end ( ) ; + + listIt ) {
countError + = ( * listIt ) - > size ( ) ;
}
// success notify needed ?
if ( needNotifySuccess = = false ) {
flag & = ~ RSLINK_PROCESS_NOTIFY_SUCCESS ;
}
// error notify needed ?
if ( countError = = 0 ) {
flag & = ~ RSLINK_PROCESS_NOTIFY_ERROR ;
}
QString result ;
if ( flag & ( RSLINK_PROCESS_NOTIFY_SUCCESS | RSLINK_PROCESS_NOTIFY_ERROR ) ) {
result + = ( links . count ( ) = = 1 ? QObject : : tr ( " %1 of %2 RetroShare link processed. " ) : QObject : : tr ( " %1 of %2 RetroShare links processed. " ) ) . arg ( countProcessed ) . arg ( links . count ( ) ) + " <br><br> " ;
}
// file
if ( flag & RSLINK_PROCESS_NOTIFY_SUCCESS ) {
if ( fileAdded . size ( ) ) {
processList ( fileAdded , QObject : : tr ( " File added " ) , QObject : : tr ( " Files added " ) , result ) ;
}
}
2011-05-07 19:14:09 -04:00
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
2011-09-11 18:07:24 -04:00
if ( fileExist . size ( ) ) {
processList ( fileExist , QObject : : tr ( " File exist " ) , QObject : : tr ( " Files exist " ) , result ) ;
}
}
// person
if ( flag & RSLINK_PROCESS_NOTIFY_SUCCESS ) {
if ( personAdded . size ( ) ) {
processList ( personAdded , QObject : : tr ( " Friend added " ) , QObject : : tr ( " Friends added " ) , result ) ;
}
}
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( personExist . size ( ) ) {
processList ( personExist , QObject : : tr ( " Friend exist " ) , QObject : : tr ( " Friends exist " ) , result ) ;
}
if ( personFailed . size ( ) ) {
processList ( personFailed , QObject : : tr ( " Friend not added " ) , QObject : : tr ( " Friends not added " ) , result ) ;
}
if ( personNotFound . size ( ) ) {
processList ( personNotFound , QObject : : tr ( " Friend not found " ) , QObject : : tr ( " Friends not found " ) , result ) ;
}
}
// forum
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( forumUnknown . size ( ) ) {
processList ( forumUnknown , QObject : : tr ( " Forum not found " ) , QObject : : tr ( " Forums not found " ) , result ) ;
}
if ( forumMsgUnknown . size ( ) ) {
processList ( forumMsgUnknown , QObject : : tr ( " Forum message not found " ) , QObject : : tr ( " Forum messages not found " ) , result ) ;
}
}
// channel
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( channelUnknown . size ( ) ) {
processList ( channelUnknown , QObject : : tr ( " Channel not found " ) , QObject : : tr ( " Channels not found " ) , result ) ;
}
if ( channelMsgUnknown . size ( ) ) {
processList ( channelMsgUnknown , QObject : : tr ( " Channel message not found " ) , QObject : : tr ( " Channel messages not found " ) , result ) ;
}
}
// message
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( messageReceipientNotAccepted . size ( ) ) {
2012-10-11 06:28:24 -04:00
processList ( messageReceipientNotAccepted , QObject : : tr ( " Recipient not accepted " ) , QObject : : tr ( " Recipients not accepted " ) , result ) ;
2011-09-11 18:07:24 -04:00
}
if ( messageReceipientUnknown . size ( ) ) {
2012-10-11 06:28:24 -04:00
processList ( messageReceipientUnknown , QObject : : tr ( " Unkown recipient " ) , QObject : : tr ( " Unkown recipients " ) , result ) ;
2011-09-11 18:07:24 -04:00
}
}
if ( flag & RSLINK_PROCESS_NOTIFY_ERROR ) {
if ( countUnknown ) {
result + = QString ( " <br>%1: %2 " ) . arg ( QObject : : tr ( " Malformed links " ) ) . arg ( countUnknown ) ;
}
if ( countInvalid ) {
result + = QString ( " <br>%1: %2 " ) . arg ( QObject : : tr ( " Invalid links " ) ) . arg ( countInvalid ) ;
}
}
2012-12-13 17:13:58 -05:00
if ( flag & RSLINK_PROCESS_NOTIFY_BAD_CHARS )
2012-12-13 17:48:36 -05:00
result + = QString ( " <br>%1 " ) . arg ( QObject : : tr ( " Warning: forbidden characters found in filenames. \n Characters <b> \" ,|,/, \\ ,<,>,*,?</b> will be replaced by '_'. " ) ) ;
2011-09-11 18:07:24 -04:00
if ( result . isEmpty ( ) = = false ) {
QMessageBox mb ( QObject : : tr ( " Result " ) , " <html><body> " + result + " </body></html> " , QMessageBox : : Information , QMessageBox : : Ok , 0 , 0 ) ;
2011-05-07 19:14:09 -04:00
mb . setWindowIcon ( QIcon ( QString : : fromUtf8 ( " :/images/rstray3.png " ) ) ) ;
mb . exec ( ) ;
}
2011-09-11 18:07:24 -04:00
2012-12-13 17:13:58 -05:00
2011-09-11 18:07:24 -04:00
return 0 ;
2010-03-10 16:38:26 -05:00
}
2012-05-11 20:40:53 -04:00
/*static*/ int RetroShareLink : : process ( const QStringList & urls , RetroShareLink : : enumType type /* = RetroShareLink::TYPE_UNKNOWN*/ , uint flag /* = RSLINK_PROCESS_NOTIFY_ALL*/ )
2011-05-15 16:21:14 -04:00
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2011-05-15 16:21:14 -04:00
2012-05-11 20:40:53 -04:00
for ( QStringList : : const_iterator it = urls . begin ( ) ; it ! = urls . end ( ) ; it + + ) {
2011-05-15 16:21:14 -04:00
RetroShareLink link ( * it ) ;
if ( link . valid ( ) & & ( type = = RetroShareLink : : TYPE_UNKNOWN | | link . type ( ) = = type ) ) {
2011-09-11 18:07:24 -04:00
links . append ( link ) ;
2011-05-15 16:21:14 -04:00
}
}
2011-09-11 18:07:24 -04:00
return process ( links , flag ) ;
2011-05-15 16:21:14 -04:00
}
2011-09-11 18:07:24 -04:00
void RSLinkClipboard : : copyLinks ( const QList < RetroShareLink > & links )
2010-03-22 15:46:58 -04:00
{
2010-07-15 07:25:34 -04:00
QString res ;
2011-09-11 18:07:24 -04:00
for ( int i = 0 ; i < links . size ( ) ; + + i )
2010-07-15 07:25:34 -04:00
res + = links [ i ] . toString ( ) + " \n " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QApplication : : clipboard ( ) - > setText ( res ) ;
2010-03-22 15:46:58 -04:00
}
2011-09-11 18:07:24 -04:00
void RSLinkClipboard : : pasteLinks ( QList < RetroShareLink > & links )
2010-03-22 15:46:58 -04:00
{
2010-07-15 07:25:34 -04:00
return parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
}
2011-09-11 18:07:24 -04:00
void RSLinkClipboard : : parseClipboard ( QList < RetroShareLink > & links )
2010-03-22 15:46:58 -04:00
{
2010-07-15 07:25:34 -04:00
// parse clipboard for links.
//
links . clear ( ) ;
QString text = QApplication : : clipboard ( ) - > text ( ) ;
std : : cerr < < " Parsing clipboard: " < < text . toStdString ( ) < < std : : endl ;
2011-04-19 15:42:44 -04:00
QRegExp rx ( QString ( " retroshare://(%1) [ ^ \ r \ n ] + " ).arg(HOST_REGEXP)) ;
2010-07-15 07:25:34 -04:00
int pos = 0 ;
while ( ( pos = rx . indexIn ( text , pos ) ) ! = - 1 )
{
QString url ( text . mid ( pos , rx . matchedLength ( ) ) ) ;
RetroShareLink link ( url ) ;
if ( link . valid ( ) )
{
// check that the link is not already in the list:
bool already = false ;
2011-09-11 18:07:24 -04:00
for ( int i = 0 ; i < links . size ( ) ; + + i )
2010-07-15 07:25:34 -04:00
if ( links [ i ] = = link )
{
2011-09-11 18:07:24 -04:00
already = true ;
break ;
}
2010-07-15 07:25:34 -04:00
if ( ! already )
{
links . push_back ( link ) ;
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
std : : cerr < < " captured link: " < < link . toString ( ) . toStdString ( ) < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2010-07-15 07:25:34 -04:00
}
}
2011-02-09 16:44:49 -05:00
# ifdef DEBUG_RSLINK
2010-07-15 07:25:34 -04:00
else
std : : cerr < < " invalid link " < < std : : endl ;
2011-02-09 16:44:49 -05:00
# endif
2010-07-15 07:25:34 -04:00
pos + = rx . matchedLength ( ) ;
}
2010-03-22 15:46:58 -04:00
}
QString RSLinkClipboard : : toString ( )
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2010-07-15 07:25:34 -04:00
parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QString res ;
2011-09-11 18:07:24 -04:00
for ( int i = 0 ; i < links . size ( ) ; + + i )
2010-07-15 07:25:34 -04:00
res + = links [ i ] . toString ( ) + " \n " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
return res ;
2010-03-22 15:46:58 -04:00
}
QString RSLinkClipboard : : toHtml ( )
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2010-07-15 07:25:34 -04:00
parseClipboard ( links ) ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
QString res ;
2011-09-11 18:07:24 -04:00
for ( int i = 0 ; i < links . size ( ) ; + + i )
2011-10-05 12:57:33 -04:00
res + = links [ i ] . toHtml ( ) + " <br> " ;
2010-03-22 15:46:58 -04:00
2010-07-15 07:25:34 -04:00
return res ;
2010-03-22 15:46:58 -04:00
}
2010-07-15 07:25:34 -04:00
2012-02-08 07:11:15 -05:00
bool RSLinkClipboard : : empty ( RetroShareLink : : enumType type /* = RetroShareLink::TYPE_UNKNOWN*/ )
2010-03-22 15:46:58 -04:00
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2010-07-15 07:25:34 -04:00
parseClipboard ( links ) ;
if ( type = = RetroShareLink : : TYPE_UNKNOWN ) {
return links . empty ( ) ;
}
2011-09-11 18:07:24 -04:00
for ( QList < RetroShareLink > : : iterator link = links . begin ( ) ; link ! = links . end ( ) ; link + + ) {
2010-07-15 07:25:34 -04:00
if ( link - > type ( ) = = type ) {
return false ;
}
}
return true ;
2010-03-22 15:46:58 -04:00
}
2012-02-08 07:11:15 -05:00
/*static*/ int RSLinkClipboard : : process ( RetroShareLink : : enumType type /* = RetroShareLink::TYPE_UNKNOWN*/ , uint flag /* = RSLINK_PROCESS_NOTIFY_ALL*/ )
2010-07-15 07:25:34 -04:00
{
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > links ;
2010-07-15 07:25:34 -04:00
pasteLinks ( links ) ;
2011-09-11 18:07:24 -04:00
QList < RetroShareLink > linksToProcess ;
for ( int i = 0 ; i < links . size ( ) ; i + + ) {
2010-07-15 07:25:34 -04:00
if ( links [ i ] . valid ( ) & & ( type = = RetroShareLink : : TYPE_UNKNOWN | | links [ i ] . type ( ) = = type ) ) {
2011-09-11 18:07:24 -04:00
linksToProcess . append ( links [ i ] ) ;
2010-07-15 07:25:34 -04:00
}
}
2011-09-11 18:07:24 -04:00
if ( linksToProcess . size ( ) = = 0 ) {
return 0 ;
}
return RetroShareLink : : process ( linksToProcess , flag ) ;
2010-07-15 07:25:34 -04:00
}
2012-01-18 15:31:30 -05:00