2014-08-21 18:02:43 -04:00
/*
This file is part of tgl - library
2013-10-23 10:26:17 -04:00
2014-08-21 18:02:43 -04:00
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 2.1 of the License , or ( at your option ) any later version .
2013-10-23 10:26:17 -04:00
2014-08-21 18:02:43 -04:00
This library is distributed in the hope that it will be useful ,
2013-10-23 10:26:17 -04:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2014-08-21 18:02:43 -04:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
2013-10-23 10:26:17 -04:00
2014-08-21 18:02:43 -04:00
You should have received a copy of the GNU Lesser General Public
License along with this library ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2013-10-23 10:26:17 -04:00
2014-08-21 18:02:43 -04:00
Copyright Vitaly Valtman 2013 - 2014
2013-10-23 10:26:17 -04:00
*/
2013-11-09 17:47:19 -05:00
2014-01-13 08:05:25 -05:00
# ifdef HAVE_CONFIG_H
2013-11-09 17:47:19 -05:00
# include "config.h"
2014-01-13 08:05:25 -05:00
# endif
2013-11-09 17:47:19 -05:00
2013-10-11 16:52:20 -04:00
# include <assert.h>
2013-10-31 19:18:34 -04:00
# include <string.h>
2013-10-11 16:52:20 -04:00
# include "structures.h"
# include "mtproto-common.h"
2014-08-21 18:02:43 -04:00
//#include "telegram.h"
2013-10-13 06:18:08 -04:00
# include "tree.h"
2013-10-18 15:30:24 -04:00
# include "loop.h"
2013-11-02 06:14:30 -04:00
# include <openssl/aes.h>
# include <openssl/sha.h>
2013-11-05 17:24:26 -05:00
# include "queries.h"
2013-11-14 19:08:24 -05:00
# include "binlog.h"
2014-08-14 14:03:33 -04:00
# include "updates.h"
2013-11-02 06:14:30 -04:00
2014-08-13 08:56:55 -04:00
# include "tgl.h"
2013-11-02 06:14:30 -04:00
# define sha1 SHA1
2014-08-21 18:02:43 -04:00
# ifndef TGL_MAX_PEER_NUM
# define TGL_MAX_PEER_NUM 100000
# endif
2014-08-13 08:56:55 -04:00
2014-08-13 11:55:16 -04:00
static int id_cmp ( struct tgl_message * M1 , struct tgl_message * M2 ) ;
# define peer_cmp(a,b) (tgl_cmp_peer_id (a->id, b->id))
2014-01-31 11:03:40 -05:00
# define peer_cmp_name(a,b) (strcmp (a->print_name, b->print_name))
2014-08-13 11:55:16 -04:00
DEFINE_TREE ( peer , tgl_peer_t * , peer_cmp , 0 )
DEFINE_TREE ( peer_by_name , tgl_peer_t * , peer_cmp_name , 0 )
DEFINE_TREE ( message , struct tgl_message * , id_cmp , 0 )
2013-11-25 11:13:36 -05:00
2014-08-13 11:55:16 -04:00
static struct tgl_message message_list = {
2013-11-25 11:13:36 -05:00
. next_use = & message_list ,
. prev_use = & message_list
} ;
2014-08-13 11:55:16 -04:00
static struct tree_peer * tgl_peer_tree ;
2014-08-13 08:56:55 -04:00
static struct tree_peer_by_name * peer_by_name_tree ;
static struct tree_message * message_tree ;
static struct tree_message * message_unsent_tree ;
2013-11-25 11:13:36 -05:00
2014-08-13 08:56:55 -04:00
static int users_allocated ;
static int chats_allocated ;
static int messages_allocated ;
static int peer_num ;
static int encr_chats_allocated ;
static int geo_chats_allocated ;
2013-12-02 12:19:08 -05:00
2014-08-13 11:55:16 -04:00
static tgl_peer_t * Peers [ TGL_MAX_PEER_NUM ] ;
2013-12-02 12:19:08 -05:00
2013-11-25 11:13:36 -05:00
2014-08-20 18:33:19 -04:00
char * tgls_default_create_print_name ( tgl_peer_id_t id , const char * a1 , const char * a2 , const char * a3 , const char * a4 ) {
2014-08-12 11:15:04 -04:00
const char * d [ 4 ] ;
d [ 0 ] = a1 ; d [ 1 ] = a2 ; d [ 2 ] = a3 ; d [ 3 ] = a4 ;
static char buf [ 10000 ] ;
buf [ 0 ] = 0 ;
int i ;
int p = 0 ;
for ( i = 0 ; i < 4 ; i + + ) {
if ( d [ i ] & & strlen ( d [ i ] ) ) {
p + = tsnprintf ( buf + p , 9999 - p , " %s%s " , p ? " _ " : " " , d [ i ] ) ;
assert ( p < 9990 ) ;
}
}
char * s = buf ;
while ( * s ) {
if ( * s = = ' ' ) { * s = ' _ ' ; }
s + + ;
}
s = buf ;
int fl = strlen ( s ) ;
int cc = 0 ;
while ( 1 ) {
2014-08-13 11:55:16 -04:00
tgl_peer_t * P = tgl_peer_get_by_name ( s ) ;
if ( ! P | | ! tgl_cmp_peer_id ( P - > id , id ) ) {
2014-08-12 11:15:04 -04:00
break ;
}
cc + + ;
assert ( cc < = 9999 ) ;
tsnprintf ( s + fl , 9999 - fl , " #%d " , cc ) ;
}
return tstrdup ( s ) ;
}
2013-12-02 12:19:08 -05:00
2014-08-13 11:55:16 -04:00
/* {{{ Fetch */
2013-11-21 14:35:49 -05:00
2014-08-13 11:55:16 -04:00
int tglf_fetch_file_location ( struct tgl_file_location * loc ) {
2013-11-21 14:35:49 -05:00
int x = fetch_int ( ) ;
2014-08-12 11:15:04 -04:00
assert ( x = = CODE_file_location_unavailable | | x = = CODE_file_location ) ;
2013-11-21 14:35:49 -05:00
if ( x = = CODE_file_location_unavailable ) {
loc - > dc = - 1 ;
loc - > volume = fetch_long ( ) ;
loc - > local_id = fetch_int ( ) ;
loc - > secret = fetch_long ( ) ;
} else {
loc - > dc = fetch_int ( ) ;
loc - > volume = fetch_long ( ) ;
loc - > local_id = fetch_int ( ) ;
loc - > secret = fetch_long ( ) ;
2013-11-14 19:08:24 -05:00
}
2013-11-21 14:35:49 -05:00
return 0 ;
2013-11-14 19:08:24 -05:00
}
2014-08-13 11:55:16 -04:00
int tglf_fetch_user_status ( struct tgl_user_status * S ) {
2013-11-21 14:35:49 -05:00
unsigned x = fetch_int ( ) ;
2014-08-12 11:15:04 -04:00
assert ( x = = CODE_user_status_empty | | x = = CODE_user_status_online | | x = = CODE_user_status_offline ) ;
2013-10-11 16:52:20 -04:00
switch ( x ) {
case CODE_user_status_empty :
S - > online = 0 ;
2013-11-21 14:35:49 -05:00
S - > when = 0 ;
2013-10-11 16:52:20 -04:00
break ;
case CODE_user_status_online :
S - > online = 1 ;
S - > when = fetch_int ( ) ;
break ;
case CODE_user_status_offline :
S - > online = - 1 ;
S - > when = fetch_int ( ) ;
break ;
default :
assert ( 0 ) ;
}
2013-11-21 14:35:49 -05:00
return 0 ;
2013-10-11 16:52:20 -04:00
}
2014-08-13 11:55:16 -04:00
long long tglf_fetch_user_photo ( struct tgl_user * U ) {
2013-11-21 14:35:49 -05:00
unsigned x = fetch_int ( ) ;
2014-08-12 11:15:04 -04:00
assert ( x = = CODE_user_profile_photo | | x = = CODE_user_profile_photo_old | | x = = CODE_user_profile_photo_empty ) ;
2013-11-21 14:35:49 -05:00
if ( x = = CODE_user_profile_photo_empty ) {
bl_do_set_user_profile_photo ( U , 0 , 0 , 0 ) ;
return 0 ;
}
long long photo_id = 1 ;
if ( x = = CODE_user_profile_photo ) {
photo_id = fetch_long ( ) ;
}
2014-08-13 11:55:16 -04:00
static struct tgl_file_location big ;
static struct tgl_file_location small ;
2014-08-13 08:56:55 -04:00
assert ( tglf_fetch_file_location ( & small ) > = 0 ) ;
assert ( tglf_fetch_file_location ( & big ) > = 0 ) ;
2013-11-21 14:35:49 -05:00
bl_do_set_user_profile_photo ( U , photo_id , & big , & small ) ;
return 0 ;
}
2014-08-13 11:55:16 -04:00
int tglf_fetch_user ( struct tgl_user * U ) {
2013-11-04 12:34:27 -05:00
unsigned x = fetch_int ( ) ;
2014-08-12 11:15:04 -04:00
assert ( x = = CODE_user_empty | | x = = CODE_user_self | | x = = CODE_user_contact | | x = = CODE_user_request | | x = = CODE_user_foreign | | x = = CODE_user_deleted ) ;
2014-08-13 11:55:16 -04:00
U - > id = TGL_MK_USER ( fetch_int ( ) ) ;
2013-11-04 12:34:27 -05:00
if ( x = = CODE_user_empty ) {
2013-11-14 19:08:24 -05:00
return 0 ;
2013-11-04 12:34:27 -05:00
}
2013-11-21 14:35:49 -05:00
2013-11-04 12:34:27 -05:00
if ( x = = CODE_user_self ) {
2014-08-13 11:55:16 -04:00
bl_do_set_our_id ( tgl_get_peer_id ( U - > id ) ) ;
2013-11-04 12:34:27 -05:00
}
2013-11-21 14:35:49 -05:00
2014-08-12 11:15:04 -04:00
int new = ! ( U - > flags & FLAG_CREATED ) ;
2013-11-21 14:35:49 -05:00
if ( new ) {
int l1 = prefetch_strlen ( ) ;
2014-08-12 11:15:04 -04:00
assert ( l1 > = 0 ) ;
2013-11-21 14:35:49 -05:00
char * s1 = fetch_str ( l1 ) ;
int l2 = prefetch_strlen ( ) ;
2014-08-12 11:15:04 -04:00
assert ( l2 > = 0 ) ;
2013-11-21 14:35:49 -05:00
char * s2 = fetch_str ( l2 ) ;
if ( x = = CODE_user_deleted & & ! ( U - > flags & FLAG_DELETED ) ) {
2014-08-13 11:55:16 -04:00
bl_do_user_add ( tgl_get_peer_id ( U - > id ) , s1 , l1 , s2 , l2 , 0 , 0 , 0 , 0 ) ;
2013-11-21 14:35:49 -05:00
bl_do_user_delete ( U ) ;
2013-11-14 19:08:24 -05:00
}
2013-11-21 14:35:49 -05:00
if ( x ! = CODE_user_deleted ) {
2014-08-13 08:56:55 -04:00
long long access_hash = 0 ;
2013-11-21 14:35:49 -05:00
if ( x ! = CODE_user_self ) {
2014-08-13 08:56:55 -04:00
access_hash = fetch_long ( ) ;
2013-11-21 14:35:49 -05:00
}
int phone_len = 0 ;
char * phone = 0 ;
if ( x ! = CODE_user_foreign ) {
phone_len = prefetch_strlen ( ) ;
2014-08-12 11:15:04 -04:00
assert ( phone_len > = 0 ) ;
2013-11-21 14:35:49 -05:00
phone = fetch_str ( phone_len ) ;
}
2014-08-13 11:55:16 -04:00
bl_do_user_add ( tgl_get_peer_id ( U - > id ) , s1 , l1 , s2 , l2 , access_hash , phone , phone_len , x = = CODE_user_contact ) ;
2014-08-13 08:56:55 -04:00
assert ( tglf_fetch_user_photo ( U ) > = 0 ) ;
assert ( tglf_fetch_user_status ( & U - > status ) > = 0 ) ;
2013-11-21 14:35:49 -05:00
if ( x = = CODE_user_self ) {
fetch_bool ( ) ;
2013-11-16 08:04:53 -05:00
}
2013-11-14 19:08:24 -05:00
}
2013-11-21 14:35:49 -05:00
} else {
int l1 = prefetch_strlen ( ) ;
char * s1 = fetch_str ( l1 ) ;
int l2 = prefetch_strlen ( ) ;
char * s2 = fetch_str ( l2 ) ;
2014-08-12 17:32:11 -04:00
bl_do_user_set_name ( U , s1 , l1 , s2 , l2 ) ;
2013-11-21 14:35:49 -05:00
if ( x = = CODE_user_deleted & & ! ( U - > flags & FLAG_DELETED ) ) {
bl_do_user_delete ( U ) ;
2013-11-14 19:08:24 -05:00
}
2013-11-21 14:35:49 -05:00
if ( x ! = CODE_user_deleted ) {
if ( x ! = CODE_user_self ) {
2014-08-12 17:32:11 -04:00
bl_do_user_set_access_hash ( U , fetch_long ( ) ) ;
2013-11-21 14:35:49 -05:00
}
if ( x ! = CODE_user_foreign ) {
int l = prefetch_strlen ( ) ;
char * s = fetch_str ( l ) ;
2014-08-12 17:32:11 -04:00
bl_do_user_set_phone ( U , s , l ) ;
2013-11-21 14:35:49 -05:00
}
2014-08-13 08:56:55 -04:00
assert ( tglf_fetch_user_photo ( U ) > = 0 ) ;
2013-11-21 14:35:49 -05:00
2014-08-13 08:56:55 -04:00
tglf_fetch_user_status ( & U - > status ) ;
2013-11-21 14:35:49 -05:00
if ( x = = CODE_user_self ) {
fetch_bool ( ) ;
}
if ( x = = CODE_user_contact ) {
2014-08-12 17:32:11 -04:00
bl_do_user_set_friend ( U , 1 ) ;
2014-08-19 08:57:55 -04:00
} else {
2014-08-12 17:32:11 -04:00
bl_do_user_set_friend ( U , 0 ) ;
2013-11-21 14:35:49 -05:00
}
2013-10-25 15:50:10 -04:00
}
2013-10-11 16:52:20 -04:00
}
2013-11-21 14:35:49 -05:00
return 0 ;
2013-10-11 16:52:20 -04:00
}
2013-10-13 06:18:08 -04:00
2014-08-13 11:55:16 -04:00
void tglf_fetch_user_full ( struct tgl_user * U ) {
2014-08-13 08:56:55 -04:00
assert ( fetch_int ( ) = = CODE_user_full ) ;
tglf_fetch_alloc_user ( ) ;
assert ( skip_type_any ( TYPE_TO_PARAM ( contacts_link ) ) > = 0 ) ;
int * start = in_ptr ;
assert ( skip_type_any ( TYPE_TO_PARAM ( photo ) ) > = 0 ) ;
bl_do_user_set_full_photo ( U , start , 4 * ( in_ptr - start ) ) ;
assert ( skip_type_any ( TYPE_TO_PARAM ( peer_notify_settings ) ) > = 0 ) ;
bl_do_user_set_blocked ( U , fetch_bool ( ) ) ;
int l1 = prefetch_strlen ( ) ;
char * s1 = fetch_str ( l1 ) ;
int l2 = prefetch_strlen ( ) ;
char * s2 = fetch_str ( l2 ) ;
bl_do_user_set_real_name ( U , s1 , l1 , s2 , l2 ) ;
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_encrypted_chat ( struct tgl_secret_chat * U ) {
2013-11-02 13:01:22 -04:00
unsigned x = fetch_int ( ) ;
assert ( x = = CODE_encrypted_chat_empty | | x = = CODE_encrypted_chat_waiting | | x = = CODE_encrypted_chat_requested | | x = = CODE_encrypted_chat | | x = = CODE_encrypted_chat_discarded ) ;
2014-08-13 11:55:16 -04:00
U - > id = TGL_MK_ENCR_CHAT ( fetch_int ( ) ) ;
2013-11-02 13:01:22 -04:00
if ( x = = CODE_encrypted_chat_empty ) {
return ;
}
2013-11-21 14:35:49 -05:00
int new = ! ( U - > flags & FLAG_CREATED ) ;
2013-11-02 13:01:22 -04:00
if ( x = = CODE_encrypted_chat_discarded ) {
2013-11-21 14:35:49 -05:00
if ( new ) {
2014-08-13 08:56:55 -04:00
vlogprintf ( E_WARNING , " Unknown chat in deleted state. May be we forgot something... \n " ) ;
2013-11-21 14:35:49 -05:00
return ;
2013-11-04 12:34:27 -05:00
}
2013-11-21 14:35:49 -05:00
bl_do_encr_chat_delete ( U ) ;
2014-08-14 18:16:01 -04:00
//write_secret_chat_file ();
2013-11-02 13:01:22 -04:00
return ;
}
2013-11-04 12:34:27 -05:00
2013-11-21 14:35:49 -05:00
static char g_key [ 256 ] ;
static char nonce [ 256 ] ;
if ( new ) {
long long access_hash = fetch_long ( ) ;
int date = fetch_int ( ) ;
int admin_id = fetch_int ( ) ;
2014-08-13 08:56:55 -04:00
int user_id = fetch_int ( ) + admin_id - tgl_state . our_id ;
2013-11-21 14:35:49 -05:00
if ( x = = CODE_encrypted_chat_waiting ) {
2014-08-13 08:56:55 -04:00
vlogprintf ( E_WARNING , " Unknown chat in waiting state. May be we forgot something... \n " ) ;
2013-11-21 14:35:49 -05:00
return ;
2013-11-02 13:01:22 -04:00
}
2013-11-21 14:35:49 -05:00
if ( x = = CODE_encrypted_chat_requested | | x = = CODE_encrypted_chat ) {
memset ( g_key , 0 , sizeof ( g_key ) ) ;
2013-11-02 13:01:22 -04:00
}
2014-08-12 11:15:04 -04:00
fetch256 ( g_key ) ;
2013-11-21 14:35:49 -05:00
if ( x = = CODE_encrypted_chat ) {
fetch_long ( ) ; // fingerprint
}
if ( x = = CODE_encrypted_chat ) {
2014-08-13 08:56:55 -04:00
vlogprintf ( E_WARNING , " Unknown chat in ok state. May be we forgot something... \n " ) ;
2013-11-21 14:35:49 -05:00
return ;
2013-11-14 19:08:24 -05:00
}
2013-11-21 14:35:49 -05:00
bl_do_encr_chat_requested ( U , access_hash , date , admin_id , user_id , ( void * ) g_key , ( void * ) nonce ) ;
2014-08-14 18:16:01 -04:00
//write_secret_chat_file ();
2013-11-02 13:01:22 -04:00
} else {
2014-08-12 17:51:16 -04:00
bl_do_encr_chat_set_access_hash ( U , fetch_long ( ) ) ;
bl_do_encr_chat_set_date ( U , fetch_int ( ) ) ;
2013-11-21 14:35:49 -05:00
if ( fetch_int ( ) ! = U - > admin_id ) {
2014-08-13 08:56:55 -04:00
vlogprintf ( E_WARNING , " Changed admin in secret chat. WTF? \n " ) ;
2013-11-21 14:35:49 -05:00
return ;
}
2014-08-13 08:56:55 -04:00
if ( U - > user_id ! = U - > admin_id + fetch_int ( ) - tgl_state . our_id ) {
vlogprintf ( E_WARNING , " Changed partner in secret chat. WTF? \n " ) ;
2013-11-21 14:35:49 -05:00
return ;
2013-11-02 13:01:22 -04:00
}
2013-11-21 14:35:49 -05:00
if ( x = = CODE_encrypted_chat_waiting ) {
2014-08-12 17:51:16 -04:00
bl_do_encr_chat_set_state ( U , sc_waiting ) ;
2014-08-14 18:16:01 -04:00
//write_secret_chat_file ();
2013-11-21 14:35:49 -05:00
return ; // We needed only access hash from here
}
if ( x = = CODE_encrypted_chat_requested | | x = = CODE_encrypted_chat ) {
memset ( g_key , 0 , sizeof ( g_key ) ) ;
2013-11-04 12:34:27 -05:00
}
2013-11-21 14:35:49 -05:00
2014-08-12 11:15:04 -04:00
fetch256 ( g_key ) ;
2013-11-21 14:35:49 -05:00
if ( x = = CODE_encrypted_chat_requested ) {
return ; // Duplicate?
2013-11-05 17:24:26 -05:00
}
2013-11-21 14:35:49 -05:00
bl_do_encr_chat_accepted ( U , ( void * ) g_key , ( void * ) nonce , fetch_long ( ) ) ;
2014-08-14 18:16:01 -04:00
//write_secret_chat_file ();
2013-11-02 13:01:22 -04:00
}
2013-10-25 13:29:02 -04:00
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_chat ( struct tgl_chat * C ) {
2013-10-13 08:30:53 -04:00
unsigned x = fetch_int ( ) ;
assert ( x = = CODE_chat_empty | | x = = CODE_chat | | x = = CODE_chat_forbidden ) ;
2014-08-13 11:55:16 -04:00
C - > id = TGL_MK_CHAT ( fetch_int ( ) ) ;
2013-10-13 08:30:53 -04:00
if ( x = = CODE_chat_empty ) {
return ;
}
2013-11-22 18:26:35 -05:00
int new = ! ( C - > flags & FLAG_CREATED ) ;
if ( new ) {
int y = 0 ;
if ( x = = CODE_chat_forbidden ) {
y | = FLAG_FORBIDDEN ;
2013-10-13 08:30:53 -04:00
}
2013-11-22 18:26:35 -05:00
int l = prefetch_strlen ( ) ;
char * s = fetch_str ( l ) ;
2014-08-13 11:55:16 -04:00
struct tgl_file_location small ;
struct tgl_file_location big ;
2013-11-22 18:26:35 -05:00
memset ( & small , 0 , sizeof ( small ) ) ;
memset ( & big , 0 , sizeof ( big ) ) ;
int users_num = - 1 ;
int date = 0 ;
int version = - 1 ;
if ( x = = CODE_chat ) {
2014-01-15 07:10:52 -05:00
unsigned z = fetch_int ( ) ;
if ( z = = CODE_chat_photo_empty ) {
2013-11-22 18:26:35 -05:00
small . dc = - 2 ;
big . dc = - 2 ;
} else {
2014-01-15 07:10:52 -05:00
assert ( z = = CODE_chat_photo ) ;
2014-08-13 08:56:55 -04:00
tglf_fetch_file_location ( & small ) ;
tglf_fetch_file_location ( & big ) ;
2013-11-22 18:26:35 -05:00
}
users_num = fetch_int ( ) ;
date = fetch_int ( ) ;
if ( fetch_bool ( ) ) {
y | = FLAG_CHAT_IN_CHAT ;
}
version = fetch_int ( ) ;
} else {
small . dc = - 2 ;
big . dc = - 2 ;
users_num = - 1 ;
date = fetch_int ( ) ;
version = - 1 ;
2013-10-14 13:26:25 -04:00
}
2013-11-22 18:26:35 -05:00
bl_do_create_chat ( C , y , s , l , users_num , date , version , & big , & small ) ;
2013-10-14 13:26:25 -04:00
} else {
2013-11-22 18:26:35 -05:00
if ( x = = CODE_chat_forbidden ) {
bl_do_chat_forbid ( C , 1 ) ;
} else {
bl_do_chat_forbid ( C , 0 ) ;
}
int l = prefetch_strlen ( ) ;
char * s = fetch_str ( l ) ;
2014-08-12 17:51:16 -04:00
bl_do_chat_set_title ( C , s , l ) ;
2013-11-22 18:26:35 -05:00
2014-08-13 11:55:16 -04:00
struct tgl_file_location small ;
struct tgl_file_location big ;
2013-11-22 18:26:35 -05:00
memset ( & small , 0 , sizeof ( small ) ) ;
memset ( & big , 0 , sizeof ( big ) ) ;
if ( x = = CODE_chat ) {
unsigned y = fetch_int ( ) ;
if ( y = = CODE_chat_photo_empty ) {
small . dc = - 2 ;
big . dc = - 2 ;
} else {
assert ( y = = CODE_chat_photo ) ;
2014-08-13 08:56:55 -04:00
tglf_fetch_file_location ( & small ) ;
tglf_fetch_file_location ( & big ) ;
2013-11-22 18:26:35 -05:00
}
2014-08-12 17:51:16 -04:00
bl_do_chat_set_photo ( C , & big , & small ) ;
2013-11-22 18:26:35 -05:00
int users_num = fetch_int ( ) ;
2014-08-12 17:51:16 -04:00
bl_do_chat_set_date ( C , fetch_int ( ) ) ;
bl_do_chat_set_set_in_chat ( C , fetch_bool ( ) ) ;
bl_do_chat_set_version ( C , users_num , fetch_int ( ) ) ;
2013-11-22 18:26:35 -05:00
} else {
2014-08-12 17:51:16 -04:00
bl_do_chat_set_date ( C , fetch_int ( ) ) ;
2013-11-22 18:26:35 -05:00
}
2013-10-14 13:26:25 -04:00
}
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_chat_full ( struct tgl_chat * C ) {
2013-10-24 13:04:44 -04:00
unsigned x = fetch_int ( ) ;
assert ( x = = CODE_messages_chat_full ) ;
assert ( fetch_int ( ) = = CODE_chat_full ) ;
2014-08-13 11:55:16 -04:00
C - > id = TGL_MK_CHAT ( fetch_int ( ) ) ;
2013-10-24 13:04:44 -04:00
x = fetch_int ( ) ;
2013-11-25 11:13:36 -05:00
int version = 0 ;
2014-08-13 11:55:16 -04:00
struct tgl_chat_user * users = 0 ;
2013-11-25 11:13:36 -05:00
int users_num = 0 ;
int admin_id = 0 ;
2013-10-24 13:04:44 -04:00
if ( x = = CODE_chat_participants ) {
2014-08-13 11:55:16 -04:00
assert ( fetch_int ( ) = = tgl_get_peer_id ( C - > id ) ) ;
2013-11-25 11:13:36 -05:00
admin_id = fetch_int ( ) ;
2013-10-24 13:04:44 -04:00
assert ( fetch_int ( ) = = CODE_vector ) ;
2013-11-25 11:13:36 -05:00
users_num = fetch_int ( ) ;
2014-08-13 11:55:16 -04:00
users = talloc ( sizeof ( struct tgl_chat_user ) * users_num ) ;
2013-10-24 13:04:44 -04:00
int i ;
2013-11-25 12:16:34 -05:00
for ( i = 0 ; i < users_num ; i + + ) {
2013-10-24 13:04:44 -04:00
assert ( fetch_int ( ) = = ( int ) CODE_chat_participant ) ;
2013-11-25 11:13:36 -05:00
users [ i ] . user_id = fetch_int ( ) ;
users [ i ] . inviter_id = fetch_int ( ) ;
users [ i ] . date = fetch_int ( ) ;
2013-10-24 13:04:44 -04:00
}
2013-11-25 11:13:36 -05:00
version = fetch_int ( ) ;
2013-10-24 13:04:44 -04:00
}
2013-11-25 11:13:36 -05:00
int * start = in_ptr ;
2014-08-12 17:32:11 -04:00
assert ( skip_type_any ( TYPE_TO_PARAM ( photo ) ) > = 0 ) ;
2013-11-25 11:13:36 -05:00
int * end = in_ptr ;
2014-08-12 17:32:11 -04:00
assert ( skip_type_any ( TYPE_TO_PARAM ( peer_notify_settings ) ) > = 0 ) ;
2013-10-24 13:04:44 -04:00
int n , i ;
assert ( fetch_int ( ) = = CODE_vector ) ;
n = fetch_int ( ) ;
for ( i = 0 ; i < n ; i + + ) {
2014-08-13 08:56:55 -04:00
tglf_fetch_alloc_chat ( ) ;
2013-10-24 13:04:44 -04:00
}
assert ( fetch_int ( ) = = CODE_vector ) ;
n = fetch_int ( ) ;
for ( i = 0 ; i < n ; i + + ) {
2014-08-13 08:56:55 -04:00
tglf_fetch_alloc_user ( ) ;
2013-10-24 13:04:44 -04:00
}
2013-11-25 11:13:36 -05:00
if ( admin_id ) {
2014-08-12 17:51:16 -04:00
bl_do_chat_set_admin ( C , admin_id ) ;
2013-11-25 11:13:36 -05:00
}
if ( version > 0 ) {
2014-08-12 17:51:16 -04:00
bl_do_chat_set_participants ( C , version , users_num , users ) ;
2014-08-13 11:55:16 -04:00
tfree ( users , sizeof ( struct tgl_chat_user ) * users_num ) ;
2013-11-25 11:13:36 -05:00
}
2014-08-12 17:51:16 -04:00
bl_do_chat_set_full_photo ( C , start , 4 * ( end - start ) ) ;
2013-10-24 13:04:44 -04:00
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_photo_size ( struct tgl_photo_size * S ) {
2013-10-18 12:00:47 -04:00
memset ( S , 0 , sizeof ( * S ) ) ;
2013-10-14 13:26:25 -04:00
unsigned x = fetch_int ( ) ;
2013-10-21 15:27:29 -04:00
assert ( x = = CODE_photo_size | | x = = CODE_photo_cached_size | | x = = CODE_photo_size_empty ) ;
2013-10-14 13:26:25 -04:00
S - > type = fetch_str_dup ( ) ;
2013-10-21 15:27:29 -04:00
if ( x ! = CODE_photo_size_empty ) {
2014-08-13 08:56:55 -04:00
tglf_fetch_file_location ( & S - > loc ) ;
2013-10-21 15:27:29 -04:00
S - > w = fetch_int ( ) ;
S - > h = fetch_int ( ) ;
if ( x = = CODE_photo_size ) {
S - > size = fetch_int ( ) ;
} else {
2013-10-27 15:35:02 -04:00
S - > size = prefetch_strlen ( ) ;
2013-11-11 13:35:31 -05:00
fetch_str ( S - > size ) ;
2013-10-21 15:27:29 -04:00
}
2013-10-14 13:26:25 -04:00
}
}
2014-08-14 14:03:33 -04:00
void tglf_fetch_geo ( struct tgl_geo * G ) {
2013-10-18 12:00:47 -04:00
unsigned x = fetch_int ( ) ;
if ( x = = CODE_geo_point ) {
G - > longitude = fetch_double ( ) ;
G - > latitude = fetch_double ( ) ;
} else {
assert ( x = = CODE_geo_point_empty ) ;
G - > longitude = 0 ;
G - > latitude = 0 ;
}
2013-10-14 13:26:25 -04:00
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_photo ( struct tgl_photo * P ) {
2013-10-14 13:26:25 -04:00
memset ( P , 0 , sizeof ( * P ) ) ;
unsigned x = fetch_int ( ) ;
2013-10-24 13:04:44 -04:00
assert ( x = = CODE_photo_empty | | x = = CODE_photo ) ;
2013-10-14 13:26:25 -04:00
P - > id = fetch_long ( ) ;
if ( x = = CODE_photo_empty ) { return ; }
P - > access_hash = fetch_long ( ) ;
P - > user_id = fetch_int ( ) ;
P - > date = fetch_int ( ) ;
P - > caption = fetch_str_dup ( ) ;
2014-08-14 14:03:33 -04:00
tglf_fetch_geo ( & P - > geo ) ;
2013-10-14 13:26:25 -04:00
assert ( fetch_int ( ) = = CODE_vector ) ;
P - > sizes_num = fetch_int ( ) ;
2014-08-13 11:55:16 -04:00
P - > sizes = talloc ( sizeof ( struct tgl_photo_size ) * P - > sizes_num ) ;
2013-10-14 13:26:25 -04:00
int i ;
for ( i = 0 ; i < P - > sizes_num ; i + + ) {
2014-08-13 08:56:55 -04:00
tglf_fetch_photo_size ( & P - > sizes [ i ] ) ;
2013-10-14 13:26:25 -04:00
}
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_video ( struct tgl_video * V ) {
2013-10-14 13:26:25 -04:00
memset ( V , 0 , sizeof ( * V ) ) ;
unsigned x = fetch_int ( ) ;
V - > id = fetch_long ( ) ;
if ( x = = CODE_video_empty ) { return ; }
V - > access_hash = fetch_long ( ) ;
V - > user_id = fetch_int ( ) ;
V - > date = fetch_int ( ) ;
V - > caption = fetch_str_dup ( ) ;
V - > duration = fetch_int ( ) ;
2014-08-12 21:22:15 -04:00
V - > mime_type = fetch_str_dup ( ) ;
2013-10-14 13:26:25 -04:00
V - > size = fetch_int ( ) ;
2014-08-13 08:56:55 -04:00
tglf_fetch_photo_size ( & V - > thumb ) ;
2013-10-14 13:26:25 -04:00
V - > dc_id = fetch_int ( ) ;
V - > w = fetch_int ( ) ;
V - > h = fetch_int ( ) ;
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_audio ( struct tgl_audio * V ) {
2013-11-15 05:37:14 -05:00
memset ( V , 0 , sizeof ( * V ) ) ;
unsigned x = fetch_int ( ) ;
V - > id = fetch_long ( ) ;
if ( x = = CODE_audio_empty ) { return ; }
V - > access_hash = fetch_long ( ) ;
V - > user_id = fetch_int ( ) ;
V - > date = fetch_int ( ) ;
V - > duration = fetch_int ( ) ;
2014-08-12 21:22:15 -04:00
V - > mime_type = fetch_str_dup ( ) ;
2013-11-15 05:37:14 -05:00
V - > size = fetch_int ( ) ;
V - > dc_id = fetch_int ( ) ;
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_document ( struct tgl_document * V ) {
2013-11-15 05:37:14 -05:00
memset ( V , 0 , sizeof ( * V ) ) ;
unsigned x = fetch_int ( ) ;
V - > id = fetch_long ( ) ;
if ( x = = CODE_document_empty ) { return ; }
V - > access_hash = fetch_long ( ) ;
V - > user_id = fetch_int ( ) ;
V - > date = fetch_int ( ) ;
V - > caption = fetch_str_dup ( ) ;
V - > mime_type = fetch_str_dup ( ) ;
V - > size = fetch_int ( ) ;
2014-08-13 08:56:55 -04:00
tglf_fetch_photo_size ( & V - > thumb ) ;
2013-11-15 05:37:14 -05:00
V - > dc_id = fetch_int ( ) ;
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_message_action ( struct tgl_message_action * M ) {
2013-10-14 13:26:25 -04:00
memset ( M , 0 , sizeof ( * M ) ) ;
unsigned x = fetch_int ( ) ;
switch ( x ) {
case CODE_message_action_empty :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_none ;
2013-10-14 13:26:25 -04:00
break ;
2013-11-22 18:26:35 -05:00
case CODE_message_action_geo_chat_create :
{
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_geo_chat_create ;
2013-11-22 18:26:35 -05:00
int l = prefetch_strlen ( ) ; // title
char * s = fetch_str ( l ) ;
int l2 = prefetch_strlen ( ) ; // checkin
char * s2 = fetch_str ( l2 ) ;
2014-08-13 08:56:55 -04:00
vlogprintf ( E_ERROR , " Message action: Created geochat %.*s in address %.*s. You are in magic land now, since nobody ever tested geochats in this app \n " , l , s , l2 , s2 ) ;
2013-11-22 18:26:35 -05:00
}
break ;
case CODE_message_action_geo_chat_checkin :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_geo_chat_checkin ;
2013-11-22 18:26:35 -05:00
break ;
2013-10-14 13:26:25 -04:00
case CODE_message_action_chat_create :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_chat_create ;
2013-10-14 13:26:25 -04:00
M - > title = fetch_str_dup ( ) ;
assert ( fetch_int ( ) = = ( int ) CODE_vector ) ;
M - > user_num = fetch_int ( ) ;
2014-01-10 06:32:57 -05:00
M - > users = talloc ( M - > user_num * 4 ) ;
2013-10-14 13:26:25 -04:00
fetch_ints ( M - > users , M - > user_num ) ;
break ;
case CODE_message_action_chat_edit_title :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_chat_edit_title ;
2013-10-14 13:26:25 -04:00
M - > new_title = fetch_str_dup ( ) ;
break ;
case CODE_message_action_chat_edit_photo :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_chat_edit_photo ;
2014-08-13 08:56:55 -04:00
tglf_fetch_photo ( & M - > photo ) ;
2013-10-14 13:26:25 -04:00
break ;
case CODE_message_action_chat_delete_photo :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_chat_delete_photo ;
2013-10-14 13:26:25 -04:00
break ;
case CODE_message_action_chat_add_user :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_chat_add_user ;
2013-10-14 13:26:25 -04:00
M - > user = fetch_int ( ) ;
break ;
case CODE_message_action_chat_delete_user :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_chat_delete_user ;
2013-10-14 13:26:25 -04:00
M - > user = fetch_int ( ) ;
break ;
default :
assert ( 0 ) ;
}
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_message_short ( struct tgl_message * M ) {
2013-11-29 16:43:56 -05:00
int new = ! ( M - > flags & FLAG_CREATED ) ;
if ( new ) {
int id = fetch_int ( ) ;
int from_id = fetch_int ( ) ;
2014-08-13 08:56:55 -04:00
int to_id = tgl_state . our_id ;
2013-11-29 16:43:56 -05:00
int l = prefetch_strlen ( ) ;
char * s = fetch_str ( l ) ;
2014-08-14 14:03:33 -04:00
tglu_fetch_pts ( ) ;
2013-11-29 16:43:56 -05:00
int date = fetch_int ( ) ;
2014-08-20 12:36:45 -04:00
//tglu_fetch_seq ();
2014-08-25 10:12:17 -04:00
int seq = fetch_int ( ) ;
assert ( seq = = tgl_state . seq + 1 ) ;
2013-11-29 16:43:56 -05:00
2014-08-25 10:04:27 -04:00
bl_do_create_message_text ( id , from_id , TGL_PEER_USER , to_id , date , 1 , l , s ) ;
2014-08-25 16:48:22 -04:00
//bl_do_msg_seq_update (id);
2013-11-29 16:43:56 -05:00
} else {
2014-08-25 16:48:22 -04:00
fetch_int ( ) ; // id
2013-11-29 16:43:56 -05:00
fetch_int ( ) ; // from_id
int l = prefetch_strlen ( ) ;
fetch_str ( l ) ; // text
2014-08-14 14:03:33 -04:00
tglu_fetch_pts ( ) ;
2013-11-29 16:43:56 -05:00
fetch_int ( ) ;
2014-08-20 12:36:45 -04:00
//tglu_fetch_seq ();
2014-08-25 10:12:17 -04:00
int seq = fetch_int ( ) ;
assert ( seq = = tgl_state . seq + 1 ) ;
2014-08-25 16:48:22 -04:00
//bl_do_msg_seq_update (id);
2013-11-29 16:43:56 -05:00
}
2013-10-16 15:19:39 -04:00
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_message_short_chat ( struct tgl_message * M ) {
2013-11-29 16:43:56 -05:00
int new = ! ( M - > flags & FLAG_CREATED ) ;
if ( new ) {
int id = fetch_int ( ) ;
int from_id = fetch_int ( ) ;
int to_id = fetch_int ( ) ;
int l = prefetch_strlen ( ) ;
char * s = fetch_str ( l ) ;
2014-08-14 14:03:33 -04:00
tglu_fetch_pts ( ) ;
2013-11-29 16:43:56 -05:00
int date = fetch_int ( ) ;
2014-08-20 12:36:45 -04:00
//tglu_fetch_seq ();
2013-11-29 16:43:56 -05:00
2014-08-25 10:12:17 -04:00
int seq = fetch_int ( ) ;
assert ( seq = = tgl_state . seq + 1 ) ;
2014-08-25 10:04:27 -04:00
bl_do_create_message_text ( id , from_id , TGL_PEER_CHAT , to_id , date , 1 , l , s ) ;
2014-08-25 16:48:22 -04:00
//bl_do_msg_seq_update (id);
2013-11-29 16:43:56 -05:00
} else {
2014-08-25 16:48:22 -04:00
fetch_int ( ) ; // id
2013-11-29 16:43:56 -05:00
fetch_int ( ) ; // from_id
fetch_int ( ) ; // to_id
int l = prefetch_strlen ( ) ;
fetch_str ( l ) ; // text
2014-08-14 14:03:33 -04:00
tglu_fetch_pts ( ) ;
2013-11-29 16:43:56 -05:00
fetch_int ( ) ;
2014-08-20 12:36:45 -04:00
//tglu_fetch_seq ();
2014-08-25 10:12:17 -04:00
int seq = fetch_int ( ) ;
assert ( seq = = tgl_state . seq + 1 ) ;
2014-08-25 16:48:22 -04:00
//bl_do_msg_seq_update (id);
2013-11-29 16:43:56 -05:00
}
2013-10-16 15:19:39 -04:00
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_message_media ( struct tgl_message_media * M ) {
2013-10-14 13:26:25 -04:00
memset ( M , 0 , sizeof ( * M ) ) ;
2014-08-18 12:39:04 -04:00
//M->type = fetch_int ();
int x = fetch_int ( ) ;
switch ( x ) {
2013-10-14 13:26:25 -04:00
case CODE_message_media_empty :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_none ;
2013-10-14 13:26:25 -04:00
break ;
case CODE_message_media_photo :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_photo ;
2014-08-13 08:56:55 -04:00
tglf_fetch_photo ( & M - > photo ) ;
2013-10-14 13:26:25 -04:00
break ;
case CODE_message_media_video :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_video ;
2014-08-13 11:55:16 -04:00
tglf_fetch_video ( & M - > video ) ;
2013-10-14 13:26:25 -04:00
break ;
2013-11-15 05:37:14 -05:00
case CODE_message_media_audio :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_audio ;
2014-08-13 11:55:16 -04:00
tglf_fetch_audio ( & M - > audio ) ;
2013-11-15 05:37:14 -05:00
break ;
case CODE_message_media_document :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_document ;
2014-08-13 11:55:16 -04:00
tglf_fetch_document ( & M - > document ) ;
2013-11-15 05:37:14 -05:00
break ;
2013-10-14 13:26:25 -04:00
case CODE_message_media_geo :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_geo ;
2014-08-14 14:03:33 -04:00
tglf_fetch_geo ( & M - > geo ) ;
2013-10-14 13:26:25 -04:00
break ;
case CODE_message_media_contact :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_contact ;
2013-10-14 13:26:25 -04:00
M - > phone = fetch_str_dup ( ) ;
M - > first_name = fetch_str_dup ( ) ;
M - > last_name = fetch_str_dup ( ) ;
M - > user_id = fetch_int ( ) ;
break ;
case CODE_message_media_unsupported :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_unsupported ;
2014-01-10 09:37:56 -05:00
M - > data_size = prefetch_strlen ( ) ;
M - > data = talloc ( M - > data_size ) ;
memcpy ( M - > data , fetch_str ( M - > data_size ) , M - > data_size ) ;
2013-10-14 13:26:25 -04:00
break ;
default :
2014-08-13 08:56:55 -04:00
vlogprintf ( E_ERROR , " type = 0x%08x \n " , M - > type ) ;
2013-10-14 13:26:25 -04:00
assert ( 0 ) ;
}
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_message_media_encrypted ( struct tgl_message_media * M ) {
2013-11-02 13:01:22 -04:00
memset ( M , 0 , sizeof ( * M ) ) ;
unsigned x = fetch_int ( ) ;
int l ;
2013-11-04 12:34:27 -05:00
switch ( x ) {
2013-11-02 13:01:22 -04:00
case CODE_decrypted_message_media_empty :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_none ;
//M->type = CODE_message_media_empty;
2013-11-02 13:01:22 -04:00
break ;
case CODE_decrypted_message_media_photo :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_photo_encr ;
//M->type = x;
2013-11-02 13:01:22 -04:00
l = prefetch_strlen ( ) ;
fetch_str ( l ) ; // thumb
fetch_int ( ) ; // thumb_w
fetch_int ( ) ; // thumb_h
M - > encr_photo . w = fetch_int ( ) ;
M - > encr_photo . h = fetch_int ( ) ;
M - > encr_photo . size = fetch_int ( ) ;
2013-11-04 12:34:27 -05:00
l = prefetch_strlen ( ) ;
2013-11-02 13:01:22 -04:00
assert ( l > 0 ) ;
2014-01-10 06:32:57 -05:00
M - > encr_photo . key = talloc ( 32 ) ;
2013-11-04 12:34:27 -05:00
memset ( M - > encr_photo . key , 0 , 32 ) ;
if ( l < = 32 ) {
memcpy ( M - > encr_photo . key + ( 32 - l ) , fetch_str ( l ) , l ) ;
} else {
memcpy ( M - > encr_photo . key , fetch_str ( l ) + ( l - 32 ) , 32 ) ;
}
2014-01-10 06:32:57 -05:00
M - > encr_photo . iv = talloc ( 32 ) ;
2013-11-04 12:34:27 -05:00
l = prefetch_strlen ( ) ;
assert ( l > 0 ) ;
memset ( M - > encr_photo . iv , 0 , 32 ) ;
if ( l < = 32 ) {
memcpy ( M - > encr_photo . iv + ( 32 - l ) , fetch_str ( l ) , l ) ;
} else {
memcpy ( M - > encr_photo . iv , fetch_str ( l ) + ( l - 32 ) , 32 ) ;
}
2013-11-02 13:01:22 -04:00
break ;
case CODE_decrypted_message_media_video :
2014-08-12 21:22:15 -04:00
case CODE_decrypted_message_media_video_l12 :
2014-08-18 12:39:04 -04:00
//M->type = CODE_decrypted_message_media_video;
M - > type = tgl_message_media_video_encr ;
2013-11-02 13:01:22 -04:00
l = prefetch_strlen ( ) ;
fetch_str ( l ) ; // thumb
fetch_int ( ) ; // thumb_w
fetch_int ( ) ; // thumb_h
2013-11-15 05:37:14 -05:00
M - > encr_video . duration = fetch_int ( ) ;
2014-08-12 21:22:15 -04:00
if ( x = = CODE_decrypted_message_media_video ) {
M - > encr_video . mime_type = fetch_str_dup ( ) ;
}
2013-11-02 13:01:22 -04:00
M - > encr_video . w = fetch_int ( ) ;
M - > encr_video . h = fetch_int ( ) ;
M - > encr_video . size = fetch_int ( ) ;
2013-11-15 05:37:14 -05:00
l = prefetch_strlen ( ) ;
assert ( l > 0 ) ;
2014-01-10 06:32:57 -05:00
M - > encr_video . key = talloc0 ( 32 ) ;
2013-11-15 05:37:14 -05:00
if ( l < = 32 ) {
memcpy ( M - > encr_video . key + ( 32 - l ) , fetch_str ( l ) , l ) ;
} else {
memcpy ( M - > encr_video . key , fetch_str ( l ) + ( l - 32 ) , 32 ) ;
}
2014-01-10 06:32:57 -05:00
M - > encr_video . iv = talloc ( 32 ) ;
2013-11-15 05:37:14 -05:00
l = prefetch_strlen ( ) ;
assert ( l > 0 ) ;
memset ( M - > encr_video . iv , 0 , 32 ) ;
if ( l < = 32 ) {
memcpy ( M - > encr_video . iv + ( 32 - l ) , fetch_str ( l ) , l ) ;
} else {
memcpy ( M - > encr_video . iv , fetch_str ( l ) + ( l - 32 ) , 32 ) ;
}
break ;
case CODE_decrypted_message_media_audio :
2014-08-12 21:22:15 -04:00
case CODE_decrypted_message_media_audio_l12 :
2014-08-18 12:39:04 -04:00
//M->type = CODE_decrypted_message_media_audio;
M - > type = tgl_message_media_audio_encr ;
2013-11-15 05:37:14 -05:00
M - > encr_audio . duration = fetch_int ( ) ;
2014-08-12 21:22:15 -04:00
if ( x = = CODE_decrypted_message_media_audio ) {
M - > encr_audio . mime_type = fetch_str_dup ( ) ;
}
2013-11-15 05:37:14 -05:00
M - > encr_audio . size = fetch_int ( ) ;
l = prefetch_strlen ( ) ;
assert ( l > 0 ) ;
2014-01-10 06:32:57 -05:00
M - > encr_video . key = talloc0 ( 32 ) ;
2013-11-15 05:37:14 -05:00
if ( l < = 32 ) {
memcpy ( M - > encr_video . key + ( 32 - l ) , fetch_str ( l ) , l ) ;
} else {
memcpy ( M - > encr_video . key , fetch_str ( l ) + ( l - 32 ) , 32 ) ;
}
2014-01-10 06:32:57 -05:00
M - > encr_video . iv = talloc0 ( 32 ) ;
2013-11-15 05:37:14 -05:00
l = prefetch_strlen ( ) ;
assert ( l > 0 ) ;
if ( l < = 32 ) {
memcpy ( M - > encr_video . iv + ( 32 - l ) , fetch_str ( l ) , l ) ;
} else {
memcpy ( M - > encr_video . iv , fetch_str ( l ) + ( l - 32 ) , 32 ) ;
}
break ;
case CODE_decrypted_message_media_document :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_document_encr ;
2013-11-15 05:37:14 -05:00
l = prefetch_strlen ( ) ;
fetch_str ( l ) ; // thumb
fetch_int ( ) ; // thumb_w
fetch_int ( ) ; // thumb_h
M - > encr_document . file_name = fetch_str_dup ( ) ;
M - > encr_document . mime_type = fetch_str_dup ( ) ;
M - > encr_video . size = fetch_int ( ) ;
2013-11-02 13:01:22 -04:00
2013-11-04 12:34:27 -05:00
l = prefetch_strlen ( ) ;
2013-11-02 13:01:22 -04:00
assert ( l > 0 ) ;
2014-01-10 06:32:57 -05:00
M - > encr_video . key = talloc0 ( 32 ) ;
2013-11-04 12:34:27 -05:00
if ( l < = 32 ) {
memcpy ( M - > encr_video . key + ( 32 - l ) , fetch_str ( l ) , l ) ;
} else {
memcpy ( M - > encr_video . key , fetch_str ( l ) + ( l - 32 ) , 32 ) ;
}
2014-01-10 06:32:57 -05:00
M - > encr_video . iv = talloc0 ( 32 ) ;
2013-11-04 12:34:27 -05:00
l = prefetch_strlen ( ) ;
assert ( l > 0 ) ;
if ( l < = 32 ) {
memcpy ( M - > encr_video . iv + ( 32 - l ) , fetch_str ( l ) , l ) ;
} else {
memcpy ( M - > encr_video . iv , fetch_str ( l ) + ( l - 32 ) , 32 ) ;
}
2013-11-02 13:01:22 -04:00
break ;
/* case CODE_decrypted_message_media_file:
M - > type = x ;
M - > encr_file . filename = fetch_str_dup ( ) ;
l = prefetch_strlen ( ) ;
fetch_str ( l ) ; // thumb
l = fetch_int ( ) ;
assert ( l > 0 ) ;
2014-01-10 06:32:57 -05:00
M - > encr_file . key = talloc ( l ) ;
2013-11-02 13:01:22 -04:00
memcpy ( M - > encr_file . key , fetch_str ( l ) , l ) ;
l = fetch_int ( ) ;
assert ( l > 0 ) ;
2014-01-10 06:32:57 -05:00
M - > encr_file . iv = talloc ( l ) ;
2013-11-02 13:01:22 -04:00
memcpy ( M - > encr_file . iv , fetch_str ( l ) , l ) ;
break ;
*/
case CODE_decrypted_message_media_geo_point :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_geo ;
2013-11-02 13:01:22 -04:00
M - > geo . longitude = fetch_double ( ) ;
M - > geo . latitude = fetch_double ( ) ;
break ;
case CODE_decrypted_message_media_contact :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_media_contact ;
2013-11-02 13:01:22 -04:00
M - > phone = fetch_str_dup ( ) ;
M - > first_name = fetch_str_dup ( ) ;
M - > last_name = fetch_str_dup ( ) ;
M - > user_id = fetch_int ( ) ;
break ;
default :
2014-08-13 08:56:55 -04:00
vlogprintf ( E_ERROR , " type = 0x%08x \n " , x ) ;
2013-11-29 16:43:56 -05:00
assert ( 0 ) ;
}
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_message_action_encrypted ( struct tgl_message_action * M ) {
2013-11-29 16:43:56 -05:00
unsigned x = fetch_int ( ) ;
switch ( x ) {
case CODE_decrypted_message_action_set_message_t_t_l :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_set_message_ttl ;
2013-11-29 16:43:56 -05:00
M - > ttl = fetch_int ( ) ;
break ;
2014-08-12 21:22:15 -04:00
case CODE_decrypted_message_action_read_messages :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_read_messages ;
2014-08-12 21:22:15 -04:00
{
assert ( fetch_int ( ) = = CODE_vector ) ;
int n = fetch_int ( ) ;
M - > read_cnt = n ;
while ( n - - > 0 ) {
long long id = fetch_long ( ) ;
2014-08-13 11:55:16 -04:00
struct tgl_message * N = tgl_message_get ( id ) ;
2014-08-12 21:22:15 -04:00
if ( N ) {
N - > unread = 0 ;
}
}
}
break ;
case CODE_decrypted_message_action_delete_messages :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_delete_messages ;
2014-08-12 21:22:15 -04:00
{
assert ( fetch_int ( ) = = CODE_vector ) ;
int n = fetch_int ( ) ;
M - > delete_cnt = n ;
while ( n - - > 0 ) {
fetch_long ( ) ;
}
}
break ;
case CODE_decrypted_message_action_screenshot_messages :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_screenshot_messages ;
2014-08-12 21:22:15 -04:00
{
assert ( fetch_int ( ) = = CODE_vector ) ;
int n = fetch_int ( ) ;
M - > screenshot_cnt = n ;
while ( n - - > 0 ) {
fetch_long ( ) ;
}
}
break ;
case CODE_decrypted_message_action_notify_layer :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_notify_layer ;
2014-08-12 21:22:15 -04:00
M - > layer = fetch_int ( ) ;
break ;
case CODE_decrypted_message_action_flush_history :
2014-08-18 12:39:04 -04:00
M - > type = tgl_message_action_flush_history ;
2014-08-12 21:22:15 -04:00
break ;
2013-11-29 16:43:56 -05:00
default :
2014-08-13 08:56:55 -04:00
vlogprintf ( E_ERROR , " x = 0x%08x \n " , x ) ;
2013-11-02 13:01:22 -04:00
assert ( 0 ) ;
}
}
2014-08-13 11:55:16 -04:00
tgl_peer_id_t tglf_fetch_peer_id ( void ) {
2013-10-18 12:00:47 -04:00
unsigned x = fetch_int ( ) ;
if ( x = = CODE_peer_user ) {
2014-08-13 11:55:16 -04:00
return TGL_MK_USER ( fetch_int ( ) ) ;
2013-10-18 12:00:47 -04:00
} else {
assert ( CODE_peer_chat ) ;
2014-08-13 11:55:16 -04:00
return TGL_MK_CHAT ( fetch_int ( ) ) ;
2013-10-18 12:00:47 -04:00
}
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_message ( struct tgl_message * M ) {
2013-10-14 13:26:25 -04:00
unsigned x = fetch_int ( ) ;
assert ( x = = CODE_message_empty | | x = = CODE_message | | x = = CODE_message_forwarded | | x = = CODE_message_service ) ;
2013-11-29 16:43:56 -05:00
int id = fetch_int ( ) ;
assert ( M - > id = = id ) ;
2013-10-14 13:26:25 -04:00
if ( x = = CODE_message_empty ) {
return ;
}
2013-11-29 16:43:56 -05:00
int fwd_from_id = 0 ;
int fwd_date = 0 ;
2013-10-14 13:26:25 -04:00
if ( x = = CODE_message_forwarded ) {
2013-11-29 16:43:56 -05:00
fwd_from_id = fetch_int ( ) ;
fwd_date = fetch_int ( ) ;
2013-10-14 13:26:25 -04:00
}
2013-11-29 16:43:56 -05:00
int from_id = fetch_int ( ) ;
2014-08-13 11:55:16 -04:00
tgl_peer_id_t to_id = tglf_fetch_peer_id ( ) ;
2013-11-29 16:43:56 -05:00
fetch_bool ( ) ; // out.
int unread = fetch_bool ( ) ;
int date = fetch_int ( ) ;
int new = ! ( M - > flags & FLAG_CREATED ) ;
2013-10-14 13:26:25 -04:00
if ( x = = CODE_message_service ) {
2013-11-29 16:43:56 -05:00
int * start = in_ptr ;
2014-08-12 11:15:04 -04:00
2014-08-12 17:32:11 -04:00
assert ( skip_type_any ( TYPE_TO_PARAM ( message_action ) ) > = 0 ) ;
2014-08-12 11:15:04 -04:00
2013-11-29 16:43:56 -05:00
if ( new ) {
if ( fwd_from_id ) {
2014-08-21 16:35:27 -04:00
bl_do_create_message_service_fwd ( id , from_id , tgl_get_peer_type ( to_id ) , tgl_get_peer_id ( to_id ) , date , fwd_from_id , fwd_date , unread , start , ( in_ptr - start ) ) ;
2013-11-29 16:43:56 -05:00
} else {
2014-08-21 16:35:27 -04:00
bl_do_create_message_service ( id , from_id , tgl_get_peer_type ( to_id ) , tgl_get_peer_id ( to_id ) , date , unread , start , ( in_ptr - start ) ) ;
2013-11-29 16:43:56 -05:00
}
}
2013-10-14 13:26:25 -04:00
} else {
2013-11-29 16:43:56 -05:00
int l = prefetch_strlen ( ) ;
char * s = fetch_str ( l ) ;
int * start = in_ptr ;
2014-08-12 11:15:04 -04:00
2014-08-12 17:32:11 -04:00
assert ( skip_type_any ( TYPE_TO_PARAM ( message_media ) ) > = 0 ) ;
2014-08-12 11:15:04 -04:00
2013-11-29 16:43:56 -05:00
if ( new ) {
if ( fwd_from_id ) {
2014-08-21 16:35:27 -04:00
bl_do_create_message_media_fwd ( id , from_id , tgl_get_peer_type ( to_id ) , tgl_get_peer_id ( to_id ) , date , fwd_from_id , fwd_date , unread , l , s , start , in_ptr - start ) ;
2013-11-29 16:43:56 -05:00
} else {
2014-08-21 16:35:27 -04:00
bl_do_create_message_media ( id , from_id , tgl_get_peer_type ( to_id ) , tgl_get_peer_id ( to_id ) , date , unread , l , s , start , in_ptr - start ) ;
2013-11-29 16:43:56 -05:00
}
}
2013-10-13 08:30:53 -04:00
}
2013-11-29 16:43:56 -05:00
bl_do_set_unread ( M , unread ) ;
2013-10-13 08:30:53 -04:00
}
2013-10-13 06:18:08 -04:00
2014-08-14 14:03:33 -04:00
void tglf_tglf_fetch_geo_message ( struct tgl_message * M ) {
2013-11-01 15:57:57 -04:00
memset ( M , 0 , sizeof ( * M ) ) ;
unsigned x = fetch_int ( ) ;
assert ( x = = CODE_geo_chat_message_empty | | x = = CODE_geo_chat_message | | x = = CODE_geo_chat_message_service ) ;
2014-08-13 11:55:16 -04:00
M - > to_id = TGL_MK_GEO_CHAT ( fetch_int ( ) ) ;
2013-11-01 15:57:57 -04:00
M - > id = fetch_int ( ) ;
if ( x = = CODE_geo_chat_message_empty ) {
M - > flags | = 1 ;
return ;
}
2014-08-13 11:55:16 -04:00
M - > from_id = TGL_MK_USER ( fetch_int ( ) ) ;
2013-11-01 15:57:57 -04:00
M - > date = fetch_int ( ) ;
if ( x = = CODE_geo_chat_message_service ) {
M - > service = 1 ;
2014-08-13 08:56:55 -04:00
tglf_fetch_message_action ( & M - > action ) ;
2013-11-01 15:57:57 -04:00
} else {
M - > message = fetch_str_dup ( ) ;
2014-01-21 09:36:46 -05:00
M - > message_len = strlen ( M - > message ) ;
2014-08-13 08:56:55 -04:00
tglf_fetch_message_media ( & M - > media ) ;
2013-11-01 15:57:57 -04:00
}
}
2013-11-25 11:13:36 -05:00
static int * decr_ptr ;
static int * decr_end ;
2013-11-02 06:14:30 -04:00
2014-08-13 11:55:16 -04:00
static int decrypt_encrypted_message ( struct tgl_secret_chat * E ) {
2013-11-02 06:14:30 -04:00
int * msg_key = decr_ptr ;
decr_ptr + = 4 ;
assert ( decr_ptr < decr_end ) ;
static unsigned char sha1a_buffer [ 20 ] ;
static unsigned char sha1b_buffer [ 20 ] ;
static unsigned char sha1c_buffer [ 20 ] ;
static unsigned char sha1d_buffer [ 20 ] ;
static unsigned char buf [ 64 ] ;
memcpy ( buf , msg_key , 16 ) ;
memcpy ( buf + 16 , E - > key , 32 ) ;
sha1 ( buf , 48 , sha1a_buffer ) ;
memcpy ( buf , E - > key + 8 , 16 ) ;
memcpy ( buf + 16 , msg_key , 16 ) ;
memcpy ( buf + 32 , E - > key + 12 , 16 ) ;
sha1 ( buf , 48 , sha1b_buffer ) ;
memcpy ( buf , E - > key + 16 , 32 ) ;
memcpy ( buf + 32 , msg_key , 16 ) ;
sha1 ( buf , 48 , sha1c_buffer ) ;
memcpy ( buf , msg_key , 16 ) ;
memcpy ( buf + 16 , E - > key + 24 , 32 ) ;
sha1 ( buf , 48 , sha1d_buffer ) ;
static unsigned char key [ 32 ] ;
2013-11-04 12:34:27 -05:00
memcpy ( key , sha1a_buffer + 0 , 8 ) ;
memcpy ( key + 8 , sha1b_buffer + 8 , 12 ) ;
memcpy ( key + 20 , sha1c_buffer + 4 , 12 ) ;
static unsigned char iv [ 32 ] ;
memcpy ( iv , sha1a_buffer + 8 , 12 ) ;
memcpy ( iv + 12 , sha1b_buffer + 0 , 8 ) ;
memcpy ( iv + 20 , sha1c_buffer + 16 , 4 ) ;
memcpy ( iv + 24 , sha1d_buffer + 0 , 8 ) ;
2013-11-02 06:14:30 -04:00
AES_KEY aes_key ;
AES_set_decrypt_key ( key , 256 , & aes_key ) ;
AES_ige_encrypt ( ( void * ) decr_ptr , ( void * ) decr_ptr , 4 * ( decr_end - decr_ptr ) , & aes_key , iv , 0 ) ;
2014-01-21 11:02:34 -05:00
memset ( & aes_key , 0 , sizeof ( aes_key ) ) ;
2013-11-02 06:14:30 -04:00
2013-11-04 12:34:27 -05:00
int x = * ( decr_ptr ) ;
2013-11-05 17:24:26 -05:00
if ( x < 0 | | ( x & 3 ) ) {
return - 1 ;
}
2013-11-04 12:34:27 -05:00
assert ( x > = 0 & & ! ( x & 3 ) ) ;
sha1 ( ( void * ) decr_ptr , 4 + x , sha1a_buffer ) ;
2013-11-02 06:14:30 -04:00
2013-11-04 12:34:27 -05:00
if ( memcmp ( sha1a_buffer + 4 , msg_key , 16 ) ) {
2014-08-13 08:56:55 -04:00
vlogprintf ( E_WARNING , " Sha1 mismatch \n " ) ;
2013-11-02 06:14:30 -04:00
return - 1 ;
}
return 0 ;
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_encrypted_message ( struct tgl_message * M ) {
2013-11-02 06:14:30 -04:00
unsigned x = fetch_int ( ) ;
assert ( x = = CODE_encrypted_message | | x = = CODE_encrypted_message_service ) ;
2013-11-04 12:34:27 -05:00
unsigned sx = x ;
2013-11-29 16:43:56 -05:00
int new = ! ( M - > flags & FLAG_CREATED ) ;
long long id = fetch_long ( ) ;
int to_id = fetch_int ( ) ;
2014-08-13 11:55:16 -04:00
tgl_peer_id_t chat = TGL_MK_ENCR_CHAT ( to_id ) ;
2013-11-29 16:43:56 -05:00
int date = fetch_int ( ) ;
2014-08-13 11:55:16 -04:00
tgl_peer_t * P = tgl_peer_get ( chat ) ;
2013-11-02 06:14:30 -04:00
if ( ! P ) {
2014-08-13 08:56:55 -04:00
vlogprintf ( E_WARNING , " Encrypted message to unknown chat. Dropping \n " ) ;
2013-11-21 14:35:49 -05:00
M - > flags | = FLAG_MESSAGE_EMPTY ;
2013-11-02 06:14:30 -04:00
}
2013-11-04 12:34:27 -05:00
2013-11-02 06:14:30 -04:00
int len = prefetch_strlen ( ) ;
2013-11-04 12:34:27 -05:00
assert ( ( len & 15 ) = = 8 ) ;
2013-11-02 06:14:30 -04:00
decr_ptr = ( void * ) fetch_str ( len ) ;
2013-11-04 12:34:27 -05:00
decr_end = decr_ptr + ( len / 4 ) ;
int ok = 0 ;
if ( P ) {
if ( * ( long long * ) decr_ptr ! = P - > encr_chat . key_fingerprint ) {
2014-08-13 08:56:55 -04:00
vlogprintf ( E_WARNING , " Encrypted message with bad fingerprint to chat %s \n " , P - > print_name ) ;
2013-11-04 12:34:27 -05:00
P = 0 ;
}
decr_ptr + = 2 ;
}
2013-11-29 16:43:56 -05:00
int l = 0 ;
char * s = 0 ;
int * start = 0 ;
int * end = 0 ;
x = 0 ;
if ( P & & decrypt_encrypted_message ( & P - > encr_chat ) > = 0 & & new ) {
2013-11-04 12:34:27 -05:00
ok = 1 ;
int * save_in_ptr = in_ptr ;
int * save_in_end = in_end ;
2013-11-02 06:14:30 -04:00
in_ptr = decr_ptr ;
2013-11-29 16:43:56 -05:00
int ll = fetch_int ( ) ;
in_end = in_ptr + ll ;
x = fetch_int ( ) ;
2013-11-02 06:14:30 -04:00
if ( x = = CODE_decrypted_message_layer ) {
int layer = fetch_int ( ) ;
assert ( layer > = 0 ) ;
x = fetch_int ( ) ;
}
2013-11-04 12:34:27 -05:00
assert ( x = = CODE_decrypted_message | | x = = CODE_decrypted_message_service ) ;
2013-11-29 16:43:56 -05:00
//assert (id == fetch_long ());
fetch_long ( ) ;
ll = prefetch_strlen ( ) ;
fetch_str ( ll ) ; // random_bytes
2013-11-02 13:01:22 -04:00
if ( x = = CODE_decrypted_message ) {
2013-11-29 16:43:56 -05:00
l = prefetch_strlen ( ) ;
s = fetch_str ( l ) ;
start = in_ptr ;
2014-08-12 17:32:11 -04:00
assert ( skip_type_any ( TYPE_TO_PARAM ( decrypted_message_media ) ) > = 0 ) ;
2013-11-29 16:43:56 -05:00
end = in_ptr ;
2013-11-02 13:01:22 -04:00
} else {
2013-11-29 16:43:56 -05:00
start = in_ptr ;
2014-08-26 12:06:30 -04:00
if ( skip_type_any ( TYPE_TO_PARAM ( decrypted_message_action ) ) < 0 ) {
vlogprintf ( E_ERROR , " Skipped %ld int out of %ld. Magic = 0x%08x \n " , in_ptr - start , in_end - start , * start ) ;
assert ( 0 ) ;
}
2013-11-29 16:43:56 -05:00
end = in_ptr ;
2013-11-02 13:01:22 -04:00
}
2013-11-04 12:34:27 -05:00
in_ptr = save_in_ptr ;
in_end = save_in_end ;
2014-08-13 08:56:55 -04:00
}
2013-11-04 12:34:27 -05:00
if ( sx = = CODE_encrypted_message ) {
if ( ok ) {
2013-11-29 16:43:56 -05:00
int * start_file = in_ptr ;
2014-08-12 17:32:11 -04:00
assert ( skip_type_any ( TYPE_TO_PARAM ( encrypted_file ) ) > = 0 ) ;
2013-11-29 16:43:56 -05:00
if ( x = = CODE_decrypted_message ) {
2014-08-13 11:55:16 -04:00
bl_do_create_message_media_encr ( id , P - > encr_chat . user_id , TGL_PEER_ENCR_CHAT , to_id , date , l , s , start , end - start , start_file , in_ptr - start_file ) ;
2014-08-12 21:22:15 -04:00
} else if ( x = = CODE_decrypted_message_service ) {
2014-08-13 11:55:16 -04:00
bl_do_create_message_service_encr ( id , P - > encr_chat . user_id , TGL_PEER_ENCR_CHAT , to_id , date , start , end - start ) ;
2013-11-29 16:43:56 -05:00
}
2013-11-04 12:34:27 -05:00
} else {
2014-08-12 21:22:15 -04:00
assert ( skip_type_any ( TYPE_TO_PARAM ( encrypted_file ) ) > = 0 ) ;
2013-11-04 12:34:27 -05:00
M - > media . type = CODE_message_media_empty ;
}
2013-11-29 16:43:56 -05:00
} else {
if ( ok & & x = = CODE_decrypted_message_service ) {
2014-08-13 11:55:16 -04:00
bl_do_create_message_service_encr ( id , P - > encr_chat . user_id , TGL_PEER_ENCR_CHAT , to_id , date , start , end - start ) ;
2013-11-29 16:43:56 -05:00
}
2013-11-02 13:01:22 -04:00
}
}
2014-08-13 11:55:16 -04:00
void tglf_fetch_encrypted_message_file ( struct tgl_message_media * M ) {
2013-11-02 13:01:22 -04:00
unsigned x = fetch_int ( ) ;
assert ( x = = CODE_encrypted_file | | x = = CODE_encrypted_file_empty ) ;
if ( x = = CODE_encrypted_file_empty ) {
2014-08-18 12:39:04 -04:00
assert ( M - > type ! = tgl_message_media_photo_encr & & M - > type ! = tgl_message_media_video_encr ) ;
2013-11-02 13:01:22 -04:00
} else {
2014-08-18 12:39:04 -04:00
assert ( M - > type = = tgl_message_media_document_encr | | M - > type = = tgl_message_media_photo_encr | | M - > type = = tgl_message_media_video_encr | | M - > type = = tgl_message_media_audio_encr ) ;
2014-03-06 17:43:15 -05:00
M - > encr_photo . id = fetch_long ( ) ;
M - > encr_photo . access_hash = fetch_long ( ) ;
2014-03-06 17:44:41 -05:00
if ( ! M - > encr_photo . size ) {
M - > encr_photo . size = fetch_int ( ) ;
} else {
fetch_int ( ) ;
}
2014-03-06 17:43:15 -05:00
M - > encr_photo . dc_id = fetch_int ( ) ;
M - > encr_photo . key_fingerprint = fetch_int ( ) ;
2013-11-02 06:14:30 -04:00
}
}
2014-08-13 11:55:16 -04:00
static int id_cmp ( struct tgl_message * M1 , struct tgl_message * M2 ) {
2013-11-02 06:14:30 -04:00
if ( M1 - > id < M2 - > id ) { return - 1 ; }
else if ( M1 - > id > M2 - > id ) { return 1 ; }
else { return 0 ; }
}
2014-08-13 11:55:16 -04:00
struct tgl_user * tglf_fetch_alloc_user ( void ) {
2013-10-24 13:04:44 -04:00
int data [ 2 ] ;
prefetch_data ( data , 8 ) ;
2014-08-13 11:55:16 -04:00
tgl_peer_t * U = tgl_peer_get ( TGL_MK_USER ( data [ 1 ] ) ) ;
2013-11-21 14:35:49 -05:00
if ( ! U ) {
2013-10-24 13:04:44 -04:00
users_allocated + + ;
2014-01-10 06:32:57 -05:00
U = talloc0 ( sizeof ( * U ) ) ;
2014-08-13 11:55:16 -04:00
U - > id = TGL_MK_USER ( data [ 1 ] ) ;
tgl_peer_tree = tree_insert_peer ( tgl_peer_tree , U , lrand48 ( ) ) ;
assert ( peer_num < TGL_MAX_PEER_NUM ) ;
2013-11-04 12:34:27 -05:00
Peers [ peer_num + + ] = U ;
2013-10-13 06:18:08 -04:00
}
2014-08-13 08:56:55 -04:00
tglf_fetch_user ( & U - > user ) ;
2013-11-21 14:35:49 -05:00
return & U - > user ;
2013-10-13 06:18:08 -04:00
}
2014-08-13 11:55:16 -04:00
struct tgl_secret_chat * tglf_fetch_alloc_encrypted_chat ( void ) {
2013-11-02 13:01:22 -04:00
int data [ 2 ] ;
prefetch_data ( data , 8 ) ;
2014-08-13 11:55:16 -04:00
tgl_peer_t * U = tgl_peer_get ( TGL_MK_ENCR_CHAT ( data [ 1 ] ) ) ;
2013-11-21 14:35:49 -05:00
if ( ! U ) {
2014-01-10 06:32:57 -05:00
U = talloc0 ( sizeof ( * U ) ) ;
2014-08-13 11:55:16 -04:00
U - > id = TGL_MK_ENCR_CHAT ( data [ 1 ] ) ;
2013-11-21 14:35:49 -05:00
encr_chats_allocated + + ;
2014-08-13 11:55:16 -04:00
tgl_peer_tree = tree_insert_peer ( tgl_peer_tree , U , lrand48 ( ) ) ;
assert ( peer_num < TGL_MAX_PEER_NUM ) ;
2013-11-04 12:34:27 -05:00
Peers [ peer_num + + ] = U ;
2013-11-02 13:01:22 -04:00
}
2014-08-13 08:56:55 -04:00
tglf_fetch_encrypted_chat ( & U - > encr_chat ) ;
2013-11-21 14:35:49 -05:00
return & U - > encr_chat ;
2013-11-02 13:01:22 -04:00
}
2014-08-13 11:55:16 -04:00
struct tgl_user * tglf_fetch_alloc_user_full ( void ) {
int data [ 3 ] ;
prefetch_data ( data , 12 ) ;
tgl_peer_t * U = tgl_peer_get ( TGL_MK_USER ( data [ 2 ] ) ) ;
if ( U ) {
tglf_fetch_user_full ( & U - > user ) ;
return & U - > user ;
} else {
users_allocated + + ;
U = talloc0 ( sizeof ( * U ) ) ;
U - > id = TGL_MK_USER ( data [ 2 ] ) ;
tgl_peer_tree = tree_insert_peer ( tgl_peer_tree , U , lrand48 ( ) ) ;
tglf_fetch_user_full ( & U - > user ) ;
assert ( peer_num < TGL_MAX_PEER_NUM ) ;
Peers [ peer_num + + ] = U ;
return & U - > user ;
}
2013-11-04 12:34:27 -05:00
}
2014-08-13 11:55:16 -04:00
struct tgl_message * tglf_fetch_alloc_message ( void ) {
int data [ 2 ] ;
prefetch_data ( data , 8 ) ;
struct tgl_message * M = tgl_message_get ( data [ 1 ] ) ;
if ( ! M ) {
M = tglm_message_alloc ( data [ 1 ] ) ;
}
tglf_fetch_message ( M ) ;
return M ;
2013-11-21 14:35:49 -05:00
}
2014-08-13 11:55:16 -04:00
struct tgl_message * tglf_fetch_alloc_geo_message ( void ) {
struct tgl_message * M = talloc ( sizeof ( * M ) ) ;
2014-08-14 14:03:33 -04:00
tglf_tglf_fetch_geo_message ( M ) ;
2014-08-13 11:55:16 -04:00
struct tgl_message * M1 = tree_lookup_message ( message_tree , M ) ;
messages_allocated + + ;
if ( M1 ) {
tglm_message_del_use ( M1 ) ;
tglm_message_del_peer ( M1 ) ;
tgls_free_message ( M1 ) ;
memcpy ( M1 , M , sizeof ( * M ) ) ;
tfree ( M , sizeof ( * M ) ) ;
tglm_message_add_use ( M1 ) ;
tglm_message_add_peer ( M1 ) ;
messages_allocated - - ;
return M1 ;
} else {
tglm_message_add_use ( M ) ;
tglm_message_add_peer ( M ) ;
message_tree = tree_insert_message ( message_tree , M , lrand48 ( ) ) ;
return M ;
}
2013-11-22 18:26:35 -05:00
}
2014-08-13 11:55:16 -04:00
struct tgl_message * tglf_fetch_alloc_encrypted_message ( void ) {
2013-10-25 13:29:02 -04:00
int data [ 3 ] ;
prefetch_data ( data , 12 ) ;
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( * ( long long * ) ( data + 1 ) ) ;
if ( ! M ) {
M = talloc0 ( sizeof ( * M ) ) ;
M - > id = * ( long long * ) ( data + 1 ) ;
tglm_message_insert_tree ( M ) ;
messages_allocated + + ;
assert ( tgl_message_get ( M - > id ) = = M ) ;
}
tglf_fetch_encrypted_message ( M ) ;
return M ;
}
struct tgl_message * tglf_fetch_alloc_message_short ( void ) {
int data [ 1 ] ;
prefetch_data ( data , 4 ) ;
struct tgl_message * M = tgl_message_get ( data [ 0 ] ) ;
if ( ! M ) {
M = talloc0 ( sizeof ( * M ) ) ;
M - > id = data [ 0 ] ;
tglm_message_insert_tree ( M ) ;
messages_allocated + + ;
}
tglf_fetch_message_short ( M ) ;
return M ;
}
struct tgl_message * tglf_fetch_alloc_message_short_chat ( void ) {
int data [ 1 ] ;
prefetch_data ( data , 4 ) ;
struct tgl_message * M = tgl_message_get ( data [ 0 ] ) ;
if ( ! M ) {
M = talloc0 ( sizeof ( * M ) ) ;
M - > id = data [ 0 ] ;
tglm_message_insert_tree ( M ) ;
messages_allocated + + ;
}
tglf_fetch_message_short_chat ( M ) ;
return M ;
}
struct tgl_chat * tglf_fetch_alloc_chat ( void ) {
int data [ 2 ] ;
prefetch_data ( data , 8 ) ;
tgl_peer_t * U = tgl_peer_get ( TGL_MK_CHAT ( data [ 1 ] ) ) ;
if ( ! U ) {
chats_allocated + + ;
U = talloc0 ( sizeof ( * U ) ) ;
U - > id = TGL_MK_CHAT ( data [ 1 ] ) ;
tgl_peer_tree = tree_insert_peer ( tgl_peer_tree , U , lrand48 ( ) ) ;
assert ( peer_num < TGL_MAX_PEER_NUM ) ;
Peers [ peer_num + + ] = U ;
}
tglf_fetch_chat ( & U - > chat ) ;
return & U - > chat ;
}
struct tgl_chat * tglf_fetch_alloc_chat_full ( void ) {
int data [ 3 ] ;
prefetch_data ( data , 12 ) ;
tgl_peer_t * U = tgl_peer_get ( TGL_MK_CHAT ( data [ 2 ] ) ) ;
2013-10-25 13:29:02 -04:00
if ( U ) {
2014-08-13 11:55:16 -04:00
tglf_fetch_chat_full ( & U - > chat ) ;
return & U - > chat ;
2013-10-25 13:29:02 -04:00
} else {
2014-08-13 11:55:16 -04:00
chats_allocated + + ;
2014-01-10 06:32:57 -05:00
U = talloc0 ( sizeof ( * U ) ) ;
2014-08-13 11:55:16 -04:00
U - > id = TGL_MK_CHAT ( data [ 2 ] ) ;
tgl_peer_tree = tree_insert_peer ( tgl_peer_tree , U , lrand48 ( ) ) ;
tglf_fetch_chat_full ( & U - > chat ) ;
assert ( peer_num < TGL_MAX_PEER_NUM ) ;
2013-11-04 12:34:27 -05:00
Peers [ peer_num + + ] = U ;
2014-08-13 11:55:16 -04:00
return & U - > chat ;
2013-10-25 13:29:02 -04:00
}
}
2014-08-13 11:55:16 -04:00
/* }}} */
void tglp_insert_encrypted_chat ( tgl_peer_t * P ) {
encr_chats_allocated + + ;
tgl_peer_tree = tree_insert_peer ( tgl_peer_tree , P , lrand48 ( ) ) ;
assert ( peer_num < TGL_MAX_PEER_NUM ) ;
Peers [ peer_num + + ] = P ;
}
void tglp_insert_user ( tgl_peer_t * P ) {
users_allocated + + ;
tgl_peer_tree = tree_insert_peer ( tgl_peer_tree , P , lrand48 ( ) ) ;
assert ( peer_num < TGL_MAX_PEER_NUM ) ;
Peers [ peer_num + + ] = P ;
}
void tglp_insert_chat ( tgl_peer_t * P ) {
chats_allocated + + ;
tgl_peer_tree = tree_insert_peer ( tgl_peer_tree , P , lrand48 ( ) ) ;
assert ( peer_num < TGL_MAX_PEER_NUM ) ;
Peers [ peer_num + + ] = P ;
}
2013-10-25 13:29:02 -04:00
2014-08-13 11:55:16 -04:00
/* {{{ Free */
void tgls_free_user ( struct tgl_user * U ) {
2014-01-10 09:37:56 -05:00
if ( U - > first_name ) { tfree_str ( U - > first_name ) ; }
if ( U - > last_name ) { tfree_str ( U - > last_name ) ; }
if ( U - > print_name ) { tfree_str ( U - > print_name ) ; }
if ( U - > phone ) { tfree_str ( U - > phone ) ; }
2013-10-13 06:18:08 -04:00
}
2014-08-13 11:55:16 -04:00
void tgls_free_photo_size ( struct tgl_photo_size * S ) {
2014-01-10 09:37:56 -05:00
tfree_str ( S - > type ) ;
2013-10-18 12:00:47 -04:00
if ( S - > data ) {
2014-01-10 09:37:56 -05:00
tfree ( S - > data , S - > size ) ;
2013-10-18 12:00:47 -04:00
}
2013-10-14 13:26:25 -04:00
}
2014-08-13 11:55:16 -04:00
void tgls_free_photo ( struct tgl_photo * P ) {
2013-10-18 12:00:47 -04:00
if ( ! P - > access_hash ) { return ; }
2014-01-10 09:37:56 -05:00
if ( P - > caption ) { tfree_str ( P - > caption ) ; }
2013-10-18 12:00:47 -04:00
if ( P - > sizes ) {
int i ;
for ( i = 0 ; i < P - > sizes_num ; i + + ) {
2014-08-13 11:55:16 -04:00
tgls_free_photo_size ( & P - > sizes [ i ] ) ;
2013-10-18 12:00:47 -04:00
}
2014-08-13 11:55:16 -04:00
tfree ( P - > sizes , sizeof ( struct tgl_photo_size ) * P - > sizes_num ) ;
2013-10-14 13:26:25 -04:00
}
}
2014-08-13 11:55:16 -04:00
void tgls_free_video ( struct tgl_video * V ) {
2013-10-18 12:00:47 -04:00
if ( ! V - > access_hash ) { return ; }
2014-01-10 09:37:56 -05:00
tfree_str ( V - > caption ) ;
2014-08-13 11:55:16 -04:00
tgls_free_photo_size ( & V - > thumb ) ;
2013-10-14 13:26:25 -04:00
}
2014-08-13 11:55:16 -04:00
void tgls_free_document ( struct tgl_document * D ) {
2013-11-15 05:37:14 -05:00
if ( ! D - > access_hash ) { return ; }
2014-01-10 09:37:56 -05:00
tfree_str ( D - > caption ) ;
tfree_str ( D - > mime_type ) ;
2014-08-13 11:55:16 -04:00
tgls_free_photo_size ( & D - > thumb ) ;
2013-11-15 05:37:14 -05:00
}
2014-08-13 11:55:16 -04:00
void tgls_free_message_media ( struct tgl_message_media * M ) {
2013-10-14 13:26:25 -04:00
switch ( M - > type ) {
2014-08-18 12:39:04 -04:00
case tgl_message_media_none :
case tgl_message_media_geo :
case tgl_message_media_audio :
2013-10-14 13:26:25 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_photo :
2014-08-13 11:55:16 -04:00
tgls_free_photo ( & M - > photo ) ;
2013-10-14 13:26:25 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_video :
2014-08-13 11:55:16 -04:00
tgls_free_video ( & M - > video ) ;
2013-10-14 13:26:25 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_contact :
2014-01-10 09:37:56 -05:00
tfree_str ( M - > phone ) ;
tfree_str ( M - > first_name ) ;
tfree_str ( M - > last_name ) ;
2013-10-14 13:26:25 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_document :
2014-08-13 11:55:16 -04:00
tgls_free_document ( & M - > document ) ;
2013-11-15 05:37:14 -05:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_unsupported :
2014-01-10 09:37:56 -05:00
tfree ( M - > data , M - > data_size ) ;
2013-10-14 13:26:25 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_photo_encr :
case tgl_message_media_video_encr :
case tgl_message_media_audio_encr :
case tgl_message_media_document_encr :
2014-01-10 09:37:56 -05:00
tfree_secure ( M - > encr_photo . key , 32 ) ;
tfree_secure ( M - > encr_photo . iv , 32 ) ;
2013-11-02 13:01:22 -04:00
return ;
2013-10-14 13:26:25 -04:00
default :
2014-08-13 08:56:55 -04:00
vlogprintf ( E_ERROR , " type = 0x%08x \n " , M - > type ) ;
2013-10-14 13:26:25 -04:00
assert ( 0 ) ;
}
}
2014-08-13 11:55:16 -04:00
void tgls_free_message_action ( struct tgl_message_action * M ) {
2013-10-14 13:26:25 -04:00
switch ( M - > type ) {
2014-08-18 12:39:04 -04:00
case tgl_message_action_none :
2013-10-14 13:26:25 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_create :
2014-01-10 09:37:56 -05:00
tfree_str ( M - > title ) ;
tfree ( M - > users , M - > user_num * 4 ) ;
2013-10-14 13:26:25 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_edit_title :
2014-01-10 09:37:56 -05:00
tfree_str ( M - > new_title ) ;
2013-10-14 13:26:25 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_edit_photo :
2014-08-13 11:55:16 -04:00
tgls_free_photo ( & M - > photo ) ;
2013-10-14 13:26:25 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_delete_photo :
2013-10-14 13:26:25 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_add_user :
2013-10-14 13:26:25 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_delete_user :
2013-11-04 12:34:27 -05:00
break ;
2013-10-14 13:26:25 -04:00
default :
assert ( 0 ) ;
}
}
2014-08-13 11:55:16 -04:00
void tgls_free_message ( struct tgl_message * M ) {
2013-10-14 13:26:25 -04:00
if ( ! M - > service ) {
2014-01-21 09:36:46 -05:00
if ( M - > message ) { tfree ( M - > message , M - > message_len + 1 ) ; }
2014-08-13 11:55:16 -04:00
tgls_free_message_media ( & M - > media ) ;
2013-10-14 13:26:25 -04:00
} else {
2014-08-13 11:55:16 -04:00
tgls_free_message_action ( & M - > action ) ;
2013-10-14 13:26:25 -04:00
}
}
2014-08-13 11:55:16 -04:00
void tgls_free_chat ( struct tgl_chat * U ) {
if ( U - > title ) { tfree_str ( U - > title ) ; }
if ( U - > print_title ) { tfree_str ( U - > print_title ) ; }
}
/* }}} */
/* Messages {{{ */
void tglm_message_del_use ( struct tgl_message * M ) {
2013-10-14 13:26:25 -04:00
M - > next_use - > prev_use = M - > prev_use ;
M - > prev_use - > next_use = M - > next_use ;
}
2014-08-13 11:55:16 -04:00
void tglm_message_add_use ( struct tgl_message * M ) {
2013-10-14 13:26:25 -04:00
M - > next_use = message_list . next_use ;
M - > prev_use = & message_list ;
M - > next_use - > prev_use = M ;
M - > prev_use - > next_use = M ;
}
2014-08-13 11:55:16 -04:00
void tglm_message_add_peer ( struct tgl_message * M ) {
tgl_peer_id_t id ;
if ( ! tgl_cmp_peer_id ( M - > to_id , TGL_MK_USER ( tgl_state . our_id ) ) ) {
2013-11-04 12:34:27 -05:00
id = M - > from_id ;
} else {
id = M - > to_id ;
}
2014-08-13 11:55:16 -04:00
tgl_peer_t * P = tgl_peer_get ( id ) ;
2013-11-04 12:34:27 -05:00
if ( ! P ) {
2014-01-10 06:32:57 -05:00
P = talloc0 ( sizeof ( * P ) ) ;
2013-11-04 12:34:27 -05:00
P - > id = id ;
2014-08-13 11:55:16 -04:00
switch ( tgl_get_peer_type ( id ) ) {
case TGL_PEER_USER :
2013-11-04 12:34:27 -05:00
users_allocated + + ;
break ;
2014-08-13 11:55:16 -04:00
case TGL_PEER_CHAT :
2013-11-04 12:34:27 -05:00
chats_allocated + + ;
break ;
2014-08-13 11:55:16 -04:00
case TGL_PEER_GEO_CHAT :
2013-11-04 12:34:27 -05:00
geo_chats_allocated + + ;
break ;
2014-08-13 11:55:16 -04:00
case TGL_PEER_ENCR_CHAT :
2013-11-04 12:34:27 -05:00
encr_chats_allocated + + ;
break ;
}
2014-08-13 11:55:16 -04:00
tgl_peer_tree = tree_insert_peer ( tgl_peer_tree , P , lrand48 ( ) ) ;
assert ( peer_num < TGL_MAX_PEER_NUM ) ;
2013-11-04 12:34:27 -05:00
Peers [ peer_num + + ] = P ;
}
2013-11-29 16:43:56 -05:00
if ( ! P - > last ) {
P - > last = M ;
M - > prev = M - > next = 0 ;
} else {
2014-08-13 11:55:16 -04:00
if ( tgl_get_peer_type ( P - > id ) ! = TGL_PEER_ENCR_CHAT ) {
struct tgl_message * N = P - > last ;
struct tgl_message * NP = 0 ;
2013-11-29 16:43:56 -05:00
while ( N & & N - > id > M - > id ) {
NP = N ;
N = N - > next ;
}
if ( N ) { assert ( N - > id < M - > id ) ; }
M - > next = N ;
M - > prev = NP ;
if ( N ) { N - > prev = M ; }
if ( NP ) { NP - > next = M ; }
else { P - > last = M ; }
} else {
2014-08-13 11:55:16 -04:00
struct tgl_message * N = P - > last ;
struct tgl_message * NP = 0 ;
2013-11-29 16:43:56 -05:00
M - > next = N ;
M - > prev = NP ;
if ( N ) { N - > prev = M ; }
if ( NP ) { NP - > next = M ; }
else { P - > last = M ; }
}
}
2013-11-04 12:34:27 -05:00
}
2014-08-13 11:55:16 -04:00
void tglm_message_del_peer ( struct tgl_message * M ) {
tgl_peer_id_t id ;
if ( ! tgl_cmp_peer_id ( M - > to_id , TGL_MK_USER ( tgl_state . our_id ) ) ) {
2013-11-04 12:34:27 -05:00
id = M - > from_id ;
} else {
id = M - > to_id ;
}
2014-08-13 11:55:16 -04:00
tgl_peer_t * P = tgl_peer_get ( id ) ;
2013-11-04 12:34:27 -05:00
if ( M - > prev ) {
M - > prev - > next = M - > next ;
}
if ( M - > next ) {
M - > next - > prev = M - > prev ;
}
if ( P & & P - > last = = M ) {
P - > last = M - > next ;
}
}
2014-08-13 11:55:16 -04:00
struct tgl_message * tglm_message_alloc ( long long id ) {
struct tgl_message * M = talloc0 ( sizeof ( * M ) ) ;
2014-08-13 08:56:55 -04:00
M - > id = id ;
2014-08-13 11:55:16 -04:00
tglm_message_insert_tree ( M ) ;
2013-11-01 15:57:57 -04:00
messages_allocated + + ;
2013-11-29 16:43:56 -05:00
return M ;
2013-11-02 06:14:30 -04:00
}
2014-08-13 11:55:16 -04:00
void tglm_update_message_id ( struct tgl_message * M , long long id ) {
2013-10-16 15:19:39 -04:00
message_tree = tree_delete_message ( message_tree , M ) ;
M - > id = id ;
message_tree = tree_insert_message ( message_tree , M , lrand48 ( ) ) ;
}
2013-10-18 15:30:24 -04:00
2014-08-13 11:55:16 -04:00
void tglm_message_insert_tree ( struct tgl_message * M ) {
2013-11-29 16:43:56 -05:00
assert ( M - > id ) ;
message_tree = tree_insert_message ( message_tree , M , lrand48 ( ) ) ;
}
2014-08-13 11:55:16 -04:00
void tglm_message_remove_tree ( struct tgl_message * M ) {
2013-11-29 16:43:56 -05:00
assert ( M - > id ) ;
message_tree = tree_delete_message ( message_tree , M ) ;
}
2014-08-13 11:55:16 -04:00
void tglm_message_insert ( struct tgl_message * M ) {
tglm_message_add_use ( M ) ;
tglm_message_add_peer ( M ) ;
2013-11-29 16:43:56 -05:00
}
2014-08-13 11:55:16 -04:00
void tglm_message_insert_unsent ( struct tgl_message * M ) {
2013-11-29 16:43:56 -05:00
message_unsent_tree = tree_insert_message ( message_unsent_tree , M , lrand48 ( ) ) ;
}
2014-08-13 11:55:16 -04:00
void tglm_message_remove_unsent ( struct tgl_message * M ) {
2013-11-29 16:43:56 -05:00
message_unsent_tree = tree_delete_message ( message_unsent_tree , M ) ;
}
2014-08-13 11:55:16 -04:00
static void __send_msg ( struct tgl_message * M ) {
2014-08-13 08:56:55 -04:00
vlogprintf ( E_NOTICE , " Resending message... \n " ) ;
2014-08-13 21:31:24 -04:00
//print_message (M);
2013-11-29 16:43:56 -05:00
2014-08-13 21:31:24 -04:00
tgl_do_send_msg ( M , 0 , 0 ) ;
2013-11-29 16:43:56 -05:00
}
2014-08-13 11:55:16 -04:00
void tglm_send_all_unsent ( void ) {
2013-11-29 16:43:56 -05:00
tree_act_message ( message_unsent_tree , __send_msg ) ;
2013-10-18 15:30:24 -04:00
}
2014-08-13 11:55:16 -04:00
/* }}} */
2014-01-31 11:03:40 -05:00
2014-08-13 11:55:16 -04:00
void tglp_peer_insert_name ( tgl_peer_t * P ) {
2014-01-31 11:03:40 -05:00
peer_by_name_tree = tree_insert_peer_by_name ( peer_by_name_tree , P , lrand48 ( ) ) ;
}
2014-08-13 11:55:16 -04:00
void tglp_peer_delete_name ( tgl_peer_t * P ) {
2014-01-31 11:03:40 -05:00
peer_by_name_tree = tree_delete_peer_by_name ( peer_by_name_tree , P ) ;
}
2014-08-13 11:55:16 -04:00
tgl_peer_t * tgl_peer_get ( tgl_peer_id_t id ) {
static tgl_peer_t U ;
U . id = id ;
return tree_lookup_peer ( tgl_peer_tree , & U ) ;
}
struct tgl_message * tgl_message_get ( long long id ) {
struct tgl_message M ;
M . id = id ;
return tree_lookup_message ( message_tree , & M ) ;
}
tgl_peer_t * tgl_peer_get_by_name ( const char * s ) {
static tgl_peer_t P ;
2014-01-31 11:03:40 -05:00
P . print_name = ( void * ) s ;
2014-08-13 11:55:16 -04:00
tgl_peer_t * R = tree_lookup_peer_by_name ( peer_by_name_tree , & P ) ;
2014-01-31 11:03:40 -05:00
return R ;
}
2014-08-13 08:56:55 -04:00
2014-08-13 11:55:16 -04:00
void tgl_peer_iterator_ex ( void ( * it ) ( tgl_peer_t * P , void * extra ) , void * extra ) {
tree_act_ex_peer ( tgl_peer_tree , it , extra ) ;
2014-08-13 08:56:55 -04:00
}
2014-08-13 11:55:16 -04:00
int tgl_complete_user_list ( int index , const char * text , int len , char * * R ) {
2014-08-13 08:56:55 -04:00
index + + ;
2014-08-13 11:55:16 -04:00
while ( index < peer_num & & ( ! Peers [ index ] - > print_name | | strncmp ( Peers [ index ] - > print_name , text , len ) | | tgl_get_peer_type ( Peers [ index ] - > id ) ! = TGL_PEER_USER ) ) {
2014-08-13 08:56:55 -04:00
index + + ;
}
if ( index < peer_num ) {
* R = strdup ( Peers [ index ] - > print_name ) ;
return index ;
} else {
return - 1 ;
}
}
2014-08-13 11:55:16 -04:00
int tgl_complete_chat_list ( int index , const char * text , int len , char * * R ) {
2014-08-13 08:56:55 -04:00
index + + ;
2014-08-13 11:55:16 -04:00
while ( index < peer_num & & ( ! Peers [ index ] - > print_name | | strncmp ( Peers [ index ] - > print_name , text , len ) | | tgl_get_peer_type ( Peers [ index ] - > id ) ! = TGL_PEER_CHAT ) ) {
2014-08-13 08:56:55 -04:00
index + + ;
}
if ( index < peer_num ) {
* R = strdup ( Peers [ index ] - > print_name ) ;
return index ;
} else {
return - 1 ;
}
}
2014-08-13 11:55:16 -04:00
int tgl_complete_encr_chat_list ( int index , const char * text , int len , char * * R ) {
2014-08-13 08:56:55 -04:00
index + + ;
2014-08-13 11:55:16 -04:00
while ( index < peer_num & & ( ! Peers [ index ] - > print_name | | strncmp ( Peers [ index ] - > print_name , text , len ) | | tgl_get_peer_type ( Peers [ index ] - > id ) ! = TGL_PEER_ENCR_CHAT ) ) {
2014-08-13 08:56:55 -04:00
index + + ;
}
if ( index < peer_num ) {
* R = strdup ( Peers [ index ] - > print_name ) ;
return index ;
} else {
return - 1 ;
}
}
2014-08-13 11:55:16 -04:00
int tgl_complete_peer_list ( int index , const char * text , int len , char * * R ) {
2014-08-13 08:56:55 -04:00
index + + ;
while ( index < peer_num & & ( ! Peers [ index ] - > print_name | | strncmp ( Peers [ index ] - > print_name , text , len ) ) ) {
index + + ;
}
if ( index < peer_num ) {
* R = strdup ( Peers [ index ] - > print_name ) ;
return index ;
} else {
return - 1 ;
}
}
2014-08-13 11:55:16 -04:00
int tgl_print_stat ( char * s , int len ) {
return tsnprintf ( s , len ,
" users_allocated \t %d \n "
" chats_allocated \t %d \n "
" secret_chats_allocated \t %d \n "
" peer_num \t %d \n "
" messages_allocated \t %d \n " ,
users_allocated ,
chats_allocated ,
encr_chats_allocated ,
peer_num ,
messages_allocated
) ;
}