diff options
Diffstat (limited to 'protocols/Telegram/tgl/binlog.c')
-rw-r--r-- | protocols/Telegram/tgl/binlog.c | 1829 |
1 files changed, 0 insertions, 1829 deletions
diff --git a/protocols/Telegram/tgl/binlog.c b/protocols/Telegram/tgl/binlog.c deleted file mode 100644 index ed5d514abf..0000000000 --- a/protocols/Telegram/tgl/binlog.c +++ /dev/null @@ -1,1829 +0,0 @@ -/* - This file is part of tgl-library - - 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. - - 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 - Lesser General Public License for more details. - - 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 - - Copyright Vitaly Valtman 2013-2015 -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#if defined(WIN32) || defined(_WIN32) -#include <stdint.h> -#include <string.h> -#include <fcntl.h> -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#include <io.h> -#include <sys/locking.h> -#else -#include <unistd.h> -#include <sys/file.h> -#endif -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <fcntl.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <openssl/bn.h> - -#include "tgl-binlog.h" -#include "mtproto-common.h" -//#include "net.h" -#include "mtproto-client.h" -#include "mtproto-utils.h" - -#include "tgl.h" -#include "auto.h" -#include "auto/auto-types.h" -#include "auto/auto-skip.h" -#include "auto/auto-store-ds.h" -#include "auto/auto-fetch-ds.h" -#include "auto/auto-free-ds.h" - -#include "tgl-structures.h" -#include "tgl-methods-in.h" - -#include <openssl/sha.h> - -#define BINLOG_BUFFER_SIZE (1 << 20) -static int binlog_buffer[BINLOG_BUFFER_SIZE]; -static int *rptr; -static int *wptr; -//static int TLS->binlog_fd; -static int in_replay_log; // should be used ONLY for DEBUG - - -#define MAX_LOG_EVENT_SIZE (1 << 17) - -char *get_binlog_file_name (void); - -static void *alloc_log_event (int l) { - return binlog_buffer; -} - -static int mystreq1 (const char *a, const char *b, int l) { - if ((int)strlen (a) != l) { return 1; } - return memcmp (a, b, l); -} - -static long long binlog_pos; - -static int fetch_comb_binlog_start (struct tgl_state *TLS, void *extra) { - return 0; -} - -/* {{{ DC option */ -static int fetch_comb_binlog_dc_option (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - vlogprintf (E_NOTICE, "DC%d '%.*s' update: %.*s:%d\n", - DS_LVAL (DS_U->dc), - DS_RSTR (DS_U->name), - DS_RSTR (DS_U->ip), - DS_LVAL (DS_U->port) - ); - - tglmp_alloc_dc (TLS, - 0, - DS_LVAL (DS_U->dc), - DS_STR_DUP (DS_U->ip), - DS_LVAL (DS_U->port) - ); - return 0; -} - -static int fetch_comb_binlog_dc_option_new (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - vlogprintf (E_NOTICE, "DC%d '%.*s' update: %.*s:%d\n", - DS_LVAL (DS_U->dc), - DS_RSTR (DS_U->name), - DS_RSTR (DS_U->ip), - DS_LVAL (DS_U->port) - ); - - tglmp_alloc_dc (TLS, - DS_LVAL (DS_U->flags), - DS_LVAL (DS_U->dc), - DS_STR_DUP (DS_U->ip), - DS_LVAL (DS_U->port) - ); - return 0; -} -/* }}} */ - -/* {{{ Auth key */ -static int fetch_comb_binlog_auth_key (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - int num = DS_LVAL (DS_U->dc); - assert (num > 0 && num <= MAX_DC_ID); - assert (TLS->DC_list[num]); - - tglf_fetch_int_tuple ((void *)TLS->DC_list[num]->auth_key, DS_U->key->key, 64); - - static unsigned char sha1_buffer[20]; - SHA1 ((void *)TLS->DC_list[num]->auth_key, 256, sha1_buffer); - TLS->DC_list[num]->auth_key_id = *(long long *)(sha1_buffer + 12); - - TLS->DC_list[num]->flags |= TGLDCF_AUTHORIZED; - return 0; -} -/* }}} */ - -/* {{{ Default dc */ -static int fetch_comb_binlog_default_dc (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - int num = DS_LVAL (DS_U->dc); - assert (num > 0 && num <= MAX_DC_ID); - TLS->DC_working = TLS->DC_list[num]; - TLS->dc_working_num = num; - return 0; -} -/* }}} */ - -/* {{{ DC signed */ -static int fetch_comb_binlog_dc_signed (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - int num = DS_LVAL (DS_U->dc); - assert (num > 0 && num <= MAX_DC_ID); - assert (TLS->DC_list[num]); - TLS->DC_list[num]->flags |= TGLDCF_LOGGED_IN; - return 0; -} -/* }}} */ - -/* {{{ our user_id */ -static int fetch_comb_binlog_our_id (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - TLS->our_id = DS_LVAL (DS_U->id); - assert (TLS->our_id > 0); - if (TLS->callback.our_id) { - TLS->callback.our_id (TLS, TLS->our_id); - } - return 0; -} -/* }}} */ - -/* {{{ Set DH params */ -static int fetch_comb_binlog_set_dh_params (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - if (TLS->encr_prime) { tfree (TLS->encr_prime, 256); BN_free (TLS->encr_prime_bn); } - - TLS->encr_root = DS_LVAL (DS_U->root); - TLS->encr_prime = talloc (256); - tglf_fetch_int_tuple ((void *)TLS->encr_prime, DS_U->prime->key, 64); - - TLS->encr_prime_bn = BN_new (); - BN_bin2bn ((void *)TLS->encr_prime, 256, TLS->encr_prime_bn); - TLS->encr_param_version = DS_LVAL (DS_U->version); - - assert (tglmp_check_DH_params (TLS, TLS->encr_prime_bn, TLS->encr_root) >= 0); - - return 0; -} -/* }}} */ - -/* {{{ Set pts, qts, date, seq */ -static int fetch_comb_binlog_set_pts (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - TLS->pts = DS_LVAL (DS_U->pts); - return 0; -} - -static int fetch_comb_binlog_set_qts (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - TLS->qts = DS_LVAL (DS_U->qts); - return 0; -} - -static int fetch_comb_binlog_set_date (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - TLS->date = DS_LVAL (DS_U->date); - return 0; -} - -static int fetch_comb_binlog_set_seq (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - TLS->seq = DS_LVAL (DS_U->seq); - return 0; -} -/* }}} */ - -/* {{{ delete user */ -static int fetch_comb_binlog_user_delete (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - tgl_peer_id_t id = TGL_MK_USER (DS_LVAL (DS_U->id)); - tgl_peer_t *U = tgl_peer_get (TLS, id); - assert (U); - U->flags |= TGLUF_DELETED; - - if (TLS->callback.user_update) { - TLS->callback.user_update (TLS, (void *)U, TGL_UPDATE_DELETED); - } - return 0; -} -/* }}} */ - -/* {{{ delete secret chat */ -static int fetch_comb_binlog_encr_chat_delete (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (DS_LVAL (DS_U->id)); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - assert (_U); - struct tgl_secret_chat *U = &_U->encr_chat; - memset (U->key, 0, sizeof (U->key)); - U->flags |= TGLPF_DELETED; - U->state = sc_deleted; - if (U->g_key) { - tfree_secure (U->g_key, 256); - U->g_key = 0; - } - - if (TLS->callback.secret_chat_update) { - TLS->callback.secret_chat_update (TLS, U, TGL_UPDATE_DELETED); - } - return 0; -} -/* }}} */ - -static int fetch_comb_binlog_user_new (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - tgl_peer_id_t id = TGL_MK_USER (DS_LVAL (DS_U->id)); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - - int flags = DS_LVAL (DS_U->flags); - - unsigned updates = 0; - - if (flags & TGLPF_CREATE) { - if (!_U) { - _U = talloc0 (sizeof (*_U)); - _U->id = id; - tglp_insert_encrypted_chat (TLS, _U); - } else { - assert (!(_U->flags & TGLPF_CREATED)); - } - updates |= TGL_UPDATE_CREATED; - } else { - assert (_U->flags & TGLPF_CREATED); - } - - struct tgl_user *U = (void *)_U; - - if ((flags & 0xff) != (U->flags & 0xff)) { - updates |= TGL_UPDATE_FLAGS; - } - U->flags = flags & 0xffff; - - if (DS_U->access_hash) { - U->access_hash = DS_LVAL (DS_U->access_hash); - updates |= TGL_UPDATE_ACCESS_HASH; - } - - if (DS_U->first_name) { - if (U->first_name) { - tfree_str (U->first_name); - } - U->first_name = DS_STR_DUP (DS_U->first_name); - if (U->last_name) { - tfree_str (U->last_name); - } - U->last_name = DS_STR_DUP (DS_U->last_name); - - updates |= TGL_UPDATE_NAME; - - if (U->print_name) { - tglp_peer_delete_name (TLS, (void *)U); - tfree_str (U->print_name); - } - U->print_name = TLS->callback.create_print_name (TLS, U->id, U->first_name, U->last_name, 0, 0); - tglp_peer_insert_name (TLS, (void *)U); - } - - if (DS_U->phone) { - if (U->phone) { - tfree_str (U->phone); - } - U->phone = DS_STR_DUP (DS_U->phone); - updates |= TGL_UPDATE_PHONE; - } - - if (DS_U->username) { - if (U->username) { - tfree_str (U->username); - } - U->username = DS_STR_DUP (DS_U->username); - updates |= TGL_UPDATE_USERNAME; - } - - if (DS_U->photo) { - if (U->photo) { - tgls_free_photo (TLS, U->photo); - } - U->photo = tglf_fetch_alloc_photo_new (TLS, DS_U->photo); - U->flags |= TGLUF_HAS_PHOTO; - //updates |= TGL_UPDATE_PHOTO; - } - - if (DS_U->user_photo) { - U->photo_id = DS_LVAL (DS_U->user_photo->photo_id); - tglf_fetch_file_location_new (TLS, &U->photo_big, DS_U->user_photo->photo_big); - tglf_fetch_file_location_new (TLS, &U->photo_small, DS_U->user_photo->photo_small); - updates |= TGL_UPDATE_PHOTO; - } - - if (DS_U->real_first_name) { - if (U->real_first_name) { - tfree_str (U->real_first_name); - } - U->real_first_name = DS_STR_DUP (DS_U->real_first_name); - if (U->real_last_name) { - tfree_str (U->real_last_name); - } - U->real_last_name = DS_STR_DUP (DS_U->real_last_name); - - updates |= TGL_UPDATE_REAL_NAME; - } - - if (DS_U->last_read_in) { - U->last_read_in = DS_LVAL (DS_U->last_read_in); - tgls_messages_mark_read (TLS, U->last, 0, U->last_read_in); - } - - if (DS_U->last_read_out) { - U->last_read_out = DS_LVAL (DS_U->last_read_out); - tgls_messages_mark_read (TLS, U->last, TGLMF_OUT, U->last_read_out); - } - - if (DS_U->bot_info) { - if (U->bot_info) { - tgls_free_bot_info (TLS, U->bot_info); - } - U->bot_info = tglf_fetch_alloc_bot_info (TLS, DS_U->bot_info); - } - - if (TLS->callback.user_update && updates) { - TLS->callback.user_update (TLS, U, updates); - } - - return 0; -} - -static int fetch_comb_binlog_encr_chat_new (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - tgl_peer_id_t id = TGL_MK_ENCR_CHAT (DS_LVAL (DS_U->id)); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - - int flags = DS_LVAL (DS_U->flags); - - unsigned updates = 0; - - if (flags & TGLPF_CREATE) { - if (!_U) { - _U = talloc0 (sizeof (*_U)); - _U->id = id; - tglp_insert_encrypted_chat (TLS, _U); - } else { - assert (!(_U->flags & TGLPF_CREATED)); - } - updates |= TGL_UPDATE_CREATED; - } else { - assert (_U->flags & TGLPF_CREATED); - } - - struct tgl_secret_chat *U = (void *)_U; - - if ((flags & 0xff) != (U->flags & 0xff)) { - updates |= TGL_UPDATE_FLAGS; - } - U->flags = flags & 0xffff; - - if (DS_U->access_hash) { - U->access_hash = DS_LVAL (DS_U->access_hash); - updates |= TGL_UPDATE_ACCESS_HASH; - } - - if (DS_U->date) { - U->date = DS_LVAL (DS_U->date); - } - - if (DS_U->admin) { - U->admin_id = DS_LVAL (DS_U->admin); - } - - if (DS_U->user_id) { - U->user_id = DS_LVAL (DS_U->user_id); - } - - if (DS_U->key_fingerprint) { - U->key_fingerprint = DS_LVAL (DS_U->key_fingerprint); - } - - if (DS_U->in_seq_no) { - U->in_seq_no = DS_LVAL (DS_U->in_seq_no); - U->out_seq_no = DS_LVAL (DS_U->out_seq_no); - U->last_in_seq_no = DS_LVAL (DS_U->last_in_seq_no); - } - - tgl_peer_t *Us = tgl_peer_get (TLS, TGL_MK_USER (U->user_id)); - - if (!U->print_name) { - if (Us) { - U->print_name = TLS->callback.create_print_name (TLS, id, "!", Us->user.first_name, Us->user.last_name, 0); - } else { - static char buf[100]; - tsnprintf (buf, 99, "user#%d", U->user_id); - U->print_name = TLS->callback.create_print_name (TLS, id, "!", buf, 0, 0); - } - tglp_peer_insert_name (TLS, (void *)U); - } - - if (DS_U->g_key) { - if (!U->g_key) { - U->g_key = talloc (256); - } - tglf_fetch_int_tuple ((void *)U->g_key, DS_U->g_key->key, 64); - } - - if (DS_U->key) { - tglf_fetch_int_tuple (U->key, DS_U->key->key, 64); - } - - if (DS_U->state) { - if (U->state == sc_waiting && DS_LVAL (DS_U->state) == sc_ok) { - tgl_do_create_keys_end (TLS, U); - } - if ((int)U->state != DS_LVAL (DS_U->state)) { - switch (DS_LVAL (DS_U->state)) { - case sc_request: - updates |= TGL_UPDATE_REQUESTED; - break; - case sc_ok: - updates |= TGL_UPDATE_WORKING; - vlogprintf (E_WARNING, "Secret chat in ok state\n"); - break; - default: - break; - } - } - U->state = DS_LVAL (DS_U->state); - } - - if (TLS->callback.secret_chat_update && updates) { - TLS->callback.secret_chat_update (TLS, U, updates); - } - - return 0; -} - -static int fetch_comb_binlog_chat_new (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - tgl_peer_id_t id = TGL_MK_CHAT (DS_LVAL (DS_U->id)); - tgl_peer_t *_U = tgl_peer_get (TLS, id); - - int flags = DS_LVAL (DS_U->flags); - - unsigned updates = 0; - - if (flags & (1 << 16)) { - if (!_U) { - _U = talloc0 (sizeof (*_U)); - _U->id = id; - tglp_insert_chat (TLS, _U); - } else { - assert (!(_U->flags & TGLPF_CREATED)); - } - updates |= TGL_UPDATE_CREATED; - } else { - assert (_U->flags & TGLPF_CREATED); - } - - struct tgl_chat *C = &_U->chat; - - if ((flags & 0xff) != (C->flags & 0xff)) { - updates |= TGL_UPDATE_FLAGS; - } - C->flags = flags & 0xffff; - - if (DS_U->title) { - if (C->title) { - tfree_str (C->title); - } - C->title = DS_STR_DUP (DS_U->title); - - if (C->print_title) { - tglp_peer_delete_name (TLS, (void *)C); - tfree_str (C->print_title); - } - C->print_title = TLS->callback.create_print_name (TLS, C->id, C->title, 0, 0, 0); - tglp_peer_insert_name (TLS, (void *)C); - - updates |= TGL_UPDATE_TITLE; - } - - if (DS_U->user_num) { - C->users_num = DS_LVAL (DS_U->user_num); - } - - if (DS_U->date) { - C->date = DS_LVAL (DS_U->date); - } - - if (DS_U->chat_photo) { - tglf_fetch_file_location_new (TLS, &C->photo_big, DS_U->chat_photo->photo_big); - tglf_fetch_file_location_new (TLS, &C->photo_small, DS_U->chat_photo->photo_small); - updates |= TGL_UPDATE_PHOTO; - } - - if (DS_U->photo) { - if (C->photo) { - tgls_free_photo (TLS, C->photo); - } - C->photo = tglf_fetch_alloc_photo_new (TLS, DS_U->photo); - C->flags |= TGLPF_HAS_PHOTO; - updates |= TGL_UPDATE_PHOTO; - } - - if (DS_U->admin) { - C->admin_id = DS_LVAL (DS_U->admin); - updates |= TGL_UPDATE_ADMIN; - } - - if (DS_U->version) { - C->version = DS_LVAL (DS_U->version); - - if (C->user_list) { tfree (C->user_list, 12 * C->user_list_size); } - - C->user_list_size = DS_LVAL (DS_U->participants->cnt); - C->user_list = talloc (12 * C->user_list_size); - - int i; - for (i = 0; i < C->user_list_size; i++) { - C->user_list[i].user_id = DS_LVAL (DS_U->participants->data[i]->user_id); - C->user_list[i].inviter_id = DS_LVAL (DS_U->participants->data[i]->inviter_id); - C->user_list[i].date = DS_LVAL (DS_U->participants->data[i]->date); - } - - updates |= TGL_UPDATE_MEMBERS; - } - - if (DS_U->last_read_in) { - C->last_read_in = DS_LVAL (DS_U->last_read_in); - tgls_messages_mark_read (TLS, C->last, 0, C->last_read_in); - } - - if (DS_U->last_read_out) { - C->last_read_out = DS_LVAL (DS_U->last_read_out); - tgls_messages_mark_read (TLS, C->last, TGLMF_OUT, C->last_read_out); - } - - - if (TLS->callback.chat_update && updates) { - TLS->callback.chat_update (TLS, C, updates); - } - return 0; -} - -static int fetch_comb_binlog_chat_add_participant (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - tgl_peer_id_t id = TGL_MK_CHAT (DS_LVAL (DS_U->id)); - tgl_peer_t *_C = tgl_peer_get (TLS, id); - assert (_C && (_C->flags & TGLPF_CREATED)); - struct tgl_chat *C = &_C->chat; - - int version = DS_LVAL (DS_U->version); - int user = DS_LVAL (DS_U->user_id); - int inviter = DS_LVAL (DS_U->inviter_id); - int date = DS_LVAL (DS_U->date); - - - if (C->user_list_version > version) { return 0; } - - int i; - for (i = 0; i < C->user_list_size; i++) { - if (C->user_list[i].user_id == user) { - return 0; - } - } - - C->user_list_size ++; - C->user_list = trealloc (C->user_list, 12 * C->user_list_size - 12, 12 * C->user_list_size); - C->user_list[C->user_list_size - 1].user_id = user; - C->user_list[C->user_list_size - 1].inviter_id = inviter; - C->user_list[C->user_list_size - 1].date = date; - C->user_list_version = version; - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, C, TGL_UPDATE_MEMBERS); - } - return 0; -} - -static int fetch_comb_binlog_chat_del_participant (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - tgl_peer_id_t id = TGL_MK_CHAT (DS_LVAL (DS_U->id)); - tgl_peer_t *_C = tgl_peer_get (TLS, id); - assert (_C && (_C->flags & TGLPF_CREATED)); - struct tgl_chat *C = &_C->chat; - - int version = DS_LVAL (DS_U->version); - int user = DS_LVAL (DS_U->user_id); - if (C->user_list_version > version) { return 0; } - - int i; - for (i = 0; i < C->user_list_size; i++) { - if (C->user_list[i].user_id == user) { - struct tgl_chat_user t; - t = C->user_list[i]; - C->user_list[i] = C->user_list[C->user_list_size - 1]; - C->user_list[C->user_list_size - 1] = t; - } - } - if (C->user_list[C->user_list_size - 1].user_id != user) { return 0; } - - assert (C->user_list[C->user_list_size - 1].user_id == user); - C->user_list_size --; - C->user_list = trealloc (C->user_list, 12 * C->user_list_size + 12, 12 * C->user_list_size); - C->user_list_version = version; - - if (TLS->callback.chat_update) { - TLS->callback.chat_update (TLS, C, TGL_UPDATE_MEMBERS); - } - return 0; -} - -static int fetch_comb_binlog_message_new (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - struct tgl_message *M = tgl_message_get (TLS, DS_LVAL (DS_U->lid)); - int flags = DS_LVAL (DS_U->flags); - - if (flags & (1 << 16)) { - if (!M) { - M = tglm_message_alloc (TLS, DS_LVAL (DS_U->lid)); - } - assert (!(M->flags & TGLMF_CREATED)); - } else { - assert (M->flags & TGLMF_CREATED); - } - - assert (flags & TGLMF_CREATED); - assert (!(M->flags & TGLMF_ENCRYPTED)); - assert (!(flags & TGLMF_ENCRYPTED)); - - if ((M->flags & TGLMF_PENDING) && !(flags & TGLMF_PENDING)){ - tglm_message_remove_unsent (TLS, M); - } - if (!(M->flags & TGLMF_PENDING) && (flags & TGLMF_PENDING)){ - tglm_message_insert_unsent (TLS, M); - } - - if ((M->flags & TGLMF_UNREAD) && !(flags & TGLMF_UNREAD)) { - M->flags = (flags & 0xffff) | TGLMF_UNREAD; - } else { - M->flags = (flags & 0xffff); - } - - if (DS_U->from_id) { - M->from_id = TGL_MK_USER (DS_LVAL (DS_U->from_id)); - } - if (DS_U->to_type) { - assert (flags & 0x10000); - M->to_id = tgl_set_peer_id (DS_LVAL (DS_U->to_type), DS_LVAL (DS_U->to_id)); - assert (DS_LVAL (DS_U->to_type) != TGL_PEER_ENCR_CHAT); - } - - if (DS_U->date) { - M->date = DS_LVAL (DS_U->date); - } - - if (DS_U->fwd_from_id) { - M->fwd_from_id = TGL_MK_USER (DS_LVAL (DS_U->fwd_from_id)); - M->fwd_date = DS_LVAL (DS_U->fwd_date); - } - - if (DS_U->action) { - tglf_fetch_message_action_new (TLS, &M->action, DS_U->action); - M->flags |= TGLMF_SERVICE; - } - - if (DS_U->message) { - M->message_len = DS_U->message->len; - M->message = DS_STR_DUP (DS_U->message); - assert (!(M->flags & TGLMF_SERVICE)); - } - - if (DS_U->media) { - tglf_fetch_message_media_new (TLS, &M->media, DS_U->media); - assert (!(M->flags & TGLMF_SERVICE)); - } - - if (DS_U->reply_id) { - M->reply_id = DS_LVAL (DS_U->reply_id); - } - - if (flags & 0x10000) { - tglm_message_insert (TLS, M); - } - - if (!(flags & TGLMF_UNREAD) && (M->flags & TGLMF_UNREAD)) { - tgls_messages_mark_read (TLS, M, M->flags & TGLMF_OUT, M->id); - } - - if (DS_U->reply_markup) { - M->reply_markup = tglf_fetch_alloc_reply_markup (TLS, M->next, DS_U->reply_markup); - } - return 0; -} - -static int fetch_comb_binlog_message_encr_new (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - struct tgl_message *M = tgl_message_get (TLS, DS_LVAL (DS_U->lid)); - int flags = DS_LVAL (DS_U->flags); - - if (flags & (1 << 16)) { - if (!M) { - M = tglm_message_alloc (TLS, DS_LVAL (DS_U->lid)); - } else { - assert (!(M->flags & TGLMF_CREATED)); - } - assert (!(M->flags & TGLMF_CREATED)); - } else { - assert (M->flags & TGLMF_CREATED); - } - - assert (flags & TGLMF_CREATED); - assert (flags & TGLMF_ENCRYPTED); - - if ((M->flags & TGLMF_PENDING) && !(flags & TGLMF_PENDING)){ - tglm_message_remove_unsent (TLS, M); - } - if (!(M->flags & TGLMF_PENDING) && (flags & TGLMF_PENDING)){ - tglm_message_insert_unsent (TLS, M); - } - - M->flags = flags & 0xffff; - - if (DS_U->from_id) { - M->from_id = TGL_MK_USER (DS_LVAL (DS_U->from_id)); - } - if (DS_U->to_type) { - assert (flags & 0x10000); - M->to_id = tgl_set_peer_id (DS_LVAL (DS_U->to_type), DS_LVAL (DS_U->to_id)); - } - - if (DS_U->date) { - M->date = DS_LVAL (DS_U->date); - } - - struct tgl_secret_chat *E = (void *)tgl_peer_get (TLS, M->to_id); - assert (E); - - if (DS_U->message) { - M->message_len = DS_U->message->len; - M->message = DS_STR_DUP (DS_U->message); - assert (!(M->flags & TGLMF_SERVICE)); - } - - if (DS_U->encr_media) { - tglf_fetch_message_media_encrypted_new (TLS, &M->media, DS_U->encr_media); - assert (!(M->flags & TGLMF_SERVICE)); - } - - if (DS_U->encr_action) { - tglf_fetch_message_action_encrypted_new (TLS, &M->action, DS_U->encr_action); - M->flags |= TGLMF_SERVICE; - } - - if (DS_U->file) { - tglf_fetch_encrypted_message_file_new (TLS, &M->media, DS_U->file); - assert (!(M->flags & TGLMF_SERVICE)); - } - - if (DS_U->encr_action && !(M->flags & TGLMF_OUT) && M->action.type == tgl_message_action_notify_layer) { - E->layer = M->action.layer; - } - - if ((flags & TGLMF_CREATE) && (flags & TGLMF_OUT)) { - E->out_seq_no ++; - } - - if (flags & 0x10000) { - tglm_message_insert (TLS, M); - } - return 0; -} - -static int fetch_comb_binlog_set_msg_id (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - struct tgl_message *M = tgl_message_get (TLS, DS_LVAL (DS_U->old_id)); - assert (M); - if (M->flags & TGLMF_PENDING) { - tglm_message_remove_unsent (TLS, M); - M->flags &= ~TGLMF_PENDING; - } - - tglm_message_remove_tree (TLS, M); - tglm_message_del_peer (TLS, M); - - M->id = DS_LVAL (DS_U->new_id); - if (tgl_message_get (TLS, M->id)) { - tglm_message_del_use (TLS, M); - tgls_free_message (TLS, M); - } else { - tglm_message_insert_tree (TLS, M); - tglm_message_add_peer (TLS, M); - } - return 0; -} - -static int fetch_comb_binlog_message_delete (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - struct tgl_message *M = tgl_message_get (TLS, DS_LVAL (DS_U->lid)); - assert (M); - if (M->flags & TGLMF_PENDING) { - tglm_message_remove_unsent (TLS, M); - M->flags &= ~TGLMF_PENDING; - } - tglm_message_remove_tree (TLS, M); - tglm_message_del_peer (TLS, M); - tglm_message_del_use (TLS, M); - tgls_free_message (TLS, M); - return 0; -} - -static int fetch_comb_binlog_msg_update (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - struct tgl_message *M = tgl_message_get (TLS, DS_LVAL (DS_U->lid)); - if (!M) { return 0; } - assert (M); - - if (!(M->flags & TGLMF_ENCRYPTED)) { - if (TLS->max_msg_id < M->id) { - TLS->max_msg_id = M->id; - } - } - - if (TLS->callback.msg_receive) { - TLS->callback.msg_receive (TLS, M); - } - return 0; -} - -static int fetch_comb_binlog_reset_authorization (struct tgl_state *TLS, void *extra) { - int i; - for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i]) { - struct tgl_dc *D = TLS->DC_list[i]; - D->flags = 0; - D->state = st_init; - D->auth_key_id = D->temp_auth_key_id = 0; - } - TLS->seq = 0; - TLS->qts = 0; - return 0; -} - -static int fetch_comb_binlog_encr_chat_exchange_new (struct tgl_state *TLS, struct tl_ds_binlog_update *DS_U) { - tgl_peer_t *P = tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (DS_LVAL (DS_U->id))); - assert (P); - if (DS_U->state) { - P->encr_chat.exchange_state = DS_LVAL (DS_U->state); - } - if (DS_U->exchange_id) { - P->encr_chat.exchange_id = DS_LVAL (DS_U->exchange_id); - } - - static unsigned char sha_buffer[20]; - switch (P->encr_chat.exchange_state) { - case tgl_sce_requested: - tglf_fetch_int_tuple (P->encr_chat.exchange_key, DS_U->key->key, 64); - break; - case tgl_sce_accepted: - tglf_fetch_int_tuple (P->encr_chat.exchange_key, DS_U->key->key, 64); - - SHA1 ((unsigned char *)P->encr_chat.exchange_key, 256, sha_buffer); - P->encr_chat.exchange_key_fingerprint = *(long long *)(sha_buffer + 12); - break; - case tgl_sce_committed: - memcpy (P->encr_chat.exchange_key, P->encr_chat.key, 256); - P->encr_chat.exchange_key_fingerprint = P->encr_chat.key_fingerprint; - - tglf_fetch_int_tuple (P->encr_chat.key, DS_U->key->key, 64); - - SHA1 ((unsigned char *)P->encr_chat.key, 256, sha_buffer); - P->encr_chat.key_fingerprint = *(long long *)(sha_buffer + 12); - break; - case tgl_sce_confirmed: - P->encr_chat.exchange_state = tgl_sce_none; - if (P->encr_chat.exchange_state != tgl_sce_committed) { - memcpy (P->encr_chat.key, P->encr_chat.exchange_key, 256); - P->encr_chat.key_fingerprint = P->encr_chat.exchange_key_fingerprint; - } - break; - case tgl_sce_aborted: - P->encr_chat.exchange_state = tgl_sce_none; - if (P->encr_chat.exchange_state == tgl_sce_committed) { - memcpy (P->encr_chat.key, P->encr_chat.exchange_key, 256); - P->encr_chat.key_fingerprint = P->encr_chat.exchange_key_fingerprint; - } - break; - default: - assert (0); - } - return 0; -} - -#define FETCH_COMBINATOR_FUNCTION(NAME) \ - case CODE_ ## NAME:\ - ok = fetch_comb_ ## NAME (TLS, DS_U); \ - break; \ - - -static void replay_log_event (struct tgl_state *TLS) { - assert (rptr < wptr); - int op = *rptr; - - vlogprintf (E_DEBUG, "replay_log_event: log_pos=%"_PRINTF_INT64_"d, op=0x%08x\n", binlog_pos, op); - - in_ptr = rptr; - in_end = wptr; - if (skip_type_any (TYPE_TO_PARAM (binlog_update)) < 0) { - vlogprintf (E_ERROR, "Can not replay at %"_PRINTF_INT64_"d (magic = 0x%08x)\n", binlog_pos, *rptr); - assert (0); - } - int *end = in_ptr; - in_end = in_ptr; - in_ptr = rptr; - struct tl_ds_binlog_update *DS_U = fetch_ds_type_binlog_update (TYPE_TO_PARAM (binlog_update)); - assert (in_ptr == end); - - int ok = -1; - - switch (op) { - FETCH_COMBINATOR_FUNCTION (binlog_start) - FETCH_COMBINATOR_FUNCTION (binlog_dc_option) - FETCH_COMBINATOR_FUNCTION (binlog_dc_option_new) - FETCH_COMBINATOR_FUNCTION (binlog_auth_key) - FETCH_COMBINATOR_FUNCTION (binlog_default_dc) - FETCH_COMBINATOR_FUNCTION (binlog_dc_signed) - - FETCH_COMBINATOR_FUNCTION (binlog_our_id) - - FETCH_COMBINATOR_FUNCTION (binlog_set_dh_params) - FETCH_COMBINATOR_FUNCTION (binlog_set_pts) - FETCH_COMBINATOR_FUNCTION (binlog_set_qts) - FETCH_COMBINATOR_FUNCTION (binlog_set_date) - FETCH_COMBINATOR_FUNCTION (binlog_set_seq) - - FETCH_COMBINATOR_FUNCTION (binlog_user_new) - FETCH_COMBINATOR_FUNCTION (binlog_user_delete) - - FETCH_COMBINATOR_FUNCTION (binlog_chat_new) - //FETCH_COMBINATOR_FUNCTION (binlog_chat_delete) - - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_new) - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_delete) - FETCH_COMBINATOR_FUNCTION (binlog_chat_add_participant) - FETCH_COMBINATOR_FUNCTION (binlog_chat_del_participant) - - FETCH_COMBINATOR_FUNCTION (binlog_message_new) - FETCH_COMBINATOR_FUNCTION (binlog_message_encr_new) - FETCH_COMBINATOR_FUNCTION (binlog_message_delete) - FETCH_COMBINATOR_FUNCTION (binlog_set_msg_id) - - FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_exchange_new) - - FETCH_COMBINATOR_FUNCTION (binlog_msg_update) - FETCH_COMBINATOR_FUNCTION (binlog_reset_authorization) - default: - vlogprintf (E_ERROR, "Unknown op 0x%08x\n", op); - assert (0); - } - assert (ok >= 0); - - free_ds_type_binlog_update (DS_U, TYPE_TO_PARAM (binlog_update)); - assert (in_ptr == end); - //assert (in_ptr == in_end); - binlog_pos += (in_ptr - rptr) * 4; - rptr = in_ptr; -} - -static void create_new_binlog (struct tgl_state *TLS) { - clear_packet (); - //static int s[1000]; - - //packet_ptr = s; - out_int (CODE_binlog_start); - if (TLS->test_mode) { - out_int (CODE_binlog_dc_option); - out_int (1); - out_string (""); - out_string (TG_SERVER_TEST_1); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (2); - out_string (""); - out_string (TG_SERVER_TEST_2); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (3); - out_string (""); - out_string (TG_SERVER_TEST_3); - out_int (443); - out_int (CODE_binlog_default_dc); - out_int (2); - } else { - out_int (CODE_binlog_dc_option); - out_int (1); - out_string (""); - out_string (TG_SERVER_1); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (2); - out_string (""); - out_string (TG_SERVER_2); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (3); - out_string (""); - out_string (TG_SERVER_3); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (4); - out_string (""); - out_string (TG_SERVER_4); - out_int (443); - out_int (CODE_binlog_dc_option); - out_int (5); - out_string (""); - out_string (TG_SERVER_5); - out_int (443); - out_int (CODE_binlog_default_dc); - out_int (2); - } - -#if defined(_MSC_VER) && _MSC_VER >= 1400 - int fd = 0; - if(_sopen_s (&fd, TLS->binlog_name, _O_WRONLY | _O_EXCL | _O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE) != 0 ) { -#else - int fd = open (TLS->binlog_name, O_WRONLY | O_EXCL | O_CREAT, 0600); - if (fd < 0) { -#endif - perror ("Write new binlog"); - exit (2); - } - assert (write (fd, packet_buffer, (packet_ptr - packet_buffer) * 4) == (packet_ptr - packet_buffer) * 4); - close (fd); -} - - -void tgl_replay_log (struct tgl_state *TLS) { - if (!TLS->binlog_enabled) { return; } -#if defined(WIN32) || defined(_WIN32) - if (INVALID_FILE_ATTRIBUTES == GetFileAttributesA (TLS->binlog_name) && GetLastError () == ERROR_FILE_NOT_FOUND) { -#else - if (access (TLS->binlog_name, F_OK) < 0) { -#endif - printf ("No binlog found. Creating new one\n"); - create_new_binlog (TLS); - } -#if defined(_MSC_VER) && _MSC_VER >= 1400 - int fd = 0; - if (_sopen_s(&fd, TLS->binlog_name, _O_RDONLY | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE) != 0) { -#elif defined(WIN32) || defined(_WIN32) - int fd = open (TLS->binlog_name, O_RDONLY | O_BINARY); - if (fd < 0) { -#else - int fd = open (TLS->binlog_name, O_RDONLY); - if (fd < 0) { -#endif - perror ("binlog open"); - exit (2); - } - int end = 0; - in_replay_log = 1; - while (1) { - if (!end && wptr - rptr < MAX_LOG_EVENT_SIZE / 4) { - if (wptr == rptr) { - wptr = rptr = binlog_buffer; - } else { - int x = wptr - rptr; - memcpy (binlog_buffer, rptr, 4 * x); - wptr -= (rptr - binlog_buffer); - rptr = binlog_buffer; - } - int l = (binlog_buffer + BINLOG_BUFFER_SIZE - wptr) * 4; - int k = read (fd, wptr, l); - if (k < 0) { - perror ("read binlog"); - exit (2); - } - assert (!(k & 3)); - if (k < l) { - end = 1; - } - wptr += (k / 4); - } - if (wptr == rptr) { break; } - replay_log_event (TLS); - } - in_replay_log = 0; - close (fd); -} - -//static int b_packet_buffer[PACKET_BUFFER_SIZE]; - -void tgl_reopen_binlog_for_writing (struct tgl_state *TLS) { -#if defined(_MSC_VER) && _MSC_VER >= 1400 - if (_sopen_s (&TLS->binlog_fd, TLS->binlog_name, _O_WRONLY | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE) != 0) { -#elif defined(WIN32) || defined(_WIN32) - TLS->binlog_fd = open (TLS->binlog_name, O_WRONLY | _O_BINARY); - if (TLS->binlog_fd < 0) { -#else - TLS->binlog_fd = open (TLS->binlog_name, O_WRONLY); - if (TLS->binlog_fd < 0) { -#endif - perror ("binlog open"); - exit (2); - } - - assert (lseek (TLS->binlog_fd, binlog_pos, SEEK_SET) == binlog_pos); -#if defined(WIN32) || defined(_WIN32) - HANDLE h = INVALID_HANDLE_VALUE; - DWORD size_lower, size_upper; - DWORD err = 0; - OVERLAPPED ovlp; - int flags = 0; - - h = (HANDLE)_get_osfhandle(TLS->binlog_fd); - if (h == INVALID_HANDLE_VALUE) { - errno = EBADF; - goto error; - } - - size_lower = GetFileSize (h, &size_upper); - if (size_lower == INVALID_FILE_SIZE) { - goto get_err; - } - - memset (&ovlp, 0, sizeof ovlp); - flags |= LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY; - - if (!LockFileEx (h, flags, 0, size_lower, size_upper, &ovlp)) { - goto get_err; - } - return; - -error: - perror ("get lock"); - exit(2); - -get_err: - err = GetLastError(); - switch (err) - { - case ERROR_LOCK_VIOLATION: - errno = EAGAIN; - break; - case ERROR_NOT_ENOUGH_MEMORY: - errno = ENOMEM; - break; - case ERROR_BAD_COMMAND: - errno = EINVAL; - break; - default: - errno = err; - } - goto error; -#else - if (flock (TLS->binlog_fd, LOCK_EX | LOCK_NB) < 0) { - perror ("get lock"); - exit (2); - } -#endif -} - -static void add_log_event (struct tgl_state *TLS, const int *data, int len) { - vlogprintf (E_DEBUG, "Add log event: magic = 0x%08x, len = %d\n", data[0], len); - assert (!(len & 3)); - int *ev = talloc (len); - memcpy (ev, data, len); - rptr = (void *)ev; - wptr = rptr + (len / 4); - int *in = in_ptr; - int *end = in_end; - replay_log_event (TLS); - if (rptr != wptr) { - vlogprintf (E_ERROR, "Unread %"_PRINTF_INT64_"d ints. Len = %d\n", (long long)(wptr - rptr), len); - assert (rptr == wptr); - } - if (TLS->binlog_enabled) { - assert (TLS->binlog_fd > 0); - assert (write (TLS->binlog_fd, ev, len) == len); - } - tfree (ev, len); - in_ptr = in; - in_end = end; -} - -void bl_do_dc_option_new (struct tgl_state *TLS, int flags, int id, const char *name, int l1, const char *ip, int l2, int port) { - struct tgl_dc *DC = TLS->DC_list[id]; - - if (DC) { - struct tgl_dc_option *O = DC->options[flags & 3]; - while (O) { - if (!strncmp (O->ip, ip, l2)) { - return; - } - O = O->next; - } - } - - clear_packet (); - out_int (CODE_binlog_dc_option_new); - out_int (flags); - out_int (id); - - out_cstring (name, l1); - out_cstring (ip, l2); - out_int (port); - - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_dc_option (struct tgl_state *TLS, int id, const char *name, int l1, const char *ip, int l2, int port) { - bl_do_dc_option_new (TLS, 0, id, name, l1, ip, l2, port); -} - -void bl_do_set_working_dc (struct tgl_state *TLS, int num) { - int *ev = alloc_log_event (8); - ev[0] = CODE_binlog_default_dc; - ev[1] = num; - add_log_event (TLS, ev, 8); -} - -void bl_do_dc_signed (struct tgl_state *TLS, int id) { - clear_packet (); - out_int (CODE_binlog_dc_signed); - out_int (id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_our_id (struct tgl_state *TLS, int id) { - if (TLS->our_id) { - assert (TLS->our_id == id); - return; - } - - clear_packet (); - out_int (CODE_binlog_our_id); - out_int (id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_dh_params (struct tgl_state *TLS, int root, unsigned char prime[], int version) { - clear_packet (); - out_int (CODE_binlog_set_dh_params); - out_int (root); - out_ints ((void *)prime, 64); - out_int (version); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_pts (struct tgl_state *TLS, int pts) { - if (TLS->locks & TGL_LOCK_DIFF) { return; } - if (pts <= TLS->pts) { return; } - - clear_packet (); - out_int (CODE_binlog_set_pts); - out_int (pts); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_qts (struct tgl_state *TLS, int qts) { - if (TLS->locks & TGL_LOCK_DIFF) { return; } - if (qts <= TLS->qts) { return; } - - clear_packet (); - out_int (CODE_binlog_set_qts); - out_int (qts); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_date (struct tgl_state *TLS, int date) { - if (TLS->locks & TGL_LOCK_DIFF) { return; } - if (date <= TLS->date) { return; } - - clear_packet (); - out_int (CODE_binlog_set_date); - out_int (date); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_seq (struct tgl_state *TLS, int seq) { - if (TLS->locks & TGL_LOCK_DIFF) { return; } - if (seq <= TLS->seq) { return; } - - clear_packet (); - out_int (CODE_binlog_set_seq); - out_int (seq); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_msg_id (struct tgl_state *TLS, struct tgl_message *M, int id) { - if (M->id == id) { return; } - - clear_packet (); - out_int (CODE_binlog_set_msg_id); - out_long (M->id); - out_int (id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_user_delete (struct tgl_state *TLS, struct tgl_user *U) { - if (U->flags & TGLUF_DELETED) { return; } - - clear_packet (); - out_int (CODE_binlog_user_delete); - out_int (tgl_get_peer_id (U->id)); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_encr_chat_delete (struct tgl_state *TLS, struct tgl_secret_chat *U) { - if (!(U->flags & TGLPF_CREATED) || U->state == sc_deleted || U->state == sc_none) { return; } - - clear_packet (); - out_int (CODE_binlog_encr_chat_delete); - out_int (tgl_get_peer_id (U->id)); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_chat_add_user (struct tgl_state *TLS, struct tgl_chat *C, int version, int user, int inviter, int date) { - if (C->user_list_version >= version || !C->user_list_version) { return; } - - clear_packet (); - out_int (CODE_binlog_chat_add_participant); - out_int (tgl_get_peer_id (C->id)); - out_int (version); - out_int (user); - out_int (inviter); - out_int (date); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_chat_del_user (struct tgl_state *TLS, struct tgl_chat *C, int version, int user) { - if (C->user_list_version >= version || !C->user_list_version) { return; } - - clear_packet (); - out_int (CODE_binlog_chat_del_participant); - out_int (tgl_get_peer_id (C->id)); - out_int (version); - out_int (user); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_new (struct tgl_state *TLS, long long id, int *from_id, int *to_type, int *to_id, int *fwd_from_id, int *fwd_date, int *date, const char *message, int message_len, struct tl_ds_message_media *media, struct tl_ds_message_action *action, int *reply_id, struct tl_ds_reply_markup *reply_markup, int flags) { - clear_packet (); - assert (!(flags & 0xfffe0000)); - - out_int (CODE_binlog_message_new); - int *flags_p = packet_ptr; - out_int (flags); - assert (*flags_p == flags); - - out_long (id); - - if (from_id) { - assert (to_type); - assert (to_id); - (*flags_p) |= (1 << 17); - out_int (*from_id); - out_int (*to_type); - out_int (*to_id); - } - - if (fwd_from_id) { - assert (fwd_date); - (*flags_p) |= (1 << 18); - out_int (*fwd_from_id); - out_int (*fwd_date); - } - - if (date) { - (*flags_p) |= (1 << 19); - out_int (*date); - } - - if (message) { - (*flags_p) |= (1 << 20); - out_cstring (message, message_len); - } - - if (media) { - (*flags_p) |= (1 << 21); - store_ds_type_message_media (media, TYPE_TO_PARAM (message_media)); - } - - if (action) { - (*flags_p) |= (1 << 22); - - store_ds_type_message_action (action, TYPE_TO_PARAM (message_action)); - } - - if (reply_id) { - (*flags_p) |= (1 << 23); - out_int (*reply_id); - } - - if (reply_markup) { - (*flags_p) |= (1 << 24); - store_ds_type_reply_markup (reply_markup, TYPE_TO_PARAM (reply_markup)); - } - - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_create_message_encr_new (struct tgl_state *TLS, long long id, int *from_id, int *to_type, int *to_id, int *date, const char *message, int message_len, struct tl_ds_decrypted_message_media *media, struct tl_ds_decrypted_message_action *action, struct tl_ds_encrypted_file *file, int flags) { - clear_packet (); - assert (!(flags & 0xfffe0000)); - - out_int (CODE_binlog_message_encr_new); - int *flags_p = packet_ptr; - out_int (flags); - assert (flags & TGLMF_ENCRYPTED); - assert (*flags_p == flags); - - out_long (id); - - if (from_id) { - assert (to_id); - assert (to_type); - (*flags_p) |= (1 << 17); - out_int (*from_id); - out_int (*to_type); - out_int (*to_id); - } - - if (date) { - (*flags_p) |= (1 << 19); - out_int (*date); - } - - if (message) { - (*flags_p) |= (1 << 20); - out_cstring (message, message_len); - } - - if (media) { - (*flags_p) |= (1 << 21); - store_ds_type_decrypted_message_media (media, TYPE_TO_PARAM (decrypted_message_media)); - } - - if (action) { - (*flags_p) |= (1 << 22); - store_ds_type_decrypted_message_action (action, TYPE_TO_PARAM (decrypted_message_action)); - } - - if (file) { - (*flags_p) |= (1 << 23); - store_ds_type_encrypted_file (file, TYPE_TO_PARAM (encrypted_file)); - } - - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_message_delete (struct tgl_state *TLS, struct tgl_message *M) { - clear_packet (); - out_int (CODE_binlog_message_delete); - out_long (M->id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_msg_update (struct tgl_state *TLS, long long id) { - clear_packet (); - out_int (CODE_binlog_msg_update); - out_long (id); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_reset_authorization (struct tgl_state *TLS) { - clear_packet (); - out_int (CODE_binlog_reset_authorization); - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_encr_chat_exchange_new (struct tgl_state *TLS, struct tgl_secret_chat *E, long long *exchange_id, const void *key, int *state) { - clear_packet (); - - out_int (CODE_binlog_encr_chat_exchange_new); - out_int (tgl_get_peer_id (E->id)); - - int *flags_p = packet_ptr; - out_int (0); - - if (exchange_id) { - *flags_p |= (1 << 17); - out_long (*exchange_id); - } - - if (key) { - *flags_p |= (1 << 18); - out_ints ((void *)key, 64); - } - - if (state) { - *flags_p |= (1 << 19); - out_int (*state); - } - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); -} - -void bl_do_set_auth_key (struct tgl_state *TLS, int num, unsigned char *buf) { - int *ev = alloc_log_event (8 + 8 + 256); - ev[0] = CODE_binlog_auth_key; - ev[1] = num; - //*(long long *)(ev + 2) = fingerprint; - memcpy (ev + 2, buf, 256); - add_log_event (TLS, ev, 8 + 256); -} - -void bl_do_user_new (struct tgl_state *TLS, int id, long long *access_hash, const char *first_name, int first_name_len, const char *last_name, int last_name_len, const char *phone, int phone_len, const char *username, int username_len, struct tl_ds_photo *photo, const char *real_first_name, int real_first_name_len, const char *real_last_name, int real_last_name_len, struct tl_ds_user_profile_photo *profile_photo, int *last_read_in, int *last_read_out, struct tl_ds_bot_info *bot_info, int flags) { - tgl_peer_t *PP = tgl_peer_get (TLS, TGL_MK_USER (id)); - struct tgl_user *P = &PP->user; - - if (flags == TGL_FLAGS_UNCHANGED) { - flags = P->flags & 0xffff; - } - - clear_packet (); - out_int (CODE_binlog_user_new); - - int *flags_p = packet_ptr; - - assert (!(flags & 0xfffe0000)); - out_int (flags); - out_int (id); - - if (access_hash) { - if (!P || P->access_hash != *access_hash) { - out_long (*access_hash); - (*flags_p) |= (1 << 17); - } - } - - if (first_name) { - if (!P || !P->first_name || !P->last_name || mystreq1 (P->first_name, first_name, first_name_len) || mystreq1 (P->last_name, last_name, last_name_len)) { - out_cstring (first_name, first_name_len); - out_cstring (last_name, last_name_len); - - (*flags_p) |= (1 << 18); - } - } - - if (phone) { - if (!P || !P->phone || mystreq1 (P->phone, phone, phone_len)) { - out_cstring (phone, phone_len); - (*flags_p) |= (1 << 19); - } - } - - if (username) { - if (!P || !P->username || mystreq1 (P->username, username, username_len)) { - out_cstring (username, username_len); - (*flags_p) |= (1 << 20); - } - } - - if (photo) { - if (!P || !P->photo || P->photo->id != DS_LVAL (photo->id)) { - store_ds_type_photo (photo, TYPE_TO_PARAM (photo)); - (*flags_p) |= (1 << 21); - } - } - - if (real_first_name) { - assert (real_last_name); - if (!P || !P->real_first_name || !P->real_last_name || mystreq1 (P->real_first_name, real_first_name, real_first_name_len) || mystreq1 (P->real_last_name, real_last_name, real_last_name_len)) { - out_cstring (real_first_name, real_first_name_len); - out_cstring (real_last_name, real_last_name_len); - - (*flags_p) |= (1 << 22); - } - } - - if (profile_photo) { - if (!P || P->photo_id != DS_LVAL (profile_photo->photo_id)) { - store_ds_type_user_profile_photo (profile_photo, TYPE_TO_PARAM (user_profile_photo)); - (*flags_p) |= (1 << 23); - } - } - - if (last_read_in) { - if (!P || P->last_read_in < *last_read_in) { - out_int (*last_read_in); - (*flags_p) |= (1 << 24); - } - } - - if (last_read_out) { - if (!P || P->last_read_out < *last_read_out) { - out_int (*last_read_out); - (*flags_p) |= (1 << 25); - } - } - - if (bot_info) { - if (!P || !P->bot_info || P->bot_info->version != DS_LVAL (bot_info->version)) { - store_ds_type_bot_info (bot_info, TYPE_TO_PARAM (bot_info)); - (*flags_p) |= (1 << 26); - } - } - - if (((*flags_p) & 0xffff0000) || !P || (P->flags & 0xffff) != flags) { - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); - } -} - -void bl_do_chat_new (struct tgl_state *TLS, int id, const char *title, int title_len, int *user_num, int *date, int *version, struct tl_ds_vector *participants, struct tl_ds_chat_photo *chat_photo, struct tl_ds_photo *photo, int *admin, int *last_read_in, int *last_read_out, int flags) { - tgl_peer_t *PP = tgl_peer_get (TLS, TGL_MK_CHAT (id)); - struct tgl_chat *P = &PP->chat; - - if (flags == TGL_FLAGS_UNCHANGED) { - flags = P ? (P->flags & 0xffff) : 0; - } - - clear_packet (); - out_int (CODE_binlog_chat_new); - - int *flags_p = packet_ptr; - - assert (!(flags & 0xfffe0000)); - out_int (flags); - out_int (id); - - if (title) { - if (!P || !P->title || mystreq1 (P->title, title, title_len)) { - out_cstring (title, title_len); - (*flags_p) |= (1 << 17); - } - } - - if (user_num) { - if (!P || P->users_num != *user_num) { - out_int (*user_num); - (*flags_p) |= (1 << 18); - } - } - - if (date) { - if (!P || P->date != *date) { - out_int (*date); - (*flags_p) |= (1 << 19); - } - } - - if (version) { - assert (participants); - if (!P || *version != P->version) { - out_int (*version); - store_ds_type_vector (participants, TYPE_TO_PARAM_1 (vector, TYPE_TO_PARAM (chat_participant))); - (*flags_p) |= (1 << 20); - } - } - - if (chat_photo && chat_photo->photo_big) { - if (!P || DS_LVAL (chat_photo->photo_big->secret) != P->photo_big.secret) { - store_ds_type_chat_photo (chat_photo, TYPE_TO_PARAM (chat_photo)); - (*flags_p) |= (1 << 21); - } - } - - if (photo) { - if (!P || !P->photo || P->photo->id != DS_LVAL (photo->id)) { - store_ds_type_photo (photo, TYPE_TO_PARAM (photo)); - (*flags_p) |= (1 << 22); - } - } - - if (admin) { - if (!P || P->admin_id != *admin) { - out_int (*admin); - (*flags_p) |= (1 << 23); - } - } - - if (last_read_in) { - if (!P || P->last_read_in < *last_read_in) { - out_int (*last_read_in); - (*flags_p) |= (1 << 24); - } - } - - if (last_read_out) { - if (!P || P->last_read_out < *last_read_out) { - out_int (*last_read_out); - (*flags_p) |= (1 << 25); - } - } - - if (((*flags_p) & 0xffff0000) || !P || (P->flags & 0xffff) != flags) { - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); - } -} - -void bl_do_encr_chat_new (struct tgl_state *TLS, int id, long long *access_hash, int *date, int *admin, int *user_id, void *key, void *g_key, void *first_key_id, int *state, int *ttl, int *layer, int *in_seq_no, int *last_in_seq_no, int *out_seq_no, long long *key_fingerprint, int flags) { - tgl_peer_t *PP = tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (id)); - struct tgl_secret_chat *P = PP ? &PP->encr_chat : NULL; - - if (flags == TGL_FLAGS_UNCHANGED) { - flags = P->flags & 0xffff; - } - - clear_packet (); - out_int (CODE_binlog_encr_chat_new); - - int *flags_p = packet_ptr; - - assert (!(flags & 0xfffe0000)); - out_int (flags); - out_int (id); - - if (access_hash) { - if (!P || P->access_hash != *access_hash) { - out_long (*access_hash); - (*flags_p) |= (1 << 17); - } - } - - if (date) { - if (!P || P->date != *date) { - out_int (*date); - (*flags_p) |= (1 << 18); - } - } - - if (admin) { - if (!P || P->admin_id != *admin) { - out_int (*admin); - (*flags_p) |= (1 << 19); - } - } - - if (user_id) { - if (!P || P->user_id != *user_id) { - out_int (*user_id); - (*flags_p) |= (1 << 20); - } - } - - if (key) { - if (!P || memcmp (P->key, key, 256)) { - out_ints (key, 64); - (*flags_p) |= (1 << 21); - } - } - - if (g_key) { - if (!P || !P->g_key || memcmp (P->g_key, g_key, 256)) { - out_ints (g_key, 64); - (*flags_p) |= (1 << 22); - } - } - - if (state) { - if (!P || (int)P->state != *state) { - out_int (*state); - (*flags_p) |= (1 << 23); - } - } - - if (ttl) { - if (!P || P->ttl != *ttl) { - out_int (*ttl); - (*flags_p) |= (1 << 24); - } - } - - if (layer) { - if (!P || P->layer != *layer) { - out_int (*layer); - (*flags_p) |= (1 << 25); - } - } - - if (in_seq_no || last_in_seq_no || out_seq_no) { - if (!P || (in_seq_no && P->in_seq_no != *in_seq_no) || - (out_seq_no && P->out_seq_no != *out_seq_no) || - (last_in_seq_no && P->last_in_seq_no != *last_in_seq_no)) { - - out_int (in_seq_no ? *in_seq_no : P ? P->in_seq_no : 0); - out_int (last_in_seq_no ? *last_in_seq_no : P ? P->last_in_seq_no : 0); - out_int (out_seq_no ? *out_seq_no : P ? P->out_seq_no : 0); - (*flags_p) |= (1 << 26); - } - } - - if (key_fingerprint) { - if (!P || P->key_fingerprint != *key_fingerprint) { - out_long (*key_fingerprint); - (*flags_p) |= (1 << 27); - } - } - - if (((*flags_p) & 0xffff0000) || !P || (P->flags & 0xffff) != flags) { - add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer)); - } -} |