Remove remaining global variables

This commit is contained in:
mjentsch 2014-09-01 21:25:41 +02:00
parent 2e50ec47b7
commit d94dc52df0
10 changed files with 687 additions and 636 deletions

226
binlog.c
View file

@ -37,11 +37,6 @@
#include <openssl/sha.h>
extern int pts;
extern int qts;
extern int last_date;
extern int seq;
#define MAX_LOG_EVENT_SIZE (1 << 17)
// TODO: remove this completely
@ -51,12 +46,7 @@ char *get_binlog_file_name()
return "/home/dev-jessie/.telegram/binlog";
}
extern int our_id;
int binlog_enabled = 0;
extern int encr_root;
extern unsigned char *encr_prime;
extern int encr_param_version;
extern int messages_allocated;
void *alloc_log_event (struct binlog *bl, int l UU) {
return bl->binlog_buffer;
@ -119,7 +109,7 @@ void replay_log_event (struct telegram *instance) {
case LOG_OUR_ID:
bl->rptr ++;
{
our_id = *(bl->rptr ++);
instance->our_id = *(bl->rptr ++);
}
break;
case LOG_DC_SIGNED:
@ -158,7 +148,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
struct secret_chat *U = (void *)user_chat_get (id);
struct secret_chat *U = (void *)user_chat_get (bl, id);
assert (U);
U->key_fingerprint = *(long long *)bl->rptr;
bl->rptr += 2;
@ -170,7 +160,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
struct secret_chat *U = (void *)user_chat_get (id);
struct secret_chat *U = (void *)user_chat_get (bl, id);
assert (U);
U->key_fingerprint = *(long long *)bl->rptr;
bl->rptr += 2;
@ -187,27 +177,27 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
struct secret_chat *U = (void *)user_chat_get (id);
struct secret_chat *U = (void *)user_chat_get (bl, id);
assert (!U || !(U->flags & FLAG_CREATED));
if (!U) {
U = talloc0 (sizeof (peer_t));
U->id = id;
insert_encrypted_chat ((void *)U);
insert_encrypted_chat (bl, (void *)U);
}
U->flags |= FLAG_CREATED;
U->user_id = *(bl->rptr ++);
memcpy (U->key, bl->rptr, 256);
bl->rptr += 64;
if (!U->print_name) {
peer_t *P = user_chat_get (MK_USER (U->user_id));
peer_t *P = user_chat_get (bl, MK_USER (U->user_id));
if (P) {
U->print_name = create_print_name (U->id, "!", P->user.first_name, P->user.last_name, 0);
U->print_name = create_print_name (bl, U->id, "!", P->user.first_name, P->user.last_name, 0);
} else {
static char buf[100];
tsnprintf (buf, 99, "user#%d", U->user_id);
U->print_name = create_print_name (U->id, "!", buf, 0, 0);
U->print_name = create_print_name (bl, U->id, "!", buf, 0, 0);
}
peer_insert_name ((void *)U);
peer_insert_name (bl, (void *)U);
}
};
break;
@ -215,11 +205,11 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
struct secret_chat *U = (void *)user_chat_get (id);
struct secret_chat *U = (void *)user_chat_get (bl, id);
if (!U) {
U = talloc0 (sizeof (peer_t));
U->id = id;
insert_encrypted_chat ((void *)U);
insert_encrypted_chat (bl, (void *)U);
}
U->flags |= FLAG_CREATED;
U->state = sc_deleted;
@ -229,7 +219,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
struct secret_chat *U = (void *)user_chat_get (id);
struct secret_chat *U = (void *)user_chat_get (bl, id);
assert (U);
U->state = sc_waiting;
U->date = *(bl->rptr ++);
@ -243,11 +233,11 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
struct secret_chat *U = (void *)user_chat_get (id);
struct secret_chat *U = (void *)user_chat_get (bl, id);
if (!U) {
U = talloc0 (sizeof (peer_t));
U->id = id;
insert_encrypted_chat ((void *)U);
insert_encrypted_chat (bl, (void *)U);
}
U->flags |= FLAG_CREATED;
U->state = sc_request;
@ -256,15 +246,15 @@ void replay_log_event (struct telegram *instance) {
U->user_id = *(bl->rptr ++);
U->access_hash = *(long long *)bl->rptr;
if (!U->print_name) {
peer_t *P = user_chat_get (MK_USER (U->user_id));
peer_t *P = user_chat_get (bl, MK_USER (U->user_id));
if (P) {
U->print_name = create_print_name (U->id, "!", P->user.first_name, P->user.last_name, 0);
U->print_name = create_print_name (bl, U->id, "!", P->user.first_name, P->user.last_name, 0);
} else {
static char buf[100];
tsnprintf (buf, 99, "user#%d", U->user_id);
U->print_name = create_print_name (U->id, "!", buf, 0, 0);
U->print_name = create_print_name (bl, U->id, "!", buf, 0, 0);
}
peer_insert_name ((void *)U);
peer_insert_name (bl, (void *)U);
}
bl->rptr += 2;
};
@ -273,7 +263,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
struct secret_chat *U = (void *)user_chat_get (id);
struct secret_chat *U = (void *)user_chat_get (bl, id);
assert (U);
U->state = sc_ok;
}
@ -282,24 +272,24 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
peer_id_t id = MK_USER (fetch_int (self));
peer_t *_U = user_chat_get (id);
peer_t *_U = user_chat_get (bl, id);
if (!_U) {
_U = talloc0 (sizeof (*_U));
_U->id = id;
insert_user (_U);
insert_user (bl, _U);
} else {
assert (!(_U->flags & FLAG_CREATED));
}
struct user *U = (void *)_U;
U->flags |= FLAG_CREATED;
if (get_peer_id (id) == our_id) {
if (get_peer_id (id) == instance->our_id) {
U->flags |= FLAG_USER_SELF;
}
U->first_name = fetch_str_dup (self);
U->last_name = fetch_str_dup (self);
assert (!U->print_name);
U->print_name = create_print_name (U->id, U->first_name, U->last_name, 0, 0);
peer_insert_name ((void *)U);
U->print_name = create_print_name (bl, U->id, U->first_name, U->last_name, 0, 0);
peer_insert_name (bl, (void *)U);
U->access_hash = fetch_long (self);
U->phone = fetch_str_dup (self);
if (fetch_int (self)) {
@ -312,7 +302,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_USER (*(bl->rptr ++));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
U->flags |= FLAG_DELETED;
}
@ -321,7 +311,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_USER (*(bl->rptr ++));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
U->user.access_hash = *(long long *)bl->rptr;
bl->rptr += 2;
@ -331,7 +321,7 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
peer_id_t id = MK_USER (fetch_int (self));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
if (U->user.phone) { tfree_str (U->user.phone); }
U->user.phone = fetch_str_dup (self);
@ -342,7 +332,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_USER (*(bl->rptr ++));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
int friend = *(bl->rptr ++);
if (friend) { U->flags |= FLAG_USER_CONTACT; }
@ -353,7 +343,7 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
peer_id_t id = MK_USER (fetch_int (self));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
if (U->flags & FLAG_HAS_PHOTO) {
free_photo (&U->user.photo);
@ -366,7 +356,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_USER (*(bl->rptr ++));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
U->user.blocked = *(bl->rptr ++);
}
@ -375,7 +365,7 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
peer_id_t id = MK_USER (fetch_int (self));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
if (U->user.real_first_name) { tfree_str (U->user.real_first_name); }
if (U->user.real_last_name) { tfree_str (U->user.real_last_name); }
@ -388,7 +378,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
peer_t *_U = user_chat_get (id);
peer_t *_U = user_chat_get (bl, id);
assert (_U);
struct secret_chat *U = &_U->encr_chat;
memset (U->key, 0, sizeof (U->key));
@ -408,11 +398,11 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
peer_t *_U = user_chat_get (id);
peer_t *_U = user_chat_get (bl, id);
if (!_U) {
_U = talloc0 (sizeof (*_U));
_U->id = id;
insert_encrypted_chat (_U);
insert_encrypted_chat (bl, _U);
} else {
assert (!(_U->flags & FLAG_CREATED));
}
@ -423,16 +413,16 @@ void replay_log_event (struct telegram *instance) {
U->admin_id = *(bl->rptr ++);
U->user_id = *(bl->rptr ++);
peer_t *Us = user_chat_get (MK_USER (U->user_id));
peer_t *Us = user_chat_get (bl, MK_USER (U->user_id));
assert (!U->print_name);
if (Us) {
U->print_name = create_print_name (id, "!", Us->user.first_name, Us->user.last_name, 0);
U->print_name = create_print_name (bl, 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 = create_print_name (id, "!", buf, 0, 0);
U->print_name = create_print_name (bl, id, "!", buf, 0, 0);
}
peer_insert_name ((void *)U);
peer_insert_name (bl, (void *)U);
U->g_key = talloc (256);
U->nonce = talloc (256);
memcpy (U->g_key, bl->rptr, 256);
@ -448,7 +438,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
U->encr_chat.access_hash = *(long long *)bl->rptr;
bl->rptr += 2;
@ -458,7 +448,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
U->encr_chat.date = *(bl->rptr ++);
}
@ -467,7 +457,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U);
U->encr_chat.state = *(bl->rptr ++);
}
@ -476,7 +466,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
peer_t *_U = user_chat_get (id);
peer_t *_U = user_chat_get (bl, id);
assert (_U);
struct secret_chat *U = &_U->encr_chat;
if (!U->g_key) {
@ -492,7 +482,7 @@ void replay_log_event (struct telegram *instance) {
U->key_fingerprint = *(long long *)bl->rptr;
bl->rptr += 2;
if (U->state == sc_waiting) {
do_create_keys_end (U);
do_create_keys_end (instance, U);
}
U->state = sc_ok;
}
@ -501,7 +491,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_ENCR_CHAT (*(bl->rptr ++));
peer_t *_U = user_chat_get (id);
peer_t *_U = user_chat_get (bl, id);
assert (_U);
struct secret_chat *U = &_U->encr_chat;
memcpy (U->key, bl->rptr, 256);
@ -513,12 +503,12 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_set_dh_params:
bl->rptr ++;
{
if (encr_prime) { tfree (encr_prime, 256); }
encr_root = *(bl->rptr ++);
encr_prime = talloc (256);
memcpy (encr_prime, bl->rptr, 256);
if (instance->encr_prime) { tfree (instance->encr_prime, 256); }
instance->encr_root = *(bl->rptr ++);
instance->encr_prime = talloc (256);
memcpy (instance->encr_prime, bl->rptr, 256);
bl->rptr += 64;
encr_param_version = *(bl->rptr ++);
instance->encr_param_version = *(bl->rptr ++);
}
break;
case CODE_binlog_encr_chat_init:
@ -526,14 +516,14 @@ void replay_log_event (struct telegram *instance) {
{
peer_t *P = talloc0 (sizeof (*P));
P->id = MK_ENCR_CHAT (*(bl->rptr ++));
assert (!user_chat_get (P->id));
assert (!user_chat_get (bl, P->id));
P->encr_chat.user_id = *(bl->rptr ++);
P->encr_chat.admin_id = our_id;
insert_encrypted_chat (P);
peer_t *Us = user_chat_get (MK_USER (P->encr_chat.user_id));
P->encr_chat.admin_id = instance->our_id;
insert_encrypted_chat (bl, P);
peer_t *Us = user_chat_get (bl, MK_USER (P->encr_chat.user_id));
assert (Us);
P->print_name = create_print_name (P->id, "!", Us->user.first_name, Us->user.last_name, 0);
peer_insert_name (P);
P->print_name = create_print_name (bl, P->id, "!", Us->user.first_name, Us->user.last_name, 0);
peer_insert_name (bl, P);
memcpy (P->encr_chat.key, bl->rptr, 256);
bl->rptr += 64;
P->encr_chat.g_key = talloc (256);
@ -544,29 +534,29 @@ void replay_log_event (struct telegram *instance) {
break;
case CODE_binlog_set_pts:
bl->rptr ++;
pts = *(bl->rptr ++);
instance->proto.pts = *(bl->rptr ++);
break;
case CODE_binlog_set_qts:
bl->rptr ++;
qts = *(bl->rptr ++);
instance->proto.qts = *(bl->rptr ++);
break;
case CODE_binlog_set_date:
bl->rptr ++;
last_date = *(bl->rptr ++);
instance->proto.last_date = *(bl->rptr ++);
break;
case CODE_binlog_set_seq:
bl->rptr ++;
seq = *(bl->rptr ++);
instance->proto.seq = *(bl->rptr ++);
break;
case CODE_binlog_chat_create:
self->in_ptr ++;
{
peer_id_t id = MK_CHAT (fetch_int (self));
peer_t *_C = user_chat_get (id);
peer_t *_C = user_chat_get (bl, id);
if (!_C) {
_C = talloc0 (sizeof (*_C));
_C->id = id;
insert_chat (_C);
insert_chat (bl, _C);
} else {
assert (!(_C->flags & FLAG_CREATED));
}
@ -574,8 +564,8 @@ void replay_log_event (struct telegram *instance) {
C->flags = FLAG_CREATED | fetch_int (self);
C->title = fetch_str_dup (self);
assert (!C->print_title);
C->print_title = create_print_name (id, C->title, 0, 0, 0);
peer_insert_name ((void *)C);
C->print_title = create_print_name (bl, id, C->title, 0, 0, 0);
peer_insert_name (bl, (void *)C);
C->users_num = fetch_int (self);
C->date = fetch_int (self);
C->version = fetch_int (self);
@ -587,7 +577,7 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_chat_change_flags:
bl->rptr ++;
{
peer_t *C = user_chat_get (MK_CHAT (*(bl->rptr ++)));
peer_t *C = user_chat_get (bl, MK_CHAT (*(bl->rptr ++)));
assert (C && (C->flags & FLAG_CREATED));
C->flags |= *(bl->rptr ++);
C->flags &= ~*(bl->rptr ++);
@ -596,24 +586,24 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_set_chat_title:
self->in_ptr ++;
{
peer_t *_C = user_chat_get (MK_CHAT (fetch_int (self)));
peer_t *_C = user_chat_get (bl, MK_CHAT (fetch_int (self)));
assert (_C && (_C->flags & FLAG_CREATED));
struct chat *C = &_C->chat;
if (C->title) { tfree_str (C->title); }
C->title = fetch_str_dup (self);
if (C->print_title) {
peer_delete_name ((void *)C);
peer_delete_name (bl, (void *)C);
tfree_str (C->print_title);
}
C->print_title = create_print_name (C->id, C->title, 0, 0, 0);
peer_insert_name ((void *)C);
C->print_title = create_print_name (bl, C->id, C->title, 0, 0, 0);
peer_insert_name (bl, (void *)C);
};
bl->rptr = self->in_ptr;
break;
case CODE_binlog_set_chat_photo:
self->in_ptr ++;
{
peer_t *C = user_chat_get (MK_CHAT (fetch_int (self)));
peer_t *C = user_chat_get (bl, MK_CHAT (fetch_int (self)));
assert (C && (C->flags & FLAG_CREATED));
fetch_data (self, &C->photo_big, sizeof (struct file_location));
fetch_data (self, &C->photo_small, sizeof (struct file_location));
@ -623,7 +613,7 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_set_chat_date:
bl->rptr ++;
{
peer_t *C = user_chat_get (MK_CHAT (*(bl->rptr ++)));
peer_t *C = user_chat_get (bl, MK_CHAT (*(bl->rptr ++)));
assert (C && (C->flags & FLAG_CREATED));
C->chat.date = *(bl->rptr ++);
};
@ -631,7 +621,7 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_set_chat_version:
bl->rptr ++;
{
peer_t *C = user_chat_get (MK_CHAT (*(bl->rptr ++)));
peer_t *C = user_chat_get (bl, MK_CHAT (*(bl->rptr ++)));
assert (C && (C->flags & FLAG_CREATED));
C->chat.version = *(bl->rptr ++);
C->chat.users_num = *(bl->rptr ++);
@ -640,7 +630,7 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_set_chat_admin:
bl->rptr ++;
{
peer_t *C = user_chat_get (MK_CHAT (*(bl->rptr ++)));
peer_t *C = user_chat_get (bl, MK_CHAT (*(bl->rptr ++)));
assert (C && (C->flags & FLAG_CREATED));
C->chat.admin_id = *(bl->rptr ++);
};
@ -648,7 +638,7 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_set_chat_participants:
bl->rptr ++;
{
peer_t *C = user_chat_get (MK_CHAT (*(bl->rptr ++)));
peer_t *C = user_chat_get (bl, MK_CHAT (*(bl->rptr ++)));
assert (C && (C->flags & FLAG_CREATED));
C->chat.user_list_version = *(bl->rptr ++);
if (C->chat.user_list) { tfree (C->chat.user_list, 12 * C->chat.user_list_size); }
@ -662,7 +652,7 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
peer_id_t id = MK_CHAT (fetch_int (self));
peer_t *U = user_chat_get (id);
peer_t *U = user_chat_get (bl, id);
assert (U && (U->flags & FLAG_CREATED));
if (U->flags & FLAG_HAS_PHOTO) {
free_photo (&U->chat.photo);
@ -675,7 +665,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_CHAT (*(bl->rptr ++));
peer_t *_C = user_chat_get (id);
peer_t *_C = user_chat_get (bl, id);
assert (_C && (_C->flags & FLAG_CREATED));
struct chat *C = &_C->chat;
@ -701,7 +691,7 @@ void replay_log_event (struct telegram *instance) {
bl->rptr ++;
{
peer_id_t id = MK_CHAT (*(bl->rptr ++));
peer_t *_C = user_chat_get (id);
peer_t *_C = user_chat_get (bl, id);
assert (_C && (_C->flags & FLAG_CREATED));
struct chat *C = &_C->chat;
@ -734,12 +724,13 @@ void replay_log_event (struct telegram *instance) {
} else {
id = fetch_long (self);
}
struct message *M = message_get (id);
struct message *M = message_get(bl, id);
if (!M) {
M = talloc0 (sizeof (*M));
M->id = id;
M->instance = instance;
message_insert_tree (M);
messages_allocated ++;
bl->messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
@ -764,7 +755,7 @@ void replay_log_event (struct telegram *instance) {
M->media.type = CODE_message_media_empty;
}
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->out = get_peer_id (M->from_id) == instance->our_id;
message_insert (M);
if (op == CODE_binlog_send_message_text) {
@ -778,12 +769,12 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
int id = fetch_int (self);
struct message *M = message_get (id);
struct message *M = message_get(bl, id);
if (!M) {
M = talloc0 (sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
bl->messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
@ -803,7 +794,7 @@ void replay_log_event (struct telegram *instance) {
M->media.type = CODE_message_media_empty;
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->out = get_peer_id (M->from_id) == instance->our_id;
message_insert (M);
}
@ -813,12 +804,12 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
int id = fetch_int (self);
struct message *M = message_get (id);
struct message *M = message_get(bl, id);
if (!M) {
M = talloc0 (sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
bl->messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
@ -836,7 +827,7 @@ void replay_log_event (struct telegram *instance) {
fetch_message_media (self, &M->media);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->out = get_peer_id (M->from_id) == instance->our_id;
message_insert (M);
}
@ -846,12 +837,12 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
long long id = fetch_long (self);
struct message *M = message_get (id);
struct message *M = message_get(bl, id);
if (!M) {
M = talloc0 (sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
bl->messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
@ -871,7 +862,7 @@ void replay_log_event (struct telegram *instance) {
fetch_encrypted_message_file (self, &M->media);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->out = get_peer_id (M->from_id) == instance->our_id;
message_insert (M);
}
@ -881,12 +872,12 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
int id = fetch_int (self);
struct message *M = message_get (id);
struct message *M = message_get(bl, id);
if (!M) {
M = talloc0 (sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
bl->messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
@ -906,7 +897,7 @@ void replay_log_event (struct telegram *instance) {
fetch_message_media (self, &M->media);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->out = get_peer_id (M->from_id) == instance->our_id;
message_insert (M);
}
@ -916,12 +907,12 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
int id = fetch_int (self);
struct message *M = message_get (id);
struct message *M = message_get(bl, id);
if (!M) {
M = talloc0 (sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
bl->messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
@ -933,7 +924,7 @@ void replay_log_event (struct telegram *instance) {
fetch_message_action (self, &M->action);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->out = get_peer_id (M->from_id) == instance->our_id;
M->service = 1;
message_insert (M);
@ -944,12 +935,12 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
long long id = fetch_long (self);
struct message *M = message_get (id);
struct message *M = message_get(bl, id);
if (!M) {
M = talloc0 (sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
bl->messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
@ -962,7 +953,7 @@ void replay_log_event (struct telegram *instance) {
fetch_message_action_encrypted (self, &M->action);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->out = get_peer_id (M->from_id) == instance->our_id;
M->service = 1;
message_insert (M);
@ -973,12 +964,12 @@ void replay_log_event (struct telegram *instance) {
self->in_ptr ++;
{
int id = fetch_int (self);
struct message *M = message_get (id);
struct message *M = message_get(bl, id);
if (!M) {
M = talloc0 (sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
bl->messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
@ -991,7 +982,7 @@ void replay_log_event (struct telegram *instance) {
M->fwd_date = fetch_int (self);
fetch_message_action (self, &M->action);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->out = get_peer_id (M->from_id) == instance->our_id;
M->service = 1;
message_insert (M);
@ -1001,7 +992,7 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_set_unread:
bl->rptr ++;
{
struct message *M = message_get (*(bl->rptr ++));
struct message *M = message_get(bl, *(bl->rptr ++));
assert (M);
M->unread = 0;
}
@ -1009,7 +1000,7 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_set_message_sent:
bl->rptr ++;
{
struct message *M = message_get (*(long long *)bl->rptr);
struct message *M = message_get(bl, *(long long *)bl->rptr);
bl->rptr += 2;
assert (M);
message_remove_unsent (M);
@ -1019,7 +1010,7 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_set_msg_id:
bl->rptr ++;
{
struct message *M = message_get (*(long long *)bl->rptr);
struct message *M = message_get(bl, *(long long *)bl->rptr);
bl->rptr += 2;
assert (M);
if (M->flags & FLAG_PENDING) {
@ -1029,7 +1020,7 @@ void replay_log_event (struct telegram *instance) {
message_remove_tree (M);
message_del_peer (M);
M->id = *(bl->rptr ++);
if (message_get (M->id)) {
if (message_get(bl, M->id)) {
free_message (M);
tfree (M, sizeof (*M));
} else {
@ -1041,7 +1032,7 @@ void replay_log_event (struct telegram *instance) {
case CODE_binlog_delete_msg:
bl->rptr ++;
{
struct message *M = message_get (*(long long *)bl->rptr);
struct message *M = message_get(bl, *(long long *)bl->rptr);
bl->rptr += 2;
assert (M);
if (M->flags & FLAG_PENDING) {
@ -1250,7 +1241,6 @@ void bl_do_user_delete (struct binlog *bl, struct mtproto_connection *self, stru
add_log_event (bl, self, ev, 8);
}
extern int last_date;
void bl_do_set_user_profile_photo (struct binlog *bl, struct mtproto_connection *self, struct user *U,
long long photo_id, struct file_location *big, struct file_location *small) {
if (photo_id == U->photo_id) { return; }
@ -1258,7 +1248,7 @@ void bl_do_set_user_profile_photo (struct binlog *bl, struct mtproto_connection
int *ev = alloc_log_event (bl, 20);
ev[0] = CODE_update_user_photo;
ev[1] = get_peer_id (U->id);
ev[2] = last_date;
ev[2] = self->connection->instance->proto.last_date;
ev[3] = CODE_user_profile_photo_empty;
ev[4] = CODE_bool_false;
add_log_event (bl, self, ev, 20);
@ -1266,7 +1256,7 @@ void bl_do_set_user_profile_photo (struct binlog *bl, struct mtproto_connection
clear_packet (self);
out_int (self, CODE_update_user_photo);
out_int (self, get_peer_id (U->id));
out_int (self, last_date);
out_int (self, self->connection->instance->proto.last_date);
out_int (self, CODE_user_profile_photo);
out_long (self, photo_id);
if (small->dc >= 0) {

86
loop.c
View file

@ -48,17 +48,12 @@
extern char *auth_token;
int test_dc = 0;
int default_dc_num;
extern int binlog_enabled;
extern int unknown_user_list_pos;
extern int unknown_user_list[];
int register_mode;
extern int safe_quit;
int unread_messages;
void got_it (char *line, int len);
char **_s;
@ -289,9 +284,9 @@ extern int encr_root;
extern unsigned char *encr_prime;
extern int encr_param_version;
extern int dialog_list_got;
// TODO: Refactor
void read_secret_chat_file (const char *file) {
void read_secret_chat_file (struct telegram *instance, const char *file) {
struct binlog *bl = instance->bl;
if (binlog_enabled) { return; }
int fd = open (file, O_CREAT | O_RDWR, 0600);
@ -320,7 +315,7 @@ void read_secret_chat_file (const char *file) {
P->print_name = talloc (t + 1);
assert (read (fd, P->print_name, t) == t);
P->print_name[t] = 0;
peer_insert_name (P);
peer_insert_name (bl, P);
assert (read (fd, &E->state, 4) == 4);
assert (read (fd, &E->user_id, 4) == 4);
@ -336,21 +331,23 @@ void read_secret_chat_file (const char *file) {
}
assert (read (fd, E->key, 256) == 256);
assert (read (fd, &E->key_fingerprint, 8) == 8);
insert_encrypted_chat (P);
insert_encrypted_chat (bl, P);
}
if (version >= 1) {
assert (read (fd, &encr_root, 4) == 4);
if (encr_root) {
assert (read (fd, &encr_param_version, 4) == 4);
encr_prime = talloc (256);
assert (read (fd, encr_prime, 256) == 256);
assert (read (fd, &instance->encr_root, 4) == 4);
if (instance->encr_root) {
assert (read (fd, &instance->encr_param_version, 4) == 4);
instance->encr_prime = talloc (256);
assert (read (fd, instance->encr_prime, 256) == 256);
}
}
close (fd);
}
// TODO: Refactor
void write_secret_chat_file (const char *filename) {
void write_secret_chat_file (struct telegram *instance, const char *filename) {
struct binlog *bl = instance->bl;
if (binlog_enabled) { return; }
int fd = open (filename, O_CREAT | O_RDWR, 0600);
if (fd < 0) {
@ -362,59 +359,46 @@ void write_secret_chat_file (const char *filename) {
assert (write (fd, x, 8) == 8);
int i;
int cc = 0;
for (i = 0; i < peer_num; i++) if (get_peer_type (Peers[i]->id) == PEER_ENCR_CHAT) {
if (Peers[i]->encr_chat.state != sc_none && Peers[i]->encr_chat.state != sc_deleted) {
for (i = 0; i < bl->peer_num; i++) if (get_peer_type (bl->Peers[i]->id) == PEER_ENCR_CHAT) {
if (bl->Peers[i]->encr_chat.state != sc_none && bl->Peers[i]->encr_chat.state != sc_deleted) {
cc ++;
}
}
assert (write (fd, &cc, 4) == 4);
for (i = 0; i < peer_num; i++) if (get_peer_type (Peers[i]->id) == PEER_ENCR_CHAT) {
if (Peers[i]->encr_chat.state != sc_none && Peers[i]->encr_chat.state != sc_deleted) {
int t = get_peer_id (Peers[i]->id);
for (i = 0; i < bl->peer_num; i++) if (get_peer_type (bl->Peers[i]->id) == PEER_ENCR_CHAT) {
if (bl->Peers[i]->encr_chat.state != sc_none && bl->Peers[i]->encr_chat.state != sc_deleted) {
int t = get_peer_id (bl->Peers[i]->id);
assert (write (fd, &t, 4) == 4);
t = Peers[i]->flags;
t = bl->Peers[i]->flags;
assert (write (fd, &t, 4) == 4);
t = strlen (Peers[i]->print_name);
t = strlen (bl->Peers[i]->print_name);
assert (write (fd, &t, 4) == 4);
assert (write (fd, Peers[i]->print_name, t) == t);
assert (write (fd, bl->Peers[i]->print_name, t) == t);
assert (write (fd, &Peers[i]->encr_chat.state, 4) == 4);
assert (write (fd, &bl->Peers[i]->encr_chat.state, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.user_id, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.admin_id, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.ttl, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.access_hash, 8) == 8);
if (Peers[i]->encr_chat.state != sc_waiting) {
assert (write (fd, Peers[i]->encr_chat.g_key, 256) == 256);
assert (write (fd, &bl->Peers[i]->encr_chat.user_id, 4) == 4);
assert (write (fd, &bl->Peers[i]->encr_chat.admin_id, 4) == 4);
assert (write (fd, &bl->Peers[i]->encr_chat.ttl, 4) == 4);
assert (write (fd, &bl->Peers[i]->encr_chat.access_hash, 8) == 8);
if (bl->Peers[i]->encr_chat.state != sc_waiting) {
assert (write (fd, bl->Peers[i]->encr_chat.g_key, 256) == 256);
}
if (Peers[i]->encr_chat.state != sc_waiting) {
assert (write (fd, Peers[i]->encr_chat.nonce, 256) == 256);
if (bl->Peers[i]->encr_chat.state != sc_waiting) {
assert (write (fd, bl->Peers[i]->encr_chat.nonce, 256) == 256);
}
assert (write (fd, Peers[i]->encr_chat.key, 256) == 256);
assert (write (fd, &Peers[i]->encr_chat.key_fingerprint, 8) == 8);
assert (write (fd, bl->Peers[i]->encr_chat.key, 256) == 256);
assert (write (fd, &bl->Peers[i]->encr_chat.key_fingerprint, 8) == 8);
}
}
assert (write (fd, &encr_root, 4) == 4);
if (encr_root) {
assert (write (fd, &encr_param_version, 4) == 4);
assert (write (fd, encr_prime, 256) == 256);
assert (write (fd, &instance->encr_root, 4) == 4);
if (instance->encr_root) {
assert (write (fd, &instance->encr_param_version, 4) == 4);
assert (write (fd, instance->encr_prime, 256) == 256);
}
close (fd);
}
extern int max_chat_size;
int mcs (void) {
return max_chat_size;
}
extern int difference_got;
int dgot (void) {
return difference_got;
}
int dlgot (void) {
return dialog_list_got;
}
int readline_active;
int new_dc_num;
int wait_dialog_list;

View file

@ -797,24 +797,26 @@ void fetch_seq (struct mtproto_connection *self) {
}
void work_update_binlog (struct mtproto_connection *self) {
struct binlog *bl = self->bl;
unsigned op = fetch_int (self);
switch (op) {
case CODE_update_user_name:
{
peer_id_t user_id = MK_USER (fetch_int (self));
peer_t *UC = user_chat_get (user_id);
peer_t *UC = user_chat_get (bl, user_id);
if (UC) {
struct user *U = &UC->user;
if (U->first_name) { tfree_str (U->first_name); }
if (U->last_name) { tfree_str (U->last_name); }
if (U->print_name) {
peer_delete_name (UC);
peer_delete_name (bl, UC);
tfree_str (U->print_name);
}
U->first_name = fetch_str_dup (self);
U->last_name = fetch_str_dup (self);
U->print_name = create_print_name (U->id, U->first_name, U->last_name, 0, 0);
peer_insert_name ((void *)U);
U->print_name = create_print_name (bl, U->id, U->first_name, U->last_name, 0, 0);
peer_insert_name (bl, (void *)U);
} else {
fetch_skip_str (self);
fetch_skip_str (self);
@ -824,7 +826,7 @@ void work_update_binlog (struct mtproto_connection *self) {
case CODE_update_user_photo:
{
peer_id_t user_id = MK_USER (fetch_int (self));
peer_t *UC = user_chat_get (user_id);
peer_t *UC = user_chat_get (bl, user_id);
fetch_date (self);
if (UC) {
struct user *U = &UC->user;
@ -860,8 +862,9 @@ void work_update_binlog (struct mtproto_connection *self) {
}
void work_update (struct mtproto_connection *self, long long msg_id UU) {
struct connection *c UU = self->connection;
struct connection *c = self->connection;
struct telegram *tg = c->instance;
struct binlog *bl = self->bl;
unsigned op = fetch_int (self);
logprintf("work_update(): OP:%d\n", op);
@ -881,7 +884,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
{
int id = fetch_int (self); // id
int new = fetch_long (self); // random_id
struct message *M = message_get (new);
struct message *M = message_get (bl, new);
if (M) {
bl_do_set_msg_id (self->bl, self, M, id);
}
@ -894,7 +897,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
int i;
for (i = 0; i < n; i++) {
int id = fetch_int (self);
struct message *M = message_get (id);
struct message *M = message_get (bl, id);
if (M) {
bl_do_set_unread (self->bl, self, M, 0);
}
@ -913,7 +916,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
case CODE_update_user_typing:
{
peer_id_t id = MK_USER (fetch_int (self));
peer_t *U UU = user_chat_get (id);
peer_t *U UU = user_chat_get (bl, id);
event_update_user_typing (tg, U);
if (log_level >= 2) {
//print_start ();
@ -931,8 +934,8 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
{
peer_id_t chat_id = MK_CHAT (fetch_int (self));
peer_id_t id = MK_USER (fetch_int (self));
peer_t *C UU = user_chat_get (chat_id);
peer_t *U UU = user_chat_get (id);
peer_t *C UU = user_chat_get (bl, chat_id);
peer_t *U UU = user_chat_get (bl, id);
event_update_user_typing(tg, U);
if (log_level >= 2) {
//print_start ();
@ -951,7 +954,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
case CODE_update_user_status:
{
peer_id_t user_id = MK_USER (fetch_int (self));
peer_t *U = user_chat_get (user_id);
peer_t *U = user_chat_get (bl, user_id);
if (U) {
fetch_user_status (self, &U->user.status);
event_update_user_status(tg, U);
@ -975,7 +978,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
case CODE_update_user_name:
{
peer_id_t user_id = MK_USER (fetch_int (self));
peer_t *UC = user_chat_get (user_id);
peer_t *UC = user_chat_get (bl, user_id);
if (UC && (UC->flags & FLAG_CREATED)) {
int l1 = prefetch_strlen (self);
char *f = fetch_str (self, l1);
@ -1002,7 +1005,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
case CODE_update_user_photo:
{
peer_id_t user_id = MK_USER (fetch_int (self));
peer_t *UC = user_chat_get (user_id);
peer_t *UC = user_chat_get (bl, user_id);
fetch_date (self);
if (UC && (UC->flags & FLAG_CREATED)) {
struct user *U = &UC->user;
@ -1080,7 +1083,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
assert (x == CODE_chat_participants || x == CODE_chat_participants_forbidden);
peer_id_t chat_id = MK_CHAT (fetch_int (self));
int n = 0;
peer_t *C = user_chat_get (chat_id);
peer_t *C = user_chat_get (bl, chat_id);
if (C && (C->flags & FLAG_CREATED)) {
if (x == CODE_chat_participants) {
bl_do_set_chat_admin (self->bl, self, &C->chat, fetch_int (self));
@ -1123,7 +1126,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
case CODE_update_contact_registered:
{
peer_id_t user_id = MK_USER (fetch_int (self));
peer_t *U UU = user_chat_get (user_id);
peer_t *U UU = user_chat_get (bl, user_id);
fetch_int (self); // date
//print_start ();
//push_color (COLOR_YELLOW);
@ -1138,7 +1141,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
case CODE_update_contact_link:
{
peer_id_t user_id = MK_USER (fetch_int (self));
peer_t *U UU = user_chat_get (user_id);
peer_t *U UU = user_chat_get (bl, user_id);
//print_start ();
//push_color (COLOR_YELLOW);
//print_date (time (0));
@ -1162,7 +1165,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
case CODE_update_activation:
{
peer_id_t user_id = MK_USER (fetch_int (self));
peer_t *U UU = user_chat_get (user_id);
peer_t *U UU = user_chat_get (bl, user_id);
//print_start ();
//push_color (COLOR_YELLOW);
//print_date (time (0));
@ -1251,7 +1254,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
case CODE_update_encrypted_chat_typing:
{
peer_id_t id = MK_ENCR_CHAT (fetch_int (self));
peer_t *P = user_chat_get (id);
peer_t *P = user_chat_get (bl, id);
//print_start ();
//push_color (COLOR_YELLOW);
//print_date (time (0));
@ -1259,7 +1262,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
if (P) {
printf (" User ");
peer_id_t user_id UU = MK_USER (P->encr_chat.user_id);
//print_user_name (user_id, user_chat_get (user_id));
//print_user_name (user_id, user_chat_get (bl, user_id));
printf (" typing in secret chat ");
//print_encr_chat_name (id, P);
printf ("\n");
@ -1275,7 +1278,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
peer_id_t id = MK_ENCR_CHAT (fetch_int (self)); // chat_id
fetch_int (self); // max_date
fetch_int (self); // date
peer_t *P = user_chat_get (id);
peer_t *P = user_chat_get (bl, id);
int x = -1;
if (P && P->last) {
x = 0;
@ -1293,7 +1296,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
//push_color (COLOR_YELLOW);
//print_date (time (0));
printf (" Encrypted chat ");
//print_encr_chat_name_full (id, user_chat_get (id));
//print_encr_chat_name_full (id, user_chat_get (bl, id));
printf (": %d messages marked read \n", x);
//pop_color ();
//print_end ();
@ -1307,7 +1310,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
peer_id_t inviter_id = MK_USER (fetch_int (self));
int version = fetch_int (self);
peer_t *C = user_chat_get (chat_id);
peer_t *C = user_chat_get (bl, chat_id);
if (C && (C->flags & FLAG_CREATED)) {
bl_do_chat_add_user (self->bl, self, &C->chat, version, get_peer_id (user_id), get_peer_id (inviter_id), time (0));
}
@ -1316,11 +1319,11 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
//push_color (COLOR_YELLOW);
//print_date (time (0));
printf (" Chat ");
//print_chat_name (chat_id, user_chat_get (chat_id));
//print_chat_name (chat_id, user_chat_get (bl, chat_id));
printf (": user ");
//print_user_name (user_id, user_chat_get (user_id));
//print_user_name (user_id, user_chat_get (bl, user_id));
printf (" added by user ");
//print_user_name (inviter_id, user_chat_get (inviter_id));
//print_user_name (inviter_id, user_chat_get (bl, inviter_id));
printf ("\n");
//pop_color ();
//print_end ();
@ -1332,7 +1335,7 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
peer_id_t user_id = MK_USER (fetch_int (self));
int version = fetch_int (self);
peer_t *C = user_chat_get (chat_id);
peer_t *C = user_chat_get (bl, chat_id);
if (C && (C->flags & FLAG_CREATED)) {
bl_do_chat_del_user (self->bl, self, &C->chat, version, get_peer_id (user_id));
}
@ -1341,9 +1344,9 @@ void work_update (struct mtproto_connection *self, long long msg_id UU) {
//push_color (COLOR_YELLOW);
//print_date (time (0));
printf (" Chat ");
//print_chat_name (chat_id, user_chat_get (chat_id));
//print_chat_name (chat_id, user_chat_get (bl, chat_id));
printf (": user ");
//print_user_name (user_id, user_chat_get (user_id));
//print_user_name (user_id, user_chat_get (bl, user_id));
printf (" deleted\n");
//pop_color ();
//print_end ();
@ -1464,7 +1467,7 @@ void work_msgs_ack (struct connection *c UU, long long msg_id UU) {
for (i = 0; i < n; i++) {
long long id = fetch_long (c->mtconnection);
logprintf ("ack for %lld\n", id);
query_ack (id);
query_ack (c->instance, id);
}
}
@ -1474,9 +1477,9 @@ void work_rpc_result (struct connection *c UU, long long msg_id UU) {
long long id = fetch_long (c->mtconnection);
int op = prefetch_int (c->mtconnection);
if (op == CODE_rpc_error) {
query_error (id);
query_error (c->instance, id);
} else {
query_result (id);
query_result (c->instance, id);
}
}
@ -1510,7 +1513,7 @@ void work_packed (struct connection *c, long long msg_id) {
void work_bad_server_salt (struct connection *c UU, long long msg_id UU) {
assert (fetch_int (c->mtconnection) == (int)CODE_bad_server_salt);
long long id = fetch_long (c->mtconnection);
query_restart (id);
query_restart (c->instance, id);
fetch_int (c->mtconnection); // seq_no
fetch_int (c->mtconnection); // error_code
long long new_server_salt = fetch_long (c->mtconnection);
@ -1809,19 +1812,15 @@ struct connection_methods mtproto_methods = {
.close = rpc_close
};
// TODO: use a list or tree instead
struct mtproto_connection *Cs[100];
/**
* Create a new struct mtproto_connection connection using the giving datacenter for authorization and
* session handling
*/
struct mtproto_connection *mtproto_new(struct dc *DC, int fd, struct telegram *tg)
{
static int cs = 0;
struct mtproto_connection *mtp = talloc(sizeof(struct mtproto_connection));
Cs[cs++] = mtp;
memset(mtp, 0, sizeof(struct mtproto_connection));
struct mtproto_connection *mtp = talloc0(sizeof(struct mtproto_connection));
tg->Cs[tg->cs++] = mtp;
mtp->instance = tg;
mtp->packet_buffer = mtp->__packet_buffer + 16;
mtp->connection = fd_create_connection(DC, fd, tg, &mtproto_methods, mtp);
@ -1875,14 +1874,14 @@ void mtproto_destroy (struct mtproto_connection *self) {
void mtproto_free_closed () {
int i;
for (i = 0; i < 100; i++) {
if (Cs[i] == NULL) continue;
struct mtproto_connection *c = Cs[i];
if (tg->Cs[i] == NULL) continue;
struct mtproto_connection *c = tg->Cs[i];
logprintf ("checking mtproto_connection %d: c_state:%d destroy:%d, quries_num:%d\n",
i, c->c_state, c->destroy, c->queries_num);
if (c->destroy == 0) continue;
if (c->queries_num > 0) continue;
mtproto_destroy (c);
Cs[i] = NULL;
tg->Cs[i] = NULL;
}
}

View file

@ -213,6 +213,8 @@ struct mtproto_connection {
int longpoll_count, good_messages;
// TODO: decide whether this should be in struct telegram
// or in struct mtproto_client
int unread_messages;
int our_id;
int pts;
@ -243,6 +245,11 @@ struct mtproto_connection {
// marks this connection for destruction, so it
// will be freed once all queries received a response or timed out
int destroy;
//
// the corresponding telegram instance
//
struct telegram *instance;
};
void mtproto_connection_init (struct mtproto_connection *c);
@ -498,7 +505,7 @@ static inline void hexdump_out (struct mtproto_connection *self) {
#endif
void my_clock_gettime (int clock_id, struct timespec *T);
void mtproto_free_closed ();
void mtproto_free_closed (struct telegram *tg);
#endif

11
net.c
View file

@ -116,14 +116,14 @@ int ping_alarm (struct connection *c) {
}
void stop_ping_timer (struct connection *c) {
remove_event_timer (&c->ev);
remove_event_timer (c->instance, &c->ev);
}
void start_ping_timer (struct connection *c) {
c->ev.timeout = get_double_time () + PING_TIMEOUT;
c->ev.alarm = (void *)ping_alarm;
c->ev.self = c;
insert_event_timer (&c->ev);
insert_event_timer (c->instance, &c->ev);
}
void restart_connection (struct connection *c);
@ -138,7 +138,7 @@ void start_fail_timer (struct connection *c) {
c->ev.timeout = get_double_time () + 10;
c->ev.alarm = (void *)fail_alarm;
c->ev.self = c;
insert_event_timer (&c->ev);
insert_event_timer (c->instance, &c->ev);
}
struct connection_buffer *new_connection_buffer (int size) {
@ -636,18 +636,17 @@ int send_all_acks (struct session *S) {
void insert_msg_id (struct session *S, long long id) {
if (!S->ack_tree) {
logprintf ("Creating ack_tree pointing to session %p\n");
S->ev.alarm = (void *)send_all_acks;
S->ev.self = (void *)S;
S->ev.timeout = get_double_time () + ACK_TIMEOUT;
insert_event_timer (&S->ev);
insert_event_timer (S->c->instance, &S->ev);
}
if (!tree_lookup_long (S->ack_tree, id)) {
S->ack_tree = tree_insert_long (S->ack_tree, id, lrand48 ());
}
}
extern struct dc *DC_list[];
struct dc *alloc_dc (struct dc* DC_list[], int id, char *ip, int port UU) {
assert (!DC_list[id]);
struct dc *DC = talloc0 (sizeof (*DC));

498
queries.c

File diff suppressed because it is too large Load diff

View file

@ -22,11 +22,12 @@
#pragma once
#include "structures.h"
// forward declare telegram
struct telegram;
struct encr_video;
struct document;
struct secret_chat;
struct tree_query;
struct tree_timer;
#define QUERY_ACK_RECEIVED 1
@ -57,16 +58,16 @@ struct query {
};
struct query *send_query (struct dc *DC, int len, void *data, struct query_methods *methods, void *extra);
void query_ack (long long id);
void query_error (long long id);
void query_result (long long id);
void query_restart (long long id);
struct query *send_query (struct telegram *instance, struct dc *DC, int len, void *data, struct query_methods *methods, void *extra);
void query_ack (struct telegram *instance, long long id);
void query_error (struct telegram *instance, long long id);
void query_result (struct telegram *instance, long long id);
void query_restart (struct telegram *instance, long long id);
void insert_event_timer (struct event_timer *ev);
void remove_event_timer (struct event_timer *ev);
double next_timer_in (void);
void work_timers (void);
void insert_event_timer (struct telegram *instance, struct event_timer *ev);
void remove_event_timer (struct telegram *instance, struct event_timer *ev);
double next_timer_in (struct telegram *instance);
void work_timers (struct telegram *instance);
extern struct query_methods help_get_config_methods;
@ -113,8 +114,8 @@ void do_msg_search (struct telegram *instance, peer_id_t id, int from, int to, i
void do_accept_encr_chat_request (struct telegram *instance, struct secret_chat *E);
void do_get_difference (struct telegram*);
void do_mark_read (struct telegram *instance, peer_id_t id);
void do_visualize_key (peer_id_t id);
void do_create_keys_end (struct secret_chat *U);
void do_visualize_key (struct binlog *bl, peer_id_t id);
void do_create_keys_end (struct telegram *, struct secret_chat *U);
void do_add_user_to_chat (struct telegram *instance, peer_id_t chat_id, peer_id_t id, int limit);
void do_del_user_from_chat (struct telegram *instance, peer_id_t chat_id, peer_id_t id);
@ -128,6 +129,8 @@ void do_restore_msg (struct telegram *instance, long long id);
int get_dh_config_on_answer (struct query *q);
void fetch_dc_option (struct telegram *instance);
void free_queries (struct telegram *instance);
void free_timers (struct telegram *instance);
#endif
const char *get_last_err();

View file

@ -45,24 +45,8 @@ struct message message_list = {
.prev_use = &message_list
};
struct tree_peer *peer_tree;
struct tree_peer_by_name *peer_by_name_tree;
struct tree_message *message_tree;
struct tree_message *message_unsent_tree;
int users_allocated;
int chats_allocated;
int messages_allocated;
int peer_num;
int encr_chats_allocated;
int geo_chats_allocated;
int our_id;
int verbosity;
peer_t *Peers[MAX_PEER_NUM];
void fetch_skip_photo (struct mtproto_connection *mtp);
#define code_assert(x) if (!(x)) { logprintf ("Can not parse at line %d\n", __LINE__); assert (0); return -1; }
@ -141,7 +125,7 @@ int fetch_skip_user_status (struct mtproto_connection *mtp) {
return 0;
}
char *create_print_name (peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4) {
char *create_print_name (struct binlog *bl, peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4) {
const char *d[4];
d[0] = a1; d[1] = a2; d[2] = a3; d[3] = a4;
static char buf[10000];
@ -163,7 +147,7 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha
int fl = strlen (s);
int cc = 0;
while (1) {
peer_t *P = peer_lookup_name (s);
peer_t *P = peer_lookup_name (bl, s);
if (!P || !cmp_peer_id (P->id, id)) {
break;
}
@ -216,6 +200,8 @@ int user_get_alias(peer_t *user, char *buffer, int maxlen)
}
int fetch_user (struct mtproto_connection *mtp, struct user *U) {
struct telegram *instance = mtp->instance;
unsigned x = fetch_int (mtp);
code_assert (x == CODE_user_empty || x == CODE_user_self || x == CODE_user_contact || x == CODE_user_request || x == CODE_user_foreign || x == CODE_user_deleted);
U->id = MK_USER (fetch_int (mtp));
@ -224,8 +210,8 @@ int fetch_user (struct mtproto_connection *mtp, struct user *U) {
}
if (x == CODE_user_self) {
assert (!our_id || (our_id == get_peer_id (U->id)));
if (!our_id) {
assert (!instance->our_id || (instance->our_id == get_peer_id (U->id)));
if (!instance->our_id) {
bl_do_set_our_id (mtp->bl, mtp, get_peer_id (U->id));
// TODO: What to do here?
//write_auth_file ();
@ -306,6 +292,8 @@ int fetch_user (struct mtproto_connection *mtp, struct user *U) {
}
void fetch_encrypted_chat (struct mtproto_connection *mtp, struct secret_chat *U) {
struct telegram *instance = mtp->instance;
unsigned x = fetch_int (mtp);
assert (x == CODE_encrypted_chat_empty || x == CODE_encrypted_chat_waiting || x == CODE_encrypted_chat_requested || x == CODE_encrypted_chat || x == CODE_encrypted_chat_discarded);
U->id = MK_ENCR_CHAT (fetch_int (mtp));
@ -322,7 +310,7 @@ void fetch_encrypted_chat (struct mtproto_connection *mtp, struct secret_chat *U
bl_do_encr_chat_delete (mtp->bl, mtp, U);
// TODO: properly
write_secret_chat_file ("/home/dev-jessie/.telegram/+4915736384600/secret");
write_secret_chat_file (instance, "/home/dev-jessie/.telegram/+4915736384600/secret");
return;
}
@ -332,7 +320,7 @@ void fetch_encrypted_chat (struct mtproto_connection *mtp, struct secret_chat *U
long long access_hash = fetch_long (mtp);
int date = fetch_int (mtp);
int admin_id = fetch_int (mtp);
int user_id = fetch_int (mtp) + admin_id - our_id;
int user_id = fetch_int (mtp) + admin_id - instance->our_id;
if (x == CODE_encrypted_chat_waiting) {
logprintf ("Unknown chat in waiting state. May be we forgot something...\n");
@ -371,7 +359,7 @@ void fetch_encrypted_chat (struct mtproto_connection *mtp, struct secret_chat *U
}
bl_do_encr_chat_requested (mtp->bl, mtp, U, access_hash, date, admin_id, user_id, (void *)g_key, (void *)nonce);
write_secret_chat_file ("/home/dev-jessie/.telegram/+4915736384600/secret");
write_secret_chat_file (instance, "/home/dev-jessie/.telegram/+4915736384600/secret");
} else {
bl_do_set_encr_chat_access_hash (mtp->bl, mtp, U, fetch_long (mtp));
bl_do_set_encr_chat_date (mtp->bl, mtp, U, fetch_int (mtp));
@ -379,13 +367,13 @@ void fetch_encrypted_chat (struct mtproto_connection *mtp, struct secret_chat *U
logprintf ("Changed admin in secret chat. WTF?\n");
return;
}
if (U->user_id != U->admin_id + fetch_int (mtp) - our_id) {
if (U->user_id != U->admin_id + fetch_int (mtp) - instance->our_id) {
logprintf ("Changed partner in secret chat. WTF?\n");
return;
}
if (x == CODE_encrypted_chat_waiting) {
bl_do_set_encr_chat_state (mtp->bl, mtp, U, sc_waiting);
write_secret_chat_file ("/home/dev-jessie/.telegram/+4915736384600/secret");
write_secret_chat_file (instance, "/home/dev-jessie/.telegram/+4915736384600/secret");
return; // We needed only access hash from here
}
@ -417,7 +405,7 @@ void fetch_encrypted_chat (struct mtproto_connection *mtp, struct secret_chat *U
}
bl_do_encr_chat_accepted (mtp->bl, mtp, U, (void *)g_key, (void *)nonce, fetch_long (mtp));
}
write_secret_chat_file ("/home/dev-jessie/.telegram/+4915736384600/secret");
write_secret_chat_file (instance, "/home/dev-jessie/.telegram/+4915736384600/secret");
}
void fetch_notify_settings (struct mtproto_connection *mtp);
@ -870,12 +858,14 @@ void fetch_skip_message_action (struct mtproto_connection *mtp) {
}
void fetch_message_short (struct mtproto_connection *mtp, struct message *M) {
struct telegram *instance = mtp->instance;
int new = !(M->flags & FLAG_CREATED);
if (new) {
int id = fetch_int (mtp);
int from_id = fetch_int (mtp);
int to_id = our_id;
int to_id = instance->our_id;
int l = prefetch_strlen (mtp);
char *s = fetch_str (mtp, l);
@ -1405,6 +1395,8 @@ int decrypt_encrypted_message (struct secret_chat *E) {
}
void fetch_encrypted_message (struct mtproto_connection *mtp, struct message *M) {
struct binlog *bl = mtp->bl;
unsigned x = fetch_int (mtp);
assert (x == CODE_encrypted_message || x == CODE_encrypted_message_service);
unsigned sx = x;
@ -1414,7 +1406,7 @@ void fetch_encrypted_message (struct mtproto_connection *mtp, struct message *M)
peer_id_t chat = MK_ENCR_CHAT (to_id);
int date = fetch_int (mtp);
peer_t *P = user_chat_get (chat);
peer_t *P = user_chat_get (bl, chat);
if (!P) {
logprintf ("Encrypted message to unknown chat. Dropping\n");
M->flags |= FLAG_MESSAGE_EMPTY;
@ -1530,17 +1522,19 @@ static int id_cmp (struct message *M1, struct message *M2) {
}
struct user *fetch_alloc_user (struct mtproto_connection *mtp) {
struct binlog *bl = mtp->instance->bl;
logprintf("fetch_alloc_user()\n");
int data[2];
prefetch_data (mtp, data, 8);
peer_t *U = user_chat_get (MK_USER (data[1]));
peer_t *U = user_chat_get (bl, MK_USER (data[1]));
if (!U) {
users_allocated ++;
bl->users_allocated ++;
U = talloc0 (sizeof (*U));
U->id = MK_USER (data[1]);
peer_tree = tree_insert_peer (peer_tree, U, lrand48 ());
assert (peer_num < MAX_PEER_NUM);
Peers[peer_num ++] = U;
bl->peer_tree = tree_insert_peer (bl->peer_tree, U, lrand48 ());
assert (bl->peer_num < MAX_PEER_NUM);
bl->Peers[bl->peer_num ++] = U;
fetch_user (mtp, &U->user);
event_update_user_status(mtp->connection->instance, U);
event_peer_allocated(mtp->connection->instance, U);
@ -1552,59 +1546,62 @@ struct user *fetch_alloc_user (struct mtproto_connection *mtp) {
}
struct secret_chat *fetch_alloc_encrypted_chat (struct mtproto_connection *mtp) {
struct binlog *bl = mtp->bl;
logprintf("fetch_alloc_encrypted_chat()\n");
int data[2];
prefetch_data (mtp, data, 8);
peer_t *U = user_chat_get (MK_ENCR_CHAT (data[1]));
peer_t *U = user_chat_get (bl, MK_ENCR_CHAT (data[1]));
if (!U) {
U = talloc0 (sizeof (*U));
U->id = MK_ENCR_CHAT (data[1]);
encr_chats_allocated ++;
peer_tree = tree_insert_peer (peer_tree, U, lrand48 ());
assert (peer_num < MAX_PEER_NUM);
Peers[peer_num ++] = U;
bl->encr_chats_allocated ++;
bl->peer_tree = tree_insert_peer (bl->peer_tree, U, lrand48 ());
assert (bl->peer_num < MAX_PEER_NUM);
bl->Peers[bl->peer_num ++] = U;
}
fetch_encrypted_chat (mtp, &U->encr_chat);
event_peer_allocated(mtp->connection->instance, U);
return &U->encr_chat;
}
void insert_encrypted_chat (peer_t *P) {
encr_chats_allocated ++;
peer_tree = tree_insert_peer (peer_tree, P, lrand48 ());
assert (peer_num < MAX_PEER_NUM);
Peers[peer_num ++] = P;
void insert_encrypted_chat (struct binlog *bl, peer_t *P) {
bl->encr_chats_allocated ++;
bl->peer_tree = tree_insert_peer (bl->peer_tree, P, lrand48 ());
assert (bl->peer_num < MAX_PEER_NUM);
bl->Peers[bl->peer_num ++] = P;
}
void insert_user (peer_t *P) {
users_allocated ++;
peer_tree = tree_insert_peer (peer_tree, P, lrand48 ());
assert (peer_num < MAX_PEER_NUM);
Peers[peer_num ++] = P;
void insert_user (struct binlog *bl, peer_t *P) {
bl->users_allocated ++;
bl->peer_tree = tree_insert_peer (bl->peer_tree, P, lrand48 ());
assert (bl->peer_num < MAX_PEER_NUM);
bl->Peers[bl->peer_num ++] = P;
}
void insert_chat (peer_t *P) {
chats_allocated ++;
peer_tree = tree_insert_peer (peer_tree, P, lrand48 ());
assert (peer_num < MAX_PEER_NUM);
Peers[peer_num ++] = P;
void insert_chat (struct binlog *bl, peer_t *P) {
bl->chats_allocated ++;
bl->peer_tree = tree_insert_peer (bl->peer_tree, P, lrand48 ());
assert (bl->peer_num < MAX_PEER_NUM);
bl->Peers[bl->peer_num ++] = P;
}
struct user *fetch_alloc_user_full (struct mtproto_connection *mtp) {
struct binlog *bl = mtp->bl;
int data[3];
prefetch_data (mtp, data, 12);
peer_t *U = user_chat_get (MK_USER (data[2]));
peer_t *U = user_chat_get (bl, MK_USER (data[2]));
if (U) {
fetch_user_full (mtp, &U->user);
return &U->user;
} else {
users_allocated ++;
bl->users_allocated ++;
U = talloc0 (sizeof (*U));
U->id = MK_USER (data[2]);
peer_tree = tree_insert_peer (peer_tree, U, lrand48 ());
bl->peer_tree = tree_insert_peer (bl->peer_tree, U, lrand48 ());
fetch_user_full (mtp, &U->user);
assert (peer_num < MAX_PEER_NUM);
Peers[peer_num ++] = U;
assert (bl->peer_num < MAX_PEER_NUM);
bl->Peers[bl->peer_num ++] = U;
return &U->user;
}
}
@ -1735,33 +1732,34 @@ void message_add_use (struct message *M) {
}
void message_add_peer (struct message *M) {
struct binlog *bl = M->instance->bl;
peer_id_t id;
if (!cmp_peer_id (M->to_id, MK_USER (our_id))) {
if (!cmp_peer_id (M->to_id, MK_USER (M->instance->our_id))) {
id = M->from_id;
} else {
id = M->to_id;
}
peer_t *P = user_chat_get (id);
peer_t *P = user_chat_get (bl, id);
if (!P) {
P = talloc0 (sizeof (*P));
P->id = id;
switch (get_peer_type (id)) {
case PEER_USER:
users_allocated ++;
bl->users_allocated ++;
break;
case PEER_CHAT:
chats_allocated ++;
bl->chats_allocated ++;
break;
case PEER_GEO_CHAT:
geo_chats_allocated ++;
bl->geo_chats_allocated ++;
break;
case PEER_ENCR_CHAT:
encr_chats_allocated ++;
bl->encr_chats_allocated ++;
break;
}
peer_tree = tree_insert_peer (peer_tree, P, lrand48 ());
assert (peer_num < MAX_PEER_NUM);
Peers[peer_num ++] = P;
bl->peer_tree = tree_insert_peer (bl->peer_tree, P, lrand48 ());
assert (bl->peer_num < MAX_PEER_NUM);
bl->Peers[bl->peer_num ++] = P;
}
if (!P->last) {
P->last = M;
@ -1794,12 +1792,12 @@ void message_add_peer (struct message *M) {
void message_del_peer (struct message *M) {
peer_id_t id;
if (!cmp_peer_id (M->to_id, MK_USER (our_id))) {
if (!cmp_peer_id (M->to_id, MK_USER (M->instance->our_id))) {
id = M->from_id;
} else {
id = M->to_id;
}
peer_t *P = user_chat_get (id);
peer_t *P = user_chat_get (M->instance->bl, id);
if (M->prev) {
M->prev->next = M->next;
}
@ -1812,19 +1810,20 @@ void message_del_peer (struct message *M) {
}
struct message *fetch_alloc_message (struct mtproto_connection *mtp, struct telegram *instance) {
struct binlog *bl = mtp->bl;
logprintf("fetch_alloc_message()\n");
int data[2];
prefetch_data (mtp, data, 8);
struct message *M = message_get (data[1]);
struct message *M = message_get (bl, data[1]);
if (!M) {
M = talloc0 (sizeof (*M));
M->id = data[1];
M->instance = instance;
message_insert_tree (M);
messages_allocated ++;
mtp->bl->messages_allocated ++;
fetch_message (mtp, M);
event_update_new_message (instance, M);
return M;
}
M->instance = instance;
@ -1837,8 +1836,8 @@ struct message *fetch_alloc_geo_message (struct mtproto_connection *mtp, struct
struct message *M = talloc (sizeof (*M));
M->instance = instance;
fetch_geo_message (mtp, M);
struct message *M1 = tree_lookup_message (message_tree, M);
messages_allocated ++;
struct message *M1 = tree_lookup_message (mtp->bl->message_tree, M);
mtp->bl->messages_allocated ++;
if (M1) {
message_del_use (M1);
message_del_peer (M1);
@ -1847,30 +1846,31 @@ struct message *fetch_alloc_geo_message (struct mtproto_connection *mtp, struct
tfree (M, sizeof (*M));
message_add_use (M1);
message_add_peer (M1);
messages_allocated --;
mtp->bl->messages_allocated --;
return M1;
} else {
message_add_use (M);
message_add_peer (M);
message_tree = tree_insert_message (message_tree, M, lrand48 ());
mtp->bl->message_tree = tree_insert_message (mtp->bl->message_tree, M, lrand48 ());
return M;
}
}
struct message *fetch_alloc_encrypted_message (struct mtproto_connection *mtp,
struct telegram *instance) {
struct binlog *bl = mtp->bl;
logprintf("fetch_alloc_encrypted_message()\n");
int data[3];
prefetch_data (mtp, data, 12);
struct message *M = message_get (*(long long *)(data + 1));
struct message *M = message_get (bl, *(long long *)(data + 1));
M->instance = instance;
if (!M) {
M = talloc0 (sizeof (*M));
M->id = *(long long *)(data + 1);
message_insert_tree (M);
messages_allocated ++;
assert (message_get (M->id) == M);
mtp->bl->messages_allocated ++;
assert (message_get (bl, M->id) == M);
logprintf ("id = %lld\n", M->id);
}
fetch_encrypted_message (mtp, M);
@ -1879,51 +1879,54 @@ struct message *fetch_alloc_encrypted_message (struct mtproto_connection *mtp,
struct message *fetch_alloc_message_short (struct mtproto_connection *mtp,
struct telegram *instance) {
struct binlog *bl = mtp->bl;
int data[1];
prefetch_data (mtp, data, 4);
struct message *M = message_get (data[0]);
struct message *M = message_get (bl, data[0]);
M->instance = instance;
if (!M) {
M = talloc0 (sizeof (*M));
M->id = data[0];
message_insert_tree (M);
messages_allocated ++;
mtp->bl->messages_allocated ++;
}
fetch_message_short (mtp, M);
return M;
}
struct message *fetch_alloc_message_short_chat (struct mtproto_connection *mtp, struct telegram *instance) {
struct binlog *bl = mtp->bl;
int data[1];
prefetch_data (mtp, data, 4);
struct message *M = message_get (data[0]);
struct message *M = message_get (bl, data[0]);
M->instance = instance;
if (!M) {
M = talloc0 (sizeof (*M));
M->id = data[0];
message_insert_tree (M);
messages_allocated ++;
mtp->bl->messages_allocated ++;
}
fetch_message_short_chat (mtp, M);
return M;
}
struct chat *fetch_alloc_chat (struct mtproto_connection *mtp) {
struct binlog *bl = mtp->bl;
logprintf("fetch_alloc_chat()\n");
int data[2];
prefetch_data (mtp, data, 8);
peer_t *U = user_chat_get (MK_CHAT (data[1]));
peer_t *U = user_chat_get (bl, MK_CHAT (data[1]));
logprintf("id %d\n", U->id.id);
logprintf("type %d\n", U->id.type);
if (!U) {
chats_allocated ++;
bl->chats_allocated ++;
U = talloc0 (sizeof (*U));
U->id = MK_CHAT (data[1]);
peer_tree = tree_insert_peer (peer_tree, U, lrand48 ());
assert (peer_num < MAX_PEER_NUM);
Peers[peer_num ++] = U;
bl->peer_tree = tree_insert_peer (bl->peer_tree, U, lrand48 ());
assert (bl->peer_num < MAX_PEER_NUM);
bl->Peers[bl->peer_num ++] = U;
}
fetch_chat (mtp, &U->chat);
event_peer_allocated(mtp->connection->instance, U);
@ -1931,20 +1934,21 @@ struct chat *fetch_alloc_chat (struct mtproto_connection *mtp) {
}
struct chat *fetch_alloc_chat_full (struct mtproto_connection *mtp) {
struct binlog *bl = mtp->bl;
int data[3];
prefetch_data (mtp, data, 12);
peer_t *U = user_chat_get (MK_CHAT (data[2]));
peer_t *U = user_chat_get (bl, MK_CHAT (data[2]));
if (U) {
fetch_chat_full (mtp, &U->chat);
return &U->chat;
} else {
chats_allocated ++;
bl->chats_allocated ++;
U = talloc0 (sizeof (*U));
U->id = MK_CHAT (data[2]);
peer_tree = tree_insert_peer (peer_tree, U, lrand48 ());
bl->peer_tree = tree_insert_peer (bl->peer_tree, U, lrand48 ());
fetch_chat_full (mtp, &U->chat);
assert (peer_num < MAX_PEER_NUM);
Peers[peer_num ++] = U;
assert (bl->peer_num < MAX_PEER_NUM);
bl->Peers[bl->peer_num ++] = U;
return &U->chat;
}
}
@ -1954,47 +1958,50 @@ void free_chat (struct chat *U) {
if (U->print_title) { tfree_str (U->print_title); }
}
int print_stat (char *s, int len) {
int print_stat (struct binlog *bl, char *s, int len) {
return tsnprintf (s, len,
"users_allocated\t%d\n"
"chats_allocated\t%d\n"
"secret_chats_allocated\t%d\n"
"peer_num\t%d\n"
"messages_allocated\t%d\n",
users_allocated,
chats_allocated,
encr_chats_allocated,
peer_num,
messages_allocated
);
"bl->users_allocated\t%d\n"
"bl->chats_allocated\t%d\n"
"secret_bl->chats_allocated\t%d\n"
"bl->peer_num\t%d\n"
"bl->messages_allocated\t%d\n",
bl->users_allocated,
bl->chats_allocated,
bl->encr_chats_allocated,
bl->peer_num,
bl->messages_allocated
);
}
peer_t *user_chat_get (peer_id_t id) {
peer_t *user_chat_get (struct binlog *bl, peer_id_t id) {
static peer_t U;
U.id = id;
return tree_lookup_peer (peer_tree, &U);
return tree_lookup_peer (bl->peer_tree, &U);
}
struct message *message_get (long long id) {
struct message *message_get (struct binlog *bl, long long id) {
struct message M;
M.id = id;
return tree_lookup_message (message_tree, &M);
return tree_lookup_message (bl->message_tree, &M);
}
void update_message_id (struct message *M, long long id) {
message_tree = tree_delete_message (message_tree, M);
struct binlog *bl = M->instance->bl;
bl->message_tree = tree_delete_message (bl->message_tree, M);
M->id = id;
message_tree = tree_insert_message (message_tree, M, lrand48 ());
bl->message_tree = tree_insert_message (bl->message_tree, M, lrand48 ());
}
void message_insert_tree (struct message *M) {
struct binlog *bl = M->instance->bl;
assert (M->id);
message_tree = tree_insert_message (message_tree, M, lrand48 ());
bl->message_tree = tree_insert_message (bl->message_tree, M, lrand48 ());
}
void message_remove_tree (struct message *M) {
struct binlog *bl = M->instance->bl;
assert (M->id);
message_tree = tree_delete_message (message_tree, M);
bl->message_tree = tree_delete_message (bl->message_tree, M);
}
void message_insert (struct message *M) {
@ -2003,11 +2010,13 @@ void message_insert (struct message *M) {
}
void message_insert_unsent (struct message *M) {
message_unsent_tree = tree_insert_message (message_unsent_tree, M, lrand48 ());
struct binlog *bl = M->instance->bl;
bl->message_unsent_tree = tree_insert_message (bl->message_unsent_tree, M, lrand48 ());
}
void message_remove_unsent (struct message *M) {
message_unsent_tree = tree_delete_message (message_unsent_tree, M);
struct binlog *bl = M->instance->bl;
bl->message_unsent_tree = tree_delete_message (bl->message_unsent_tree, M);
}
void __send_msg (struct message *M) {
@ -2018,25 +2027,54 @@ void __send_msg (struct message *M) {
do_send_msg (M->instance, M);
}
void send_all_unsent (void ) {
tree_act_message (message_unsent_tree, __send_msg);
void send_all_unsent (struct binlog *bl) {
tree_act_message (bl->message_unsent_tree, __send_msg);
}
void peer_insert_name (peer_t *P) {
void peer_insert_name (struct binlog *bl, peer_t *P) {
//if (!P->print_name || !strlen (P->print_name)) { return; }
//logprintf ("+%s\n", P->print_name);
peer_by_name_tree = tree_insert_peer_by_name (peer_by_name_tree, P, lrand48 ());
bl->peer_by_name_tree = tree_insert_peer_by_name (bl->peer_by_name_tree, P, lrand48 ());
}
void peer_delete_name (peer_t *P) {
void peer_delete_name (struct binlog *bl, peer_t *P) {
//if (!P->print_name || !strlen (P->print_name)) { return; }
//logprintf ("-%s\n", P->print_name);
peer_by_name_tree = tree_delete_peer_by_name (peer_by_name_tree, P);
bl->peer_by_name_tree = tree_delete_peer_by_name (bl->peer_by_name_tree, P);
}
peer_t *peer_lookup_name (const char *s) {
peer_t *peer_lookup_name (struct binlog *bl, const char *s) {
static peer_t P;
P.print_name = (void *)s;
peer_t *R = tree_lookup_peer_by_name (peer_by_name_tree, &P);
peer_t *R = tree_lookup_peer_by_name (bl->peer_by_name_tree, &P);
return R;
}
void free_messages (struct binlog *bl)
{
while (bl->message_tree) {
struct message *M = tree_get_min_message (bl->message_tree);
assert (M);
logprintf ("freeing message: %lld\n", M->id);
bl->message_tree = tree_delete_message (bl->message_tree, M);
bl->messages_allocated --;
free_message (M);
}
}
void free_peers (struct binlog *bl)
{
while (bl->peer_by_name_tree) {
bl->peer_by_name_tree = tree_delete_peer_by_name (bl->peer_by_name_tree,
tree_get_min_peer_by_name(bl->peer_by_name_tree));
}
while (bl->peer_tree) {
union peer *P = tree_get_min_peer (bl->peer_tree);
assert (P);
bl->peer_tree = tree_delete_peer (bl->peer_tree, P);
bl->peer_num --;
free (P->print_name);
tfree (P, sizeof (union peer));
}
}

View file

@ -22,6 +22,7 @@
// forward-declrataions
struct mtproto_connection;
struct binlog;
typedef struct { int type; int id; } peer_id_t;
#include <assert.h>
@ -44,6 +45,7 @@ typedef struct { int type; int id; } peer_id_t;
#define FLAG_ENCRYPTED 4096
#define FLAG_PENDING 8192
struct file_location {
int dc;
long long volume;
@ -359,29 +361,29 @@ void message_insert_tree (struct message *M);
void free_user (struct user *U);
void free_chat (struct chat *U);
char *create_print_name (peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
char *create_print_name (struct binlog *bl, peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
int print_stat (char *s, int len);
peer_t *user_chat_get (peer_id_t id);
struct message *message_get (long long id);
int print_stat (struct binlog *bl, char *s, int len);
peer_t *user_chat_get (struct binlog *bl, peer_id_t id);
struct message *message_get (struct binlog *bl, long long id);
void update_message_id (struct message *M, long long id);
void message_insert (struct message *M);
void fetch_photo (struct mtproto_connection *mtp, struct photo *P);
void insert_encrypted_chat (peer_t *P);
void insert_user (peer_t *P);
void insert_chat (peer_t *P);
void insert_encrypted_chat (struct binlog *bl, peer_t *P);
void insert_user (struct binlog *bl, peer_t *P);
void insert_chat (struct binlog *bl, peer_t *P);
void free_photo (struct photo *P);
void message_insert_unsent (struct message *M);
void message_remove_unsent (struct message *M);
void send_all_unsent (void);
void send_all_unsent (struct binlog *bl);
void message_remove_tree (struct message *M);
void message_add_peer (struct message *M);
void message_del_peer (struct message *M);
void free_message (struct message *M);
void message_del_use (struct message *M);
void peer_insert_name (peer_t *P);
void peer_delete_name (peer_t *P);
peer_t *peer_lookup_name (const char *s);
void peer_insert_name (struct binlog *bl, peer_t *P);
void peer_delete_name (struct binlog *bl, peer_t *P);
peer_t *peer_lookup_name (struct binlog *bl, const char *s);
int user_get_alias(peer_t *user, char *buffer, int maxlen);

View file

@ -8,6 +8,7 @@
#ifndef __TELEGRAM_H__
#define __TELEGRAM_H__
#define MAX_PACKED_SIZE (1 << 24)
#define MAX_DC_NUM 9
#define MAX_PEER_NUM 100000
@ -18,12 +19,17 @@
#include <sys/types.h>
#include "glib.h"
#include "loop.h"
//#include "mtproto-client.h"
#include "tree.h"
#include "queries.h"
#include <openssl/bn.h>
// forward declarations
struct message;
struct protocol_state;
struct authorization_state;
struct tree_query;
struct tree_timer;
/*
* telegram states
@ -65,11 +71,15 @@ struct authorization_state;
// Ready for sending and receiving messages
#define STATE_READY 22
struct tree_peer;
struct tree_peer_by_name;
struct tree_message;
#define BINLOG_BUFFER_SIZE (1 << 20)
/**
* Binary log
*/
#define BINLOG_BUFFER_SIZE (1 << 20)
struct binlog {
int binlog_buffer[BINLOG_BUFFER_SIZE];
int *rptr;
@ -81,6 +91,21 @@ struct binlog {
long long binlog_pos;
int s[1000];
//
struct tree_peer *peer_tree;
struct tree_peer_by_name *peer_by_name_tree;
struct tree_message *message_tree;
struct tree_message *message_unsent_tree;
int users_allocated;
int chats_allocated;
int messages_allocated;
int peer_num;
int encr_chats_allocated;
int geo_chats_allocated;
peer_t *Peers[MAX_PEER_NUM];
};
struct telegram;
@ -105,13 +130,13 @@ struct telegram_config {
* and port by calling telegram_set_proxy. This is useful for tunelling
* the connection through a proxy server.
*/
void (*proxy_request_cb)(struct telegram *instance, const char *ip, int port);
void (*proxy_request_cb) (struct telegram *instance, const char *ip, int port);
/**
* A callback function that is called once the proxy connection is no longer
* needed. This is useful for freeing all used resources.
*/
void (*proxy_close_cb)(struct telegram *instance, int fd);
void (*proxy_close_cb) (struct telegram *instance, int fd);
/**
* A callback function that is called when a phone registration is required.
@ -143,13 +168,13 @@ struct telegram_config {
* A callback function that is called when a new message was allocated. This is useful
* for adding new messages to the GUI.
*/
void (*on_msg_handler)(struct telegram *instance, struct message *M);
void (*on_msg_handler) (struct telegram *instance, struct message *M);
/**
* A callback function that is called when a new peer was allocated. This is useful
* for populating the GUI with new peers.
*/
void (*on_peer_allocated_handler)(struct telegram *instance, void *peer);
void (*on_peer_allocated_handler) (struct telegram *instance, void *peer);
/**
* A callback function that is called when a user's status has changed
@ -202,6 +227,40 @@ struct telegram {
// valid in its context
char *phone_code_hash;
int unread_messages;
long long cur_uploading_bytes;
long long cur_uploaded_bytes;
long long cur_downloading_bytes;
long long cur_downloaded_bytes;
int our_id;
struct user User;
BN_CTX *ctx;
int encr_root;
unsigned char *encr_prime;
int encr_param_version;
int max_chat_size;
int max_bcast_size;
int want_dc_num;
int new_dc_num;
int out_message_num;
char *suser;
int nearest_dc_num;
int packed_buffer[MAX_PACKED_SIZE / 4];
struct tree_query *queries_tree;
struct tree_timer *timer_tree;
char *export_auth_str;
int export_auth_str_len;
char g_a[256];
// do_get_difference
int get_difference_active;
struct message *ML[MSG_STORE_SIZE];
int cs;
struct mtproto_connection *Cs[100];
/*
* additional user data
*/
void *extra;
};