diff --git a/binlog.c b/binlog.c index 84915e6..11b5a3f 100644 --- a/binlog.c +++ b/binlog.c @@ -37,11 +37,6 @@ #include -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) { diff --git a/loop.c b/loop.c index c2a72bf..bdeea3f 100644 --- a/loop.c +++ b/loop.c @@ -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; diff --git a/mtproto-client.c b/mtproto-client.c index e787362..411ec79 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -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; } } diff --git a/mtproto-client.h b/mtproto-client.h index 2130ec5..5fdcebe 100644 --- a/mtproto-client.h +++ b/mtproto-client.h @@ -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 diff --git a/net.c b/net.c index fad9eb5..d935d1f 100644 --- a/net.c +++ b/net.c @@ -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)); diff --git a/queries.c b/queries.c index 6389dac..63e0a4f 100644 --- a/queries.c +++ b/queries.c @@ -62,11 +62,6 @@ int verbosity; extern int offline_mode; int offline_mode = 0; -long long cur_uploading_bytes; -long long cur_uploaded_bytes; -long long cur_downloading_bytes; -long long cur_downloaded_bytes; - extern int sync_from_start; int sync_from_start = 0; @@ -74,12 +69,14 @@ void telegram_flush_queries (struct telegram *instance) { instance->config->on_output(instance); } -void out_peer_id (struct mtproto_connection *self, peer_id_t id); -#define QUERY_TIMEOUT 6.0 - #define memcmp8(a,b) memcmp ((a), (b), 8) DEFINE_TREE (query, struct query *, memcmp8, 0) ; -struct tree_query *queries_tree; + +#define event_timer_cmp(a,b) ((a)->timeout > (b)->timeout ? 1 : ((a)->timeout < (b)->timeout ? -1 : (memcmp (a, b, sizeof (struct event_timer))))) +DEFINE_TREE (timer, struct event_timer *, event_timer_cmp, 0) + +void out_peer_id (struct mtproto_connection *self, peer_id_t id); +#define QUERY_TIMEOUT 6.0 /** * Get the struct mtproto_connection connection this connection was attached to @@ -94,23 +91,21 @@ double get_double_time (void) { return tv.tv_sec + 1e-9 * tv.tv_nsec; } -struct query *query_get (long long id) { - return tree_lookup_query (queries_tree, (void *)&id); +struct query *query_get (struct telegram *instance, long long id) { + return tree_lookup_query (instance->queries_tree, (void *)&id); } int alarm_query (struct query *q) { assert (q); - if (verbosity >= 1) { - logprintf ("Alarm query %lld\n", q->msg_id); - } + struct mtproto_connection *mtp = query_get_mtproto(q); + logprintf ("Alarm query %lld\n", q->msg_id); q->ev.timeout = get_double_time () + QUERY_TIMEOUT; - insert_event_timer (&q->ev); + insert_event_timer (mtp->connection->instance, &q->ev); if (q->session->c->out_bytes >= 100000) { return 0; } - struct mtproto_connection *mtp = query_get_mtproto(q); clear_packet (mtp); out_int (mtp, CODE_msg_container); out_int (mtp, 1); @@ -123,15 +118,15 @@ int alarm_query (struct query *q) { return 0; } -void query_restart (long long id) { - struct query *q = query_get (id); +void query_restart (struct telegram *instance, long long id) { + struct query *q = query_get (instance, id); if (q) { - remove_event_timer (&q->ev); + remove_event_timer (instance, &q->ev); alarm_query (q); } } -struct query *send_query (struct dc *DC, int ints, void *data, struct query_methods *methods, void *extra) { +struct query *send_query (struct telegram *instance, struct dc *DC, int ints, void *data, struct query_methods *methods, void *extra) { logprintf("send_query(...)\n"); logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port); struct query *q = talloc0 (sizeof (*q)); @@ -144,36 +139,36 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth logprintf ( "Msg_id is %lld %p\n", q->msg_id, q); q->methods = methods; q->DC = DC; - if (queries_tree) { + if (instance->queries_tree) { if (verbosity >= 2) { - logprintf ( "%lld %lld\n", q->msg_id, queries_tree->x->msg_id); + logprintf ( "%lld %lld\n", q->msg_id, instance->queries_tree->x->msg_id); } } - queries_tree = tree_insert_query (queries_tree, q, lrand48 ()); + instance->queries_tree = tree_insert_query (instance->queries_tree, q, lrand48 ()); struct mtproto_connection *mtp = query_get_mtproto(q); logprintf("queries_num: %d\n", ++ mtp->queries_num); q->ev.alarm = (void *)alarm_query; q->ev.timeout = get_double_time () + QUERY_TIMEOUT; q->ev.self = (void *)q; - insert_event_timer (&q->ev); + insert_event_timer (instance, &q->ev); q->extra = extra; return q; } -void query_ack (long long id) { - struct query *q = query_get (id); +void query_ack (struct telegram *instance, long long id) { + struct query *q = query_get (instance, id); if (q && !(q->flags & QUERY_ACK_RECEIVED)) { assert (q->msg_id == id); q->flags |= QUERY_ACK_RECEIVED; - remove_event_timer (&q->ev); + remove_event_timer (instance, &q->ev); } } -void query_error (long long id) { - struct query *q = query_get (id); +void query_error (struct telegram *instance, long long id) { + struct query *q = query_get (instance, id); struct mtproto_connection *mtp = query_get_mtproto(q); assert (fetch_int (mtp) == CODE_rpc_error); @@ -185,9 +180,9 @@ void query_error (long long id) { logprintf ( "No such query\n"); } else { if (!(q->flags & QUERY_ACK_RECEIVED)) { - remove_event_timer (&q->ev); + remove_event_timer (instance, &q->ev); } - queries_tree = tree_delete_query (queries_tree, q); + instance->queries_tree = tree_delete_query (instance->queries_tree, q); logprintf("queries_num: %d\n", -- mtp->queries_num); if (q->methods && q->methods->on_error) { @@ -202,11 +197,8 @@ void query_error (long long id) { } -#define MAX_PACKED_SIZE (1 << 24) -static int packed_buffer[MAX_PACKED_SIZE / 4]; - -void query_result (long long id UU) { - struct query *q = query_get (id); +void query_result (struct telegram *instance, long long id UU) { + struct query *q = query_get (instance, id); struct mtproto_connection *mtp = query_get_mtproto(q); logprintf ( "result for query #%lld\n", id); @@ -222,11 +214,11 @@ void query_result (long long id UU) { fetch_int (mtp); int l = prefetch_strlen (mtp); char *s = fetch_str (mtp, l); - int total_out = tinflate (s, l, packed_buffer, MAX_PACKED_SIZE); + int total_out = tinflate (s, l, instance->packed_buffer, MAX_PACKED_SIZE); end = mtp->in_ptr; eend = mtp->in_end; //assert (total_out % 4 == 0); - mtp->in_ptr = packed_buffer; + mtp->in_ptr = instance->packed_buffer; mtp->in_end = mtp->in_ptr + total_out / 4; if (verbosity >= 4) { logprintf ( "Unzipped data: "); @@ -238,9 +230,9 @@ void query_result (long long id UU) { mtp->in_ptr = mtp->in_end; } else { if (!(q->flags & QUERY_ACK_RECEIVED)) { - remove_event_timer (&q->ev); + remove_event_timer (instance, &q->ev); } - queries_tree = tree_delete_query (queries_tree, q); + instance->queries_tree = tree_delete_query (instance->queries_tree, q); logprintf("queries_num: %d\n", -- mtp->queries_num); if (q->methods && q->methods->on_answer) { @@ -256,43 +248,36 @@ void query_result (long long id UU) { } } -#define event_timer_cmp(a,b) ((a)->timeout > (b)->timeout ? 1 : ((a)->timeout < (b)->timeout ? -1 : (memcmp (a, b, sizeof (struct event_timer))))) -DEFINE_TREE (timer, struct event_timer *, event_timer_cmp, 0) -struct tree_timer *timer_tree; -void insert_event_timer (struct event_timer *ev) { +void insert_event_timer (struct telegram *instance, struct event_timer *ev) { logprintf ( "INSERT: %lf %p %p\n", ev->timeout, ev->self, ev->alarm); - timer_tree = tree_insert_timer (timer_tree, ev, lrand48 ()); + instance->timer_tree = tree_insert_timer (instance->timer_tree, ev, lrand48 ()); } -void remove_event_timer (struct event_timer *ev) { +void remove_event_timer (struct telegram *instance, struct event_timer *ev) { logprintf ( "REMOVE: %lf %p %p\n", ev->timeout, ev->self, ev->alarm); - timer_tree = tree_delete_timer (timer_tree, ev); + instance->timer_tree = tree_delete_timer (instance->timer_tree, ev); } -double next_timer_in (void) { - if (!timer_tree) { return 1e100; } - return tree_get_min_timer (timer_tree)->timeout; +double next_timer_in (struct telegram *instance) { + if (!instance->timer_tree) { return 1e100; } + return tree_get_min_timer (instance->timer_tree)->timeout; } -void work_timers (void) { +void work_timers (struct telegram *instance) { logprintf ("work_timers ()\n"); double t = get_double_time (); - while (timer_tree) { - struct event_timer *ev = tree_get_min_timer (timer_tree); + while (instance->timer_tree) { + struct event_timer *ev = tree_get_min_timer (instance->timer_tree); assert (ev); if (ev->timeout > t) { break; } - remove_event_timer (ev); + remove_event_timer (instance, ev); assert (ev->alarm); logprintf ("Alarm\n"); ev->alarm (ev->self); } } -int max_chat_size; -int max_bcast_size; -int want_dc_num; -int new_dc_num; //extern struct dc *DC_list[]; //extern struct dc *DC_working; @@ -362,11 +347,11 @@ int help_get_config_on_answer (struct query *q UU) { for (i = 0; i < n; i++) { fetch_dc_option (instance); } - max_chat_size = fetch_int (mtp); + instance->max_chat_size = fetch_int (mtp); if (op == CODE_config) { - max_bcast_size = fetch_int (mtp); + instance->max_bcast_size = fetch_int (mtp); } - logprintf ( "max_chat_size = %d\n", max_chat_size); + logprintf ( "max_chat_size = %d\n", instance->max_chat_size); telegram_change_state(instance, STATE_CONFIG_RECEIVED, NULL); return 0; @@ -383,7 +368,7 @@ void do_help_get_config (struct telegram *instance) { clear_packet (mtp); out_int (mtp, CODE_help_get_config); struct dc *DC_working = telegram_get_working_dc(instance); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &help_get_config_methods, instance); } /* }}} */ @@ -401,7 +386,7 @@ int send_code_on_answer (struct query *q UU) { logprintf("telegram: phone_code_hash: %s\n", phone_code_hash); fetch_int (mtp); fetch_bool (mtp); - want_dc_num = -1; + instance->want_dc_num = -1; if (instance->session_state == STATE_PHONE_CODE_REQUESTED) { telegram_change_state(instance, STATE_PHONE_CODE_NOT_ENTERED, NULL); } else if (instance->session_state == STATE_CLIENT_CODE_REQUESTED) { @@ -438,17 +423,12 @@ struct query_methods send_code_methods = { .on_error = send_code_on_error }; -int code_is_sent (void) { - return want_dc_num; -} - -char *suser; void do_send_code (struct telegram *instance, const char *user) { struct mtproto_connection *mtp = instance->connection; logprintf ("sending code\n"); - suser = tstrdup (user); - want_dc_num = 0; + instance->suser = tstrdup (user); + instance->want_dc_num = 0; clear_packet (mtp); do_insert_header (mtp); out_int (mtp, CODE_auth_send_code); @@ -459,7 +439,7 @@ void do_send_code (struct telegram *instance, const char *user) { out_string (mtp, "en"); logprintf ("send_code: dc_num = %d\n", instance->auth.dc_working_num); - send_query (telegram_get_working_dc(instance), mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_code_methods, instance); + send_query (instance, telegram_get_working_dc(instance), mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_code_methods, instance); if (instance->session_state == STATE_PHONE_NOT_REGISTERED) { telegram_change_state(instance, STATE_PHONE_CODE_REQUESTED, NULL); } else if (instance->session_state == STATE_CLIENT_NOT_REGISTERED) { @@ -494,8 +474,8 @@ void do_phone_call (struct telegram *instance, const char *user) { struct mtproto_connection *mtp = instance->connection; logprintf ("calling user\n"); - suser = tstrdup (user); - want_dc_num = 0; + instance->suser = tstrdup (user); + instance->want_dc_num = 0; clear_packet (mtp); do_insert_header (mtp); out_int (mtp, CODE_auth_send_call); @@ -503,7 +483,7 @@ void do_phone_call (struct telegram *instance, const char *user) { out_string (mtp, instance->phone_code_hash); logprintf ("do_phone_call: dc_num = %d\n", instance->auth.dc_working_num); - send_query (telegram_get_working_dc(instance), mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &phone_call_methods, 0); + send_query (instance, telegram_get_working_dc(instance), mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &phone_call_methods, instance); } /* }}} */ @@ -563,32 +543,29 @@ struct query_methods check_phone_methods = { void do_auth_check_phone (struct telegram *instance, const char *user) { struct mtproto_connection *mtp = instance->connection; - suser = tstrdup (user); + instance->suser = tstrdup (user); clear_packet (mtp); out_int (mtp, CODE_auth_check_phone); out_string (mtp, user); check_phone_result = -1; struct dc *DC_working = telegram_get_working_dc(instance); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &check_phone_methods, instance); } /* }}} */ /* {{{ Nearest DC */ -int nearest_dc_num; -int nr_f (void) { - return nearest_dc_num >= 0; -} int nearest_dc_on_answer (struct query *q UU) { struct mtproto_connection *mtp = query_get_mtproto(q); + struct telegram *instance = mtp->connection->instance; assert (fetch_int (mtp) == (int)CODE_nearest_dc); char *country = fetch_str_dup (mtp); logprintf ("Server thinks that you are in %s\n", country); fetch_int (mtp); // this_dc - nearest_dc_num = fetch_int (mtp); - assert (nearest_dc_num >= 0); + instance->nearest_dc_num = fetch_int (mtp); + assert (instance->nearest_dc_num >= 0); return 0; } @@ -608,31 +585,30 @@ void do_get_nearest_dc (struct telegram *instance) { struct dc *DC_working = telegram_get_working_dc(instance); clear_packet (mtp); out_int (mtp, CODE_help_get_nearest_dc); - nearest_dc_num = -1; - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &nearest_dc_methods, 0); + instance->nearest_dc_num = -1; + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &nearest_dc_methods, instance); //net_loop (0, nr_f); //return nearest_dc_num; } /* }}} */ /* {{{ Sign in / Sign up */ -int our_id; - -struct user User; int sign_in_on_answer (struct query *q) { logprintf ("sign_in_on_answer()\n"); struct mtproto_connection *mtp = query_get_mtproto(q); + struct telegram *instance = mtp->connection->instance; + struct dc *DC_working = telegram_get_working_dc(mtp->connection->instance); assert (fetch_int (mtp) == (int)CODE_auth_authorization); int expires = fetch_int (mtp); - fetch_user (mtp, &User); - if (!our_id) { - our_id = get_peer_id (User.id); - bl_do_set_our_id (mtp->bl, mtp, our_id); + fetch_user (mtp, &instance->User); + if (!instance->our_id) { + instance->our_id = get_peer_id (instance->User.id); + bl_do_set_our_id (mtp->bl, mtp, instance->our_id); } logprintf ( "telegram: authorized successfully: name = '%s %s', phone = '%s', expires = %d\n", - User.first_name, User.last_name, User.phone, (int)(expires - get_double_time ())); + instance->User.first_name, instance->User.last_name, instance->User.phone, (int)(expires - get_double_time ())); DC_working->has_auth = 1; bl_do_dc_signed (mtp->bl, mtp, DC_working->id); @@ -661,11 +637,11 @@ void do_send_code_result (struct telegram *instance, const char *code) { struct dc *DC_working = telegram_get_working_dc(instance); clear_packet (mtp); out_int (mtp, CODE_auth_sign_in); - out_string (mtp, suser); + out_string (mtp, instance->suser); out_string(mtp, instance->phone_code_hash); out_string (mtp, code); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, - &sign_in_methods, NULL); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, + &sign_in_methods, instance); } void do_send_code_result_auth (struct telegram *instance, const char *code, const char *first_name, const char *last_name) { @@ -674,19 +650,18 @@ void do_send_code_result_auth (struct telegram *instance, const char *code, cons clear_packet (mtp); out_int (mtp, CODE_auth_sign_up); - out_string (mtp ,suser); + out_string (mtp, instance->suser); out_string (mtp, instance->phone_code_hash); out_string (mtp, code); out_string (mtp, first_name); out_string (mtp, last_name); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &sign_in_methods, instance); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &sign_in_methods, instance); } /* }}} */ /* {{{ Get contacts */ extern char *user_list[]; -int contacts_got = 0; int get_contacts_on_answer (struct query *q UU) { struct mtproto_connection *mtp = query_get_mtproto(q); int i; @@ -703,7 +678,6 @@ int get_contacts_on_answer (struct query *q UU) { for (i = 0; i < n; i++) { fetch_alloc_user (mtp); } - contacts_got = 1; return 0; } @@ -715,11 +689,10 @@ void do_update_contact_list (struct telegram *instance) { struct mtproto_connection *mtp = instance->connection; struct dc *DC_working = telegram_get_working_dc(instance); - contacts_got = 0; clear_packet (mtp); out_int (mtp, CODE_contacts_get_contacts); out_string (mtp, ""); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_contacts_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_contacts_methods, instance); } @@ -888,14 +861,11 @@ struct query_methods msg_send_encr_methods = { .on_answer = msg_send_encr_on_answer }; -int out_message_num; -int our_id; - void do_send_encr_msg (struct telegram *instance, struct message *M) { struct mtproto_connection *mtp = instance->connection; struct dc *DC_working = telegram_get_working_dc(instance); - peer_t *P = user_chat_get (M->to_id); + peer_t *P = user_chat_get (mtp->bl, M->to_id); if (!P || P->encr_chat.state != sc_ok) { return; } clear_packet (mtp); @@ -914,7 +884,7 @@ void do_send_encr_msg (struct telegram *instance, struct message *M) { out_int (mtp, CODE_decrypted_message_media_empty); encr_finish (mtp, &P->encr_chat); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &msg_send_encr_methods, M); } @@ -931,13 +901,13 @@ void do_send_msg (struct telegram *instance, struct message *M) { out_peer_id (mtp, M->to_id); out_cstring (mtp, M->message, M->message_len); out_long (mtp, M->id); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &msg_send_methods, M); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &msg_send_methods, M); } void do_send_message (struct telegram *instance, peer_id_t id, const char *msg, int len) { struct mtproto_connection *mtp = instance->connection; if (get_peer_type (id) == PEER_ENCR_CHAT) { - peer_t *P = user_chat_get (id); + peer_t *P = user_chat_get (mtp->bl, id); if (!P) { logprintf ("Can not send to unknown encrypted chat\n"); return; @@ -950,8 +920,8 @@ void do_send_message (struct telegram *instance, peer_id_t id, const char *msg, long long t; secure_random (&t, 8); logprintf ("t = %lld, len = %d\n", t, len); - bl_do_send_message_text (mtp->bl, mtp, t, our_id, get_peer_type (id), get_peer_id (id), time (0), len, msg); - struct message *M = message_get (t); + bl_do_send_message_text (mtp->bl, mtp, t, instance->our_id, get_peer_type (id), get_peer_id (id), time (0), len, msg); + struct message *M = message_get (mtp->bl, t); assert (M); do_send_msg (instance, M); //print_message (M); @@ -1016,7 +986,7 @@ void do_messages_mark_read (struct telegram *instance, peer_id_t id, int max_id) out_peer_id (mtp, id); out_int (mtp, max_id); out_int (mtp, 0); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &mark_read_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &mark_read_methods, 0); } void do_messages_mark_read_encr (struct telegram *instance, peer_id_t id, long long access_hash, int last_time) { @@ -1029,11 +999,13 @@ void do_messages_mark_read_encr (struct telegram *instance, peer_id_t id, long l out_int (mtp, get_peer_id (id)); out_long (mtp, access_hash); out_int (mtp, last_time); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &mark_read_encr_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &mark_read_encr_methods, 0); } void do_mark_read (struct telegram *instance, peer_id_t id) { - peer_t *P = user_chat_get (id); + struct mtproto_connection *mtp = instance->connection; + + peer_t *P = user_chat_get (mtp->bl, id); if (!P) { logprintf ("Unknown peer\n"); return; @@ -1112,8 +1084,9 @@ struct query_methods get_history_methods = { .on_answer = get_history_on_answer, }; -void do_get_local_history (peer_id_t id, int limit) { - peer_t *P = user_chat_get (id); +void do_get_local_history (struct telegram *instance, peer_id_t id, int limit) { + struct mtproto_connection *mtp = instance->connection; + peer_t *P = user_chat_get (mtp->bl, id); if (!P || !P->last) { return; } struct message *M = P->last; int count = 1; @@ -1132,7 +1105,7 @@ void do_get_history (struct telegram *instance, peer_id_t id, int limit) { struct dc *DC_working = telegram_get_working_dc(instance); struct mtproto_connection *mtp = instance->connection; if (get_peer_type (id) == PEER_ENCR_CHAT || offline_mode) { - do_get_local_history (id, limit); + do_get_local_history (instance, id, limit); do_mark_read (instance, id); return; } @@ -1147,7 +1120,7 @@ void do_get_history (struct telegram *instance, peer_id_t id, int limit) { extra->instance = instance; extra->peer_id = id; - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_history_methods, extra); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_history_methods, extra); } /* }}} */ @@ -1202,13 +1175,13 @@ int get_dialogs_on_answer (struct query *q UU) { peer_t *UC UU; switch (get_peer_type (plist[i])) { case PEER_USER: - UC = user_chat_get (plist[i]); + UC = user_chat_get (mtp->bl, plist[i]); logprintf ("User "); //print_user_name (plist[i], UC); logprintf (": %d unread\n", dlist[2 * i + 1]); break; case PEER_CHAT: - UC = user_chat_get (plist[i]); + UC = user_chat_get (mtp->bl, plist[i]); logprintf ("Chat "); //print_chat_name (plist[i], UC); logprintf (": %d unread\n", dlist[2 * i + 1]); @@ -1235,7 +1208,7 @@ void do_get_dialog_list (struct telegram *instance) { out_int (mtp, 0); out_int (mtp, 0); out_int (mtp, 1000); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_dialogs_methods, instance); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_dialogs_methods, instance); } /* }}} */ @@ -1267,7 +1240,7 @@ void out_peer_id (struct mtproto_connection *self, peer_id_t id) { out_int (self, get_peer_id (id)); break; case PEER_USER: - U = user_chat_get (id); + U = user_chat_get (self->bl, id); if (U && U->user.access_hash) { out_int (self, CODE_input_peer_foreign); out_int (self, get_peer_id (id)); @@ -1288,9 +1261,9 @@ struct send_file_extra { }; void send_part (struct telegram *instance, struct send_file *f); -int send_file_part_on_answer (struct query *q) { - struct mtproto_connection *mtp = query_get_mtproto(q); +int send_file_part_on_answer (struct query *q) { + struct mtproto_connection *mtp = query_get_mtproto (q); struct send_file_extra *extra = q->extra; assert (fetch_int (mtp) == (int)CODE_bool_true); send_part (extra->instance, extra->file); @@ -1359,7 +1332,7 @@ void send_part (struct telegram *instance, struct send_file *f) { struct dc *DC_working = telegram_get_working_dc(instance); if (f->fd >= 0) { if (!f->part_num) { - cur_uploading_bytes += f->size; + instance->cur_uploading_bytes += f->size; } clear_packet (mtp); if (f->size < (16 << 20)) { @@ -1376,7 +1349,7 @@ void send_part (struct telegram *instance, struct send_file *f) { int x = read (f->fd, buf, f->part_size); assert (x > 0); f->offset += x; - cur_uploaded_bytes += x; + instance->cur_uploaded_bytes += x; if (f->encr) { if (x & 15) { @@ -1405,10 +1378,10 @@ void send_part (struct telegram *instance, struct send_file *f) { struct send_file_extra *extra = malloc(sizeof(struct send_file_extra)); extra->instance = instance; extra->file = f; - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_file_part_methods, extra); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_file_part_methods, extra); } else { - cur_uploaded_bytes -= f->size; - cur_uploading_bytes -= f->size; + instance->cur_uploaded_bytes -= f->size; + instance->cur_uploading_bytes -= f->size; //update_prompt (); clear_packet (mtp); assert (f->media_type == CODE_input_media_uploaded_photo || f->media_type == CODE_input_media_uploaded_video || f->media_type == CODE_input_media_uploaded_thumb_video || f->media_type == CODE_input_media_uploaded_audio || f->media_type == CODE_input_media_uploaded_document || f->media_type == CODE_input_media_uploaded_thumb_document); @@ -1450,14 +1423,14 @@ void send_part (struct telegram *instance, struct send_file *f) { } out_long (mtp, -lrand48 () * (1ll << 32) - lrand48 ()); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_file_methods, instance); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_file_methods, instance); } else { struct message *M = talloc0 (sizeof (*M)); out_int (mtp, CODE_messages_send_encrypted_file); out_int (mtp, CODE_input_encrypted_chat); out_int (mtp, get_peer_id (f->to_id)); - peer_t *P = user_chat_get (f->to_id); + peer_t *P = user_chat_get (mtp->bl, f->to_id); assert (P); out_long (mtp, P->encr_chat.access_hash); long long r = -lrand48 () * (1ll << 32) - lrand48 (); @@ -1531,7 +1504,7 @@ void send_part (struct telegram *instance, struct send_file *f) { M->media.encr_photo.size = f->size; M->flags = FLAG_ENCRYPTED; - M->from_id = MK_USER (our_id); + M->from_id = MK_USER (instance->our_id); M->to_id = f->to_id; M->unread = 1; M->message = tstrdup (""); @@ -1539,7 +1512,7 @@ void send_part (struct telegram *instance, struct send_file *f) { M->id = r; M->date = time (0); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_encr_file_methods, M); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_encr_file_methods, M); } tfree_str (f->file_name); tfree (f, sizeof (*f)); @@ -1555,7 +1528,7 @@ void send_file_thumb (struct telegram *instance, struct send_file *f) { out_long (mtp, f->thumb_id); out_int (mtp, 0); out_cstring (mtp, (void *)thumb_file, thumb_file_size); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_file_part_methods, f); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_file_part_methods, f); } void do_send_photo (struct telegram *instance, int type, peer_id_t to_id, char *file_name) { @@ -1660,7 +1633,7 @@ void do_forward_message (struct telegram *instance, peer_id_t id, int n) { out_peer_id (mtp, id); out_int (mtp, n); out_long (mtp, lrand48 () * (1ll << 32) + lrand48 ()); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &fwd_msg_methods, instance); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &fwd_msg_methods, instance); } /* }}} */ @@ -1702,7 +1675,7 @@ void do_rename_chat (struct telegram *instance, peer_id_t id, char *name UU) { assert (get_peer_type (id) == PEER_CHAT); out_int (mtp, get_peer_id (id)); out_string (mtp, name); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &rename_chat_methods, instance); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &rename_chat_methods, instance); } /* }}} */ @@ -1720,9 +1693,9 @@ void print_chat_info (struct chat *C) { int i; for (i = 0; i < C->user_list_size; i++) { logprintf ("\t\t"); - //print_user_name (MK_USER (C->user_list[i].user_id), user_chat_get (MK_USER (C->user_list[i].user_id))); + //print_user_name (MK_USER (C->user_list[i].user_id), user_chat_get (mtp->bl, MK_USER (C->user_list[i].user_id))); logprintf (" invited by "); - //print_user_name (MK_USER (C->user_list[i].inviter_id), user_chat_get (MK_USER (C->user_list[i].inviter_id))); + //print_user_name (MK_USER (C->user_list[i].inviter_id), user_chat_get (mtp->bl, MK_USER (C->user_list[i].inviter_id))); logprintf (" at "); //print_date_full (C->user_list[i].date); if (C->user_list[i].user_id == C->admin_id) { @@ -1752,7 +1725,7 @@ void do_get_chat_info (struct telegram *instance, peer_id_t id) { struct dc *DC_working = telegram_get_working_dc(instance); struct mtproto_connection *mtp = instance->connection; if (offline_mode) { - peer_t *C = user_chat_get (id); + peer_t *C = user_chat_get (mtp->bl, id); if (!C) { logprintf ("No such chat\n"); } else { @@ -1764,7 +1737,7 @@ void do_get_chat_info (struct telegram *instance, peer_id_t id) { out_int (mtp, CODE_messages_get_full_chat); assert (get_peer_type (id) == PEER_CHAT); out_int (mtp, get_peer_id (id)); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &chat_info_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &chat_info_methods, 0); } /* }}} */ @@ -1809,7 +1782,7 @@ void do_get_user_info (struct telegram *instance, peer_id_t id) { struct dc *DC_working = telegram_get_working_dc(instance); struct mtproto_connection *mtp = instance->connection; if (offline_mode) { - peer_t *C = user_chat_get (id); + peer_t *C = user_chat_get (mtp->bl, id); if (!C) { logprintf ("No such user\n"); } else { @@ -1820,7 +1793,7 @@ void do_get_user_info (struct telegram *instance, peer_id_t id) { clear_packet (mtp); out_int (mtp, CODE_users_get_full_user); assert (get_peer_type (id) == PEER_USER); - peer_t *U = user_chat_get (id); + peer_t *U = user_chat_get (mtp->bl, id); if (U && U->user.access_hash) { out_int (mtp, CODE_input_user_foreign); out_int (mtp, get_peer_id (id)); @@ -1829,7 +1802,7 @@ void do_get_user_info (struct telegram *instance, peer_id_t id) { out_int (mtp, CODE_input_user_contact); out_int (mtp, get_peer_id (id)); } - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &user_info_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &user_info_methods, 0); } /* }}} */ @@ -1862,7 +1835,7 @@ void do_get_user_list_info_silent (struct telegram *instance, int num, int *list out_int (mtp, list[i]); //out_long (0); } - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &user_list_info_silent_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &user_list_info_silent_methods, 0); } /* }}} */ @@ -1885,9 +1858,9 @@ struct download { }; -void end_load (struct download *D) { - cur_downloading_bytes -= D->size; - cur_downloaded_bytes -= D->size; +void end_load (struct telegram *instance, struct download *D) { + instance->cur_downloading_bytes -= D->size; + instance->cur_downloaded_bytes -= D->size; //update_prompt (); close (D->fd); if (D->next == 1) { @@ -1934,7 +1907,7 @@ int download_on_answer (struct query *q) { fetch_int (mtp); // mtime int len = prefetch_strlen (mtp); assert (len >= 0); - cur_downloaded_bytes += len; + instance->cur_downloaded_bytes += len; //update_prompt (); if (D->iv) { unsigned char *ptr = (void *)fetch_str (mtp, len); @@ -1955,7 +1928,7 @@ int download_on_answer (struct query *q) { load_next_part (instance, D); return 0; } else { - end_load (D); + end_load (instance, D); return 0; } } @@ -1983,16 +1956,16 @@ void load_next_part (struct telegram *instance, struct download *D) { if (stat (buf, &st) >= 0) { D->offset = st.st_size; if (D->offset >= D->size) { - cur_downloading_bytes += D->size; - cur_downloaded_bytes += D->offset; + instance->cur_downloading_bytes += D->size; + instance->cur_downloaded_bytes += D->offset; logprintf ("Already downloaded\n"); - end_load (D); + end_load (instance, D); return; } } - cur_downloading_bytes += D->size; - cur_downloaded_bytes += D->offset; + instance->cur_downloading_bytes += D->size; + instance->cur_downloaded_bytes += D->offset; //update_prompt (); } clear_packet (mtp); @@ -2018,8 +1991,8 @@ void load_next_part (struct telegram *instance, struct download *D) { extra->instance = instance; extra->dl = D; - send_query (instance->auth.DC_list[D->dc], mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &download_methods, extra); - //send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &download_methods, D); + send_query (instance, instance->auth.DC_list[D->dc], mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &download_methods, extra); + //send_query (instance, DC_working, packet_ptr - packet_buffer, packet_buffer, &download_methods, D); } void do_load_photo_size (struct telegram *instance, struct photo_size *P, int next) { @@ -2141,30 +2114,23 @@ void do_load_encr_video (struct telegram *instance, struct encr_video *V, int ne /* }}} */ /* {{{ Export auth */ -char *export_auth_str; -int export_auth_str_len; -int is_export_auth_str (void) { - return export_auth_str != 0; -} -int isn_export_auth_str (void) { - return export_auth_str == 0; -} int export_auth_on_answer (struct query *q UU) { struct mtproto_connection *mtp = query_get_mtproto(q); + struct telegram *instance = mtp->connection->instance; assert (fetch_int (mtp) == (int)CODE_auth_exported_authorization); int l = fetch_int (mtp); - if (!our_id) { - our_id = l; + if (!instance->our_id) { + instance->our_id = l; } else { - assert (our_id == l); + assert (instance->our_id == l); } l = prefetch_strlen (mtp); char *s = talloc (l); memcpy (s, fetch_str (mtp, l), l); - export_auth_str_len = l; - export_auth_str = s; + instance->export_auth_str_len = l; + instance->export_auth_str = s; return 0; } @@ -2176,23 +2142,24 @@ struct query_methods export_auth_methods = { void do_export_auth (struct telegram *instance, int num) { struct dc *DC_working = telegram_get_working_dc(instance); struct mtproto_connection *mtp = instance->connection; - export_auth_str = 0; + instance->export_auth_str = 0; clear_packet (mtp); out_int (mtp, CODE_auth_export_authorization); out_int (mtp, num); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &export_auth_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &export_auth_methods, 0); } /* }}} */ /* {{{ Import auth */ int import_auth_on_answer (struct query *q UU) { struct mtproto_connection *mtp = query_get_mtproto(q); - assert (fetch_int (mtp) == (int)CODE_auth_authorization); + struct telegram *instance = mtp->connection->instance; + assert (fetch_int (mtp) == (int)CODE_auth_authorization); fetch_int (mtp); // expires fetch_alloc_user (mtp); - tfree_str (export_auth_str); - export_auth_str = 0; + tfree_str (instance->export_auth_str); + instance->export_auth_str = 0; return 0; } @@ -2203,11 +2170,12 @@ struct query_methods import_auth_methods = { void do_import_auth (struct telegram *instance, int num) { struct mtproto_connection *mtp = instance->connection; + clear_packet (mtp); out_int (mtp, CODE_auth_import_authorization); - out_int (mtp, our_id); - out_cstring (mtp, export_auth_str, export_auth_str_len); - send_query (instance->auth.DC_list[num], mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &import_auth_methods, 0); + out_int (mtp, instance->our_id); + out_cstring (mtp, instance->export_auth_str, instance->export_auth_str_len); + send_query (instance, instance->auth.DC_list[num], mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &import_auth_methods, 0); } /* }}} */ @@ -2281,7 +2249,7 @@ void do_add_contact (struct telegram *instance, const char *phone, int phone_len out_cstring (mtp, first_name, first_name_len); out_cstring (mtp, last_name, last_name_len); out_int (mtp, force ? CODE_bool_true : CODE_bool_false); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &add_contact_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &add_contact_methods, 0); } /* }}} */ @@ -2315,7 +2283,7 @@ void do_msg_search (struct telegram *instance, peer_id_t id, int from, int to, i out_int (mtp, 0); // offset out_int (mtp, 0); // max_id out_int (mtp, limit); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &msg_search_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &msg_search_methods, 0); } /* }}} */ @@ -2360,7 +2328,7 @@ void do_contacts_search (struct telegram *instance, int limit, const char *s) { out_int (mtp, CODE_contacts_search); out_string (mtp, s); out_int (mtp, limit); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &contacts_search_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &contacts_search_methods, 0); } /* }}} */ @@ -2422,11 +2390,6 @@ struct query_methods send_encr_request_methods = { .on_answer = send_encr_request_on_answer }; -int encr_root; -unsigned char *encr_prime; -int encr_param_version; -BN_CTX *ctx; - void do_send_accept_encr_chat (struct telegram *instance, struct secret_chat *E, unsigned char *random) { struct dc *DC_working = telegram_get_working_dc(instance); struct mtproto_connection *mtp = instance->connection; @@ -2448,16 +2411,16 @@ void do_send_accept_encr_chat (struct telegram *instance, struct secret_chat *E, ensure_ptr (b); BIGNUM *g_a = BN_bin2bn (E->g_key, 256, 0); ensure_ptr (g_a); - assert (check_g (encr_prime, g_a) >= 0); - if (!ctx) { - ctx = BN_CTX_new (); - ensure_ptr (ctx); + assert (check_g (instance->encr_prime, g_a) >= 0); + if (!instance->ctx) { + instance->ctx = BN_CTX_new (); + ensure_ptr (instance->ctx); } - BIGNUM *p = BN_bin2bn (encr_prime, 256, 0); + BIGNUM *p = BN_bin2bn (instance->encr_prime, 256, 0); ensure_ptr (p); BIGNUM *r = BN_new (); ensure_ptr (r); - ensure (BN_mod_exp (r, g_a, b, p, ctx)); + ensure (BN_mod_exp (r, g_a, b, p, instance->ctx)); static unsigned char kk[256]; memset (kk, 0, sizeof (kk)); BN_bn2bin (r, kk); @@ -2475,8 +2438,8 @@ void do_send_accept_encr_chat (struct telegram *instance, struct secret_chat *E, out_int (mtp, get_peer_id (E->id)); out_long (mtp, E->access_hash); - ensure (BN_set_word (g_a, encr_root)); - ensure (BN_mod_exp (r, g_a, b, p, ctx)); + ensure (BN_set_word (g_a, instance->encr_root)); + ensure (BN_mod_exp (r, g_a, b, p, instance->ctx)); static unsigned char buf[256]; memset (buf, 0, sizeof (buf)); BN_bn2bin (r, buf); @@ -2488,25 +2451,25 @@ void do_send_accept_encr_chat (struct telegram *instance, struct secret_chat *E, BN_clear_free (p); BN_clear_free (r); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_encr_accept_methods, E); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_encr_accept_methods, E); } -void do_create_keys_end (struct secret_chat *U) { - assert (encr_prime); +void do_create_keys_end (struct telegram *instance, struct secret_chat *U) { + assert (instance->encr_prime); BIGNUM *g_b = BN_bin2bn (U->g_key, 256, 0); ensure_ptr (g_b); - assert (check_g (encr_prime, g_b) >= 0); - if (!ctx) { - ctx = BN_CTX_new (); - ensure_ptr (ctx); + assert (check_g (instance->encr_prime, g_b) >= 0); + if (!instance->ctx) { + instance->ctx = BN_CTX_new (); + ensure_ptr (instance->ctx); } - BIGNUM *p = BN_bin2bn (encr_prime, 256, 0); + BIGNUM *p = BN_bin2bn (instance->encr_prime, 256, 0); ensure_ptr (p); BIGNUM *r = BN_new (); ensure_ptr (r); BIGNUM *a = BN_bin2bn ((void *)U->key, 256, 0); ensure_ptr (a); - ensure (BN_mod_exp (r, g_b, a, p, ctx)); + ensure (BN_mod_exp (r, g_b, a, p, instance->ctx)); unsigned char *t = talloc (256); memcpy (t, U->key, 256); @@ -2522,7 +2485,7 @@ void do_create_keys_end (struct secret_chat *U) { sha1 ((void *)U->key, 256, sha_buffer); long long k = *(long long *)(sha_buffer + 12); if (k != U->key_fingerprint) { - logprintf ("version = %d\n", encr_param_version); + logprintf ("version = %d\n", instance->encr_param_version); hexdump ((void *)U->nonce, (void *)(U->nonce + 256)); hexdump ((void *)U->g_key, (void *)(U->g_key + 256)); hexdump ((void *)U->key, (void *)(U->key + 64)); @@ -2551,45 +2514,44 @@ void do_send_create_encr_chat (struct telegram *instance, void *x, unsigned char for (i = 0; i < 256; i++) { random[i] ^= random_here[i]; } - if (!ctx) { - ctx = BN_CTX_new (); - ensure_ptr (ctx); + if (!instance->ctx) { + instance->ctx = BN_CTX_new (); + ensure_ptr (instance->ctx); } BIGNUM *a = BN_bin2bn (random, 256, 0); ensure_ptr (a); - BIGNUM *p = BN_bin2bn (encr_prime, 256, 0); + BIGNUM *p = BN_bin2bn (instance->encr_prime, 256, 0); ensure_ptr (p); BIGNUM *g = BN_new (); ensure_ptr (g); - ensure (BN_set_word (g, encr_root)); + ensure (BN_set_word (g, instance->encr_root)); BIGNUM *r = BN_new (); ensure_ptr (r); - ensure (BN_mod_exp (r, g, a, p, ctx)); + ensure (BN_mod_exp (r, g, a, p, instance->ctx)); BN_clear_free (a); - static char g_a[256]; - memset (g_a, 0, 256); + memset (instance->g_a, 0, 256); - BN_bn2bin (r, (void *)g_a); + BN_bn2bin (r, (void *)instance->g_a); int t = lrand48 (); - while (user_chat_get (MK_ENCR_CHAT (t))) { + while (user_chat_get (mtp->bl, MK_ENCR_CHAT (t))) { t = lrand48 (); } - bl_do_encr_chat_init (mtp->bl, mtp, t, user_id, (void *)random, (void *)g_a); - peer_t *_E = user_chat_get (MK_ENCR_CHAT (t)); + bl_do_encr_chat_init (mtp->bl, mtp, t, user_id, (void *)random, (void *)instance->g_a); + peer_t *_E = user_chat_get (mtp->bl, MK_ENCR_CHAT (t)); assert (_E); struct secret_chat *E = &_E->encr_chat; clear_packet (mtp); out_int (mtp, CODE_messages_request_encryption); - peer_t *U = user_chat_get (MK_USER (E->user_id)); + peer_t *U = user_chat_get (mtp->bl, MK_USER (E->user_id)); assert (U); if (U && U->user.access_hash) { out_int (mtp, CODE_input_user_foreign); @@ -2600,15 +2562,15 @@ void do_send_create_encr_chat (struct telegram *instance, void *x, unsigned char out_int (mtp, E->user_id); } out_int (mtp, get_peer_id (E->id)); - out_cstring (mtp, g_a, 256); + out_cstring (mtp, instance->g_a, 256); // TODO: properly... - write_secret_chat_file ("/home/dev-jessie/.telegram/+4915736384600/secret"); + write_secret_chat_file (instance, "/home/dev-jessie/.telegram/+4915736384600/secret"); BN_clear_free (g); BN_clear_free (p); BN_clear_free (r); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_encr_request_methods, E); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &send_encr_request_methods, E); } struct create_encr_chat_extra { @@ -2666,14 +2628,14 @@ void do_accept_encr_chat_request (struct telegram *instance, struct secret_chat clear_packet (mtp); out_int (mtp, CODE_messages_get_dh_config); - out_int (mtp, encr_param_version); + out_int (mtp, instance->encr_param_version); out_int (mtp, 256); struct create_encr_chat_extra *extra = malloc(sizeof(struct create_encr_chat_extra)); extra->callback = do_send_accept_encr_chat; extra->instance = instance; extra->data = (void*)E; - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_dh_config_methods, extra); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_dh_config_methods, extra); } void do_create_encr_chat_request (struct telegram *instance, int user_id) { @@ -2682,21 +2644,20 @@ void do_create_encr_chat_request (struct telegram *instance, int user_id) { clear_packet (mtp); out_int (mtp, CODE_messages_get_dh_config); - out_int (mtp, encr_param_version); + out_int (mtp, instance->encr_param_version); out_int (mtp, 256); struct create_encr_chat_extra *extra = malloc(sizeof(struct create_encr_chat_extra)); extra->callback = do_send_accept_encr_chat; extra->instance = instance; extra->data = (void *)(long)user_id; - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_dh_config_methods, extra); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_dh_config_methods, extra); } /* }}} */ /* {{{ Get difference */ -int unread_messages; -int difference_got; -int seq, pts, qts, last_date; +//int difference_got; +//int seq, pts, qts, last_date; int get_state_on_answer (struct query *q UU) { struct mtproto_connection *mtp = query_get_mtproto(q); struct telegram *instance = q->extra; @@ -2707,34 +2668,30 @@ int get_state_on_answer (struct query *q UU) { bl_do_set_qts (mtp->bl, mtp, fetch_int (mtp)); bl_do_set_date (mtp->bl, mtp, fetch_int (mtp)); bl_do_set_seq (mtp->bl, mtp, fetch_int (mtp)); - unread_messages = fetch_int (mtp); + instance->unread_messages = fetch_int (mtp); //write_state_file (); - difference_got = 1; telegram_store_session (instance); return 0; } -int get_difference_active; int get_difference_on_answer (struct query *q UU) { struct mtproto_connection *mtp = query_get_mtproto(q); struct telegram *instance = q->extra; logprintf("get_difference_on_answer()\n"); - get_difference_active = 0; + instance->get_difference_active = 0; unsigned x = fetch_int (mtp); if (x == CODE_updates_difference_empty) { bl_do_set_date (mtp->bl, mtp, fetch_int (mtp)); bl_do_set_seq (mtp->bl, mtp, fetch_int (mtp)); - difference_got = 1; } else if (x == CODE_updates_difference || x == CODE_updates_difference_slice) { int n, i; assert (fetch_int (mtp) == CODE_vector); n = fetch_int (mtp); - static struct message *ML[10000]; int ml_pos = 0; for (i = 0; i < n; i++) { if (ml_pos < 10000) { - ML[ml_pos ++] = fetch_alloc_message (mtp, instance); + instance->ML[ml_pos ++] = fetch_alloc_message (mtp, instance); } else { fetch_alloc_message (mtp, instance); } @@ -2743,7 +2700,7 @@ int get_difference_on_answer (struct query *q UU) { n = fetch_int (mtp); for (i = 0; i < n; i++) { if (ml_pos < 10000) { - ML[ml_pos ++] = fetch_alloc_encrypted_message (mtp, instance); + instance->ML[ml_pos ++] = fetch_alloc_encrypted_message (mtp, instance); } else { fetch_alloc_encrypted_message (mtp, instance); } @@ -2751,7 +2708,7 @@ int get_difference_on_answer (struct query *q UU) { assert (fetch_int (mtp) == CODE_vector); n = fetch_int (mtp); for (i = 0; i < n; i++) { - work_update (0, 0); + work_update (mtp, 0); } assert (fetch_int (mtp) == CODE_vector); n = fetch_int (mtp); @@ -2770,16 +2727,16 @@ int get_difference_on_answer (struct query *q UU) { bl_do_set_qts (mtp->bl, mtp, fetch_int (mtp)); bl_do_set_date (mtp->bl, mtp, fetch_int (mtp)); bl_do_set_seq (mtp->bl, mtp, fetch_int (mtp)); - unread_messages = fetch_int (mtp); + instance->unread_messages = fetch_int (mtp); //write_state_file (); for (i = 0; i < ml_pos; i++) { - event_update_new_message (instance, ML[i]); + event_update_new_message (instance, instance->ML[i]); ////print_message (ML[i]); } if (x == CODE_updates_difference_slice) { do_get_difference (instance); } else { - difference_got = 1; + //difference_got = 1; } } else { assert (0); @@ -2800,23 +2757,27 @@ void do_get_difference (struct telegram *instance) { struct mtproto_connection *mtp = instance->connection; struct dc *DC_working = telegram_get_working_dc(instance); - logprintf("do_get_difference()\n"); - get_difference_active = 1; - difference_got = 0; + instance->get_difference_active = 1; + //difference_got = 0; clear_packet (mtp); do_insert_header (mtp); - if (seq > 0 || sync_from_start) { - if (pts == 0) { pts = 1; } - if (qts == 0) { qts = 1; } - if (last_date == 0) { last_date = 1; } + if (instance->proto.seq > 0 || sync_from_start) { + if (instance->proto.pts == 0) { instance->proto.pts = 1; } + if (instance->proto.qts == 0) { instance->proto.qts = 1; } + if (instance->proto.last_date == 0) { instance->proto.last_date = 1; } + + logprintf("do_get_difference(pts:%d, last_date:%d, qts: %d)\n", + instance->proto.pts, instance->proto.last_date, instance->proto.qts); out_int (mtp, CODE_updates_get_difference); - out_int (mtp, pts); - out_int (mtp, last_date); - out_int (mtp, qts); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_difference_methods, instance); + out_int (mtp, instance->proto.pts); + out_int (mtp, instance->proto.last_date); + out_int (mtp, instance->proto.qts); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_difference_methods, instance); } else { + logprintf("do_updates_get_state()\n", + instance->proto.pts, instance->proto.last_date, instance->proto.qts); out_int (mtp, CODE_updates_get_state); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_state_methods, instance); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_state_methods, instance); } } /* }}} */ @@ -2824,9 +2785,9 @@ void do_get_difference (struct telegram *instance) { /* {{{ Visualize key */ //char *colors[4] = {COLOR_GREY, COLOR_CYAN, COLOR_BLUE, COLOR_GREEN}; -void do_visualize_key (peer_id_t id) { +void do_visualize_key (struct binlog *bl, peer_id_t id) { assert (get_peer_type (id) == PEER_ENCR_CHAT); - peer_t *P = user_chat_get (id); + peer_t *P = user_chat_get (bl, id); assert (P); if (P->encr_chat.state != sc_ok) { logprintf ("Chat is not initialized yet\n"); @@ -2895,7 +2856,7 @@ void do_get_suggested (struct telegram *instance) { clear_packet (mtp); out_int (mtp, CODE_contacts_get_suggested); out_int (mtp, 100); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_suggested_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &get_suggested_methods, 0); } /* }}} */ @@ -2913,7 +2874,7 @@ void do_add_user_to_chat (struct telegram *instance, peer_id_t chat_id, peer_id_ out_int (mtp, get_peer_id (chat_id)); assert (get_peer_type (id) == PEER_USER); - peer_t *U = user_chat_get (id); + peer_t *U = user_chat_get (mtp->bl, id); if (U && U->user.access_hash) { out_int (mtp, CODE_input_user_foreign); out_int (mtp, get_peer_id (id)); @@ -2923,7 +2884,7 @@ void do_add_user_to_chat (struct telegram *instance, peer_id_t chat_id, peer_id_ out_int (mtp, get_peer_id (id)); } out_int (mtp, limit); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &add_user_to_chat_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &add_user_to_chat_methods, 0); } void do_del_user_from_chat (struct telegram *instance, peer_id_t chat_id, peer_id_t id) { @@ -2934,7 +2895,7 @@ void do_del_user_from_chat (struct telegram *instance, peer_id_t chat_id, peer_i out_int (mtp, get_peer_id (chat_id)); assert (get_peer_type (id) == PEER_USER); - peer_t *U = user_chat_get (id); + peer_t *U = user_chat_get (mtp->bl, id); if (U && U->user.access_hash) { out_int (mtp, CODE_input_user_foreign); out_int (mtp, get_peer_id (id)); @@ -2943,16 +2904,17 @@ void do_del_user_from_chat (struct telegram *instance, peer_id_t chat_id, peer_i out_int (mtp, CODE_input_user_contact); out_int (mtp, get_peer_id (id)); } - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &add_user_to_chat_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &add_user_to_chat_methods, 0); } /* }}} */ /* {{{ Create secret chat */ -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); void do_create_secret_chat (struct telegram *instance, peer_id_t id) { + struct mtproto_connection *mtp = instance->connection; assert (get_peer_type (id) == PEER_USER); - peer_t *U = user_chat_get (id); + peer_t *U = user_chat_get (mtp->bl, id); if (!U) { logprintf ("Can not create chat with unknown user\n"); return; @@ -2970,7 +2932,7 @@ struct query_methods create_group_chat_methods = { void do_create_group_chat (struct telegram *instance, peer_id_t id, char *chat_topic) { struct mtproto_connection *mtp = instance->connection; assert (get_peer_type (id) == PEER_USER); - peer_t *U = user_chat_get (id); + peer_t *U = user_chat_get (mtp->bl, id); if (!U) { logprintf ("Can not create chat with unknown user\n"); return; @@ -2988,7 +2950,7 @@ void do_create_group_chat (struct telegram *instance, peer_id_t id, char *chat_t out_int (mtp, get_peer_id (id)); } out_string (mtp, chat_topic); - send_query (telegram_get_working_dc(instance), mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &create_group_chat_methods, 0); + send_query (instance, telegram_get_working_dc(instance), mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &create_group_chat_methods, 0); } /* }}} */ @@ -3017,7 +2979,7 @@ void do_delete_msg (struct telegram *instance, long long id) { out_int (mtp, CODE_vector); out_int (mtp, 1); out_int (mtp, id); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &delete_msg_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &delete_msg_methods, 0); } /* }}} */ @@ -3045,7 +3007,7 @@ void do_restore_msg (struct telegram *instance, long long id) { out_int (mtp, CODE_vector); out_int (mtp, 1); out_int (mtp, id); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &restore_msg_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &restore_msg_methods, 0); } /* }}} */ int update_status_on_answer (struct query *q UU) { @@ -3065,7 +3027,7 @@ void do_update_status (struct telegram *instance, int online UU) { clear_packet (mtp); out_int (mtp, CODE_account_update_status); out_int (mtp, online ? CODE_bool_false : CODE_bool_true); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &update_status_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &update_status_methods, 0); } int update_typing_on_answer (struct query *q UU) { @@ -3085,6 +3047,14 @@ void do_update_typing (struct telegram *instance, peer_id_t id) { out_int (mtp, CODE_messages_set_typing); out_peer_id (mtp, id); out_int (mtp, CODE_bool_true); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &update_typing_methods, 0); + send_query (instance, DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &update_typing_methods, 0); +} + +int telegram_has_output (struct telegram *instance) +{ + if (instance->session_state == STATE_READY) { + return tree_count_query (instance->queries_tree) > 0; + } + return instance->connection->queries_num > 0; } diff --git a/queries.h b/queries.h index 8587d67..30435d6 100644 --- a/queries.h +++ b/queries.h @@ -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(); diff --git a/structures.c b/structures.c index 8b36ab1..d887814 100644 --- a/structures.c +++ b/structures.c @@ -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)); + } +} + diff --git a/structures.h b/structures.h index 616f417..ff68ad1 100644 --- a/structures.h +++ b/structures.h @@ -22,6 +22,7 @@ // forward-declrataions struct mtproto_connection; +struct binlog; typedef struct { int type; int id; } peer_id_t; #include @@ -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); diff --git a/telegram.h b/telegram.h index f1b85b9..a5c3468 100644 --- a/telegram.h +++ b/telegram.h @@ -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 #include "glib.h" #include "loop.h" -//#include "mtproto-client.h" +#include "tree.h" +#include "queries.h" +#include // 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; };