diff --git a/Makefile.in b/Makefile.in index 72ece7c..7dd4653 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ DIR_LIST=${DEP} ${AUTO} ${EXE} ${OBJ} ${DEP}/auto ${OBJ}/auto EXE_LIST=${EXE}/generate ${EXE}/tlc ${EXE}/telegram-cli -TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/net.o ${OBJ}/mtproto-common.o ${OBJ}/mtproto-client.o ${OBJ}/queries.o ${OBJ}/structures.o ${OBJ}/binlog.o ${OBJ}/lua-tg.o ${OBJ}/auto/auto.o +TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/net.o ${OBJ}/mtproto-common.o ${OBJ}/mtproto-client.o ${OBJ}/queries.o ${OBJ}/structures.o ${OBJ}/binlog.o ${OBJ}/lua-tg.o ${OBJ}/auto/auto.o ${OBJ}/tgl.o TLC_OBJECTS=${OBJ}/tlc.o ${OBJ}/tl-parser.o ${OBJ}/crc32.o GENERATE_OBJECTS=${OBJ}/generate.o COMMON_OBJECTS=${OBJ}/tools.o diff --git a/binlog.c b/binlog.c index 810bbab..66d6527 100644 --- a/binlog.c +++ b/binlog.c @@ -18,11 +18,11 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif #ifdef USE_LUA -# include "lua-tg.h" +# include "lua-tg.h" #endif #include #include @@ -41,13 +41,17 @@ #include "net.h" #include "include.h" #include "mtproto-client.h" +#include "loop.h" + +#include "tgl.h" #include #define BINLOG_BUFFER_SIZE (1 << 20) -int binlog_buffer[BINLOG_BUFFER_SIZE]; -int *rptr; -int *wptr; +static int binlog_buffer[BINLOG_BUFFER_SIZE]; +static int *rptr; +static int *wptr; + extern int test_dc; extern int pts; @@ -61,7 +65,6 @@ char *get_binlog_file_name (void); extern struct dc *DC_list[]; extern struct dc *DC_working; extern int dc_working_num; -extern int our_id; extern int binlog_enabled; extern int encr_root; extern unsigned char *encr_prime; @@ -74,7 +77,7 @@ void *alloc_log_event (int l UU) { return binlog_buffer; } -long long binlog_pos; +static long long binlog_pos; int fetch_comb_binlog_start (void *extra) { return 0; @@ -90,9 +93,7 @@ int fetch_comb_binlog_dc_option (void *extra) { char *ip = fetch_str (l2); int port = fetch_int (); - if (verbosity) { - logprintf ("DC%d '%s' update: %s:%d\n", id, name, ip, port); - } + vlogprintf (E_NOTICE, "DC%d '%s' update: %s:%d\n", id, name, ip, port); alloc_dc (id, tstrndup (ip, l2), port); return 0; @@ -117,9 +118,9 @@ int fetch_comb_binlog_default_dc (void *extra) { } int fetch_comb_binlog_our_id (void *extra) { - our_id = fetch_int (); + tgl_state.our_id = fetch_int (); #ifdef USE_LUA - lua_our_id (our_id); + lua_our_id (tgl_state.our_id); #endif return 0; } @@ -190,7 +191,7 @@ int fetch_comb_binlog_user_add (void *extra) { } struct user *U = (void *)_U; U->flags |= FLAG_CREATED; - if (get_peer_id (id) == our_id) { + if (get_peer_id (id) == tgl_state.our_id) { U->flags |= FLAG_USER_SELF; } U->first_name = fetch_str_dup (); @@ -274,7 +275,7 @@ int fetch_comb_binlog_user_set_full_photo (void *extra) { if (U->flags & FLAG_HAS_PHOTO) { free_photo (&U->user.photo); } - fetch_photo (&U->user.photo); + tglf_fetch_photo (&U->user.photo); #ifdef USE_LUA lua_user_update (&U->user); @@ -347,8 +348,8 @@ int fetch_comb_binlog_user_set_photo (void *extra) { } else { assert (y == CODE_user_profile_photo); U->user.photo_id = fetch_long (); - fetch_file_location (&U->user.photo_small); - fetch_file_location (&U->user.photo_big); + tglf_fetch_file_location (&U->user.photo_small); + tglf_fetch_file_location (&U->user.photo_big); } #ifdef USE_LUA @@ -502,7 +503,7 @@ int fetch_comb_binlog_encr_chat_init (void *extra) { P->id = MK_ENCR_CHAT (fetch_int ()); assert (!peer_get (P->id)); P->encr_chat.user_id = fetch_int (); - P->encr_chat.admin_id = our_id; + P->encr_chat.admin_id = tgl_state.our_id; insert_encrypted_chat (P); peer_t *Us = peer_get (MK_USER (P->encr_chat.user_id)); assert (Us); @@ -649,7 +650,7 @@ int fetch_comb_binlog_chat_set_full_photo (void *extra) { if (C->flags & FLAG_HAS_PHOTO) { free_photo (&C->chat.photo); } - fetch_photo (&C->chat.photo); + tglf_fetch_photo (&C->chat.photo); #ifdef USE_LUA lua_chat_update (&C->chat); @@ -722,10 +723,7 @@ int fetch_comb_binlog_create_message_text (void *extra) { struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -753,7 +751,7 @@ int fetch_comb_binlog_create_message_text (void *extra) { } M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; message_insert (M); @@ -768,10 +766,7 @@ int fetch_comb_binlog_send_message_text (void *extra) { struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -799,7 +794,7 @@ int fetch_comb_binlog_send_message_text (void *extra) { } M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; message_insert (M); message_insert_unsent (M); @@ -816,10 +811,7 @@ int fetch_comb_binlog_send_message_action_encr (void *extra) { struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -832,10 +824,10 @@ int fetch_comb_binlog_send_message_action_encr (void *extra) { M->date = fetch_int (); M->media.type = CODE_decrypted_message_media_empty; - fetch_message_action_encrypted ((void *)peer_get (M->to_id), &M->action); + tglf_fetch_message_action_encrypted (&M->action); M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; M->service = 1; message_insert (M); @@ -853,10 +845,7 @@ int fetch_comb_binlog_create_message_text_fwd (void *extra) { struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -887,7 +876,7 @@ int fetch_comb_binlog_create_message_text_fwd (void *extra) { } M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; message_insert (M); @@ -901,10 +890,7 @@ int fetch_comb_binlog_create_message_media (void *extra) { int id = fetch_int (); struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -920,9 +906,9 @@ int fetch_comb_binlog_create_message_media (void *extra) { M->message[l] = 0; M->message_len = l; - fetch_message_media (&M->media); + tglf_fetch_message_media (&M->media); M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; message_insert (M); #ifdef USE_LUA @@ -935,10 +921,7 @@ int fetch_comb_binlog_create_message_media_encr (void *extra) { long long id = fetch_long (); struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -954,10 +937,10 @@ int fetch_comb_binlog_create_message_media_encr (void *extra) { M->message[l] = 0; M->message_len = l; - fetch_message_media_encrypted (&M->media); - fetch_encrypted_message_file (&M->media); + tglf_fetch_message_media_encrypted (&M->media); + tglf_fetch_encrypted_message_file (&M->media); M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; message_insert (M); #ifdef USE_LUA @@ -970,10 +953,7 @@ int fetch_comb_binlog_create_message_media_fwd (void *extra) { int id = fetch_int (); struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -992,9 +972,9 @@ int fetch_comb_binlog_create_message_media_fwd (void *extra) { M->message[l] = 0; M->message_len = l; - fetch_message_media (&M->media); + tglf_fetch_message_media (&M->media); M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; message_insert (M); #ifdef USE_LUA @@ -1007,10 +987,7 @@ int fetch_comb_binlog_create_message_service (void *extra) { int id = fetch_int (); struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -1020,9 +997,9 @@ int fetch_comb_binlog_create_message_service (void *extra) { M->to_id = set_peer_id (t, fetch_int ()); M->date = fetch_int (); - fetch_message_action (&M->action); + tglf_fetch_message_action (&M->action); M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; M->service = 1; message_insert (M); @@ -1036,10 +1013,7 @@ int fetch_comb_binlog_create_message_service_encr (void *extra) { long long id = fetch_long (); struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -1053,11 +1027,15 @@ int fetch_comb_binlog_create_message_service_encr (void *extra) { struct secret_chat *E = (void *)peer_get (M->to_id); assert (E); - fetch_message_action_encrypted (0, &M->action); + tglf_fetch_message_action_encrypted (&M->action); M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; M->service = 1; + if (!M->out && M->action.type == CODE_decrypted_message_action_notify_layer) { + E->layer = M->action.layer; + } + message_insert (M); #ifdef USE_LUA lua_new_msg (M); @@ -1069,10 +1047,7 @@ int fetch_comb_binlog_create_message_service_fwd (void *extra) { int id = fetch_int (); struct message *M = message_get (id); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = id; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (id); } else { assert (!(M->flags & FLAG_CREATED)); } @@ -1085,9 +1060,9 @@ int fetch_comb_binlog_create_message_service_fwd (void *extra) { M->fwd_from_id = MK_USER (fetch_int ()); M->fwd_date = fetch_int (); - fetch_message_action (&M->action); + tglf_fetch_message_action (&M->action); M->unread = 1; - M->out = get_peer_id (M->from_id) == our_id; + M->out = get_peer_id (M->from_id) == tgl_state.our_id; M->service = 1; message_insert (M); @@ -1260,7 +1235,7 @@ void create_new_binlog (void) { out_int (CODE_binlog_dc_option); out_int (1); out_string (""); - out_string (test_dc ? TG_SERVER_TEST : TG_SERVER); + out_string (tgl_params.test_mode ? TG_SERVER_TEST : TG_SERVER); out_int (443); out_int (CODE_binlog_default_dc); out_int (1); @@ -1365,10 +1340,15 @@ void bl_do_set_auth_key_id (int num, unsigned char *buf) { } void bl_do_set_our_id (int id) { + if (tgl_state.our_id) { + assert (tgl_state.our_id == id); + return; + } int *ev = alloc_log_event (8); ev[0] = CODE_binlog_our_id; ev[1] = id; add_log_event (ev, 8); + write_auth_file (); } void bl_do_user_add (int id, const char *f, int fl, const char *l, int ll, long long access_token, const char *p, int pl, int contact) { diff --git a/interface.c b/interface.c index 39a32db..a5f4106 100644 --- a/interface.c +++ b/interface.c @@ -46,6 +46,8 @@ #include "mtproto-common.h" +#include "tgl.h" + #define ALLOW_MULT 1 char *default_prompt = "> "; @@ -144,12 +146,12 @@ peer_id_t next_token_user (void) { else { return PEER_NOT_FOUND; } } - int index = 0; - while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_USER)) { - index ++; - } - if (index < peer_num) { - return Peers[index]->id; + char c = s[l]; + peer_t *P = peer_lookup_name (s); + s[l] = c; + + if (P && get_peer_type (P->id) == PEER_USER) { + return P->id; } else { return PEER_NOT_FOUND; } @@ -168,12 +170,12 @@ peer_id_t next_token_chat (void) { else { return PEER_NOT_FOUND; } } - int index = 0; - while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_CHAT)) { - index ++; - } - if (index < peer_num) { - return Peers[index]->id; + char c = s[l]; + peer_t *P = peer_lookup_name (s); + s[l] = c; + + if (P && get_peer_type (P->id) == PEER_CHAT) { + return P->id; } else { return PEER_NOT_FOUND; } @@ -184,12 +186,12 @@ peer_id_t next_token_encr_chat (void) { char *s = next_token (&l); if (!s) { return PEER_NOT_FOUND; } - int index = 0; - while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_ENCR_CHAT)) { - index ++; - } - if (index < peer_num) { - return Peers[index]->id; + char c = s[l]; + peer_t *P = peer_lookup_name (s); + s[l] = c; + + if (P && get_peer_type (P->id) == PEER_ENCR_CHAT) { + return P->id; } else { return PEER_NOT_FOUND; } @@ -214,13 +216,13 @@ peer_id_t next_token_peer (void) { if (r >= 0) { return set_peer_id (PEER_CHAT, r); } else { return PEER_NOT_FOUND; } } - - int index = 0; - while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name))) { - index ++; - } - if (index < peer_num) { - return Peers[index]->id; + + char c = s[l]; + peer_t *P = peer_lookup_name (s); + s[l] = c; + + if (P) { + return P->id; } else { return PEER_NOT_FOUND; } @@ -431,58 +433,6 @@ int get_complete_mode (void) { } } -int complete_user_list (int index, const char *text, int len, char **R) { - index ++; - while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_USER)) { - index ++; - } - if (index < peer_num) { - *R = strdup (Peers[index]->print_name); - return index; - } else { - return -1; - } -} - -int complete_chat_list (int index, const char *text, int len, char **R) { - index ++; - while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_CHAT)) { - index ++; - } - if (index < peer_num) { - *R = strdup (Peers[index]->print_name); - return index; - } else { - return -1; - } -} - -int complete_encr_chat_list (int index, const char *text, int len, char **R) { - index ++; - while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_ENCR_CHAT)) { - index ++; - } - if (index < peer_num) { - *R = strdup (Peers[index]->print_name); - return index; - } else { - return -1; - } -} - -int complete_user_chat_list (int index, const char *text, int len, char **R) { - index ++; - while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) { - index ++; - } - if (index < peer_num) { - *R = strdup (Peers[index]->print_name); - return index; - } else { - return -1; - } -} - int complete_string_list (char **list, int index, const char *text, int len, char **R) { index ++; while (list[index] && strncmp (list[index], text, len)) { @@ -533,7 +483,7 @@ char *command_generator (const char *text, int state) { if (c) { rl_line_buffer[rl_point] = c; } return R; case 2: - index = complete_user_chat_list (index, text, len, &R); + index = complete_peer_list (index, text, len, &R); if (c) { rl_line_buffer[rl_point] = c; } return R; case 3: @@ -674,7 +624,7 @@ void interpreter (char *line UU) { do_get_dialog_list (); } else if (IS_WORD ("stats")) { static char stat_buf[1 << 15]; - print_stat (stat_buf, (1 << 15) - 1); + tgl_print_stat (stat_buf, (1 << 15) - 1); printf ("%s\n", stat_buf); } else if (IS_WORD ("msg")) { GET_PEER; @@ -1392,8 +1342,6 @@ void print_date_full (long t) { printf ("[%04d/%02d/%02d %02d:%02d:%02d]", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } -int our_id; - void print_service_message (struct message *M) { assert (M); print_start (); @@ -1578,7 +1526,7 @@ void print_message (struct message *M) { print_chat_name (M->to_id, peer_get (M->to_id)); printf (" "); print_user_name (M->from_id, peer_get (M->from_id)); - if ((get_peer_type (M->from_id) == PEER_USER) && (get_peer_id (M->from_id) == our_id)) { + if ((get_peer_type (M->from_id) == PEER_USER) && (get_peer_id (M->from_id) == tgl_state.our_id)) { push_color (COLOR_GREEN); } else { push_color (COLOR_BLUE); diff --git a/interface.h b/interface.h index 99f0319..19c2fc7 100644 --- a/interface.h +++ b/interface.h @@ -33,6 +33,11 @@ #define COLOR_INVERSE "\033[7m" +#define E_ERROR 0 +#define E_WARNING 1 +#define E_NOTICE 2 +#define E_DEBUG 3 + char *get_default_prompt (void); char *complete_none (const char *text, int state); char **complete_text (char *text, int start, int end); @@ -40,6 +45,15 @@ void interpreter (char *line); void rprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2))); void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2))); + +#define vlogprintf(v,...) \ + do { \ + if (tgl_params.verbosity >= (v)) {\ + logprintf (__VA_ARGS__);\ + }\ + } while (0);\ + + void hexdump (int *in_ptr, int *in_end); struct message; diff --git a/loop.c b/loop.c index 2b39c42..d65ba80 100644 --- a/loop.c +++ b/loop.c @@ -52,6 +52,9 @@ #include "loop.h" #include "binlog.h" #include "lua-tg.h" +#include "structures.h" + +#include "tgl.h" #include "auto.h" @@ -177,7 +180,6 @@ void write_dc (int auth_file_fd, struct dc *DC) { assert (write (auth_file_fd, &DC->has_auth, 4) == 4); } -int our_id; void write_auth_file (void) { if (binlog_enabled) { return; } int auth_file_fd = open (get_auth_key_filename (), O_CREAT | O_RDWR, 0600); @@ -199,7 +201,7 @@ void write_auth_file (void) { assert (write (auth_file_fd, &x, 4) == 4); } } - assert (write (auth_file_fd, &our_id, 4) == 4); + assert (write (auth_file_fd, &tgl_state.our_id, 4) == 4); close (auth_file_fd); } @@ -227,7 +229,7 @@ void read_dc (int auth_file_fd, int id, unsigned ver) { } void empty_auth_file (void) { - alloc_dc (1, tstrdup (test_dc ? TG_SERVER_TEST : TG_SERVER), 443); + alloc_dc (1, tstrdup (tgl_params.test_mode ? TG_SERVER_TEST : TG_SERVER), 443); dc_working_num = 1; auth_state = 0; write_auth_file (); @@ -263,7 +265,7 @@ void read_auth_file (void) { read_dc (auth_file_fd, i, m); } } - int l = read (auth_file_fd, &our_id, 4); + int l = read (auth_file_fd, &tgl_state.our_id, 4); if (l < 4) { assert (!l); } @@ -387,6 +389,40 @@ void read_secret_chat_file (void) { close (fd); } +void count_encr_peer (peer_t *P, void *cc) { + if (get_peer_type (P->id) == PEER_ENCR_CHAT && P->encr_chat.state != sc_none && P->encr_chat.state != sc_deleted) { + (*(int *)cc) ++; + } +} + +void write_encr_peer (peer_t *P, void *pfd) { + int fd = *(int *)pfd; + if (get_peer_type (P->id) == PEER_ENCR_CHAT && P->encr_chat.state != sc_none && P->encr_chat.state != sc_deleted) { + int t = get_peer_id (P->id); + assert (write (fd, &t, 4) == 4); + t = P->flags; + assert (write (fd, &t, 4) == 4); + t = strlen (P->print_name); + assert (write (fd, &t, 4) == 4); + assert (write (fd, P->print_name, t) == t); + + assert (write (fd, &P->encr_chat.state, 4) == 4); + + assert (write (fd, &P->encr_chat.user_id, 4) == 4); + assert (write (fd, &P->encr_chat.admin_id, 4) == 4); + assert (write (fd, &P->encr_chat.ttl, 4) == 4); + assert (write (fd, &P->encr_chat.access_hash, 8) == 8); + if (P->encr_chat.state != sc_waiting) { + assert (write (fd, P->encr_chat.g_key, 256) == 256); + } + if (P->encr_chat.state != sc_waiting) { + assert (write (fd, P->encr_chat.nonce, 256) == 256); + } + assert (write (fd, P->encr_chat.key, 256) == 256); + assert (write (fd, &P->encr_chat.key_fingerprint, 8) == 8); + } +} + void write_secret_chat_file (void) { if (binlog_enabled) { return; } int fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600); @@ -397,40 +433,11 @@ void write_secret_chat_file (void) { x[0] = SECRET_CHAT_FILE_MAGIC; x[1] = 1; 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) { - 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); - assert (write (fd, &t, 4) == 4); - t = Peers[i]->flags; - assert (write (fd, &t, 4) == 4); - t = strlen (Peers[i]->print_name); - assert (write (fd, &t, 4) == 4); - assert (write (fd, Peers[i]->print_name, t) == t); - - assert (write (fd, &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); - } - if (Peers[i]->encr_chat.state != sc_waiting) { - assert (write (fd, 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); - } - } + int cc = 0; + peer_iterator_ex (count_encr_peer, &cc); + peer_iterator_ex (write_encr_peer, &fd); + assert (write (fd, &encr_root, 4) == 4); if (encr_root) { assert (write (fd, &encr_param_version, 4) == 4); diff --git a/lua-tg.c b/lua-tg.c index b956cf4..e57fcbc 100644 --- a/lua-tg.c +++ b/lua-tg.c @@ -343,11 +343,7 @@ void *lua_ptr[MAX_LUA_COMMANDS]; static int pos; static peer_t *get_peer (const char *s) { - int index = 0; - while (index < peer_num && (!Peers[index]->print_name || strcmp (Peers[index]->print_name, s))) { - index ++; - } - return index == peer_num ? 0 : Peers[index]; + return peer_lookup_name (s); } void lua_do_all (void) { diff --git a/main.c b/main.c index 44de05a..d6c56bc 100644 --- a/main.c +++ b/main.c @@ -57,6 +57,8 @@ # include "lua-tg.h" #endif +#include "tgl.h" + #define PROGNAME "telegram-client" #define VERSION "0.01" @@ -79,7 +81,6 @@ char *auth_token; int msg_num_mode; char *config_filename; char *prefix; -int test_dc; char *auth_file_name; char *state_file_name; char *secret_chat_file_name; @@ -296,9 +297,10 @@ void parse_config (void) { memcpy (buf, prefix, l); buf[l ++] = '.'; } - test_dc = 0; + + tgl_params.test_mode = 0; strcpy (buf + l, "test"); - config_lookup_bool (&conf, buf, &test_dc); + config_lookup_bool (&conf, buf, &tgl_params.test_mode); strcpy (buf + l, "log_level"); long long t = log_level; @@ -369,7 +371,6 @@ void usage (void) { } extern char *rsa_public_key_name; -extern int verbosity; extern int default_dc_num; char *log_net_file; @@ -392,7 +393,7 @@ void args_parse (int argc, char **argv) { rsa_public_key_name = tstrdup (optarg); break; case 'v': - verbosity ++; + tgl_params.verbosity ++; break; case 'N': msg_num_mode ++; diff --git a/mtproto-client.c b/mtproto-client.c index d58391f..f98eaac 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -779,7 +779,6 @@ int auth_work_start (struct connection *c UU) { void rpc_execute_answer (struct connection *c, long long msg_id UU); int unread_messages; -int our_id; int pts; int qts; int last_date; @@ -881,8 +880,8 @@ void work_update_binlog (void) { } else { assert (y == CODE_user_profile_photo); U->photo_id = fetch_long (); - fetch_file_location (&U->photo_small); - fetch_file_location (&U->photo_big); + tglf_fetch_file_location (&U->photo_small); + tglf_fetch_file_location (&U->photo_big); } } else { struct file_location t; @@ -891,8 +890,8 @@ void work_update_binlog (void) { } else { assert (y == CODE_user_profile_photo); fetch_long (); // photo_id - fetch_file_location (&t); - fetch_file_location (&t); + tglf_fetch_file_location (&t); + tglf_fetch_file_location (&t); } } fetch_bool (); @@ -908,7 +907,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { switch (op) { case CODE_update_new_message: { - struct message *M = fetch_alloc_message (); + struct message *M = tglf_fetch_alloc_message (); assert (M); fetch_pts (); unread_messages ++; @@ -990,7 +989,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { peer_id_t user_id = MK_USER (fetch_int ()); peer_t *U = peer_get (user_id); if (U) { - fetch_user_status (&U->user.status); + tglf_fetch_user_status (&U->user.status); if (log_level >= 3) { print_start (); push_color (COLOR_YELLOW); @@ -1004,7 +1003,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { } } else { struct user_status t; - fetch_user_status (&t); + tglf_fetch_user_status (&t); } } break; @@ -1055,8 +1054,8 @@ void work_update (struct connection *c UU, long long msg_id UU) { } else { assert (y == CODE_user_profile_photo); photo_id = fetch_long (); - fetch_file_location (&small); - fetch_file_location (&big); + tglf_fetch_file_location (&small); + tglf_fetch_file_location (&big); } bl_do_set_user_profile_photo (U, photo_id, &big, &small); @@ -1075,8 +1074,8 @@ void work_update (struct connection *c UU, long long msg_id UU) { } else { assert (y == CODE_user_profile_photo); fetch_long (); // photo_id - fetch_file_location (&t); - fetch_file_location (&t); + tglf_fetch_file_location (&t); + tglf_fetch_file_location (&t); } } fetch_bool (); @@ -1228,7 +1227,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { break; case CODE_update_new_geo_chat_message: { - struct message *M = fetch_alloc_geo_message (); + struct message *M = tglf_fetch_alloc_geo_message (); unread_messages ++; print_message (M); update_prompt (); @@ -1236,7 +1235,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { break; case CODE_update_new_encrypted_message: { - struct message *M = fetch_alloc_encrypted_message (); + struct message *M = tglf_fetch_alloc_encrypted_message (); unread_messages ++; print_message (M); update_prompt (); @@ -1245,7 +1244,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { break; case CODE_update_encryption: { - struct secret_chat *E = fetch_alloc_encrypted_chat (); + struct secret_chat *E = tglf_fetch_alloc_encrypted_chat (); if (verbosity >= 2) { logprintf ("Secret chat state = %d\n", E->state); } @@ -1441,12 +1440,12 @@ void work_updates (struct connection *c, long long msg_id) { assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_user (); + tglf_fetch_alloc_user (); } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_chat (); + tglf_fetch_alloc_chat (); } bl_do_set_date (fetch_int ()); bl_do_set_seq (fetch_int ()); @@ -1455,7 +1454,7 @@ void work_updates (struct connection *c, long long msg_id) { void work_update_short_message (struct connection *c UU, long long msg_id UU) { assert (fetch_int () == (int)CODE_update_short_message); - struct message *M = fetch_alloc_message_short (); + struct message *M = tglf_fetch_alloc_message_short (); unread_messages ++; print_message (M); update_prompt (); @@ -1466,7 +1465,7 @@ void work_update_short_message (struct connection *c UU, long long msg_id UU) { void work_update_short_chat_message (struct connection *c UU, long long msg_id UU) { assert (fetch_int () == CODE_update_short_chat_message); - struct message *M = fetch_alloc_message_short_chat (); + struct message *M = tglf_fetch_alloc_message_short_chat (); unread_messages ++; print_message (M); update_prompt (); diff --git a/queries.c b/queries.c index 6948129..06fdd70 100644 --- a/queries.c +++ b/queries.c @@ -54,6 +54,7 @@ #include "no-preview.h" #include "binlog.h" #include "auto.h" +#include "tgl.h" #define sha1 SHA1 @@ -630,7 +631,6 @@ int do_get_nearest_dc (void) { /* {{{ Sign in / Sign up */ int sign_in_ok; -int our_id; int sign_in_is_ok (void) { return sign_in_ok; } @@ -640,11 +640,9 @@ struct user User; int sign_in_on_answer (struct query *q UU) { assert (fetch_int () == (int)CODE_auth_authorization); int expires = fetch_int (); - fetch_user (&User); - if (!our_id) { - our_id = get_peer_id (User.id); - - bl_do_set_our_id (our_id); + tglf_fetch_user (&User); + if (!tgl_state.our_id) { + bl_do_set_our_id (get_peer_id (User.id)); } sign_in_ok = 1; if (verbosity) { @@ -714,7 +712,7 @@ int get_contacts_on_answer (struct query *q UU) { assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - struct user *U = fetch_alloc_user (); + struct user *U = tglf_fetch_alloc_user (); print_start (); push_color (COLOR_YELLOW); printf ("User #%d: ", get_peer_id (U->id)); @@ -846,7 +844,7 @@ void do_send_encr_chat_layer (struct secret_chat *E) { int action[2]; action[0] = CODE_decrypted_message_action_notify_layer; action[1] = 15; - bl_do_send_message_action_encr (t, our_id, get_peer_type (E->id), get_peer_id (E->id), time (0), 2, action); + bl_do_send_message_action_encr (t, tgl_state.our_id, get_peer_type (E->id), get_peer_id (E->id), time (0), 2, action); struct message *M = message_get (t); assert (M); @@ -891,7 +889,7 @@ int msg_send_on_answer (struct query *q UU) { if (b == CODE_contacts_foreign_link_requested) { fetch_bool (); } - struct user *U = fetch_alloc_user (); + struct user *U = tglf_fetch_alloc_user (); U->flags &= ~(FLAG_USER_IN_CONTACT | FLAG_USER_OUT_CONTACT); if (a == CODE_contacts_my_link_contact) { @@ -937,7 +935,6 @@ struct query_methods msg_send_encr_methods = { }; int out_message_num; -int our_id; void do_send_encr_msg_action (struct message *M) { peer_t *P = peer_get (M->to_id); @@ -1024,7 +1021,7 @@ void do_send_message (peer_id_t id, const char *msg, int len) { long long t; secure_random (&t, 8); logprintf ("t = %lld, len = %d\n", t, len); - bl_do_send_message_text (t, our_id, get_peer_type (id), get_peer_id (id), time (0), len, msg); + bl_do_send_message_text (t, tgl_state.our_id, get_peer_type (id), get_peer_id (id), time (0), len, msg); struct message *M = message_get (t); assert (M); do_send_msg (M); @@ -1137,7 +1134,7 @@ int get_history_on_answer (struct query *q UU) { assert (fetch_int () == CODE_vector); int n = fetch_int (); for (i = 0; i < n; i++) { - struct message *M = fetch_alloc_message (); + struct message *M = tglf_fetch_alloc_message (); if (i <= 9999) { ML[i] = M; } @@ -1150,12 +1147,12 @@ int get_history_on_answer (struct query *q UU) { assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_chat (); + tglf_fetch_alloc_chat (); } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_user (); + tglf_fetch_alloc_user (); } if (sn > 0 && q->extra) { do_messages_mark_read (*(peer_id_t *)&(q->extra), ML[0]->id); @@ -1217,11 +1214,11 @@ int get_dialogs_on_answer (struct query *q UU) { for (i = 0; i < n; i++) { assert (fetch_int () == (int)CODE_dialog); if (i < 100) { - plist[i] = fetch_peer_id (); + plist[i] = tglf_fetch_peer_id (); dlist[2 * i + 0] = fetch_int (); dlist[2 * i + 1] = fetch_int (); } else { - fetch_peer_id (); + tglf_fetch_peer_id (); fetch_int (); fetch_int (); } @@ -1230,17 +1227,17 @@ int get_dialogs_on_answer (struct query *q UU) { assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_message (); + tglf_fetch_alloc_message (); } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_chat (); + tglf_fetch_alloc_chat (); } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_user (); + tglf_fetch_alloc_user (); } print_start (); push_color (COLOR_YELLOW); @@ -1336,17 +1333,17 @@ int send_file_part_on_answer (struct query *q) { int send_file_on_answer (struct query *q UU) { assert (fetch_int () == (int)CODE_messages_stated_message); - struct message *M = fetch_alloc_message (); + struct message *M = tglf_fetch_alloc_message (); assert (fetch_int () == CODE_vector); int n, i; n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_chat (); + tglf_fetch_alloc_chat (); } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_user (); + tglf_fetch_alloc_user (); } fetch_pts (); fetch_seq (); @@ -1563,7 +1560,7 @@ void send_part (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 (tgl_state.our_id); M->to_id = f->to_id; M->unread = 1; M->message = tstrdup (""); @@ -1653,17 +1650,17 @@ void do_send_photo (int type, peer_id_t to_id, char *file_name) { /* {{{ Forward */ int fwd_msg_on_answer (struct query *q UU) { assert (fetch_int () == (int)CODE_messages_stated_message); - struct message *M = fetch_alloc_message (); + struct message *M = tglf_fetch_alloc_message (); assert (fetch_int () == CODE_vector); int n, i; n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_chat (); + tglf_fetch_alloc_chat (); } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_user (); + tglf_fetch_alloc_user (); } fetch_pts (); fetch_seq (); @@ -1693,17 +1690,17 @@ void do_forward_message (peer_id_t id, int n) { /* {{{ Rename chat */ int rename_chat_on_answer (struct query *q UU) { assert (fetch_int () == (int)CODE_messages_stated_message); - struct message *M = fetch_alloc_message (); + struct message *M = tglf_fetch_alloc_message (); assert (fetch_int () == CODE_vector); int n, i; n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_chat (); + tglf_fetch_alloc_chat (); } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_user (); + tglf_fetch_alloc_user (); } fetch_pts (); fetch_seq (); @@ -1752,7 +1749,7 @@ void print_chat_info (struct chat *C) { } int chat_info_on_answer (struct query *q UU) { - struct chat *C = fetch_alloc_chat_full (); + struct chat *C = tglf_fetch_alloc_chat_full (); print_chat_info (C); return 0; } @@ -1803,7 +1800,7 @@ void print_user_info (struct user *U) { } int user_info_on_answer (struct query *q UU) { - struct user *U = fetch_alloc_user_full (); + struct user *U = tglf_fetch_alloc_user_full (); print_user_info (U); return 0; } @@ -1845,7 +1842,7 @@ int user_list_info_silent_on_answer (struct query *q UU) { int n = fetch_int (); int i; for (i = 0; i < n; i++) { - fetch_alloc_user (); + tglf_fetch_alloc_user (); } return 0; } @@ -2140,13 +2137,8 @@ int isn_export_auth_str (void) { int export_auth_on_answer (struct query *q UU) { assert (fetch_int () == (int)CODE_auth_exported_authorization); - int l = fetch_int (); - if (!our_id) { - our_id = l; - } else { - assert (our_id == l); - } - l = prefetch_strlen (); + bl_do_set_our_id (fetch_int ()); + int l = prefetch_strlen (); char *s = talloc (l); memcpy (s, fetch_str (l), l); export_auth_str_len = l; @@ -2174,7 +2166,7 @@ void do_export_auth (int num) { int import_auth_on_answer (struct query *q UU) { assert (fetch_int () == (int)CODE_auth_authorization); fetch_int (); // expires - fetch_alloc_user (); + tglf_fetch_alloc_user (); tfree (export_auth_str, export_auth_str_len); export_auth_str = 0; return 0; @@ -2190,7 +2182,7 @@ void do_import_auth (int num) { clear_packet (); do_insert_header (); out_int (CODE_auth_import_authorization); - out_int (our_id); + out_int (tgl_state.our_id); out_cstring (export_auth_str, export_auth_str_len); send_query (DC_list[num], packet_ptr - packet_buffer, packet_buffer, &import_auth_methods, 0); net_loop (0, isn_export_auth_str); @@ -2222,7 +2214,7 @@ int add_contact_on_answer (struct query *q UU) { assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n ; i++) { - struct user *U = fetch_alloc_user (); + struct user *U = tglf_fetch_alloc_user (); print_start (); push_color (COLOR_YELLOW); printf ("User #%d: ", get_peer_id (U->id)); @@ -2322,7 +2314,7 @@ int contacts_search_on_answer (struct query *q UU) { print_start (); push_color (COLOR_YELLOW); for (i = 0; i < n; i++) { - struct user *U = fetch_alloc_user (); + struct user *U = tglf_fetch_alloc_user (); printf ("User "); push_color (COLOR_RED); printf ("%s %s", U->first_name, U->last_name); @@ -2350,7 +2342,7 @@ void do_contacts_search (int limit, const char *s) { /* {{{ Encr accept */ int send_encr_accept_on_answer (struct query *q UU) { - struct secret_chat *E = fetch_alloc_encrypted_chat (); + struct secret_chat *E = tglf_fetch_alloc_encrypted_chat (); if (E->state == sc_ok) { print_start (); @@ -2373,7 +2365,7 @@ int send_encr_accept_on_answer (struct query *q UU) { } int send_encr_request_on_answer (struct query *q UU) { - struct secret_chat *E = fetch_alloc_encrypted_chat (); + struct secret_chat *E = tglf_fetch_alloc_encrypted_chat (); if (E->state == sc_deleted) { print_start (); push_color (COLOR_YELLOW); @@ -2682,18 +2674,18 @@ int get_difference_on_answer (struct query *q UU) { int ml_pos = 0; for (i = 0; i < n; i++) { if (ml_pos < 10000) { - ML[ml_pos ++] = fetch_alloc_message (); + ML[ml_pos ++] = tglf_fetch_alloc_message (); } else { - fetch_alloc_message (); + tglf_fetch_alloc_message (); } } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { if (ml_pos < 10000) { - ML[ml_pos ++] = fetch_alloc_encrypted_message (); + ML[ml_pos ++] = tglf_fetch_alloc_encrypted_message (); } else { - fetch_alloc_encrypted_message (); + tglf_fetch_alloc_encrypted_message (); } } assert (fetch_int () == CODE_vector); @@ -2704,12 +2696,12 @@ int get_difference_on_answer (struct query *q UU) { assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_chat (); + tglf_fetch_alloc_chat (); } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_user (); + tglf_fetch_alloc_user (); } assert (fetch_int () == (int)CODE_updates_state); bl_do_set_pts (fetch_int ()); @@ -2815,7 +2807,7 @@ int get_suggested_on_answer (struct query *q UU) { print_start (); push_color (COLOR_YELLOW); for (i = 0; i < m; i++) { - peer_t *U = (void *)fetch_alloc_user (); + peer_t *U = (void *)tglf_fetch_alloc_user (); assert (get_peer_id (U->id) == l[2 * i]); print_user_name (U->id, U); printf (" phone %s: %d mutual friends\n", U->user.phone, l[2 * i + 1]); diff --git a/structures.c b/structures.c index fa1f316..5554b42 100644 --- a/structures.c +++ b/structures.c @@ -33,8 +33,11 @@ #include "queries.h" #include "binlog.h" +#include "tgl.h" + #define sha1 SHA1 + static int id_cmp (struct message *M1, struct message *M2); #define peer_cmp(a,b) (cmp_peer_id (a->id, b->id)) #define peer_cmp_name(a,b) (strcmp (a->print_name, b->print_name)) @@ -43,28 +46,25 @@ DEFINE_TREE(peer_by_name,peer_t *,peer_cmp_name,0) DEFINE_TREE(message,struct message *,id_cmp,0) -struct message message_list = { +static struct message message_list = { .next_use = &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; +static struct tree_peer *peer_tree; +static struct tree_peer_by_name *peer_by_name_tree; +static struct tree_message *message_tree; +static 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; +static int users_allocated; +static int chats_allocated; +static int messages_allocated; +static int peer_num; +static int encr_chats_allocated; +static int geo_chats_allocated; -int our_id; -int verbosity; +static peer_t *Peers[MAX_PEER_NUM]; -peer_t *Peers[MAX_PEER_NUM]; -extern int binlog_enabled; char *create_print_name (peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4) { @@ -106,7 +106,7 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha * */ -int fetch_file_location (struct file_location *loc) { +int tglf_fetch_file_location (struct file_location *loc) { int x = fetch_int (); assert (x == CODE_file_location_unavailable || x == CODE_file_location); @@ -124,7 +124,7 @@ int fetch_file_location (struct file_location *loc) { return 0; } -int fetch_user_status (struct user_status *S) { +int tglf_fetch_user_status (struct user_status *S) { unsigned x = fetch_int (); assert (x == CODE_user_status_empty || x == CODE_user_status_online || x == CODE_user_status_offline); switch (x) { @@ -152,7 +152,7 @@ int fetch_user_status (struct user_status *S) { * */ -long long fetch_user_photo (struct user *U) { +long long tglf_fetch_user_photo (struct user *U) { unsigned x = fetch_int (); assert (x == CODE_user_profile_photo || x == CODE_user_profile_photo_old || x == CODE_user_profile_photo_empty); if (x == CODE_user_profile_photo_empty) { @@ -165,14 +165,14 @@ long long fetch_user_photo (struct user *U) { } static struct file_location big; static struct file_location small; - assert (fetch_file_location (&small) >= 0); - assert (fetch_file_location (&big) >= 0); + assert (tglf_fetch_file_location (&small) >= 0); + assert (tglf_fetch_file_location (&big) >= 0); bl_do_set_user_profile_photo (U, photo_id, &big, &small); return 0; } -int fetch_user (struct user *U) { +int tglf_fetch_user (struct user *U) { unsigned x = fetch_int (); 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 ()); @@ -181,11 +181,7 @@ int fetch_user (struct user *U) { } if (x == CODE_user_self) { - assert (!our_id || (our_id == get_peer_id (U->id))); - if (!our_id) { - bl_do_set_our_id (get_peer_id (U->id)); - write_auth_file (); - } + bl_do_set_our_id (get_peer_id (U->id)); } int new = !(U->flags & FLAG_CREATED); @@ -202,9 +198,9 @@ int fetch_user (struct user *U) { bl_do_user_delete (U); } if (x != CODE_user_deleted) { - long long access_token = 0; + long long access_hash = 0; if (x != CODE_user_self) { - access_token = fetch_long (); + access_hash = fetch_long (); } int phone_len = 0; char *phone = 0; @@ -213,10 +209,10 @@ int fetch_user (struct user *U) { assert (phone_len >= 0); phone = fetch_str (phone_len); } - bl_do_user_add (get_peer_id (U->id), s1, l1, s2, l2, access_token, phone, phone_len, x == CODE_user_contact); - if (fetch_user_photo (U) < 0) { return -1; } - - if (fetch_user_status (&U->status) < 0) { return -1; } + bl_do_user_add (get_peer_id (U->id), s1, l1, s2, l2, access_hash, phone, phone_len, x == CODE_user_contact); + assert (tglf_fetch_user_photo (U) >= 0); + assert (tglf_fetch_user_status (&U->status) >= 0); + if (x == CODE_user_self) { fetch_bool (); } @@ -241,9 +237,9 @@ int fetch_user (struct user *U) { char *s = fetch_str (l); bl_do_user_set_phone (U, s, l); } - assert (fetch_user_photo (U) >= 0); + assert (tglf_fetch_user_photo (U) >= 0); - fetch_user_status (&U->status); + tglf_fetch_user_status (&U->status); if (x == CODE_user_self) { fetch_bool (); } @@ -258,7 +254,26 @@ int fetch_user (struct user *U) { return 0; } -void fetch_encrypted_chat (struct secret_chat *U) { +void tglf_fetch_user_full (struct user *U) { + assert (fetch_int () == CODE_user_full); + tglf_fetch_alloc_user (); + assert (skip_type_any (TYPE_TO_PARAM (contacts_link)) >= 0); + + int *start = in_ptr; + assert (skip_type_any (TYPE_TO_PARAM (photo)) >= 0); + bl_do_user_set_full_photo (U, start, 4 * (in_ptr - start)); + + assert (skip_type_any (TYPE_TO_PARAM (peer_notify_settings)) >= 0); + + bl_do_user_set_blocked (U, fetch_bool ()); + int l1 = prefetch_strlen (); + char *s1 = fetch_str (l1); + int l2 = prefetch_strlen (); + char *s2 = fetch_str (l2); + bl_do_user_set_real_name (U, s1, l1, s2, l2); +} + +void tglf_fetch_encrypted_chat (struct secret_chat *U) { unsigned x = fetch_int (); assert (x == CODE_encrypted_chat_empty || x == CODE_encrypted_chat_waiting || x == CODE_encrypted_chat_requested || x == CODE_encrypted_chat || x == CODE_encrypted_chat_discarded); U->id = MK_ENCR_CHAT (fetch_int ()); @@ -269,7 +284,7 @@ void fetch_encrypted_chat (struct secret_chat *U) { if (x == CODE_encrypted_chat_discarded) { if (new) { - logprintf ("Unknown chat in deleted state. May be we forgot something...\n"); + vlogprintf (E_WARNING, "Unknown chat in deleted state. May be we forgot something...\n"); return; } bl_do_encr_chat_delete (U); @@ -283,10 +298,10 @@ void fetch_encrypted_chat (struct secret_chat *U) { long long access_hash = fetch_long (); int date = fetch_int (); int admin_id = fetch_int (); - int user_id = fetch_int () + admin_id - our_id; + int user_id = fetch_int () + admin_id - tgl_state.our_id; if (x == CODE_encrypted_chat_waiting) { - logprintf ("Unknown chat in waiting state. May be we forgot something...\n"); + vlogprintf (E_WARNING, "Unknown chat in waiting state. May be we forgot something...\n"); return; } if (x == CODE_encrypted_chat_requested || x == CODE_encrypted_chat) { @@ -300,7 +315,7 @@ void fetch_encrypted_chat (struct secret_chat *U) { } if (x == CODE_encrypted_chat) { - logprintf ("Unknown chat in ok state. May be we forgot something...\n"); + vlogprintf (E_WARNING, "Unknown chat in ok state. May be we forgot something...\n"); return; } @@ -310,11 +325,11 @@ void fetch_encrypted_chat (struct secret_chat *U) { bl_do_encr_chat_set_access_hash (U, fetch_long ()); bl_do_encr_chat_set_date (U, fetch_int ()); if (fetch_int () != U->admin_id) { - logprintf ("Changed admin in secret chat. WTF?\n"); + vlogprintf (E_WARNING, "Changed admin in secret chat. WTF?\n"); return; } - if (U->user_id != U->admin_id + fetch_int () - our_id) { - logprintf ("Changed partner in secret chat. WTF?\n"); + if (U->user_id != U->admin_id + fetch_int () - tgl_state.our_id) { + vlogprintf (E_WARNING, "Changed partner in secret chat. WTF?\n"); return; } if (x == CODE_encrypted_chat_waiting) { @@ -333,27 +348,8 @@ void fetch_encrypted_chat (struct secret_chat *U) { return; // Duplicate? } bl_do_encr_chat_accepted (U, (void *)g_key, (void *)nonce, fetch_long ()); + write_secret_chat_file (); } - write_secret_chat_file (); -} - -void fetch_user_full (struct user *U) { - assert (fetch_int () == CODE_user_full); - fetch_alloc_user (); - assert (skip_type_any (TYPE_TO_PARAM (contacts_link)) >= 0); - - int *start = in_ptr; - assert (skip_type_any (TYPE_TO_PARAM (photo)) >= 0); - bl_do_user_set_full_photo (U, start, 4 * (in_ptr - start)); - - assert (skip_type_any (TYPE_TO_PARAM (peer_notify_settings)) >= 0); - - bl_do_user_set_blocked (U, fetch_bool ()); - int l1 = prefetch_strlen (); - char *s1 = fetch_str (l1); - int l2 = prefetch_strlen (); - char *s2 = fetch_str (l2); - bl_do_user_set_real_name (U, s1, l1, s2, l2); } void fetch_chat (struct chat *C) { @@ -387,8 +383,8 @@ void fetch_chat (struct chat *C) { big.dc = -2; } else { assert (z == CODE_chat_photo); - fetch_file_location (&small); - fetch_file_location (&big); + tglf_fetch_file_location (&small); + tglf_fetch_file_location (&big); } users_num = fetch_int (); date = fetch_int (); @@ -427,8 +423,8 @@ void fetch_chat (struct chat *C) { big.dc = -2; } else { assert (y == CODE_chat_photo); - fetch_file_location (&small); - fetch_file_location (&big); + tglf_fetch_file_location (&small); + tglf_fetch_file_location (&big); } bl_do_chat_set_photo (C, &big, &small); int users_num = fetch_int (); @@ -446,8 +442,6 @@ void fetch_chat_full (struct chat *C) { assert (x == CODE_messages_chat_full); assert (fetch_int () == CODE_chat_full); C->id = MK_CHAT (fetch_int ()); - //C->flags &= ~(FLAG_DELETED | FLAG_FORBIDDEN | FLAG_CHAT_IN_CHAT); - //C->flags |= FLAG_CREATED; x = fetch_int (); int version = 0; struct chat_user *users = 0; @@ -478,12 +472,12 @@ void fetch_chat_full (struct chat *C) { assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_chat (); + tglf_fetch_alloc_chat (); } assert (fetch_int () == CODE_vector); n = fetch_int (); for (i = 0; i < n; i++) { - fetch_alloc_user (); + tglf_fetch_alloc_user (); } if (admin_id) { bl_do_chat_set_admin (C, admin_id); @@ -495,22 +489,20 @@ void fetch_chat_full (struct chat *C) { bl_do_chat_set_full_photo (C, start, 4 * (end - start)); } -void fetch_photo_size (struct photo_size *S) { +void tglf_fetch_photo_size (struct photo_size *S) { memset (S, 0, sizeof (*S)); unsigned x = fetch_int (); assert (x == CODE_photo_size || x == CODE_photo_cached_size || x == CODE_photo_size_empty); S->type = fetch_str_dup (); if (x != CODE_photo_size_empty) { - fetch_file_location (&S->loc); + tglf_fetch_file_location (&S->loc); S->w = fetch_int (); S->h = fetch_int (); if (x == CODE_photo_size) { S->size = fetch_int (); } else { S->size = prefetch_strlen (); -// S->data = talloc (S->size); fetch_str (S->size); -// memcpy (S->data, fetch_str (S->size), S->size); } } } @@ -527,7 +519,7 @@ void fetch_geo (struct geo *G) { } } -void fetch_photo (struct photo *P) { +void tglf_fetch_photo (struct photo *P) { memset (P, 0, sizeof (*P)); unsigned x = fetch_int (); assert (x == CODE_photo_empty || x == CODE_photo); @@ -543,7 +535,7 @@ void fetch_photo (struct photo *P) { P->sizes = talloc (sizeof (struct photo_size) * P->sizes_num); int i; for (i = 0; i < P->sizes_num; i++) { - fetch_photo_size (&P->sizes[i]); + tglf_fetch_photo_size (&P->sizes[i]); } } @@ -559,7 +551,7 @@ void fetch_video (struct video *V) { V->duration = fetch_int (); V->mime_type = fetch_str_dup (); V->size = fetch_int (); - fetch_photo_size (&V->thumb); + tglf_fetch_photo_size (&V->thumb); V->dc_id = fetch_int (); V->w = fetch_int (); V->h = fetch_int (); @@ -590,11 +582,11 @@ void fetch_document (struct document *V) { V->caption = fetch_str_dup (); V->mime_type = fetch_str_dup (); V->size = fetch_int (); - fetch_photo_size (&V->thumb); + tglf_fetch_photo_size (&V->thumb); V->dc_id = fetch_int (); } -void fetch_message_action (struct message_action *M) { +void tglf_fetch_message_action (struct message_action *M) { memset (M, 0, sizeof (*M)); unsigned x = fetch_int (); M->type = x; @@ -607,7 +599,7 @@ void fetch_message_action (struct message_action *M) { char *s = fetch_str (l); int l2 = prefetch_strlen (); // checkin char *s2 = fetch_str (l2); - logprintf ("Message action: Created geochat %.*s in address %.*s\n", l, s, l2, s2); + vlogprintf (E_ERROR, "Message action: Created geochat %.*s in address %.*s. You are in magic land now, since nobody ever tested geochats in this app\n", l, s, l2, s2); } break; case CODE_message_action_geo_chat_checkin: @@ -623,7 +615,7 @@ void fetch_message_action (struct message_action *M) { M->new_title = fetch_str_dup (); break; case CODE_message_action_chat_edit_photo: - fetch_photo (&M->photo); + tglf_fetch_photo (&M->photo); break; case CODE_message_action_chat_delete_photo: break; @@ -638,13 +630,13 @@ void fetch_message_action (struct message_action *M) { } } -void fetch_message_short (struct message *M) { +void tglf_fetch_message_short (struct message *M) { int new = !(M->flags & FLAG_CREATED); if (new) { int id = fetch_int (); int from_id = fetch_int (); - int to_id = our_id; + int to_id = tgl_state.our_id; int l = prefetch_strlen (); char *s = fetch_str (l); @@ -666,7 +658,7 @@ void fetch_message_short (struct message *M) { } } -void fetch_message_short_chat (struct message *M) { +void tglf_fetch_message_short_chat (struct message *M) { int new = !(M->flags & FLAG_CREATED); if (new) { @@ -696,14 +688,14 @@ void fetch_message_short_chat (struct message *M) { } -void fetch_message_media (struct message_media *M) { +void tglf_fetch_message_media (struct message_media *M) { memset (M, 0, sizeof (*M)); M->type = fetch_int (); switch (M->type) { case CODE_message_media_empty: break; case CODE_message_media_photo: - fetch_photo (&M->photo); + tglf_fetch_photo (&M->photo); break; case CODE_message_media_video: fetch_video (&M->video); @@ -729,12 +721,12 @@ void fetch_message_media (struct message_media *M) { memcpy (M->data, fetch_str (M->data_size), M->data_size); break; default: - logprintf ("type = 0x%08x\n", M->type); + vlogprintf (E_ERROR, "type = 0x%08x\n", M->type); assert (0); } } -void fetch_message_media_encrypted (struct message_media *M) { +void tglf_fetch_message_media_encrypted (struct message_media *M) { memset (M, 0, sizeof (*M)); unsigned x = fetch_int (); int l; @@ -886,12 +878,12 @@ void fetch_message_media_encrypted (struct message_media *M) { M->user_id = fetch_int (); break; default: - logprintf ("type = 0x%08x\n", x); + vlogprintf (E_ERROR, "type = 0x%08x\n", x); assert (0); } } -void fetch_message_action_encrypted (struct secret_chat *E, struct message_action *M) { +void tglf_fetch_message_action_encrypted (struct message_action *M) { unsigned x = fetch_int (); switch (x) { case CODE_decrypted_message_action_set_message_t_t_l: @@ -938,20 +930,17 @@ void fetch_message_action_encrypted (struct secret_chat *E, struct message_actio case CODE_decrypted_message_action_notify_layer: M->type = x; M->layer = fetch_int (); - //if (M->from_id != our_id) { - // E->layer = M->layer; - //} break; case CODE_decrypted_message_action_flush_history: M->type = x; break; default: - logprintf ("x = 0x%08x\n", x); + vlogprintf (E_ERROR, "x = 0x%08x\n", x); assert (0); } } -peer_id_t fetch_peer_id (void) { +peer_id_t tglf_fetch_peer_id (void) { unsigned x =fetch_int (); if (x == CODE_peer_user) { return MK_USER (fetch_int ()); @@ -977,7 +966,7 @@ void fetch_message (struct message *M) { fwd_date = fetch_int (); } int from_id = fetch_int (); - peer_id_t to_id = fetch_peer_id (); + peer_id_t to_id = tglf_fetch_peer_id (); fetch_bool (); // out. @@ -1030,11 +1019,11 @@ void fetch_geo_message (struct message *M) { M->date = fetch_int (); if (x == CODE_geo_chat_message_service) { M->service = 1; - fetch_message_action (&M->action); + tglf_fetch_message_action (&M->action); } else { M->message = fetch_str_dup (); M->message_len = strlen (M->message); - fetch_message_media (&M->media); + tglf_fetch_message_media (&M->media); } } @@ -1092,13 +1081,13 @@ int decrypt_encrypted_message (struct secret_chat *E) { sha1 ((void *)decr_ptr, 4 + x, sha1a_buffer); if (memcmp (sha1a_buffer + 4, msg_key, 16)) { - logprintf ("Sha1 mismatch\n"); + vlogprintf (E_WARNING, "Sha1 mismatch\n"); return -1; } return 0; } -void fetch_encrypted_message (struct message *M) { +void tglf_fetch_encrypted_message (struct message *M) { unsigned x = fetch_int (); assert (x == CODE_encrypted_message || x == CODE_encrypted_message_service); unsigned sx = x; @@ -1110,7 +1099,7 @@ void fetch_encrypted_message (struct message *M) { peer_t *P = peer_get (chat); if (!P) { - logprintf ("Encrypted message to unknown chat. Dropping\n"); + vlogprintf (E_WARNING, "Encrypted message to unknown chat. Dropping\n"); M->flags |= FLAG_MESSAGE_EMPTY; } @@ -1122,7 +1111,7 @@ void fetch_encrypted_message (struct message *M) { int ok = 0; if (P) { if (*(long long *)decr_ptr != P->encr_chat.key_fingerprint) { - logprintf ("Encrypted message with bad fingerprint to chat %s\n", P->print_name); + vlogprintf (E_WARNING, "Encrypted message with bad fingerprint to chat %s\n", P->print_name); P = 0; } decr_ptr += 2; @@ -1163,12 +1152,7 @@ void fetch_encrypted_message (struct message *M) { } in_ptr = save_in_ptr; in_end = save_in_end; - } else { - if (P && new) { - assert (0); - } - } - + } if (sx == CODE_encrypted_message) { if (ok) { int *start_file = in_ptr; @@ -1189,7 +1173,7 @@ void fetch_encrypted_message (struct message *M) { } } -void fetch_encrypted_message_file (struct message_media *M) { +void tglf_fetch_encrypted_message_file (struct message_media *M) { unsigned x = fetch_int (); assert (x == CODE_encrypted_file || x == CODE_encrypted_file_empty); if (x == CODE_encrypted_file_empty) { @@ -1215,7 +1199,7 @@ static int id_cmp (struct message *M1, struct message *M2) { else { return 0; } } -struct user *fetch_alloc_user (void) { +struct user *tglf_fetch_alloc_user (void) { int data[2]; prefetch_data (data, 8); peer_t *U = peer_get (MK_USER (data[1])); @@ -1227,11 +1211,11 @@ struct user *fetch_alloc_user (void) { assert (peer_num < MAX_PEER_NUM); Peers[peer_num ++] = U; } - fetch_user (&U->user); + tglf_fetch_user (&U->user); return &U->user; } -struct secret_chat *fetch_alloc_encrypted_chat (void) { +struct secret_chat *tglf_fetch_alloc_encrypted_chat (void) { int data[2]; prefetch_data (data, 8); peer_t *U = peer_get (MK_ENCR_CHAT (data[1])); @@ -1243,7 +1227,7 @@ struct secret_chat *fetch_alloc_encrypted_chat (void) { assert (peer_num < MAX_PEER_NUM); Peers[peer_num ++] = U; } - fetch_encrypted_chat (&U->encr_chat); + tglf_fetch_encrypted_chat (&U->encr_chat); return &U->encr_chat; } @@ -1268,19 +1252,19 @@ void insert_chat (peer_t *P) { Peers[peer_num ++] = P; } -struct user *fetch_alloc_user_full (void) { +struct user *tglf_fetch_alloc_user_full (void) { int data[3]; prefetch_data (data, 12); peer_t *U = peer_get (MK_USER (data[2])); if (U) { - fetch_user_full (&U->user); + tglf_fetch_user_full (&U->user); return &U->user; } else { users_allocated ++; U = talloc0 (sizeof (*U)); U->id = MK_USER (data[2]); peer_tree = tree_insert_peer (peer_tree, U, lrand48 ()); - fetch_user_full (&U->user); + tglf_fetch_user_full (&U->user); assert (peer_num < MAX_PEER_NUM); Peers[peer_num ++] = U; return &U->user; @@ -1359,7 +1343,7 @@ void free_message_media (struct message_media *M) { case 0: break; default: - logprintf ("%08x\n", M->type); + vlogprintf (E_ERROR, "type = 0x%08x\n", M->type); assert (0); } } @@ -1414,7 +1398,7 @@ void message_add_use (struct message *M) { void message_add_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 (tgl_state.our_id))) { id = M->from_id; } else { id = M->to_id; @@ -1472,7 +1456,7 @@ 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 (tgl_state.our_id))) { id = M->from_id; } else { id = M->to_id; @@ -1489,22 +1473,27 @@ void message_del_peer (struct message *M) { } } -struct message *fetch_alloc_message (void) { +struct message *message_alloc (long long id) { + struct message *M = talloc0 (sizeof (*M)); + M->id = id; + message_insert_tree (M); + messages_allocated ++; + return M; +} + +struct message *tglf_fetch_alloc_message (void) { int data[2]; prefetch_data (data, 8); struct message *M = message_get (data[1]); if (!M) { - M = talloc0 (sizeof (*M)); - M->id = data[1]; - message_insert_tree (M); - messages_allocated ++; + M = message_alloc (data[1]); } fetch_message (M); return M; } -struct message *fetch_alloc_geo_message (void) { +struct message *tglf_fetch_alloc_geo_message (void) { struct message *M = talloc (sizeof (*M)); fetch_geo_message (M); struct message *M1 = tree_lookup_message (message_tree, M); @@ -1527,7 +1516,7 @@ struct message *fetch_alloc_geo_message (void) { } } -struct message *fetch_alloc_encrypted_message (void) { +struct message *tglf_fetch_alloc_encrypted_message (void) { int data[3]; prefetch_data (data, 12); struct message *M = message_get (*(long long *)(data + 1)); @@ -1539,11 +1528,11 @@ struct message *fetch_alloc_encrypted_message (void) { messages_allocated ++; assert (message_get (M->id) == M); } - fetch_encrypted_message (M); + tglf_fetch_encrypted_message (M); return M; } -struct message *fetch_alloc_message_short (void) { +struct message *tglf_fetch_alloc_message_short (void) { int data[1]; prefetch_data (data, 4); struct message *M = message_get (data[0]); @@ -1554,11 +1543,11 @@ struct message *fetch_alloc_message_short (void) { message_insert_tree (M); messages_allocated ++; } - fetch_message_short (M); + tglf_fetch_message_short (M); return M; } -struct message *fetch_alloc_message_short_chat (void) { +struct message *tglf_fetch_alloc_message_short_chat (void) { int data[1]; prefetch_data (data, 4); struct message *M = message_get (data[0]); @@ -1569,11 +1558,11 @@ struct message *fetch_alloc_message_short_chat (void) { message_insert_tree (M); messages_allocated ++; } - fetch_message_short_chat (M); + tglf_fetch_message_short_chat (M); return M; } -struct chat *fetch_alloc_chat (void) { +struct chat *tglf_fetch_alloc_chat (void) { int data[2]; prefetch_data (data, 8); peer_t *U = peer_get (MK_CHAT (data[1])); @@ -1589,7 +1578,7 @@ struct chat *fetch_alloc_chat (void) { return &U->chat; } -struct chat *fetch_alloc_chat_full (void) { +struct chat *tglf_fetch_alloc_chat_full (void) { int data[3]; prefetch_data (data, 12); peer_t *U = peer_get (MK_CHAT (data[2])); @@ -1613,7 +1602,7 @@ void free_chat (struct chat *U) { if (U->print_title) { tfree_str (U->print_title); } } -int print_stat (char *s, int len) { +int tgl_print_stat (char *s, int len) { return tsnprintf (s, len, "users_allocated\t%d\n" "chats_allocated\t%d\n" @@ -1669,8 +1658,8 @@ void message_remove_unsent (struct message *M) { message_unsent_tree = tree_delete_message (message_unsent_tree, M); } -void __send_msg (struct message *M) { - logprintf ("Resending message...\n"); +static void __send_msg (struct message *M) { + vlogprintf (E_NOTICE, "Resending message...\n"); print_message (M); do_send_msg (M); @@ -1681,14 +1670,10 @@ void send_all_unsent (void ) { } void peer_insert_name (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 ()); } void peer_delete_name (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); } @@ -1698,3 +1683,59 @@ peer_t *peer_lookup_name (const char *s) { peer_t *R = tree_lookup_peer_by_name (peer_by_name_tree, &P); return R; } + +void peer_iterator_ex (void (*it)(peer_t *P, void *extra), void *extra) { + tree_act_ex_peer (peer_tree, it, extra); +} + +int complete_user_list (int index, const char *text, int len, char **R) { + index ++; + while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_USER)) { + index ++; + } + if (index < peer_num) { + *R = strdup (Peers[index]->print_name); + return index; + } else { + return -1; + } +} + +int complete_chat_list (int index, const char *text, int len, char **R) { + index ++; + while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_CHAT)) { + index ++; + } + if (index < peer_num) { + *R = strdup (Peers[index]->print_name); + return index; + } else { + return -1; + } +} + +int complete_encr_chat_list (int index, const char *text, int len, char **R) { + index ++; + while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_ENCR_CHAT)) { + index ++; + } + if (index < peer_num) { + *R = strdup (Peers[index]->print_name); + return index; + } else { + return -1; + } +} + +int complete_peer_list (int index, const char *text, int len, char **R) { + index ++; + while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) { + index ++; + } + if (index < peer_num) { + *R = strdup (Peers[index]->print_name); + return index; + } else { + return -1; + } +} diff --git a/structures.h b/structures.h index f986037..b1e76d4 100644 --- a/structures.h +++ b/structures.h @@ -20,364 +20,31 @@ #define __STRUCTURES_H__ #include -typedef struct { int type; int id; } peer_id_t; +#include "tgl-layout.h" +#include "tgl-fetch.h" -//#define FLAG_EMPTY 1 -#define FLAG_MESSAGE_EMPTY 1 -#define FLAG_DELETED 2 -#define FLAG_FORBIDDEN 4 -#define FLAG_HAS_PHOTO 8 -#define FLAG_CREATED 16 +char *create_print_name (peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4); -#define FLAG_USER_SELF 128 -#define FLAG_USER_FOREIGN 256 -#define FLAG_USER_CONTACT 512 -#define FLAG_USER_IN_CONTACT 1024 -#define FLAG_USER_OUT_CONTACT 2048 - -#define FLAG_CHAT_IN_CHAT 128 - -#define FLAG_ENCRYPTED 4096 -#define FLAG_PENDING 8192 -#pragma pack(push,4) -struct file_location { - int dc; - long long volume; - int local_id; - long long secret; -}; -#pragma pack(pop) - -struct photo_size { - char *type; - struct file_location loc; - int w; - int h; - int size; - char *data; -}; - -struct geo { - double longitude; - double latitude; -}; - -struct photo { - long long id; - long long access_hash; - int user_id; - int date; - char *caption; - struct geo geo; - int sizes_num; - struct photo_size *sizes; -}; - -struct encr_photo { - long long id; - long long access_hash; - int dc_id; - int size; - int key_fingerprint; - - unsigned char *key; - unsigned char *iv; - int w; - int h; -}; - -struct encr_video { - long long id; - long long access_hash; - int dc_id; - int size; - int key_fingerprint; - - unsigned char *key; - unsigned char *iv; - int w; - int h; - int duration; - char *mime_type; -}; - -struct encr_audio { - long long id; - long long access_hash; - int dc_id; - int size; - int key_fingerprint; - - unsigned char *key; - unsigned char *iv; - int duration; - char *mime_type; -}; - -struct encr_document { - long long id; - long long access_hash; - int dc_id; - int size; - int key_fingerprint; - - unsigned char *key; - unsigned char *iv; - char *file_name; - char *mime_type; -}; - -struct encr_file { - char *filename; - unsigned char *key; - unsigned char *iv; -}; - - -struct user_status { - int online; - int when; -}; - -struct user { - peer_id_t id; - int flags; - struct message *last; - char *print_name; - int structure_version; - struct file_location photo_big; - struct file_location photo_small; - long long photo_id; - struct photo photo; - char *first_name; - char *last_name; - char *phone; - long long access_hash; - struct user_status status; - int blocked; - char *real_first_name; - char *real_last_name; -}; - -struct chat_user { - int user_id; - int inviter_id; - int date; -}; - -struct chat { - peer_id_t id; - int flags; - struct message *last; - char *print_title; - int structure_version; - struct file_location photo_big; - struct file_location photo_small; - struct photo photo; - char *title; - int users_num; - int user_list_size; - int user_list_version; - struct chat_user *user_list; - int date; - int version; - int admin_id; -}; - -enum secret_chat_state { - sc_none, - sc_waiting, - sc_request, - sc_ok, - sc_deleted -}; - -struct secret_chat { - peer_id_t id; - int flags; - struct message *last; - char *print_name; - int structure_version; - struct file_location photo_big; - struct file_location photo_small; - struct photo photo; - int user_id; - int admin_id; - int date; - int ttl; - int layer; - long long access_hash; - unsigned char *g_key; - unsigned char *nonce; - - enum secret_chat_state state; - int key[64]; - long long key_fingerprint; -}; - -typedef union peer { - struct { - peer_id_t id; - int flags; - struct message *last; - char *print_name; - int structure_version; - struct file_location photo_big; - struct file_location photo_small; - struct photo photo; - }; - struct user user; - struct chat chat; - struct secret_chat encr_chat; -} peer_t; - -struct video { - long long id; - long long access_hash; - int user_id; - int date; - int size; - int dc_id; - struct photo_size thumb; - char *caption; - int duration; - int w; - int h; - char *mime_type; -}; - -struct audio { - long long id; - long long access_hash; - int user_id; - int date; - int size; - int dc_id; - int duration; - char *mime_type; -}; - -struct document { - long long id; - long long access_hash; - int user_id; - int date; - int size; - int dc_id; - struct photo_size thumb; - char *caption; - char *mime_type; -}; - -struct message_action { - unsigned type; - union { - struct { - char *title; - int user_num; - int *users; - }; - char *new_title; - struct photo photo; - int user; - int ttl; - int layer; - int read_cnt; - int delete_cnt; - int screenshot_cnt; - }; -}; - -struct message_media { - unsigned type; - union { - struct photo photo; - struct video video; - struct audio audio; - struct document document; - struct geo geo; - struct { - char *phone; - char *first_name; - char *last_name; - int user_id; - }; - struct encr_photo encr_photo; - struct encr_video encr_video; - struct encr_audio encr_audio; - struct encr_document encr_document; - struct encr_file encr_file; - struct { - void *data; - int data_size; - }; - }; -}; - -struct message { - struct message *next_use, *prev_use; - struct message *next, *prev; - long long id; - int flags; - peer_id_t fwd_from_id; - int fwd_date; - peer_id_t from_id; - peer_id_t to_id; - int out; - int unread; - int date; - int service; - union { - struct message_action action; - struct { - char *message; - int message_len; - struct message_media media; - }; - }; -}; - -int fetch_file_location (struct file_location *loc); -int fetch_user_status (struct user_status *S); -int fetch_user (struct user *U); -struct user *fetch_alloc_user (void); -struct user *fetch_alloc_user_full (void); -struct chat *fetch_alloc_chat (void); -struct chat *fetch_alloc_chat_full (void); -struct secret_chat *fetch_alloc_encrypted_chat (void); -struct message *fetch_alloc_message (void); -struct message *fetch_alloc_geo_message (void); -struct message *fetch_alloc_message_short (void); -struct message *fetch_alloc_message_short_chat (void); -struct message *fetch_alloc_encrypted_message (void); -void fetch_encrypted_message_file (struct message_media *M); -void fetch_skip_encrypted_message_file (void); -void fetch_encrypted_message_file (struct message_media *M); -void fetch_message_action_encrypted (struct secret_chat *E, struct message_action *M); -peer_id_t fetch_peer_id (void); - -void fetch_message_media (struct message_media *M); -void fetch_message_media_encrypted (struct message_media *M); -void fetch_message_action (struct message_action *M); -void message_insert_tree (struct message *M); +struct message *message_alloc (long long id); 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); -int print_stat (char *s, int len); +int tgl_print_stat (char *s, int len); peer_t *peer_get (peer_id_t id); +peer_t *peer_lookup_name (const char *s); struct message *message_get (long long id); + + + +void message_insert_tree (struct message *M); void update_message_id (struct message *M, long long id); void message_insert (struct message *M); void free_photo (struct photo *P); -void fetch_photo (struct photo *P); void insert_encrypted_chat (peer_t *P); void insert_user (peer_t *P); void insert_chat (peer_t *P); -void fetch_photo (struct photo *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); @@ -388,8 +55,12 @@ 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_iterator_ex (void (*it)(peer_t *P, void *extra), void *extra); +int complete_user_list (int index, const char *text, int len, char **R); +int complete_chat_list (int index, const char *text, int len, char **R); +int complete_encr_chat_list (int index, const char *text, int len, char **R); +int complete_peer_list (int index, const char *text, int len, char **R); #define PEER_USER 1 #define PEER_CHAT 2 #define PEER_GEO_CHAT 3 diff --git a/tgl-fetch.h b/tgl-fetch.h new file mode 100644 index 0000000..9d42f45 --- /dev/null +++ b/tgl-fetch.h @@ -0,0 +1,25 @@ +#ifndef __TGL_FETCH_H__ +#define __TGL_FETCH_H__ + +int tglf_fetch_file_location (struct file_location *loc); +int tglf_fetch_user_status (struct user_status *S); +int tglf_fetch_user (struct user *U); +struct user *tglf_fetch_alloc_user (void); +struct user *tglf_fetch_alloc_user_full (void); +struct chat *tglf_fetch_alloc_chat (void); +struct chat *tglf_fetch_alloc_chat_full (void); +struct secret_chat *tglf_fetch_alloc_encrypted_chat (void); +struct message *tglf_fetch_alloc_message (void); +struct message *tglf_fetch_alloc_geo_message (void); +struct message *tglf_fetch_alloc_message_short (void); +struct message *tglf_fetch_alloc_message_short_chat (void); +struct message *tglf_fetch_alloc_encrypted_message (void); +void tglf_fetch_encrypted_message_file (struct message_media *M); +peer_id_t tglf_fetch_peer_id (void); + +void tglf_fetch_message_media (struct message_media *M); +void tglf_fetch_message_media_encrypted (struct message_media *M); +void tglf_fetch_message_action (struct message_action *M); +void tglf_fetch_message_action_encrypted (struct message_action *M); +void tglf_fetch_photo (struct photo *P); +#endif diff --git a/tgl-layout.h b/tgl-layout.h new file mode 100644 index 0000000..faee2a4 --- /dev/null +++ b/tgl-layout.h @@ -0,0 +1,321 @@ +#ifndef __TGL_LAYOUT_H__ +#define __TGL_LAYOUT_H__ + +#define FLAG_MESSAGE_EMPTY 1 +#define FLAG_DELETED 2 +#define FLAG_FORBIDDEN 4 +#define FLAG_HAS_PHOTO 8 +#define FLAG_CREATED 16 + +#define FLAG_USER_SELF 128 +#define FLAG_USER_FOREIGN 256 +#define FLAG_USER_CONTACT 512 +#define FLAG_USER_IN_CONTACT 1024 +#define FLAG_USER_OUT_CONTACT 2048 + +#define FLAG_CHAT_IN_CHAT 128 + +#define FLAG_ENCRYPTED 4096 +#define FLAG_PENDING 8192 + +#pragma pack(push,4) + +typedef struct { int type; int id; } peer_id_t; + +struct file_location { + int dc; + long long volume; + int local_id; + long long secret; +}; + +struct photo_size { + char *type; + struct file_location loc; + int w; + int h; + int size; + char *data; +}; + +struct geo { + double longitude; + double latitude; +}; + +struct photo { + long long id; + long long access_hash; + int user_id; + int date; + char *caption; + struct geo geo; + int sizes_num; + struct photo_size *sizes; +}; + +struct encr_photo { + long long id; + long long access_hash; + int dc_id; + int size; + int key_fingerprint; + + unsigned char *key; + unsigned char *iv; + int w; + int h; +}; + +struct encr_video { + long long id; + long long access_hash; + int dc_id; + int size; + int key_fingerprint; + + unsigned char *key; + unsigned char *iv; + int w; + int h; + int duration; + char *mime_type; +}; + +struct encr_audio { + long long id; + long long access_hash; + int dc_id; + int size; + int key_fingerprint; + + unsigned char *key; + unsigned char *iv; + int duration; + char *mime_type; +}; + +struct encr_document { + long long id; + long long access_hash; + int dc_id; + int size; + int key_fingerprint; + + unsigned char *key; + unsigned char *iv; + char *file_name; + char *mime_type; +}; + +struct encr_file { + char *filename; + unsigned char *key; + unsigned char *iv; +}; + + +struct user_status { + int online; + int when; +}; + +struct user { + peer_id_t id; + int flags; + struct message *last; + char *print_name; + int structure_version; + struct file_location photo_big; + struct file_location photo_small; + long long photo_id; + struct photo photo; + char *first_name; + char *last_name; + char *phone; + long long access_hash; + struct user_status status; + int blocked; + char *real_first_name; + char *real_last_name; +}; + +struct chat_user { + int user_id; + int inviter_id; + int date; +}; + +struct chat { + peer_id_t id; + int flags; + struct message *last; + char *print_title; + int structure_version; + struct file_location photo_big; + struct file_location photo_small; + struct photo photo; + char *title; + int users_num; + int user_list_size; + int user_list_version; + struct chat_user *user_list; + int date; + int version; + int admin_id; +}; + +enum secret_chat_state { + sc_none, + sc_waiting, + sc_request, + sc_ok, + sc_deleted +}; + +struct secret_chat { + peer_id_t id; + int flags; + struct message *last; + char *print_name; + int structure_version; + struct file_location photo_big; + struct file_location photo_small; + struct photo photo; + int user_id; + int admin_id; + int date; + int ttl; + int layer; + long long access_hash; + unsigned char *g_key; + unsigned char *nonce; + + enum secret_chat_state state; + int key[64]; + long long key_fingerprint; +}; + +typedef union peer { + struct { + peer_id_t id; + int flags; + struct message *last; + char *print_name; + int structure_version; + struct file_location photo_big; + struct file_location photo_small; + struct photo photo; + }; + struct user user; + struct chat chat; + struct secret_chat encr_chat; +} peer_t; + +struct video { + long long id; + long long access_hash; + int user_id; + int date; + int size; + int dc_id; + struct photo_size thumb; + char *caption; + int duration; + int w; + int h; + char *mime_type; +}; + +struct audio { + long long id; + long long access_hash; + int user_id; + int date; + int size; + int dc_id; + int duration; + char *mime_type; +}; + +struct document { + long long id; + long long access_hash; + int user_id; + int date; + int size; + int dc_id; + struct photo_size thumb; + char *caption; + char *mime_type; +}; + +struct message_action { + unsigned type; + union { + struct { + char *title; + int user_num; + int *users; + }; + char *new_title; + struct photo photo; + int user; + int ttl; + int layer; + int read_cnt; + int delete_cnt; + int screenshot_cnt; + }; +}; + +struct message_media { + unsigned type; + union { + struct photo photo; + struct video video; + struct audio audio; + struct document document; + struct geo geo; + struct { + char *phone; + char *first_name; + char *last_name; + int user_id; + }; + struct encr_photo encr_photo; + struct encr_video encr_video; + struct encr_audio encr_audio; + struct encr_document encr_document; + struct encr_file encr_file; + struct { + void *data; + int data_size; + }; + }; +}; + +struct message { + struct message *next_use, *prev_use; + struct message *next, *prev; + long long id; + int flags; + peer_id_t fwd_from_id; + int fwd_date; + peer_id_t from_id; + peer_id_t to_id; + int out; + int unread; + int date; + int service; + union { + struct message_action action; + struct { + char *message; + int message_len; + struct message_media media; + }; + }; +}; +#pragma pack(pop) +#endif diff --git a/tgl.c b/tgl.c new file mode 100644 index 0000000..e8a5c7c --- /dev/null +++ b/tgl.c @@ -0,0 +1,8 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tgl.h" +struct tgl_params tgl_params; +struct tgl_state tgl_state; + diff --git a/tgl.h b/tgl.h new file mode 100644 index 0000000..29cd91f --- /dev/null +++ b/tgl.h @@ -0,0 +1,17 @@ +#ifndef __TGL_H__ +#define __TGL_H__ + +// Do not modify this structure, unless you know what you do +struct tgl_state { + int our_id; // ID of logged in user +}; +extern struct tgl_state tgl_state; + +// Should be set before first use of lib +struct tgl_params { + int test_mode; // Connect to test DC + int verbosity; // May be modified any moment +}; +extern struct tgl_params tgl_params; + +#endif diff --git a/tree.h b/tree.h index 7ab60c3..d0bac44 100644 --- a/tree.h +++ b/tree.h @@ -134,6 +134,13 @@ void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) {\ tree_act_ ## X_NAME (T->right, act); \ }\ \ +void tree_act_ex_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE, void *), void *extra) {\ + if (!T) { return; } \ + tree_act_ex_ ## X_NAME (T->left, act, extra); \ + act (T->x, extra); \ + tree_act_ex_ ## X_NAME (T->right, act, extra); \ +}\ +\ int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) { \ if (!T) { return 0; }\ return 1 + tree_count_ ## X_NAME (T->left) + tree_count_ ## X_NAME (T->right); \