2007-12-11 20:43:17 -05:00
/*
* libretroshare / src / services msgservice . cc
*
* Services for RetroShare .
*
* Copyright 2004 - 2008 by Robert Fernie .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* USA .
*
* Please report all bugs and problems to " retroshare@lunamutt.com " .
*
*/
2010-08-06 05:40:23 -04:00
# include "retroshare/rsiface.h"
2013-05-01 17:13:40 -04:00
# include "retroshare/rspeers.h"
2009-02-22 12:36:39 -05:00
2007-12-11 20:43:17 -05:00
# include "pqi/pqibin.h"
# include "pqi/pqiarchive.h"
2011-07-09 14:39:34 -04:00
# include "pqi/p3linkmgr.h"
2013-04-29 16:44:48 -04:00
# include "pqi/authgpg.h"
2007-12-11 20:43:17 -05:00
# include "services/p3msgservice.h"
2013-05-03 17:02:44 -04:00
# include "pgp/pgpkeyutil.h"
2008-03-31 10:06:59 -04:00
# include "pqi/pqinotify.h"
2007-12-11 20:43:17 -05:00
2008-07-10 12:29:18 -04:00
# include "util/rsdebug.h"
2008-02-04 12:55:13 -05:00
# include "util/rsdir.h"
2012-03-30 19:02:52 -04:00
# include "util/rsstring.h"
2013-05-04 18:03:48 -04:00
# include "util/radix64.h"
2013-04-29 16:44:48 -04:00
# include "util/rsrandom.h"
2008-02-04 12:55:13 -05:00
2007-12-11 20:43:17 -05:00
# include <iomanip>
2010-09-25 08:54:34 -04:00
# include <map>
2007-12-11 20:43:17 -05:00
2013-08-09 13:02:29 -04:00
//#define DEBUG_DISTANT_MSG
2013-08-04 10:11:59 -04:00
//#define DISABLE_DISTANT_MESSAGES
2013-05-08 12:58:22 -04:00
2007-12-11 20:43:17 -05:00
const int msgservicezone = 54319 ;
2013-04-29 16:44:48 -04:00
static const uint32_t RS_DISTANT_MSG_STATUS_TUNNEL_OK = 0x0001 ;
static const uint32_t RS_DISTANT_MSG_STATUS_TUNNEL_DN = 0x0000 ;
static const uint32_t DISTANT_MSG_HASH_SIZE = 20 ;
2013-08-02 19:00:36 -04:00
static const uint8_t ENCRYPTED_MSG_PROTOCOL_VERSION_01 = 0x37 ;
2007-12-11 20:43:17 -05:00
/* Another little hack ..... unique message Ids
* will be handled in this class . . . . .
* These are unique within this run of the server ,
* and are not stored long term . . . .
*
* Only 3 entry points :
* ( 1 ) from network . . . .
* ( 2 ) from local send
* ( 3 ) from storage . . .
*/
2011-07-09 14:39:34 -04:00
p3MsgService : : p3MsgService ( p3LinkMgr * lm )
2010-09-20 18:11:09 -04:00
: p3Service ( RS_SERVICE_TYPE_MSG ) , p3Config ( CONFIG_TYPE_MSGS ) ,
2012-05-01 05:18:55 -04:00
mLinkMgr ( lm ) , mMsgMtx ( " p3MsgService " ) , mMsgUniqueId ( time ( NULL ) )
2007-12-11 20:43:17 -05:00
{
2013-05-01 17:13:40 -04:00
_serialiser = new RsMsgSerialiser ( ) ;
addSerialType ( _serialiser ) ;
2010-09-23 17:27:34 -04:00
2013-09-05 14:45:40 -04:00
mDistantMessagingEnabled = true ;
2012-05-01 05:18:55 -04:00
/* Initialize standard tag types */
if ( lm )
initStandardTagTypes ( ) ;
2007-12-11 20:43:17 -05:00
}
2008-02-04 16:40:34 -05:00
uint32_t p3MsgService : : getNewUniqueMsgId ( )
2008-02-04 12:55:13 -05:00
{
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
return mMsgUniqueId + + ;
}
2007-12-11 20:43:17 -05:00
int p3MsgService : : tick ( )
{
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::tick() " ) ;
/* don't worry about increasing tick rate!
* ( handled by p3service )
*/
incomingMsgs ( ) ;
2013-04-29 16:44:48 -04:00
static time_t last_management_time = 0 ;
time_t now = time ( NULL ) ;
if ( now > last_management_time + 5 )
{
manageDistantPeers ( ) ;
2013-08-31 17:10:04 -04:00
checkOutgoingMessages ( ) ;
2013-04-29 16:44:48 -04:00
last_management_time = now ;
}
2007-12-11 20:43:17 -05:00
return 0 ;
}
int p3MsgService : : status ( )
{
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::status() " ) ;
return 1 ;
}
2012-05-01 05:18:55 -04:00
void p3MsgService : : processMsg ( RsMsgItem * mi , bool incoming )
2011-05-21 12:26:00 -04:00
{
mi - > recvTime = time ( NULL ) ;
mi - > msgId = getNewUniqueMsgId ( ) ;
{
2012-04-26 19:41:14 -04:00
RsStackMutex stack ( mMsgMtx ) ; /*** STACK LOCKED MTX ***/
2011-05-21 12:26:00 -04:00
2012-05-01 05:18:55 -04:00
if ( incoming )
2011-05-21 12:26:00 -04:00
{
2012-04-26 19:41:14 -04:00
/* from a peer */
2013-05-04 18:03:48 -04:00
mi - > msgFlags & = ( RS_MSG_FLAGS_ENCRYPTED | RS_MSG_FLAGS_SYSTEM ) ; // remove flags except those
2012-05-01 05:18:55 -04:00
mi - > msgFlags | = RS_MSG_FLAGS_NEW ;
2012-04-26 19:41:14 -04:00
pqiNotify * notify = getPqiNotify ( ) ;
if ( notify )
{
std : : string title , message ;
librs : : util : : ConvertUtf16ToUtf8 ( mi - > subject , title ) ;
librs : : util : : ConvertUtf16ToUtf8 ( mi - > message , message ) ;
2013-08-31 09:12:26 -04:00
if ( mi - > msgFlags & RS_MSG_FLAGS_ENCRYPTED )
notify - > AddPopupMessage ( RS_POPUP_ENCRYPTED_MSG , mi - > PeerId ( ) , title , message ) ;
else
notify - > AddPopupMessage ( RS_POPUP_MSG , mi - > PeerId ( ) , title , message ) ;
2012-04-26 19:41:14 -04:00
std : : string out ;
rs_sprintf ( out , " %lu " , mi - > msgId ) ;
notify - > AddFeedItem ( RS_FEED_ITEM_MESSAGE , out , " " , " " ) ;
}
}
2012-05-01 05:18:55 -04:00
else
{
mi - > msgFlags | = RS_MSG_OUTGOING ;
}
2012-04-26 19:41:14 -04:00
imsg [ mi - > msgId ] = mi ;
RsMsgSrcId * msi = new RsMsgSrcId ( ) ;
msi - > msgId = mi - > msgId ;
msi - > srcId = mi - > PeerId ( ) ;
mSrcIds . insert ( std : : pair < uint32_t , RsMsgSrcId * > ( msi - > msgId , msi ) ) ;
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2011-05-21 12:26:00 -04:00
}
2012-04-26 19:41:14 -04:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_ADD ) ;
2011-05-21 12:26:00 -04:00
/**** STACK UNLOCKED ***/
}
2011-09-09 15:37:38 -04:00
bool p3MsgService : : checkAndRebuildPartialMessage ( RsMsgItem * ci )
{
// Check is the item is ending an incomplete item.
//
std : : map < std : : string , RsMsgItem * > : : iterator it = _pendingPartialMessages . find ( ci - > PeerId ( ) ) ;
bool ci_is_partial = ci - > msgFlags & RS_MSG_FLAGS_PARTIAL ;
if ( it ! = _pendingPartialMessages . end ( ) )
{
//#ifdef CHAT_DEBUG
std : : cerr < < " Pending message found. Happending it. " < < std : : endl ;
//#endif
// Yes, there is. Append the item to ci.
ci - > message = it - > second - > message + ci - > message ;
ci - > msgFlags | = it - > second - > msgFlags ;
delete it - > second ;
if ( ! ci_is_partial )
_pendingPartialMessages . erase ( it ) ;
}
if ( ci_is_partial )
{
//#ifdef CHAT_DEBUG
std : : cerr < < " Message is partial, storing for later. " < < std : : endl ;
//#endif
// The item is a partial message. Push it, and wait for the rest.
//
_pendingPartialMessages [ ci - > PeerId ( ) ] = ci ;
return false ;
}
else
{
//#ifdef CHAT_DEBUG
std : : cerr < < " Message is complete, using it now. " < < std : : endl ;
//#endif
return true ;
}
}
2011-05-21 12:26:00 -04:00
int p3MsgService : : incomingMsgs ( )
2007-12-11 20:43:17 -05:00
{
RsMsgItem * mi ;
int i = 0 ;
2009-02-22 12:36:39 -05:00
2007-12-11 20:43:17 -05:00
while ( ( mi = ( RsMsgItem * ) recvItem ( ) ) ! = NULL )
{
2013-04-29 16:44:48 -04:00
handleIncomingItem ( mi ) ;
+ + i ;
}
2008-02-04 16:40:34 -05:00
2013-04-29 16:44:48 -04:00
return i ;
}
void p3MsgService : : handleIncomingItem ( RsMsgItem * mi )
{
bool changed = false ;
if ( checkAndRebuildPartialMessage ( mi ) ) // only returns true when a msg is complete.
{
processMsg ( mi , true ) ;
changed = true ;
2007-12-11 20:43:17 -05:00
}
2009-02-22 12:36:39 -05:00
if ( changed )
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2007-12-11 20:43:17 -05:00
}
2011-08-12 09:42:30 -04:00
void p3MsgService : : statusChange ( const std : : list < pqipeer > & /*plist*/ )
2008-02-07 11:18:34 -05:00
{
/* should do it properly! */
checkOutgoingMessages ( ) ;
}
2011-09-09 15:37:38 -04:00
void p3MsgService : : checkSizeAndSendMessage ( RsMsgItem * msg )
{
// We check the message item, and possibly split it into multiple messages, if the message is too big.
static const uint32_t MAX_STRING_SIZE = 15000 ;
std : : cerr < < " Msg is size " < < msg - > message . size ( ) < < std : : endl ;
while ( msg - > message . size ( ) > MAX_STRING_SIZE )
{
// chop off the first 15000 wchars
RsMsgItem * item = new RsMsgItem ( * msg ) ;
item - > message = item - > message . substr ( 0 , MAX_STRING_SIZE ) ;
msg - > message = msg - > message . substr ( MAX_STRING_SIZE , msg - > message . size ( ) - MAX_STRING_SIZE ) ;
std : : cerr < < " Chopped off msg of size " < < item - > message . size ( ) < < std : : endl ;
// Indicate that the message is to be continued.
//
item - > msgFlags | = RS_MSG_FLAGS_PARTIAL ;
2013-04-29 18:32:58 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_DISTANT )
2013-09-08 07:16:13 -04:00
sendPrivateMsgItem ( item ) ;
2013-04-29 18:32:58 -04:00
else
sendItem ( item ) ;
2011-09-09 15:37:38 -04:00
}
std : : cerr < < " Chopped off msg of size " < < msg - > message . size ( ) < < std : : endl ;
2013-04-29 18:32:58 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_DISTANT )
sendPrivateMsgItem ( msg ) ;
else
sendItem ( msg ) ;
2011-09-09 15:37:38 -04:00
}
2007-12-11 20:43:17 -05:00
int p3MsgService : : checkOutgoingMessages ( )
{
/* iterate through the outgoing queue
*
* if online , send
*/
2010-05-07 18:23:38 -04:00
bool changed = false ;
2013-05-01 17:13:40 -04:00
std : : list < RsMsgItem * > output_queue ;
2008-02-04 12:55:13 -05:00
2007-12-11 20:43:17 -05:00
{
2011-07-09 14:39:34 -04:00
const std : : string ownId = mLinkMgr - > getOwnId ( ) ;
2007-12-11 20:43:17 -05:00
2010-05-07 18:23:38 -04:00
std : : list < uint32_t > : : iterator it ;
std : : list < uint32_t > toErase ;
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
for ( mit = msgOutgoing . begin ( ) ; mit ! = msgOutgoing . end ( ) ; mit + + )
2008-01-25 02:49:28 -05:00
{
2010-05-28 10:42:54 -04:00
if ( mit - > second - > msgFlags & RS_MSG_FLAGS_TRASH ) {
continue ;
}
2010-05-07 18:23:38 -04:00
/* find the certificate */
std : : string pid = mit - > second - > PeerId ( ) ;
2013-08-31 17:10:04 -04:00
bool tunnel_is_ok = false ;
2010-05-07 18:23:38 -04:00
2013-08-31 17:10:04 -04:00
if ( mit - > second - > msgFlags & RS_MSG_FLAGS_DISTANT )
{
// Do we have a tunnel already?
//
const std : : string & hash = mit - > second - > PeerId ( ) ;
std : : map < std : : string , DistantMessengingContact > : : iterator it = _messenging_contacts . find ( hash ) ;
if ( it ! = _messenging_contacts . end ( ) )
{
tunnel_is_ok = ( it - > second . status = = RS_DISTANT_MSG_STATUS_TUNNEL_OK ) ;
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " checkOutGoingMessages(): distant contact found. tunnel_is_ok = " < < tunnel_is_ok < < std : : endl ;
# endif
}
else
{
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " checkOutGoingMessages(): distant contact not found. Asking for tunnels for hash " < < hash < < std : : endl ;
# endif
// no. Ask for monitoring tunnels.
rsTurtle - > monitorTunnels ( hash , this ) ;
tunnel_is_ok = false ;
DistantMessengingContact & contact ( _messenging_contacts [ hash ] ) ;
contact . status = RS_DISTANT_MSG_STATUS_TUNNEL_DN ;
contact . pending_messages = true ;
}
}
if ( tunnel_is_ok | | mLinkMgr - > isOnline ( pid ) | | pid = = ownId ) /* FEEDBACK Msg to Ourselves */
2010-05-07 18:23:38 -04:00
{
/* send msg */
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::checkOutGoingMessages() Sending out message " ) ;
/* remove the pending flag */
( mit - > second ) - > msgFlags & = ~ RS_MSG_FLAGS_PENDING ;
2013-05-01 17:13:40 -04:00
output_queue . push_back ( mit - > second ) ;
2010-05-07 18:23:38 -04:00
toErase . push_back ( mit - > first ) ;
changed = true ;
}
else
{
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::checkOutGoingMessages() Delaying until available... " ) ;
}
2007-12-11 20:43:17 -05:00
}
2010-05-07 18:23:38 -04:00
/* clean up */
for ( it = toErase . begin ( ) ; it ! = toErase . end ( ) ; it + + )
2007-12-11 20:43:17 -05:00
{
2010-05-07 18:23:38 -04:00
mit = msgOutgoing . find ( * it ) ;
if ( mit ! = msgOutgoing . end ( ) )
{
msgOutgoing . erase ( mit ) ;
}
2010-11-10 15:37:02 -05:00
std : : map < uint32_t , RsMsgSrcId * > : : iterator srcIt = mSrcIds . find ( * it ) ;
if ( srcIt ! = mSrcIds . end ( ) ) {
delete ( srcIt - > second ) ;
mSrcIds . erase ( srcIt ) ;
}
2007-12-11 20:43:17 -05:00
}
2008-02-04 12:55:13 -05:00
2010-05-07 18:23:38 -04:00
if ( toErase . size ( ) > 0 )
2008-02-04 12:55:13 -05:00
{
2010-05-07 18:23:38 -04:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-02-04 12:55:13 -05:00
}
}
2013-05-01 17:13:40 -04:00
for ( std : : list < RsMsgItem * > : : const_iterator it ( output_queue . begin ( ) ) ; it ! = output_queue . end ( ) ; + + it )
2013-08-31 17:10:04 -04:00
{
2013-05-01 17:13:40 -04:00
checkSizeAndSendMessage ( * it ) ;
2013-08-31 17:10:04 -04:00
if ( ( * it ) - > msgFlags & RS_MSG_FLAGS_DISTANT )
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
_messenging_contacts [ ( * it ) - > PeerId ( ) ] . pending_messages = false ;
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " checkOutgoingMessages(): removing pending message flag for hash " < < ( * it ) - > PeerId ( ) < < " . " < < std : : endl ;
# endif
}
}
2010-05-07 18:23:38 -04:00
if ( changed )
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2008-02-07 11:18:34 -05:00
2007-12-11 20:43:17 -05:00
return 0 ;
}
2010-12-18 14:35:07 -05:00
bool p3MsgService : : saveList ( bool & cleanup , std : : list < RsItem * > & itemList )
2007-12-11 20:43:17 -05:00
{
2010-09-20 18:11:09 -04:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
std : : map < uint32_t , RsMsgTagType * > : : iterator mit2 ;
std : : map < uint32_t , RsMsgTags * > : : iterator mit3 ;
2010-11-10 15:37:02 -05:00
std : : map < uint32_t , RsMsgSrcId * > : : iterator lit ;
2010-11-02 17:11:11 -04:00
std : : map < uint32_t , RsMsgParentId * > : : iterator mit4 ;
2008-02-04 16:40:34 -05:00
2010-10-31 15:29:26 -04:00
MsgTagType stdTags ;
2010-09-25 08:54:34 -04:00
2010-09-20 18:11:09 -04:00
cleanup = false ;
2007-12-11 20:43:17 -05:00
2010-09-20 18:11:09 -04:00
mMsgMtx . lock ( ) ;
2007-12-11 20:43:17 -05:00
for ( mit = imsg . begin ( ) ; mit ! = imsg . end ( ) ; mit + + )
2010-09-20 18:11:09 -04:00
itemList . push_back ( mit - > second ) ;
2007-12-11 20:43:17 -05:00
2010-11-10 15:37:02 -05:00
for ( lit = mSrcIds . begin ( ) ; lit ! = mSrcIds . end ( ) ; lit + + )
itemList . push_back ( lit - > second ) ;
2010-10-31 15:29:26 -04:00
2007-12-11 20:43:17 -05:00
for ( mit = msgOutgoing . begin ( ) ; mit ! = msgOutgoing . end ( ) ; mit + + )
2010-09-20 18:11:09 -04:00
itemList . push_back ( mit - > second ) ;
2010-08-19 17:47:26 -04:00
2011-05-21 12:26:00 -04:00
for ( mit2 = mTags . begin ( ) ; mit2 ! = mTags . end ( ) ; mit2 + + )
itemList . push_back ( mit2 - > second ) ;
2010-08-19 17:47:26 -04:00
for ( mit3 = mMsgTags . begin ( ) ; mit3 ! = mMsgTags . end ( ) ; mit3 + + )
2010-09-20 18:11:09 -04:00
itemList . push_back ( mit3 - > second ) ;
2010-08-19 17:47:26 -04:00
2010-11-02 17:11:11 -04:00
for ( mit4 = mParentId . begin ( ) ; mit4 ! = mParentId . end ( ) ; mit4 + + )
itemList . push_back ( mit4 - > second ) ;
2013-05-05 15:13:27 -04:00
for ( std : : map < std : : string , DistantMessengingInvite > : : const_iterator it ( _messenging_invites . begin ( ) ) ; it ! = _messenging_invites . end ( ) ; + + it )
{
RsPublicMsgInviteConfigItem * item = new RsPublicMsgInviteConfigItem ;
item - > hash = it - > first ;
item - > time_stamp = it - > second . time_of_validity ;
itemList . push_back ( item ) ;
}
2013-08-09 13:02:29 -04:00
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
RsTlvKeyValue kv ;
kv . key = " DISTANT_MESSAGES_ENABLED " ;
kv . value = mDistantMessagingEnabled ? " YES " : " NO " ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
itemList . push_back ( vitem ) ;
2010-12-18 14:35:07 -05:00
return true ;
2010-09-20 18:11:09 -04:00
}
2009-03-20 19:37:06 -04:00
2010-09-20 18:11:09 -04:00
void p3MsgService : : saveDone ( )
{
// unlocks mutex which has been locked by savelist
mMsgMtx . unlock ( ) ;
}
2009-03-20 19:37:06 -04:00
2010-09-20 18:11:09 -04:00
RsSerialiser * p3MsgService : : setupSerialiser ( )
{
2013-08-09 13:02:29 -04:00
RsSerialiser * rss = new RsSerialiser ;
rss - > addSerialType ( new RsMsgSerialiser ( true ) ) ;
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
2010-09-20 18:11:09 -04:00
return rss ;
2007-12-11 20:43:17 -05:00
}
2010-08-22 18:12:26 -04:00
// build list of standard tag types
static void getStandardTagTypes ( MsgTagType & tags )
{
/* create standard tag types, the text must be translated in the GUI */
tags . types [ RS_MSGTAGTYPE_IMPORTANT ] = std : : pair < std : : string , uint32_t > ( " Important " , 0xFF0000 ) ;
tags . types [ RS_MSGTAGTYPE_WORK ] = std : : pair < std : : string , uint32_t > ( " Work " , 0xFF9900 ) ;
tags . types [ RS_MSGTAGTYPE_PERSONAL ] = std : : pair < std : : string , uint32_t > ( " Personal " , 0x009900 ) ;
tags . types [ RS_MSGTAGTYPE_TODO ] = std : : pair < std : : string , uint32_t > ( " Todo " , 0x3333FF ) ;
tags . types [ RS_MSGTAGTYPE_LATER ] = std : : pair < std : : string , uint32_t > ( " Later " , 0x993399 ) ;
}
// Initialize the standard tag types after load
void p3MsgService : : initStandardTagTypes ( )
{
bool bChanged = false ;
2011-07-09 14:39:34 -04:00
std : : string ownId = mLinkMgr - > getOwnId ( ) ;
2010-08-22 18:12:26 -04:00
MsgTagType tags ;
getStandardTagTypes ( tags ) ;
std : : map < uint32_t , std : : pair < std : : string , uint32_t > > : : iterator tit ;
for ( tit = tags . types . begin ( ) ; tit ! = tags . types . end ( ) ; tit + + ) {
std : : map < uint32_t , RsMsgTagType * > : : iterator mit = mTags . find ( tit - > first ) ;
if ( mit = = mTags . end ( ) ) {
RsMsgTagType * tagType = new RsMsgTagType ( ) ;
tagType - > PeerId ( ownId ) ;
tagType - > tagId = tit - > first ;
tagType - > text = tit - > second . first ;
tagType - > rgb_color = tit - > second . second ;
mTags . insert ( std : : pair < uint32_t , RsMsgTagType * > ( tit - > first , tagType ) ) ;
bChanged = true ;
}
}
if ( bChanged ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
}
2010-12-18 14:35:07 -05:00
bool p3MsgService : : loadList ( std : : list < RsItem * > & load )
2007-12-11 20:43:17 -05:00
{
2010-08-19 17:47:26 -04:00
RsMsgItem * mitem ;
RsMsgTagType * mtt ;
RsMsgTags * mti ;
2010-10-31 15:29:26 -04:00
RsMsgSrcId * msi ;
2010-11-02 17:11:11 -04:00
RsMsgParentId * msp ;
2013-05-05 15:13:27 -04:00
RsPublicMsgInviteConfigItem * msv ;
2007-12-11 20:43:17 -05:00
2010-09-20 18:11:09 -04:00
std : : list < RsMsgItem * > items ;
2010-09-25 08:54:34 -04:00
std : : list < RsItem * > : : iterator it ;
std : : map < uint32_t , RsMsgTagType * > : : iterator tagIt ;
2010-10-31 15:29:26 -04:00
std : : map < uint32_t , std : : string > srcIdMsgMap ;
std : : map < uint32_t , std : : string > : : iterator srcIt ;
2013-08-09 13:02:29 -04:00
bool distant_messaging_set = false ;
2008-02-04 16:40:34 -05:00
2010-06-04 19:39:33 -04:00
// load items and calculate next unique msgId
2010-09-20 18:11:09 -04:00
for ( it = load . begin ( ) ; it ! = load . end ( ) ; it + + )
2007-12-11 20:43:17 -05:00
{
2010-09-20 18:11:09 -04:00
if ( NULL ! = ( mitem = dynamic_cast < RsMsgItem * > ( * it ) ) )
2007-12-11 20:43:17 -05:00
{
/* STORE MsgID */
2010-06-04 19:39:33 -04:00
if ( mitem - > msgId > = mMsgUniqueId ) {
mMsgUniqueId = mitem - > msgId + 1 ;
}
items . push_back ( mitem ) ;
}
2010-09-20 18:11:09 -04:00
else if ( NULL ! = ( mtt = dynamic_cast < RsMsgTagType * > ( * it ) ) )
2013-05-05 15:13:27 -04:00
{
// delete standard tags as they are now save in config
if ( mTags . end ( ) = = ( tagIt = mTags . find ( mtt - > tagId ) ) )
{
mTags . insert ( std : : pair < uint32_t , RsMsgTagType * > ( mtt - > tagId , mtt ) ) ;
}
else
{
delete mTags [ mtt - > tagId ] ;
mTags . erase ( tagIt ) ;
mTags . insert ( std : : pair < uint32_t , RsMsgTagType * > ( mtt - > tagId , mtt ) ) ;
}
2010-09-25 08:54:34 -04:00
2010-08-19 17:47:26 -04:00
}
2010-09-20 18:11:09 -04:00
else if ( NULL ! = ( mti = dynamic_cast < RsMsgTags * > ( * it ) ) )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
mMsgTags . insert ( std : : pair < uint32_t , RsMsgTags * > ( mti - > msgId , mti ) ) ;
2010-08-19 17:47:26 -04:00
}
2010-10-31 15:29:26 -04:00
else if ( NULL ! = ( msi = dynamic_cast < RsMsgSrcId * > ( * it ) ) )
{
srcIdMsgMap . insert ( std : : pair < uint32_t , std : : string > ( msi - > msgId , msi - > srcId ) ) ;
2010-11-10 15:37:02 -05:00
mSrcIds . insert ( std : : pair < uint32_t , RsMsgSrcId * > ( msi - > msgId , msi ) ) ; // does not need to be kept
2010-10-31 15:29:26 -04:00
}
2010-11-02 17:11:11 -04:00
else if ( NULL ! = ( msp = dynamic_cast < RsMsgParentId * > ( * it ) ) )
{
mParentId . insert ( std : : pair < uint32_t , RsMsgParentId * > ( msp - > msgId , msp ) ) ;
}
2013-05-05 15:13:27 -04:00
else if ( NULL ! = ( msv = dynamic_cast < RsPublicMsgInviteConfigItem * > ( * it ) ) )
{
_messenging_invites [ msv - > hash ] . time_of_validity = msv - > time_stamp ;
}
2013-08-09 13:02:29 -04:00
RsConfigKeyValueSet * vitem = NULL ;
if ( NULL ! = ( vitem = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ) )
for ( std : : list < RsTlvKeyValue > : : const_iterator kit = vitem - > tlvkvs . pairs . begin ( ) ; kit ! = vitem - > tlvkvs . pairs . end ( ) ; + + kit )
if ( kit - > key = = " DISTANT_MESSAGES_ENABLED " )
{
# ifdef CHAT_DEBUG
std : : cerr < < " Loaded config default nick name for distant chat: " < < kit - > value < < std : : endl ;
# endif
enableDistantMessaging ( kit - > value = = " YES " ) ;
distant_messaging_set = true ;
}
}
if ( ! distant_messaging_set )
{
std : : cerr < < " No config value for distant messaging. Setting it to true. " < < std : : endl ;
enableDistantMessaging ( true ) ;
2010-06-04 19:39:33 -04:00
}
2008-02-07 11:18:34 -05:00
2010-06-04 19:39:33 -04:00
// sort items into lists
2010-09-20 18:11:09 -04:00
std : : list < RsMsgItem * > : : iterator msgIt ;
for ( msgIt = items . begin ( ) ; msgIt ! = items . end ( ) ; msgIt + + )
2010-06-04 19:39:33 -04:00
{
2010-09-20 18:11:09 -04:00
mitem = * msgIt ;
2008-07-09 05:55:09 -04:00
2010-06-04 19:39:33 -04:00
/* STORE MsgID */
if ( mitem - > msgId = = 0 ) {
mitem - > msgId = getNewUniqueMsgId ( ) ;
}
2008-02-07 11:18:34 -05:00
2010-11-10 15:37:02 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
srcIt = srcIdMsgMap . find ( mitem - > msgId ) ;
if ( srcIt ! = srcIdMsgMap . end ( ) ) {
mitem - > PeerId ( srcIt - > second ) ;
srcIdMsgMap . erase ( srcIt ) ;
}
2010-06-04 19:39:33 -04:00
/* switch depending on the PENDING
* flags
*/
if ( mitem - > msgFlags & RS_MSG_FLAGS_PENDING )
{
//std::cerr << "MSG_PENDING";
//std::cerr << std::endl;
//mitem->print(std::cerr);
msgOutgoing [ mitem - > msgId ] = mitem ;
2007-12-11 20:43:17 -05:00
}
else
{
2010-11-10 15:37:02 -05:00
imsg [ mitem - > msgId ] = mitem ;
}
}
2010-10-31 15:29:26 -04:00
2010-11-10 15:37:02 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-06-04 19:39:33 -04:00
2010-11-10 15:37:02 -05:00
/* remove missing msgId in mSrcIds */
for ( srcIt = srcIdMsgMap . begin ( ) ; srcIt ! = srcIdMsgMap . end ( ) ; srcIt + + ) {
std : : map < uint32_t , RsMsgSrcId * > : : iterator it = mSrcIds . find ( srcIt - > first ) ;
if ( it ! = mSrcIds . end ( ) ) {
delete ( it - > second ) ;
mSrcIds . erase ( it ) ;
2007-12-11 20:43:17 -05:00
}
}
2010-11-02 17:11:11 -04:00
/* remove missing msgId in mParentId */
std : : map < uint32_t , RsMsgParentId * > : : iterator mit = mParentId . begin ( ) ;
while ( mit ! = mParentId . end ( ) ) {
if ( imsg . find ( mit - > first ) = = imsg . end ( ) ) {
if ( msgOutgoing . find ( mit - > first ) = = msgOutgoing . end ( ) ) {
/* not found */
mParentId . erase ( mit + + ) ;
continue ;
}
}
mit + + ;
}
2008-02-07 11:18:34 -05:00
return true ;
2007-12-11 20:43:17 -05:00
}
void p3MsgService : : loadWelcomeMsg ( )
{
/* Load Welcome Message */
RsMsgItem * msg = new RsMsgItem ( ) ;
2011-07-09 14:39:34 -04:00
//msg -> PeerId(mLinkMgr->getOwnId());
2007-12-11 20:43:17 -05:00
2011-03-06 07:58:18 -05:00
msg - > sendTime = time ( NULL ) ;
msg - > recvTime = time ( NULL ) ;
msg - > msgFlags = RS_MSG_FLAGS_NEW ;
2007-12-11 20:43:17 -05:00
2008-01-26 08:00:57 -05:00
msg - > subject = L " Welcome to Retroshare " ;
2007-12-11 20:43:17 -05:00
2011-03-06 07:58:18 -05:00
msg - > message = L " Send and receive messages with your friends... \n " ;
msg - > message + = L " These can hold recommendations from your local shared files. \n \n " ;
msg - > message + = L " Add recommendations through the Local Files Dialog. \n \n " ;
msg - > message + = L " Enjoy. " ;
2007-12-11 20:43:17 -05:00
2008-02-04 12:55:13 -05:00
msg - > msgId = getNewUniqueMsgId ( ) ;
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-11-04 14:03:54 -04:00
imsg [ msg - > msgId ] = msg ;
IndicateConfigChanged ( ) ;
2008-02-04 12:55:13 -05:00
}
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
/****************************************/
/****************************************/
bool p3MsgService : : getMessageSummaries ( std : : list < MsgInfoSummary > & msgList )
{
/* do stuff */
msgList . clear ( ) ;
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-04 12:55:13 -05:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
for ( mit = imsg . begin ( ) ; mit ! = imsg . end ( ) ; mit + + )
{
MsgInfoSummary mis ;
initRsMIS ( mit - > second , mis ) ;
msgList . push_back ( mis ) ;
}
for ( mit = msgOutgoing . begin ( ) ; mit ! = msgOutgoing . end ( ) ; mit + + )
{
MsgInfoSummary mis ;
initRsMIS ( mit - > second , mis ) ;
msgList . push_back ( mis ) ;
}
2010-05-13 15:20:40 -04:00
return true ;
2007-12-11 20:43:17 -05:00
}
2010-11-02 17:11:11 -04:00
bool p3MsgService : : getMessage ( const std : : string & mId , MessageInfo & msg )
2008-02-04 12:55:13 -05:00
{
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
uint32_t msgId = atoi ( mId . c_str ( ) ) ;
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-04 12:55:13 -05:00
mit = imsg . find ( msgId ) ;
if ( mit = = imsg . end ( ) )
{
mit = msgOutgoing . find ( msgId ) ;
if ( mit = = msgOutgoing . end ( ) )
{
return false ;
}
}
/* mit valid */
initRsMI ( mit - > second , msg ) ;
return true ;
}
2010-05-28 10:42:54 -04:00
void p3MsgService : : getMessageCount ( unsigned int * pnInbox , unsigned int * pnInboxNew , unsigned int * pnOutbox , unsigned int * pnDraftbox , unsigned int * pnSentbox , unsigned int * pnTrashbox )
2010-05-13 15:20:40 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
if ( pnInbox ) * pnInbox = 0 ;
if ( pnInboxNew ) * pnInboxNew = 0 ;
if ( pnOutbox ) * pnOutbox = 0 ;
if ( pnDraftbox ) * pnDraftbox = 0 ;
if ( pnSentbox ) * pnSentbox = 0 ;
2010-05-28 10:42:54 -04:00
if ( pnTrashbox ) * pnTrashbox = 0 ;
2010-05-13 15:20:40 -04:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
std : : map < uint32_t , RsMsgItem * > * apMsg [ 2 ] = { & imsg , & msgOutgoing } ;
for ( int i = 0 ; i < 2 ; i + + ) {
for ( mit = apMsg [ i ] - > begin ( ) ; mit ! = apMsg [ i ] - > end ( ) ; mit + + ) {
MsgInfoSummary mis ;
initRsMIS ( mit - > second , mis ) ;
2010-05-28 10:42:54 -04:00
if ( mis . msgflags & RS_MSG_TRASH ) {
if ( pnTrashbox ) ( * pnTrashbox ) + + ;
continue ;
}
2010-05-13 15:20:40 -04:00
switch ( mis . msgflags & RS_MSG_BOXMASK ) {
case RS_MSG_INBOX :
if ( pnInbox ) ( * pnInbox ) + + ;
if ( ( mis . msgflags & RS_MSG_NEW ) = = RS_MSG_NEW ) {
if ( pnInboxNew ) ( * pnInboxNew ) + + ;
}
break ;
case RS_MSG_OUTBOX :
if ( pnOutbox ) ( * pnOutbox ) + + ;
break ;
case RS_MSG_DRAFTBOX :
if ( pnDraftbox ) ( * pnDraftbox ) + + ;
break ;
case RS_MSG_SENTBOX :
if ( pnSentbox ) ( * pnSentbox ) + + ;
break ;
}
}
}
}
2008-02-04 12:55:13 -05:00
/* remove based on the unique mid (stored in sid) */
2010-11-02 17:11:11 -04:00
bool p3MsgService : : removeMsgId ( const std : : string & mid )
2008-02-04 12:55:13 -05:00
{
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
uint32_t msgId = atoi ( mid . c_str ( ) ) ;
2010-08-22 18:12:26 -04:00
if ( msgId = = 0 ) {
std : : cerr < < " p3MsgService::removeMsgId: Unknown msgId " < < msgId < < std : : endl ;
return false ;
}
bool changed = false ;
2008-02-04 12:55:13 -05:00
{
2009-02-22 12:36:39 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-04 12:55:13 -05:00
2009-02-22 12:36:39 -05:00
mit = imsg . find ( msgId ) ;
if ( mit ! = imsg . end ( ) )
{
2010-08-22 18:12:26 -04:00
changed = true ;
2009-02-22 12:36:39 -05:00
RsMsgItem * mi = mit - > second ;
imsg . erase ( mit ) ;
delete mi ;
}
2008-02-04 12:55:13 -05:00
2009-02-22 12:36:39 -05:00
mit = msgOutgoing . find ( msgId ) ;
if ( mit ! = msgOutgoing . end ( ) )
{
changed = true ;
RsMsgItem * mi = mit - > second ;
msgOutgoing . erase ( mit ) ;
delete mi ;
}
2010-11-10 15:37:02 -05:00
std : : map < uint32_t , RsMsgSrcId * > : : iterator srcIt = mSrcIds . find ( msgId ) ;
if ( srcIt ! = mSrcIds . end ( ) ) {
changed = true ;
delete ( srcIt - > second ) ;
mSrcIds . erase ( srcIt ) ;
}
2008-02-04 12:55:13 -05:00
}
2010-08-22 18:12:26 -04:00
if ( changed ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
setMessageTag ( mid , 0 , false ) ;
2010-11-02 17:11:11 -04:00
setMsgParentId ( msgId , 0 ) ;
2010-08-22 18:12:26 -04:00
2009-02-22 12:36:39 -05:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
2010-08-22 18:12:26 -04:00
}
2009-02-22 12:36:39 -05:00
2010-08-22 18:12:26 -04:00
return changed ;
2008-02-04 12:55:13 -05:00
}
2011-05-23 19:45:31 -04:00
bool p3MsgService : : markMsgIdRead ( const std : : string & mid , bool unreadByUser )
2008-02-04 12:55:13 -05:00
{
2009-02-22 12:36:39 -05:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
2008-02-04 12:55:13 -05:00
uint32_t msgId = atoi ( mid . c_str ( ) ) ;
2010-08-22 18:12:26 -04:00
bool changed = false ;
2008-02-04 12:55:13 -05:00
{
2009-02-22 12:36:39 -05:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
mit = imsg . find ( msgId ) ;
if ( mit ! = imsg . end ( ) )
{
RsMsgItem * mi = mit - > second ;
2010-08-22 18:12:26 -04:00
uint32_t msgFlags = mi - > msgFlags ;
/* remove new state */
mi - > msgFlags & = ~ ( RS_MSG_FLAGS_NEW ) ;
/* set state from user */
2011-05-23 19:45:31 -04:00
if ( unreadByUser ) {
2010-08-22 18:12:26 -04:00
mi - > msgFlags | = RS_MSG_FLAGS_UNREAD_BY_USER ;
} else {
mi - > msgFlags & = ~ RS_MSG_FLAGS_UNREAD_BY_USER ;
}
if ( mi - > msgFlags ! = msgFlags )
{
changed = true ;
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
} else {
return false ;
2009-02-22 12:36:39 -05:00
}
2010-08-22 18:12:26 -04:00
} /* UNLOCKED */
2009-02-22 12:36:39 -05:00
2010-08-22 18:12:26 -04:00
if ( changed ) {
2010-08-09 08:16:21 -04:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
}
2010-08-22 18:12:26 -04:00
return true ;
2008-02-04 12:55:13 -05:00
}
2010-11-02 17:11:11 -04:00
bool p3MsgService : : setMsgFlag ( const std : : string & mid , uint32_t flag , uint32_t mask )
{
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
uint32_t msgId = atoi ( mid . c_str ( ) ) ;
bool changed = false ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
mit = imsg . find ( msgId ) ;
if ( mit = = imsg . end ( ) )
{
mit = msgOutgoing . find ( msgId ) ;
if ( mit = = msgOutgoing . end ( ) )
{
return false ;
}
}
uint32_t oldFlag = mit - > second - > msgFlags ;
mit - > second - > msgFlags & = ~ mask ;
mit - > second - > msgFlags | = flag ;
if ( mit - > second - > msgFlags ! = oldFlag ) {
changed = true ;
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
} /* UNLOCKED */
if ( changed ) {
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
}
return true ;
}
bool p3MsgService : : getMsgParentId ( const std : : string & msgId , std : : string & msgParentId )
{
msgParentId . clear ( ) ;
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < uint32_t , RsMsgParentId * > : : iterator mit = mParentId . find ( atoi ( msgId . c_str ( ) ) ) ;
if ( mit = = mParentId . end ( ) ) {
return false ;
}
2012-04-17 17:00:54 -04:00
rs_sprintf ( msgParentId , " %lu " , mit - > second - > msgParentId ) ;
2010-11-02 17:11:11 -04:00
return true ;
}
bool p3MsgService : : setMsgParentId ( uint32_t msgId , uint32_t msgParentId )
{
std : : map < uint32_t , RsMsgParentId * > : : iterator mit ;
bool changed = false ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
mit = mParentId . find ( msgId ) ;
if ( mit = = mParentId . end ( ) )
{
if ( msgParentId ) {
RsMsgParentId * msp = new RsMsgParentId ( ) ;
2011-07-09 14:39:34 -04:00
msp - > PeerId ( mLinkMgr - > getOwnId ( ) ) ;
2010-11-02 17:11:11 -04:00
msp - > msgId = msgId ;
msp - > msgParentId = msgParentId ;
mParentId . insert ( std : : pair < uint32_t , RsMsgParentId * > ( msgId , msp ) ) ;
changed = true ;
}
} else {
if ( msgParentId ) {
if ( mit - > second - > msgParentId ! = msgParentId ) {
mit - > second - > msgParentId = msgParentId ;
changed = true ;
}
} else {
delete mit - > second ;
mParentId . erase ( mit ) ;
changed = true ;
}
}
} /* UNLOCKED */
if ( changed ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
return true ;
}
2008-02-04 12:55:13 -05:00
/****************************************/
/****************************************/
/* Message Items */
int p3MsgService : : sendMessage ( RsMsgItem * item )
{
pqioutput ( PQL_DEBUG_BASIC , msgservicezone ,
" p3MsgService::sendMessage() " ) ;
2008-02-07 11:18:34 -05:00
item - > msgId = getNewUniqueMsgId ( ) ; /* grabs Mtx as well */
2010-11-10 15:37:02 -05:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-04 16:40:34 -05:00
2010-11-10 15:37:02 -05:00
/* add pending flag */
item - > msgFlags | = ( RS_MSG_FLAGS_OUTGOING | RS_MSG_FLAGS_PENDING ) ;
/* STORE MsgID */
msgOutgoing [ item - > msgId ] = item ;
2011-07-09 14:39:34 -04:00
if ( item - > PeerId ( ) ! = mLinkMgr - > getOwnId ( ) ) {
2010-11-10 15:37:02 -05:00
/* not to the loopback device */
RsMsgSrcId * msi = new RsMsgSrcId ( ) ;
msi - > msgId = item - > msgId ;
msi - > srcId = item - > PeerId ( ) ;
mSrcIds . insert ( std : : pair < uint32_t , RsMsgSrcId * > ( msi - > msgId , msi ) ) ;
}
}
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2011-07-03 09:02:18 -04:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_ADD ) ;
checkOutgoingMessages ( ) ;
2008-02-04 12:55:13 -05:00
return 1 ;
}
bool p3MsgService : : MessageSend ( MessageInfo & info )
{
std : : list < std : : string > : : const_iterator pit ;
2013-08-31 08:49:04 -04:00
2008-02-04 12:55:13 -05:00
for ( pit = info . msgto . begin ( ) ; pit ! = info . msgto . end ( ) ; pit + + )
{
RsMsgItem * msg = initMIRsMsg ( info , * pit ) ;
if ( msg )
{
sendMessage ( msg ) ;
}
}
for ( pit = info . msgcc . begin ( ) ; pit ! = info . msgcc . end ( ) ; pit + + )
{
RsMsgItem * msg = initMIRsMsg ( info , * pit ) ;
if ( msg )
{
sendMessage ( msg ) ;
}
}
for ( pit = info . msgbcc . begin ( ) ; pit ! = info . msgbcc . end ( ) ; pit + + )
{
RsMsgItem * msg = initMIRsMsg ( info , * pit ) ;
if ( msg )
{
sendMessage ( msg ) ;
}
}
/* send to ourselves as well */
2012-05-01 05:18:55 -04:00
RsMsgItem * msg = initMIRsMsg ( info , mLinkMgr - > getOwnId ( ) ) ;
2008-02-04 12:55:13 -05:00
if ( msg )
{
2013-08-31 08:49:04 -04:00
std : : list < std : : string > : : iterator it ;
// Update destination ids in place of distant message hash, since this Outgoing message is for display
//
for ( it = msg - > msgbcc . ids . begin ( ) ; it ! = msg - > msgbcc . ids . end ( ) ; it + + )
if ( info . encryption_keys . find ( * it ) ! = info . encryption_keys . end ( ) ) * it = info . encryption_keys [ * it ] ;
for ( it = msg - > msgcc . ids . begin ( ) ; it ! = msg - > msgcc . ids . end ( ) ; it + + )
if ( info . encryption_keys . find ( * it ) ! = info . encryption_keys . end ( ) ) * it = info . encryption_keys [ * it ] ;
for ( it = msg - > msgto . ids . begin ( ) ; it ! = msg - > msgto . ids . end ( ) ; it + + )
if ( info . encryption_keys . find ( * it ) ! = info . encryption_keys . end ( ) ) * it = info . encryption_keys [ * it ] ;
2013-08-31 08:54:47 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNED )
msg - > msgFlags | = RS_MSG_FLAGS_SIGNATURE_CHECKS ; // this is always true, since we are sending the message
2011-05-21 12:26:00 -04:00
/* use processMsg to get the new msgId */
2012-05-01 05:18:55 -04:00
processMsg ( msg , false ) ;
2011-05-21 12:26:00 -04:00
// return new message id
2012-04-17 17:00:54 -04:00
rs_sprintf ( info . msgId , " %lu " , msg - > msgId ) ;
2008-02-04 12:55:13 -05:00
}
return true ;
}
2012-05-01 05:18:55 -04:00
bool p3MsgService : : SystemMessage ( const std : : wstring & title , const std : : wstring & message , uint32_t systemFlag )
{
if ( ( systemFlag & RS_MSG_SYSTEM ) = = 0 ) {
/* no flag specified */
return false ;
}
std : : string ownId = mLinkMgr - > getOwnId ( ) ;
RsMsgItem * msg = new RsMsgItem ( ) ;
msg - > PeerId ( ownId ) ;
msg - > msgFlags = 0 ;
if ( systemFlag & RS_MSG_USER_REQUEST ) {
msg - > msgFlags | = RS_MSG_FLAGS_USER_REQUEST ;
}
2012-05-05 18:20:05 -04:00
if ( systemFlag & RS_MSG_FRIEND_RECOMMENDATION ) {
msg - > msgFlags | = RS_MSG_FLAGS_FRIEND_RECOMMENDATION ;
}
2012-05-01 05:18:55 -04:00
msg - > msgId = 0 ;
msg - > sendTime = time ( NULL ) ;
msg - > recvTime = 0 ;
msg - > subject = title ;
msg - > message = message ;
msg - > msgto . ids . push_back ( ownId ) ;
processMsg ( msg , true ) ;
return true ;
}
2010-11-02 17:11:11 -04:00
bool p3MsgService : : MessageToDraft ( MessageInfo & info , const std : : string & msgParentId )
2010-05-25 05:32:14 -04:00
{
2011-07-09 14:39:34 -04:00
RsMsgItem * msg = initMIRsMsg ( info , mLinkMgr - > getOwnId ( ) ) ;
2010-05-25 05:32:14 -04:00
if ( msg )
{
uint32_t msgId = 0 ;
if ( info . msgId . empty ( ) = = false ) {
2010-05-28 10:42:54 -04:00
msgId = atoi ( info . msgId . c_str ( ) ) ;
2010-05-25 05:32:14 -04:00
}
if ( msgId ) {
msg - > msgId = msgId ;
} else {
msg - > msgId = getNewUniqueMsgId ( ) ; /* grabs Mtx as well */
}
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
/* add pending flag */
msg - > msgFlags | = ( RS_MSG_OUTGOING | RS_MSG_FLAGS_DRAFT ) ;
if ( msgId ) {
// remove existing message
2010-05-28 10:42:54 -04:00
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
mit = imsg . find ( msgId ) ;
if ( mit ! = imsg . end ( ) ) {
RsMsgItem * mi = mit - > second ;
imsg . erase ( mit ) ;
delete mi ;
2010-05-25 05:32:14 -04:00
}
}
/* STORE MsgID */
imsg [ msg - > msgId ] = msg ;
2010-09-11 06:39:40 -04:00
// return new message id
2012-04-17 17:00:54 -04:00
rs_sprintf ( info . msgId , " %lu " , msg - > msgId ) ;
2010-05-25 05:32:14 -04:00
}
2010-11-02 17:11:11 -04:00
setMsgParentId ( msg - > msgId , atoi ( msgParentId . c_str ( ) ) ) ;
2010-05-25 05:32:14 -04:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
return true ;
}
return false ;
}
2010-08-22 18:12:26 -04:00
bool p3MsgService : : getMessageTagTypes ( MsgTagType & tags )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-08-19 17:47:26 -04:00
std : : map < uint32_t , RsMsgTagType * > : : iterator mit ;
2010-08-22 18:12:26 -04:00
for ( mit = mTags . begin ( ) ; mit ! = mTags . end ( ) ; mit + + ) {
2010-08-19 17:47:26 -04:00
std : : pair < std : : string , uint32_t > p ( mit - > second - > text , mit - > second - > rgb_color ) ;
tags . types . insert ( std : : pair < uint32_t , std : : pair < std : : string , uint32_t > > ( mit - > first , p ) ) ;
}
return true ;
}
2010-08-22 18:12:26 -04:00
bool p3MsgService : : setMessageTagType ( uint32_t tagId , std : : string & text , uint32_t rgb_color )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
int nNotifyType = 0 ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
std : : map < uint32_t , RsMsgTagType * > : : iterator mit ;
mit = mTags . find ( tagId ) ;
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
if ( mit = = mTags . end ( ) ) {
if ( tagId < RS_MSGTAGTYPE_USER ) {
std : : cerr < < " p3MsgService::MessageSetTagType: Standard tag type " < < tagId < < " cannot be inserted " < < std : : endl ;
return false ;
}
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
/* new tag */
RsMsgTagType * tagType = new RsMsgTagType ( ) ;
2011-07-09 14:39:34 -04:00
tagType - > PeerId ( mLinkMgr - > getOwnId ( ) ) ;
2010-08-22 18:12:26 -04:00
tagType - > rgb_color = rgb_color ;
tagType - > tagId = tagId ;
tagType - > text = text ;
mTags . insert ( std : : pair < uint32_t , RsMsgTagType * > ( tagId , tagType ) ) ;
nNotifyType = NOTIFY_TYPE_ADD ;
} else {
if ( mit - > second - > text ! = text | | mit - > second - > rgb_color ! = rgb_color ) {
/* modify existing tag */
if ( tagId > = RS_MSGTAGTYPE_USER ) {
mit - > second - > text = text ;
} else {
/* don't change text for standard tag types */
if ( mit - > second - > text ! = text ) {
std : : cerr < < " p3MsgService::MessageSetTagType: Text " < < text < < " for standard tag type " < < tagId < < " cannot be changed " < < std : : endl ;
}
}
mit - > second - > rgb_color = rgb_color ;
nNotifyType = NOTIFY_TYPE_MOD ;
}
}
} /* UNLOCKED */
if ( nNotifyType ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGE_TAGS , nNotifyType ) ;
2010-08-19 17:47:26 -04:00
return true ;
}
return false ;
}
2010-08-22 18:12:26 -04:00
bool p3MsgService : : removeMessageTagType ( uint32_t tagId )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
if ( tagId < RS_MSGTAGTYPE_USER ) {
std : : cerr < < " p3MsgService::MessageRemoveTagType: Can't delete standard tag type " < < tagId < < std : : endl ;
return false ;
}
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
std : : map < uint32_t , RsMsgTagType * > : : iterator mit ;
mit = mTags . find ( tagId ) ;
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
if ( mit = = mTags . end ( ) ) {
/* tag id not found */
std : : cerr < < " p3MsgService::MessageRemoveTagType: Tag Id not found " < < tagId < < std : : endl ;
return false ;
}
/* search for messages with this tag type */
std : : map < uint32_t , RsMsgTags * > : : iterator mit1 ;
for ( mit1 = mMsgTags . begin ( ) ; mit1 ! = mMsgTags . end ( ) ; ) {
RsMsgTags * tag = mit1 - > second ;
std : : list < uint32_t > : : iterator lit ;
lit = std : : find ( tag - > tagIds . begin ( ) , tag - > tagIds . end ( ) , tagId ) ;
if ( lit ! = tag - > tagIds . end ( ) ) {
tag - > tagIds . erase ( lit ) ;
if ( tag - > tagIds . size ( ) = = 0 ) {
/* remove empty tag */
delete ( tag ) ;
2010-10-11 11:52:12 -04:00
mMsgTags . erase ( mit1 + + ) ;
2010-08-22 18:12:26 -04:00
continue ;
}
}
mit1 + + ;
}
/* remove tag type */
delete ( mit - > second ) ;
mTags . erase ( mit ) ;
} /* UNLOCKED */
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGE_TAGS , NOTIFY_TYPE_DEL ) ;
return true ;
}
2010-11-02 17:11:11 -04:00
bool p3MsgService : : getMessageTag ( const std : : string & msgId , MsgTagInfo & info )
2010-08-22 18:12:26 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
uint32_t mid = atoi ( msgId . c_str ( ) ) ;
if ( mid = = 0 ) {
std : : cerr < < " p3MsgService::MessageGetMsgTag: Unknown msgId " < < msgId < < std : : endl ;
return false ;
}
std : : map < uint32_t , RsMsgTags * > : : iterator mit ;
if ( mMsgTags . end ( ) ! = ( mit = mMsgTags . find ( mid ) ) ) {
2012-04-17 17:00:54 -04:00
rs_sprintf ( info . msgId , " %lu " , mit - > second - > msgId ) ;
2010-08-22 18:12:26 -04:00
info . tagIds = mit - > second - > tagIds ;
return true ;
}
return false ;
2010-08-19 17:47:26 -04:00
}
2010-08-22 18:12:26 -04:00
/* set == false && tagId == 0 --> remove all */
2010-11-02 17:11:11 -04:00
bool p3MsgService : : setMessageTag ( const std : : string & msgId , uint32_t tagId , bool set )
2010-08-19 17:47:26 -04:00
{
2010-08-22 18:12:26 -04:00
uint32_t mid = atoi ( msgId . c_str ( ) ) ;
if ( mid = = 0 ) {
std : : cerr < < " p3MsgService::MessageSetMsgTag: Unknown msgId " < < msgId < < std : : endl ;
return false ;
}
if ( tagId = = 0 ) {
if ( set = = true ) {
std : : cerr < < " p3MsgService::MessageSetMsgTag: No valid tagId given " < < tagId < < std : : endl ;
return false ;
}
}
int nNotifyType = 0 ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < uint32_t , RsMsgTags * > : : iterator mit ;
mit = mMsgTags . find ( mid ) ;
if ( mit = = mMsgTags . end ( ) ) {
if ( set ) {
/* new msg */
RsMsgTags * tag = new RsMsgTags ( ) ;
2011-07-09 14:39:34 -04:00
tag - > PeerId ( mLinkMgr - > getOwnId ( ) ) ;
2010-08-22 18:12:26 -04:00
tag - > msgId = mid ;
tag - > tagIds . push_back ( tagId ) ;
mMsgTags . insert ( std : : pair < uint32_t , RsMsgTags * > ( tag - > msgId , tag ) ) ;
nNotifyType = NOTIFY_TYPE_ADD ;
}
} else {
RsMsgTags * tag = mit - > second ;
/* search existing tagId */
std : : list < uint32_t > : : iterator lit ;
if ( tagId ) {
lit = std : : find ( tag - > tagIds . begin ( ) , tag - > tagIds . end ( ) , tagId ) ;
} else {
lit = tag - > tagIds . end ( ) ;
}
if ( set ) {
if ( lit = = tag - > tagIds . end ( ) ) {
tag - > tagIds . push_back ( tagId ) ;
/* keep the list sorted */
tag - > tagIds . sort ( ) ;
nNotifyType = NOTIFY_TYPE_ADD ;
}
} else {
if ( tagId = = 0 ) {
/* remove all */
delete ( tag ) ;
mMsgTags . erase ( mit ) ;
nNotifyType = NOTIFY_TYPE_DEL ;
} else {
if ( lit ! = tag - > tagIds . end ( ) ) {
tag - > tagIds . erase ( lit ) ;
nNotifyType = NOTIFY_TYPE_DEL ;
if ( tag - > tagIds . size ( ) = = 0 ) {
/* remove empty tag */
delete ( tag ) ;
mMsgTags . erase ( mit ) ;
}
}
}
}
}
} /* UNLOCKED */
if ( nNotifyType ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGE_TAGS , nNotifyType ) ;
2010-08-19 17:47:26 -04:00
2010-08-22 18:12:26 -04:00
return true ;
}
return false ;
2010-08-19 17:47:26 -04:00
}
2010-08-22 18:12:26 -04:00
bool p3MsgService : : resetMessageStandardTagTypes ( MsgTagType & tags )
{
MsgTagType standardTags ;
2010-09-25 08:54:34 -04:00
getStandardTagTypes ( standardTags ) ;
2010-08-22 18:12:26 -04:00
std : : map < uint32_t , std : : pair < std : : string , uint32_t > > : : iterator mit ;
for ( mit = standardTags . types . begin ( ) ; mit ! = standardTags . types . end ( ) ; mit + + ) {
tags . types [ mit - > first ] = mit - > second ;
}
return true ;
}
2010-08-19 17:47:26 -04:00
2010-05-28 10:42:54 -04:00
/* move message to trash based on the unique mid */
2010-11-02 17:11:11 -04:00
bool p3MsgService : : MessageToTrash ( const std : : string & mid , bool bTrash )
2010-05-28 10:42:54 -04:00
{
std : : map < uint32_t , RsMsgItem * > : : iterator mit ;
uint32_t msgId = atoi ( mid . c_str ( ) ) ;
bool bChanged = false ;
bool bFound = false ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
RsMsgItem * mi = NULL ;
mit = imsg . find ( msgId ) ;
if ( mit ! = imsg . end ( ) ) {
mi = mit - > second ;
} else {
mit = msgOutgoing . find ( msgId ) ;
if ( mit ! = msgOutgoing . end ( ) ) {
mi = mit - > second ;
}
}
if ( mi ) {
bFound = true ;
if ( bTrash ) {
if ( ( mi - > msgFlags & RS_MSG_FLAGS_TRASH ) = = 0 ) {
mi - > msgFlags | = RS_MSG_FLAGS_TRASH ;
bChanged = true ;
}
} else {
if ( mi - > msgFlags & RS_MSG_FLAGS_TRASH ) {
mi - > msgFlags & = ~ RS_MSG_FLAGS_TRASH ;
bChanged = true ;
}
}
}
}
if ( bChanged ) {
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
checkOutgoingMessages ( ) ;
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_MESSAGELIST , NOTIFY_TYPE_MOD ) ;
}
return bFound ;
}
2008-02-04 12:55:13 -05:00
/****************************************/
/****************************************/
/****************************************/
/**** HELPER FNS For Chat/Msg/Channel Lists ************
* These aren ' t required to be locked , unless
* the data used is from internal stores - > then they should be .
*/
void p3MsgService : : initRsMI ( RsMsgItem * msg , MessageInfo & mi )
{
mi . msgflags = 0 ;
/* translate flags, if we sent it... outgoing */
if ( ( msg - > msgFlags & RS_MSG_FLAGS_OUTGOING )
2012-05-01 05:18:55 -04:00
/*|| (msg->PeerId() == mLinkMgr->getOwnId())*/ )
2008-02-04 12:55:13 -05:00
{
mi . msgflags | = RS_MSG_OUTGOING ;
}
/* if it has a pending flag, then its in the outbox */
if ( msg - > msgFlags & RS_MSG_FLAGS_PENDING )
{
mi . msgflags | = RS_MSG_PENDING ;
}
2011-03-06 07:58:18 -05:00
if ( msg - > msgFlags & RS_MSG_FLAGS_DRAFT )
{
mi . msgflags | = RS_MSG_DRAFT ;
}
if ( msg - > msgFlags & RS_MSG_FLAGS_NEW )
2008-02-04 12:55:13 -05:00
{
mi . msgflags | = RS_MSG_NEW ;
}
2013-05-04 18:03:48 -04:00
2013-08-02 19:00:36 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNED )
mi . msgflags | = RS_MSG_SIGNED ;
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNATURE_CHECKS )
mi . msgflags | = RS_MSG_SIGNATURE_CHECKS ;
2013-05-04 18:03:48 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_ENCRYPTED )
mi . msgflags | = RS_MSG_ENCRYPTED ;
2010-08-22 18:12:26 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_TRASH )
{
mi . msgflags | = RS_MSG_TRASH ;
}
2011-03-06 07:58:18 -05:00
if ( msg - > msgFlags & RS_MSG_FLAGS_UNREAD_BY_USER )
2010-08-22 18:12:26 -04:00
{
mi . msgflags | = RS_MSG_UNREAD_BY_USER ;
}
2010-11-02 17:11:11 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_REPLIED )
{
mi . msgflags | = RS_MSG_REPLIED ;
}
if ( msg - > msgFlags & RS_MSG_FLAGS_FORWARDED )
{
mi . msgflags | = RS_MSG_FORWARDED ;
}
2011-05-23 19:45:31 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_STAR )
{
mi . msgflags | = RS_MSG_STAR ;
}
2012-05-01 05:18:55 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_USER_REQUEST )
{
mi . msgflags | = RS_MSG_USER_REQUEST ;
}
2012-05-05 18:20:05 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_FRIEND_RECOMMENDATION )
{
mi . msgflags | = RS_MSG_FRIEND_RECOMMENDATION ;
}
2008-02-04 12:55:13 -05:00
mi . ts = msg - > sendTime ;
mi . srcId = msg - > PeerId ( ) ;
{
//msg->msgId;
2012-04-17 17:00:54 -04:00
rs_sprintf ( mi . msgId , " %lu " , msg - > msgId ) ;
2008-02-04 12:55:13 -05:00
}
std : : list < std : : string > : : iterator pit ;
for ( pit = msg - > msgto . ids . begin ( ) ;
pit ! = msg - > msgto . ids . end ( ) ; pit + + )
{
mi . msgto . push_back ( * pit ) ;
}
for ( pit = msg - > msgcc . ids . begin ( ) ;
pit ! = msg - > msgcc . ids . end ( ) ; pit + + )
{
mi . msgcc . push_back ( * pit ) ;
}
for ( pit = msg - > msgbcc . ids . begin ( ) ;
pit ! = msg - > msgbcc . ids . end ( ) ; pit + + )
{
mi . msgbcc . push_back ( * pit ) ;
}
mi . title = msg - > subject ;
mi . msg = msg - > message ;
mi . attach_title = msg - > attachment . title ;
mi . attach_comment = msg - > attachment . comment ;
mi . count = 0 ;
mi . size = 0 ;
std : : list < RsTlvFileItem > : : iterator it ;
for ( it = msg - > attachment . items . begin ( ) ;
it ! = msg - > attachment . items . end ( ) ; it + + )
{
FileInfo fi ;
2011-03-06 07:58:18 -05:00
fi . fname = RsDirUtil : : getTopDir ( it - > name ) ;
2008-02-04 12:55:13 -05:00
fi . size = it - > filesize ;
fi . hash = it - > hash ;
fi . path = it - > path ;
mi . files . push_back ( fi ) ;
mi . count + + ;
mi . size + = fi . size ;
}
}
void p3MsgService : : initRsMIS ( RsMsgItem * msg , MsgInfoSummary & mis )
{
mis . msgflags = 0 ;
2013-05-04 18:03:48 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_ENCRYPTED )
mis . msgflags | = RS_MSG_ENCRYPTED ;
2013-08-02 19:00:36 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNED )
mis . msgflags | = RS_MSG_SIGNED ;
if ( msg - > msgFlags & RS_MSG_FLAGS_SIGNATURE_CHECKS )
mis . msgflags | = RS_MSG_SIGNATURE_CHECKS ;
2008-02-04 12:55:13 -05:00
/* translate flags, if we sent it... outgoing */
if ( ( msg - > msgFlags & RS_MSG_FLAGS_OUTGOING )
2012-04-26 19:41:14 -04:00
/*|| (msg->PeerId() == mLinkMgr->getOwnId())*/ )
2008-02-04 12:55:13 -05:00
{
mis . msgflags | = RS_MSG_OUTGOING ;
}
/* if it has a pending flag, then its in the outbox */
if ( msg - > msgFlags & RS_MSG_FLAGS_PENDING )
{
mis . msgflags | = RS_MSG_PENDING ;
}
2011-03-06 07:58:18 -05:00
if ( msg - > msgFlags & RS_MSG_FLAGS_DRAFT )
{
mis . msgflags | = RS_MSG_DRAFT ;
}
if ( msg - > msgFlags & RS_MSG_FLAGS_NEW )
2008-02-04 12:55:13 -05:00
{
mis . msgflags | = RS_MSG_NEW ;
}
2010-05-28 10:42:54 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_TRASH )
{
mis . msgflags | = RS_MSG_TRASH ;
}
2012-04-26 19:41:14 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_UNREAD_BY_USER )
2010-08-22 18:12:26 -04:00
{
mis . msgflags | = RS_MSG_UNREAD_BY_USER ;
}
2010-11-02 17:11:11 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_REPLIED )
{
mis . msgflags | = RS_MSG_REPLIED ;
}
if ( msg - > msgFlags & RS_MSG_FLAGS_FORWARDED )
{
mis . msgflags | = RS_MSG_FORWARDED ;
}
2011-05-23 19:45:31 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_STAR )
{
mis . msgflags | = RS_MSG_STAR ;
}
2012-05-01 05:18:55 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_USER_REQUEST )
{
mis . msgflags | = RS_MSG_USER_REQUEST ;
}
2012-05-05 18:20:05 -04:00
if ( msg - > msgFlags & RS_MSG_FLAGS_FRIEND_RECOMMENDATION )
{
mis . msgflags | = RS_MSG_FRIEND_RECOMMENDATION ;
}
2008-02-04 12:55:13 -05:00
mis . srcId = msg - > PeerId ( ) ;
{
//msg->msgId;
2012-04-17 17:00:54 -04:00
rs_sprintf ( mis . msgId , " %lu " , msg - > msgId ) ;
2008-02-04 12:55:13 -05:00
}
mis . title = msg - > subject ;
mis . count = msg - > attachment . items . size ( ) ;
mis . ts = msg - > sendTime ;
}
2012-05-01 05:18:55 -04:00
RsMsgItem * p3MsgService : : initMIRsMsg ( MessageInfo & info , const std : : string & to )
2008-02-04 12:55:13 -05:00
{
RsMsgItem * msg = new RsMsgItem ( ) ;
msg - > PeerId ( to ) ;
msg - > msgFlags = 0 ;
msg - > msgId = 0 ;
msg - > sendTime = time ( NULL ) ;
msg - > recvTime = 0 ;
msg - > subject = info . title ;
2013-05-03 17:02:44 -04:00
msg - > message = info . msg ;
2008-02-04 12:55:13 -05:00
std : : list < std : : string > : : iterator pit ;
for ( pit = info . msgto . begin ( ) ; pit ! = info . msgto . end ( ) ; pit + + )
{
msg - > msgto . ids . push_back ( * pit ) ;
}
for ( pit = info . msgcc . begin ( ) ; pit ! = info . msgcc . end ( ) ; pit + + )
{
msg - > msgcc . ids . push_back ( * pit ) ;
}
/* We don't fill in bcc (unless to ourselves) */
2011-07-09 14:39:34 -04:00
if ( to = = mLinkMgr - > getOwnId ( ) )
2008-02-04 12:55:13 -05:00
{
for ( pit = info . msgbcc . begin ( ) ; pit ! = info . msgbcc . end ( ) ; pit + + )
{
msg - > msgbcc . ids . push_back ( * pit ) ;
}
}
msg - > attachment . title = info . attach_title ;
msg - > attachment . comment = info . attach_comment ;
2013-04-29 18:32:58 -04:00
RsPeerDetails details ;
if ( ! rsPeers - > getPeerDetails ( to , details ) )
msg - > msgFlags | = RS_MSG_FLAGS_DISTANT ;
2008-02-04 12:55:13 -05:00
std : : list < FileInfo > : : iterator it ;
for ( it = info . files . begin ( ) ; it ! = info . files . end ( ) ; it + + )
{
RsTlvFileItem mfi ;
mfi . hash = it - > hash ;
mfi . name = it - > fname ;
mfi . filesize = it - > size ;
msg - > attachment . items . push_back ( mfi ) ;
}
2012-05-01 05:18:55 -04:00
/* translate flags from outside */
if ( info . msgflags & RS_MSG_USER_REQUEST )
msg - > msgFlags | = RS_MSG_FLAGS_USER_REQUEST ;
2013-04-29 18:32:58 -04:00
2012-05-05 18:20:05 -04:00
if ( info . msgflags & RS_MSG_FRIEND_RECOMMENDATION )
msg - > msgFlags | = RS_MSG_FLAGS_FRIEND_RECOMMENDATION ;
2012-05-01 05:18:55 -04:00
2013-08-02 19:00:36 -04:00
if ( info . msgflags & RS_MSG_SIGNED )
msg - > msgFlags | = RS_MSG_FLAGS_SIGNED ;
2013-05-03 17:02:44 -04:00
// See if we need to encrypt this message. If so, we replace the msg text
// by the whole message serialized and binary encrypted, so as to obfuscate
// all its content.
//
if ( info . encryption_keys . find ( to ) ! = info . encryption_keys . end ( ) )
encryptMessage ( info . encryption_keys [ to ] , msg ) ;
//std::cerr << "p3MsgService::initMIRsMsg()" << std::endl;
2008-07-09 05:55:09 -04:00
//msg->print(std::cerr);
2008-02-04 12:55:13 -05:00
return msg ;
}
2013-04-29 16:44:48 -04:00
2013-05-03 17:02:44 -04:00
bool p3MsgService : : encryptMessage ( const std : : string & pgp_id , RsMsgItem * item )
{
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-05-03 17:02:44 -04:00
std : : cerr < < " Encrypting message with public key " < < pgp_id < < " in place. " < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2013-05-03 17:02:44 -04:00
2013-08-02 19:00:36 -04:00
// 0 - happend own id to the data.
2013-05-03 17:02:44 -04:00
//
uint32_t rssize = _serialiser - > size ( item ) ;
2013-08-02 19:00:36 -04:00
unsigned char * data = ( unsigned char * ) malloc ( 1 + rssize + KEY_ID_SIZE ) ;
// -1 - setup protocol version
//
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " adding protocol version TAG = " < < std : : hex < < ( int ) ENCRYPTED_MSG_PROTOCOL_VERSION_01 < < std : : dec < < std : : endl ;
# endif
data [ 0 ] = ENCRYPTED_MSG_PROTOCOL_VERSION_01 ;
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " adding own key ID " < < AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) < < std : : endl ;
# endif
memcpy ( & data [ 1 ] , PGPIdType ( AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) ) . toByteArray ( ) , KEY_ID_SIZE ) ;
// 1 - serialise the whole message item into a binary chunk.
//
2013-05-03 17:02:44 -04:00
2013-08-02 19:00:36 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " serialising item... " < < std : : endl ;
# endif
if ( ! _serialiser - > serialise ( item , & data [ 1 + KEY_ID_SIZE ] , & rssize ) )
2013-05-03 17:02:44 -04:00
{
2013-09-08 07:16:13 -04:00
std : : cerr < < " (EE) p3MsgService::encryptMessage(): Serialization error. " < < std : : endl ;
2013-08-02 19:00:36 -04:00
free ( data ) ;
2013-05-03 17:02:44 -04:00
return false ;
}
2013-08-02 19:00:36 -04:00
// 2 - now sign the data, if necessary, and put the signature up front
uint32_t signature_length = 0 ;
unsigned char * signature_data = NULL ;
if ( item - > msgFlags & RS_MSG_FLAGS_SIGNED )
{
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Signing the message... " < < std : : endl ;
# endif
signature_length = 2000 ;
signature_data = new unsigned char [ signature_length ] ;
if ( ! AuthGPG : : getAuthGPG ( ) - > SignDataBin ( data , 1 + rssize + KEY_ID_SIZE , signature_data , & signature_length ) )
{
free ( data ) ;
std : : cerr < < " Signature failed! " < < std : : endl ;
return false ;
}
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " After signature: signature size = " < < signature_length < < std : : endl ;
# endif
}
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " total decrypted size = " < < KEY_ID_SIZE + 1 + rssize + signature_length < < std : : endl ;
# endif
// 3 - happend the signature to the serialized data.
if ( signature_length > 0 )
{
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Appending signature. " < < std : : endl ;
# endif
data = ( uint8_t * ) realloc ( data , 1 + rssize + signature_length + KEY_ID_SIZE ) ;
memcpy ( & data [ 1 + rssize + KEY_ID_SIZE ] , signature_data , signature_length ) ;
}
// 2 - pgp-encrypt the whole chunk with the user-supplied public key.
2013-05-03 17:02:44 -04:00
//
2013-08-02 19:00:36 -04:00
uint32_t encrypted_size = 1 + rssize + KEY_ID_SIZE + signature_length + 1000 ;
2013-05-03 17:02:44 -04:00
unsigned char * encrypted_data = new unsigned char [ encrypted_size ] ;
2013-08-02 19:00:36 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Encrypting for Key ID " < < pgp_id < < std : : endl ;
# endif
if ( ! AuthGPG : : getAuthGPG ( ) - > encryptDataBin ( pgp_id , data , 1 + rssize + signature_length + KEY_ID_SIZE , encrypted_data , & encrypted_size ) )
2013-05-03 17:02:44 -04:00
{
2013-08-02 19:00:36 -04:00
free ( data ) ;
2013-05-03 17:02:44 -04:00
delete [ ] encrypted_data ;
std : : cerr < < " Encryption failed! " < < std : : endl ;
return false ;
}
2013-08-02 19:00:36 -04:00
free ( data ) ;
2013-05-03 17:02:44 -04:00
2013-08-02 19:00:36 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Decrypted size = " < < 1 + rssize + signature_length + KEY_ID_SIZE < < std : : endl ;
std : : cerr < < " Encrypted size = " < < encrypted_size < < std : : endl ;
std : : cerr < < " First bytes of encrypted data: " < < std : : hex < < ( int ) encrypted_data [ 0 ] < < " " < < ( int ) encrypted_data [ 1 ] < < " " < < ( int ) encrypted_data [ 2 ] < < std : : dec < < std : : endl ;
std : : cerr < < " Encrypted data hash = " < < RsDirUtil : : sha1sum ( encrypted_data , encrypted_size ) . toStdString ( ) < < std : : endl ;
# endif
2013-05-03 17:02:44 -04:00
// Now turn the binary encrypted chunk into a readable radix string.
//
2013-05-04 18:03:48 -04:00
std : : string armoured_data ;
Radix64 : : encode ( ( char * ) encrypted_data , encrypted_size , armoured_data ) ;
2013-05-03 17:02:44 -04:00
delete [ ] encrypted_data ;
std : : wstring encrypted_msg ;
2013-08-02 19:00:36 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Converting to radix64 " < < std : : endl ;
# endif
2013-05-03 17:02:44 -04:00
if ( ! librs : : util : : ConvertUtf8ToUtf16 ( armoured_data , encrypted_msg ) )
return false ;
// wipe the item clean and replace the message by the encrypted data.
item - > message = encrypted_msg ;
item - > subject = L " " ;
item - > msgcc . ids . clear ( ) ;
item - > msgbcc . ids . clear ( ) ;
item - > msgto . ids . clear ( ) ;
item - > msgFlags | = RS_MSG_FLAGS_ENCRYPTED ;
2013-05-04 18:15:05 -04:00
item - > attachment . TlvClear ( ) ;
2013-05-03 17:02:44 -04:00
2013-08-02 19:00:36 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Done " < < std : : endl ;
# endif
2013-05-03 17:02:44 -04:00
return true ;
}
2013-05-04 18:03:48 -04:00
bool p3MsgService : : decryptMessage ( const std : : string & mId )
2013-05-03 17:02:44 -04:00
{
2013-05-04 18:03:48 -04:00
uint32_t msgId = atoi ( mId . c_str ( ) ) ;
std : : string encrypted_string ;
2013-07-31 12:34:34 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Decrypting message with Id " < < mId < < std : : endl ;
# endif
2013-05-04 18:03:48 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < uint32_t , RsMsgItem * > : : iterator mit = imsg . find ( msgId ) ;
if ( mit = = imsg . end ( ) | | ! librs : : util : : ConvertUtf16ToUtf8 ( mit - > second - > message , encrypted_string ) )
2013-07-31 12:34:34 -04:00
{
std : : cerr < < " Can't find this message in msg list. Id= " < < mId < < std : : endl ;
2013-05-04 18:03:48 -04:00
return false ;
2013-07-31 12:34:34 -04:00
}
2013-05-04 18:03:48 -04:00
}
char * encrypted_data ;
size_t encrypted_size ;
Radix64 : : decode ( encrypted_string , encrypted_data , encrypted_size ) ;
2013-07-31 12:34:34 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-08-02 19:00:36 -04:00
std : : cerr < < " Message has been radix64 decoded. " < < std : : endl ;
2013-07-31 12:34:34 -04:00
# endif
2013-05-04 18:03:48 -04:00
uint32_t decrypted_size = encrypted_size + 500 ;
unsigned char * decrypted_data = new unsigned char [ decrypted_size ] ;
2013-08-02 19:00:36 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Calling decryption. Encrypted data size = " < < encrypted_size < < " , Allocated size = " < < decrypted_size < < std : : endl ;
std : : cerr < < " First bytes of encrypted data: " < < std : : hex < < ( int ) ( ( unsigned char * ) encrypted_data ) [ 0 ] < < " " < < ( int ) ( ( unsigned char * ) encrypted_data ) [ 1 ] < < " " < < ( int ) ( ( unsigned char * ) encrypted_data ) [ 2 ] < < std : : dec < < std : : endl ;
std : : cerr < < " Encrypted data hash = " < < RsDirUtil : : sha1sum ( ( uint8_t * ) encrypted_data , encrypted_size ) . toStdString ( ) < < std : : endl ;
# endif
2013-05-04 18:03:48 -04:00
if ( ! AuthGPG : : getAuthGPG ( ) - > decryptDataBin ( encrypted_data , encrypted_size , decrypted_data , & decrypted_size ) )
{
delete [ ] encrypted_data ;
delete [ ] decrypted_data ;
std : : cerr < < " decryption failed! " < < std : : endl ;
return false ;
}
2013-07-31 12:34:34 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-08-02 19:00:36 -04:00
std : : cerr < < " Message has succesfully decrypted. Decrypted size = " < < decrypted_size < < std : : endl ;
# endif
// 1 - get the sender's id
unsigned char protocol_version = decrypted_data [ 0 ] ;
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Read protocol version number " < < std : : hex < < ( int ) protocol_version < < std : : dec < < std : : endl ;
# endif
if ( protocol_version ! = ENCRYPTED_MSG_PROTOCOL_VERSION_01 )
{
std : : cerr < < " Bad version number " < < std : : hex < < ( int ) protocol_version < < std : : dec < < " => packet is dropped. " < < std : : endl ;
delete [ ] encrypted_data ;
delete [ ] decrypted_data ;
return false ;
}
PGPIdType senders_id ( & decrypted_data [ 1 ] ) ;
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Sender's ID: " < < senders_id . toStdString ( ) < < std : : endl ;
2013-07-31 12:34:34 -04:00
# endif
2013-08-02 19:00:36 -04:00
// 2 - deserialize the item
2013-05-04 18:03:48 -04:00
2013-08-02 19:00:36 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Deserializing... " < < std : : endl ;
# endif
uint32_t item_size = decrypted_size ; // just needs to be larger than the actual size.
RsMsgItem * item = dynamic_cast < RsMsgItem * > ( _serialiser - > deserialise ( & decrypted_data [ 1 + KEY_ID_SIZE ] , & item_size ) ) ;
2013-05-04 18:03:48 -04:00
if ( item = = NULL )
2013-07-31 12:34:34 -04:00
{
std : : cerr < < " Decrypted message could not be deserialized. " < < std : : endl ;
2013-05-04 18:03:48 -04:00
return false ;
2013-07-31 12:34:34 -04:00
}
2013-05-04 18:03:48 -04:00
2013-08-02 19:00:36 -04:00
// 3 - check signature
bool signature_present = false ;
bool signature_ok = false ;
if ( 1 + item_size + KEY_ID_SIZE < decrypted_size )
{
std : : cerr < < " Signature is present. Verifying it... " < < std : : endl ;
PGPFingerprintType fingerprint ;
if ( ! AuthGPG : : getAuthGPG ( ) - > getKeyFingerprint ( senders_id , fingerprint ) )
{
std : : cerr < < " Cannot get fingerprint " < < std : : endl ;
return false ;
}
std : : cerr < < " Fingerprint = " < < fingerprint . toStdString ( ) < < std : : endl ;
signature_present = true ;
signature_ok = AuthGPG : : getAuthGPG ( ) - > VerifySignBin ( decrypted_data , 1 + KEY_ID_SIZE + item_size , & decrypted_data [ 1 + KEY_ID_SIZE + item_size ] , decrypted_size - KEY_ID_SIZE - item_size - 1 , fingerprint . toStdString ( ) ) ;
}
else if ( 1 + item_size + KEY_ID_SIZE = = decrypted_size )
std : : cerr < < " No signature in this packet " < < std : : endl ;
else
{
std : : cerr < < " Structural error in packet: sizes do not match. Dropping the message. " < < std : : endl ;
return false ;
}
delete [ ] decrypted_data ;
// 4 - replace the item with the decrypted data, and update flags
2013-07-31 12:34:34 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-08-02 19:00:36 -04:00
std : : cerr < < " Decrypted message was succesfully deserialized. New message: " < < std : : endl ;
2013-07-31 12:34:34 -04:00
item - > print ( std : : cerr , 0 ) ;
# endif
2013-08-30 16:40:28 -04:00
std : : string own_hash ;
std : : string own_pgp_id = AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) ;
getDistantMessageHash ( own_pgp_id , own_hash ) ;
2013-05-04 18:03:48 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2013-07-31 12:34:34 -04:00
// Keer the id.
RsMsgItem & msgi ( * imsg [ msgId ] ) ;
msgi = * item ; // copy everything
msgi . msgId = msgId ; // restore the correct message id, to make it consistent
msgi . msgFlags & = ~ RS_MSG_FLAGS_ENCRYPTED ; // just in case.
2013-08-02 19:00:36 -04:00
msgi . PeerId ( senders_id . toStdString ( ) ) ;
2013-08-30 16:40:28 -04:00
for ( std : : list < std : : string > : : iterator it ( msgi . msgto . ids . begin ( ) ) ; it ! = msgi . msgto . ids . end ( ) ; + + it ) if ( * it = = own_hash ) * it = own_pgp_id ;
for ( std : : list < std : : string > : : iterator it ( msgi . msgcc . ids . begin ( ) ) ; it ! = msgi . msgcc . ids . end ( ) ; + + it ) if ( * it = = own_hash ) * it = own_pgp_id ;
for ( std : : list < std : : string > : : iterator it ( msgi . msgbcc . ids . begin ( ) ) ; it ! = msgi . msgbcc . ids . end ( ) ; + + it ) if ( * it = = own_hash ) * it = own_pgp_id ;
2013-08-02 19:00:36 -04:00
if ( signature_present )
{
msgi . msgFlags | = RS_MSG_FLAGS_SIGNED ;
if ( signature_ok )
msgi . msgFlags | = RS_MSG_FLAGS_SIGNATURE_CHECKS ; // just in case.
else
msgi . msgFlags & = ~ RS_MSG_FLAGS_SIGNATURE_CHECKS ; // just in case.
}
2013-08-30 17:06:23 -04:00
std : : map < uint32_t , RsMsgSrcId * > : : iterator it = mSrcIds . find ( msgi . msgId ) ;
if ( it = = mSrcIds . end ( ) )
{
std : : cerr < < " Warning: could not find message source for id " < < msgi . msgId < < " . Weird. " < < std : : endl ;
RsMsgSrcId * msi = new RsMsgSrcId ( ) ;
msi - > msgId = msgi . msgId ;
msi - > srcId = senders_id . toStdString ( ) ;
mSrcIds . insert ( std : : pair < uint32_t , RsMsgSrcId * > ( msi - > msgId , msi ) ) ;
}
else
{
std : : cerr < < " Substituting source name for message id " < < msgi . msgId < < " : " < < it - > second - > srcId < < " -> " < < senders_id . toStdString ( ) < < std : : endl ;
it - > second - > srcId = senders_id . toStdString ( ) ;
}
2013-05-04 18:03:48 -04:00
}
delete item ;
2013-05-05 15:13:27 -04:00
IndicateConfigChanged ( ) ;
2013-05-03 17:02:44 -04:00
return true ;
}
2013-04-29 16:44:48 -04:00
void p3MsgService : : connectToTurtleRouter ( p3turtle * pt )
{
mTurtle = pt ;
pt - > registerTunnelService ( this ) ;
}
bool p3MsgService : : createDistantOfflineMessengingInvite ( time_t time_of_validity , TurtleFileHash & hash )
{
unsigned char hash_bytes [ DISTANT_MSG_HASH_SIZE ] ;
RSRandom : : random_bytes ( hash_bytes , DISTANT_MSG_HASH_SIZE ) ;
hash = t_RsGenericIdType < DISTANT_MSG_HASH_SIZE > ( hash_bytes ) . toStdString ( false ) ;
DistantMessengingInvite invite ;
2013-04-29 18:32:58 -04:00
invite . time_of_validity = time_of_validity + time ( NULL ) ;
2013-04-29 16:44:48 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
_messenging_invites [ hash ] = invite ;
}
2013-05-05 15:13:27 -04:00
IndicateConfigChanged ( ) ;
2013-04-29 16:44:48 -04:00
return true ;
}
2013-07-31 12:34:34 -04:00
void p3MsgService : : enableDistantMessaging ( bool b )
{
// compute the hash
std : : string hash ;
if ( ! getDistantMessageHash ( AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) , hash ) )
return ;
2013-08-09 13:02:29 -04:00
bool cchanged = false ;
2013-07-31 12:34:34 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < ( b ? " Enabling " : " Disabling " ) < < " distant messaging, with hash = " < < hash < < std : : endl ;
# endif
{
2013-08-09 13:02:29 -04:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2013-07-31 12:34:34 -04:00
2013-08-09 13:02:29 -04:00
std : : map < std : : string , DistantMessengingInvite > : : iterator it = _messenging_invites . find ( hash ) ;
if ( b & & it = = _messenging_invites . end ( ) )
{
DistantMessengingInvite invite ;
invite . time_of_validity = time ( NULL ) + 10 * 365 * 86400 ; // 10 years from now
_messenging_invites [ hash ] = invite ;
mDistantMessagingEnabled = true ;
cchanged = true ;
}
if ( ( ! b ) & & it ! = _messenging_invites . end ( ) )
{
_messenging_invites . erase ( it ) ;
mDistantMessagingEnabled = false ;
cchanged = true ;
}
2013-07-31 12:34:34 -04:00
}
2013-08-09 13:02:29 -04:00
if ( cchanged )
2013-07-31 12:34:34 -04:00
IndicateConfigChanged ( ) ;
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " List of distant message invites: " < < std : : endl ;
for ( std : : map < std : : string , DistantMessengingInvite > : : const_iterator it ( _messenging_invites . begin ( ) ) ; it ! = _messenging_invites . end ( ) ; + + it )
std : : cerr < < " hash = " < < it - > first < < std : : endl ;
# endif
}
bool p3MsgService : : distantMessagingEnabled ( )
{
// compute the hash
std : : string hash ;
if ( ! getDistantMessageHash ( AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) , hash ) )
return false ;
2013-08-09 13:02:29 -04:00
bool res ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
res = _messenging_invites . find ( hash ) ! = _messenging_invites . end ( ) ;
}
return res ;
2013-07-31 12:34:34 -04:00
}
bool p3MsgService : : getDistantMessageHash ( const std : : string & pgp_id , std : : string & hash )
{
if ( pgp_id . length ( ) ! = 16 )
{
std : : cerr < < " pgp id \" " < < pgp_id < < " \" is not valid! Something definitly wrong. " < < std : : endl ;
return false ;
}
hash = RsDirUtil : : sha1sum ( ( uint8_t * ) pgp_id . c_str ( ) , 16 ) . toStdString ( ) ;
// Also check that we have the public key.
return AuthGPG : : getAuthGPG ( ) - > isKeySupported ( pgp_id ) ;
}
2013-04-29 16:44:48 -04:00
bool p3MsgService : : getDistantOfflineMessengingInvites ( std : : vector < DistantOfflineMessengingInvite > & invites )
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
for ( std : : map < std : : string , DistantMessengingInvite > : : const_iterator it ( _messenging_invites . begin ( ) ) ; it ! = _messenging_invites . end ( ) ; + + it )
{
DistantOfflineMessengingInvite invite ;
invite . hash = it - > first ;
invite . issuer_pgp_id = AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) ;
invite . time_of_validity = it - > second . time_of_validity ;
2013-04-29 18:32:58 -04:00
invites . push_back ( invite ) ;
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 18:32:58 -04:00
std : : cerr < < " adding invite with hash " < < invite . hash < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2013-04-29 16:44:48 -04:00
}
return true ;
}
2013-06-09 13:54:54 -04:00
bool p3MsgService : : handleTunnelRequest ( const std : : string & hash , const std : : string & /*peer_id*/ )
2013-04-29 16:44:48 -04:00
{
2013-05-01 17:13:40 -04:00
2013-04-29 16:44:48 -04:00
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < std : : string , DistantMessengingInvite > : : const_iterator it = _messenging_invites . find ( hash ) ;
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-05-01 17:13:40 -04:00
if ( it ! = _messenging_invites . end ( ) )
2013-07-31 12:34:34 -04:00
{
std : : cerr < < " p3MsgService::handleTunnelRequest: received TR for hash " < < hash < < std : : endl ;
2013-05-01 17:13:40 -04:00
std : : cerr < < " Responding OK! " < < std : : endl ;
2013-07-31 12:34:34 -04:00
}
2013-05-08 12:58:22 -04:00
# endif
2013-05-01 17:13:40 -04:00
2013-04-29 16:44:48 -04:00
return it ! = _messenging_invites . end ( ) ;
}
void p3MsgService : : manageDistantPeers ( )
{
// now possibly flush pending messages
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
std : : cerr < < " p3MsgService::manageDistantPeers() " < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2013-04-29 16:44:48 -04:00
time_t now = time ( NULL ) ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
// clean dead invites.
//
for ( std : : map < std : : string , DistantMessengingInvite > : : iterator it ( _messenging_invites . begin ( ) ) ; it ! = _messenging_invites . end ( ) ; )
if ( it - > second . time_of_validity < now )
{
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
std : : cerr < < " Removing outdated invite " < < it - > second . time_of_validity < < " , hash= " < < it - > first < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2013-04-29 16:44:48 -04:00
std : : map < std : : string , DistantMessengingInvite > : : iterator tmp ( it ) ;
+ + tmp ;
_messenging_invites . erase ( it ) ;
it = tmp ;
}
else
+ + it ;
// clean dead contacts.
//
for ( std : : map < std : : string , DistantMessengingContact > : : iterator it ( _messenging_contacts . begin ( ) ) ; it ! = _messenging_contacts . end ( ) ; )
2013-08-31 17:10:04 -04:00
if ( ( ! it - > second . pending_messages ) & & it - > second . status = = RS_DISTANT_MSG_STATUS_TUNNEL_DN )
2013-04-29 16:44:48 -04:00
{
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
std : : cerr < < " Removing dead contact with no pending msgs and dead tunnel. hash= " < < it - > first < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2013-04-29 16:44:48 -04:00
std : : map < std : : string , DistantMessengingContact > : : iterator tmp ( it ) ;
+ + tmp ;
_messenging_contacts . erase ( it ) ;
it = tmp ;
}
else
+ + it ;
}
}
2013-06-09 13:54:54 -04:00
void p3MsgService : : addVirtualPeer ( const TurtleFileHash & hash , const TurtleVirtualPeerId & vpid , RsTurtleGenericTunnelItem : : Direction /*dir*/ )
2013-04-29 16:44:48 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
// A new tunnel has been created. We need to flush pending messages for the corresponding peer.
//std::map<std::string,DistantMessengingContact>::const_iterator it = _messenging_contacts.find(hash) ;
DistantMessengingContact & contact ( _messenging_contacts [ hash ] ) ; // possibly creates it.
contact . virtual_peer_id = vpid ;
contact . last_hit_time = time ( NULL ) ;
contact . status = RS_DISTANT_MSG_STATUS_TUNNEL_OK ;
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
std : : cerr < < " p3MsgService::addVirtualPeer(): adding virtual peer " < < vpid < < " for hash " < < hash < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2013-04-29 16:44:48 -04:00
}
2013-07-31 12:34:34 -04:00
void p3MsgService : : removeVirtualPeer ( const TurtleFileHash & hash , const TurtleVirtualPeerId & vpid )
2013-04-29 16:44:48 -04:00
{
2013-07-31 12:34:34 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Removing virtual peer " < < vpid < < " for hash " < < hash < < std : : endl ;
# endif
2013-04-29 16:44:48 -04:00
2013-07-31 12:34:34 -04:00
bool remove_tunnel = false ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
2013-04-29 16:44:48 -04:00
2013-07-31 12:34:34 -04:00
DistantMessengingContact & contact ( _messenging_contacts [ hash ] ) ; // possibly creates it.
2013-04-29 16:44:48 -04:00
2013-07-31 12:34:34 -04:00
contact . status = RS_DISTANT_MSG_STATUS_TUNNEL_DN ;
contact . virtual_peer_id . clear ( ) ;
2013-08-31 17:10:04 -04:00
if ( ! contact . pending_messages )
2013-07-31 12:34:34 -04:00
remove_tunnel = true ;
}
2013-08-02 19:00:36 -04:00
if ( remove_tunnel ) // We do that whenever we're client or server. But normally, we should only do it when we're client.
2013-07-31 12:34:34 -04:00
{
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Also removing tunnel, since pending messages have been sent. " < < std : : endl ;
# endif
mTurtle - > stopMonitoringTunnels ( hash ) ;
}
2013-04-29 16:44:48 -04:00
}
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
static void printBinaryData ( void * data , uint32_t size )
{
static const char outl [ 16 ] = { ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' , ' 8 ' , ' 9 ' , ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' } ;
for ( uint32_t j = 0 ; j < size ; j + + )
{
std : : cerr < < outl [ ( ( ( uint8_t * ) data ) [ j ] > > 4 ) ] ;
std : : cerr < < outl [ ( ( uint8_t * ) data ) [ j ] & 0xf ] ;
}
}
2013-05-08 12:58:22 -04:00
# endif
2013-04-29 16:44:48 -04:00
void p3MsgService : : sendTurtleData ( const std : : string & hash , RsMsgItem * msgitem )
{
// The item is serialized and turned into a generic turtle item.
2013-08-02 19:00:36 -04:00
uint32_t msg_serialized_rssize = _serialiser - > size ( msgitem ) ;
unsigned char * msg_serialized_data = new unsigned char [ msg_serialized_rssize ] ;
2013-04-29 16:44:48 -04:00
2013-08-02 19:00:36 -04:00
if ( ! _serialiser - > serialise ( msgitem , msg_serialized_data , & msg_serialized_rssize ) )
2013-04-29 16:44:48 -04:00
{
std : : cerr < < " (EE) p3MsgService::sendTurtleData(): Serialization error. " < < std : : endl ;
2013-08-02 19:00:36 -04:00
delete [ ] msg_serialized_data ;
2013-04-29 16:44:48 -04:00
return ;
}
RsTurtleGenericDataItem * item = new RsTurtleGenericDataItem ;
2013-08-02 19:00:36 -04:00
item - > data_bytes = malloc ( msg_serialized_rssize ) ;
item - > data_size = msg_serialized_rssize ;
memcpy ( item - > data_bytes , msg_serialized_data , msg_serialized_rssize ) ;
delete [ ] msg_serialized_data ;
2013-04-29 16:44:48 -04:00
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
printBinaryData ( item - > data_bytes , item - > data_size ) ;
std : : cerr < < std : : endl ;
2013-05-08 12:58:22 -04:00
# endif
2013-04-29 16:44:48 -04:00
// do we have a working tunnel for that hash ?
// If not, put on the contact's waiting list.
std : : string virtual_peer_id ;
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < std : : string , DistantMessengingContact > : : const_iterator it = _messenging_contacts . find ( hash ) ;
if ( it = = _messenging_contacts . end ( ) )
{
std : : cerr < < " (EE) p3MsgService::sendTurtleData(): Can't find hash " < < hash < < " in recorded contact list. " < < std : : endl ;
2013-08-02 19:00:36 -04:00
delete [ ] msg_serialized_data ;
2013-04-29 16:44:48 -04:00
return ;
}
if ( ! it - > second . status = = RS_DISTANT_MSG_STATUS_TUNNEL_OK )
{
std : : cerr < < " p3MsgService::sendTurtleData(): tunnel is not ok. Putting items on waiting list. " < < std : : endl ;
return ;
}
virtual_peer_id = it - > second . virtual_peer_id ;
}
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
std : : cerr < < " p3MsgService::sendTurtleData(): Sending through virtual peer: " < < virtual_peer_id < < std : : endl ;
std : : cerr < < " item->data_size = " < < item - > data_size < < std : : endl ;
std : : cerr < < " data = " ;
2013-05-08 12:58:22 -04:00
# endif
2013-04-29 16:44:48 -04:00
mTurtle - > sendTurtleData ( virtual_peer_id , item ) ;
}
void p3MsgService : : receiveTurtleData ( RsTurtleGenericTunnelItem * gitem , const std : : string & hash ,
2013-06-09 13:54:54 -04:00
const std : : string & virtual_peer_id , RsTurtleGenericTunnelItem : : Direction /*direction*/ )
2013-04-29 16:44:48 -04:00
{
RsTurtleGenericDataItem * item = dynamic_cast < RsTurtleGenericDataItem * > ( gitem ) ;
if ( item = = NULL )
{
std : : cerr < < " (EE) p3MsgService::receiveTurtleData(): item is not a data item. That is an error. " < < std : : endl ;
return ;
}
2013-07-31 12:34:34 -04:00
# ifdef DISABLE_DISTANT_MESSAGES
std : : cerr < < " Received distant message item. Protocol is not yet finalized. Droping the item. " < < std : : endl ;
delete item ;
return ;
# endif
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
std : : cerr < < " p3MsgService::sendTurtleData(): Receiving through virtual peer: " < < virtual_peer_id < < std : : endl ;
std : : cerr < < " gitem->data_size = " < < item - > data_size < < std : : endl ;
std : : cerr < < " data = " ;
printBinaryData ( item - > data_bytes , item - > data_size ) ;
std : : cerr < < std : : endl ;
2013-06-09 13:54:54 -04:00
# else
( void ) virtual_peer_id ;
2013-05-08 12:58:22 -04:00
# endif
2013-04-29 16:44:48 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < std : : string , DistantMessengingContact > : : iterator it = _messenging_contacts . find ( hash ) ;
if ( it = = _messenging_contacts . end ( ) )
{
std : : cerr < < " (EE) p3MsgService::sendTurtleData(): Can't find hash " < < hash < < " in recorded contact list. " < < std : : endl ;
return ;
}
it - > second . status = RS_DISTANT_MSG_STATUS_TUNNEL_OK ;
it - > second . last_hit_time = time ( NULL ) ;
}
RsItem * itm = _serialiser - > deserialise ( item - > data_bytes , & item - > data_size ) ;
RsMsgItem * mitm = dynamic_cast < RsMsgItem * > ( itm ) ;
if ( mitm ! = NULL )
{
mitm - > PeerId ( hash ) ;
handleIncomingItem ( mitm ) ;
}
else
{
std : : cerr < < " (EE) p3MsgService::receiveTurtleData(): received item is not a RsMsgItem!! " < < std : : endl ;
delete itm ;
}
}
void p3MsgService : : sendPrivateMsgItem ( RsMsgItem * msgitem )
{
2013-05-08 12:58:22 -04:00
# ifdef DEBUG_DISTANT_MSG
2013-04-29 16:44:48 -04:00
std : : cerr < < " p3MsgService::sendDistanteMsgItem(): sending distant msg item to peer " < < msgitem - > PeerId ( ) < < std : : endl ;
2013-08-31 17:10:04 -04:00
// std::cerr << " asking for tunnels" << std::endl;
// std::cerr << " recording msg info" << std::endl;
2013-05-08 12:58:22 -04:00
# endif
2013-08-31 17:10:04 -04:00
// const std::string& hash = msgitem->PeerId() ;
// rsTurtle->monitorTunnels(hash,this) ; // create a tunnel for it, and put the msg on the waiting list.
2013-04-29 16:44:48 -04:00
{
RsStackMutex stack ( mMsgMtx ) ; /********** STACK LOCKED MTX ******/
// allocate a new contact. If it does not exist, set its tunnel state to DN
//
2013-08-31 17:10:04 -04:00
std : : map < std : : string , DistantMessengingContact > : : iterator it = _messenging_contacts . find ( msgitem - > PeerId ( ) ) ;
2013-04-29 16:44:48 -04:00
if ( it = = _messenging_contacts . end ( ) )
2013-08-31 17:10:04 -04:00
{
std : : cerr < < " (EE) p3MsgService::sendPrivateMsgItem(): ERROR: no tunnel for message to send. This should not happen. " < < std : : endl ;
return ;
}
if ( it - > second . status ! = RS_DISTANT_MSG_STATUS_TUNNEL_OK )
{
std : : cerr < < " (WW) p3MsgService::sendPrivateMsgItem(): WARNING: no tunnel for message to send. This should not happen. " < < std : : endl ;
return ;
}
2013-04-29 16:44:48 -04:00
2013-08-31 17:10:04 -04:00
if ( ! it - > second . pending_messages )
std : : cerr < < " (WW) p3MsgService::sendPrivateMsgItem(): WARNING: no pending message flag. This should not happen. " < < std : : endl ;
2013-04-29 16:44:48 -04:00
}
2013-08-31 17:10:04 -04:00
# ifdef DEBUG_DISTANT_MSG
std : : cerr < < " Flushing msg " < < msgitem - > msgId < < " for peer id " < < msgitem - > PeerId ( ) < < std : : endl ;
# endif
sendTurtleData ( msgitem - > PeerId ( ) , msgitem ) ;
2013-04-29 16:44:48 -04:00
}