summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tgl/binlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tgl/binlog.c')
-rw-r--r--protocols/Telegram/tgl/binlog.c1829
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));
- }
-}