diff --git a/binlog.c b/binlog.c index bf9faaa..4cfb948 100644 --- a/binlog.c +++ b/binlog.c @@ -1140,7 +1140,6 @@ static int fetch_comb_binlog_set_msg_id (void *extra) { M->id = fetch_int (); if (tgl_message_get (M->id)) { tgls_free_message (M); - tfree (M, sizeof (*M)); } else { tglm_message_insert_tree (M); tglm_message_add_peer (M); @@ -1159,7 +1158,6 @@ static int fetch_comb_binlog_delete_msg (void *extra) { tglm_message_del_peer (M); tglm_message_del_use (M); tgls_free_message (M); - tfree (M, sizeof (*M)); return 0; } diff --git a/interface.c b/interface.c index 4e6dafe..92c48ed 100644 --- a/interface.c +++ b/interface.c @@ -957,6 +957,33 @@ void do_main_session (int arg_num, struct arg args[], struct in_ev *ev) { if (ev) { ev->refcnt ++; } } +extern char *default_username; +extern char *config_filename; +extern char *prefix; +extern char *auth_file_name; +extern char *state_file_name; +extern char *secret_chat_file_name; +extern char *downloads_directory; +extern char *config_directory; +extern char *binlog_file_name; +extern char *lua_file; + +void do_clear (int arg_num, struct arg args[], struct in_ev *ev) { + tgl_free_all (); + free (default_username); + free (config_filename); + free (prefix); + free (auth_file_name); + free (state_file_name); + free (secret_chat_file_name); + free (downloads_directory); + free (config_directory); + free (binlog_file_name); + free (lua_file); + do_halt (0); +} + + struct command commands[] = { {"help", {ca_none}, do_help, "help\tPrints this help"}, {"contact_list", {ca_none}, do_contact_list, "contact_list\tPrints contact list"}, @@ -1013,6 +1040,7 @@ struct command commands[] = { {"import_card", {ca_string, ca_none}, do_import_card, "import_card \tGets user by card and prints it name. You can then send messages to him as usual"}, {"send_contact", {ca_peer, ca_string, ca_string, ca_string, ca_none}, do_send_contact, "send_contact \tSends contact (not necessary telegram user)"}, {"main_session", {ca_none}, do_main_session, "main_session\tSends updates to this connection (or terminal). Useful only with listening socket"}, + {"clear", {ca_none}, do_clear, "clear\tClears all data and exits. For debug."}, {0, {ca_none}, 0, ""} }; diff --git a/main.c b/main.c index 6fc1ec5..8c140ad 100644 --- a/main.c +++ b/main.c @@ -82,9 +82,8 @@ "# Feel free to put something here\n" int verbosity; -char *default_username; -char *auth_token; int msg_num_mode; +char *default_username; char *config_filename; char *prefix; char *auth_file_name; @@ -93,11 +92,11 @@ char *secret_chat_file_name; char *downloads_directory; char *config_directory; char *binlog_file_name; +char *lua_file; int binlog_enabled; extern int log_level; int sync_from_start; int allow_weak_random; -char *lua_file; int disable_colors; int readline_disabled; int disable_output; @@ -371,6 +370,7 @@ void parse_config (void) { printf ("[%s] created\n", downloads_directory); } } + config_destroy (&conf); } #else void parse_config (void) { diff --git a/mtproto-client.c b/mtproto-client.c index 703badc..81d6dd9 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -1424,3 +1424,22 @@ void tglmp_regenerate_temp_auth_key (struct tgl_dc *D) { create_temp_auth_key (S->c); } } + +void tgls_free_session (struct tgl_session *S) { + S->ack_tree = tree_clear_long (S->ack_tree); + if (S->ev) { event_free (S->ev); } + if (S->c) { + tgl_state.net_methods->free (S->c); + } + tfree (S, sizeof (*S)); +} + +void tgls_free_dc (struct tgl_dc *DC) { + if (DC->ip) { tfree_str (DC->ip); } + + struct tgl_session *S = DC->sessions[0]; + if (S) { tgls_free_session (S); } + + if (DC->ev) { event_free (DC->ev); } + tfree (DC, sizeof (*DC)); +} diff --git a/mtproto-client.h b/mtproto-client.h index bf4fd47..ffc25b1 100644 --- a/mtproto-client.h +++ b/mtproto-client.h @@ -55,4 +55,5 @@ void tglmp_regenerate_temp_auth_key (struct tgl_dc *D); void tgln_insert_msg_id (struct tgl_session *S, long long id); void tglmp_on_start (void); void tgl_dc_authorize (struct tgl_dc *DC); +void tgls_free_dc (struct tgl_dc *DC); #endif diff --git a/net.c b/net.c index 68559a1..dd3c24e 100644 --- a/net.c +++ b/net.c @@ -572,6 +572,30 @@ static struct tgl_session *get_session (struct connection *c) { return c->session; } +static void tgln_free (struct connection *c) { + if (c->ip) { tfree_str (c->ip); } + struct connection_buffer *b = c->out_head; + while (b) { + struct connection_buffer *d = b; + b = b->next; + delete_connection_buffer (d); + } + b = c->in_head; + while (b) { + struct connection_buffer *d = b; + b = b->next; + delete_connection_buffer (d); + } + + if (c->ping_ev) { event_free (c->ping_ev); } + if (c->fail_ev) { event_free (c->fail_ev); } + if (c->read_ev) { event_free (c->read_ev); } + if (c->write_ev) { event_free (c->write_ev); } + + if (c->fd >= 0) { close (c->fd); } + tfree (c, sizeof (*c)); +} + struct tgl_net_methods tgl_conn_methods = { .write_out = tgln_write_out, .read_in = tgln_read_in, @@ -580,5 +604,6 @@ struct tgl_net_methods tgl_conn_methods = { .incr_out_packet_num = incr_out_packet_num, .get_dc = get_dc, .get_session = get_session, - .create_connection = tgln_create_connection + .create_connection = tgln_create_connection, + .free = tgln_free }; diff --git a/structures.c b/structures.c index 5c8733f..15a24fc 100644 --- a/structures.c +++ b/structures.c @@ -34,6 +34,7 @@ #include "queries.h" #include "binlog.h" #include "updates.h" +#include "mtproto-client.h" #include "tgl.h" @@ -634,6 +635,7 @@ void tglf_fetch_message_action (struct tgl_message_action *M) { M->user = fetch_int (); break; default: + vlogprintf (E_ERROR, "type = %d\n", x); assert (0); } } @@ -1326,7 +1328,7 @@ struct tgl_message *tglf_fetch_alloc_geo_message (void) { if (M1) { tglm_message_del_use (M1); tglm_message_del_peer (M1); - tgls_free_message (M1); + tgls_clear_message (M1); memcpy (M1, M, sizeof (*M)); tfree (M, sizeof (*M)); tglm_message_add_use (M1); @@ -1461,12 +1463,6 @@ void tgl_insert_empty_chat (int cid) { } /* {{{ Free */ -void tgls_free_user (struct tgl_user *U) { - if (U->first_name) { tfree_str (U->first_name); } - if (U->last_name) { tfree_str (U->last_name); } - if (U->print_name) { tfree_str (U->print_name); } - if (U->phone) { tfree_str (U->phone); } -} void tgls_free_photo_size (struct tgl_photo_size *S) { tfree_str (S->type); @@ -1498,10 +1494,9 @@ void tgls_free_audio (struct tgl_audio *A) { } void tgls_free_document (struct tgl_document *D) { - tfree_str (D->mime_type); if (!D->access_hash) { return; } - tfree_str (D->caption); - tfree_str (D->mime_type); + if (D->mime_type) { tfree_str (D->mime_type);} + if (D->caption) {tfree_str (D->caption);} tgls_free_photo_size (&D->thumb); } @@ -1558,17 +1553,25 @@ void tgls_free_message_action (struct tgl_message_action *M) { tgls_free_photo (&M->photo); break; case tgl_message_action_chat_delete_photo: - break; case tgl_message_action_chat_add_user: - break; case tgl_message_action_chat_delete_user: + case tgl_message_action_geo_chat_create: + case tgl_message_action_geo_chat_checkin: + case tgl_message_action_set_message_ttl: + case tgl_message_action_read_messages: + case tgl_message_action_delete_messages: + case tgl_message_action_screenshot_messages: + case tgl_message_action_flush_history: + case tgl_message_action_notify_layer: break; + default: + vlogprintf (E_ERROR, "type = 0x%08x\n", M->type); assert (0); } } -void tgls_free_message (struct tgl_message *M) { +void tgls_clear_message (struct tgl_message *M) { if (!M->service) { if (M->message) { tfree (M->message, M->message_len + 1); } tgls_free_message_media (&M->media); @@ -1577,9 +1580,49 @@ void tgls_free_message (struct tgl_message *M) { } } +void tgls_free_message (struct tgl_message *M) { + tgls_clear_message (M); + tfree (M, sizeof (*M)); +} + void tgls_free_chat (struct tgl_chat *U) { if (U->title) { tfree_str (U->title); } if (U->print_title) { tfree_str (U->print_title); } + if (U->user_list) { + tfree (U->user_list, U->user_list_size * 12); + } + tgls_free_photo (&U->photo); + tfree (U, sizeof (*U)); +} + +void tgls_free_user (struct tgl_user *U) { + if (U->first_name) { tfree_str (U->first_name); } + if (U->last_name) { tfree_str (U->last_name); } + if (U->print_name) { tfree_str (U->print_name); } + if (U->phone) { tfree_str (U->phone); } + if (U->real_first_name) { tfree_str (U->real_first_name); } + if (U->real_last_name) { tfree_str (U->real_last_name); } + tgls_free_photo (&U->photo); + tfree (U, sizeof (*U)); +} + +void tgls_free_encr_chat (struct tgl_secret_chat *U) { + if (U->print_name) { tfree_str (U->print_name); } + if (U->g_key) { tfree (U->g_key, 256); } + if (U->nonce) { tfree (U->nonce, 256); } + tfree (U, sizeof (*U)); +} + +void tgls_free_peer (tgl_peer_t *P) { + if (tgl_get_peer_type (P->id) == TGL_PEER_USER) { + tgls_free_user ((void *)P); + } else if (tgl_get_peer_type (P->id) == TGL_PEER_CHAT) { + tgls_free_chat ((void *)P); + } else if (tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT) { + tgls_free_encr_chat ((void *)P); + } else { + assert (0); + } } /* }}} */ @@ -1815,6 +1858,32 @@ int tgl_complete_peer_list (int index, const char *text, int len, char **R) { } } +void tgl_free_all (void) { + tree_act_peer (tgl_peer_tree, tgls_free_peer); + tgl_peer_tree = tree_clear_peer (tgl_peer_tree); + peer_by_name_tree = tree_clear_peer_by_name (peer_by_name_tree); + tree_act_message (message_tree, tgls_free_message); + message_tree = tree_clear_message (message_tree); + tree_act_message (message_unsent_tree, tgls_free_message); + message_unsent_tree = tree_clear_message (message_unsent_tree); + + if (tgl_state.encr_prime) { tfree (tgl_state.encr_prime, 256); } + + + if (tgl_state.binlog_name) { tfree_str (tgl_state.binlog_name); } + if (tgl_state.auth_file) { tfree_str (tgl_state.auth_file); } + if (tgl_state.downloads_directory) { tfree_str (tgl_state.downloads_directory); } + + int i; + for (i = 0; i < tgl_state.rsa_key_num; i++) { + tfree_str (tgl_state.rsa_key_list[i]); + } + + for (i = 0; i <= tgl_state.max_dc_num; i++) if (tgl_state.DC_list[i]) { + tgls_free_dc (tgl_state.DC_list[i]); + } +} + int tgl_print_stat (char *s, int len) { return tsnprintf (s, len, "users_allocated\t%d\n" diff --git a/structures.h b/structures.h index 9b0002e..d9db912 100644 --- a/structures.h +++ b/structures.h @@ -31,6 +31,7 @@ void tgls_free_user (struct tgl_user *U); void tgls_free_chat (struct tgl_chat *U); void tgls_free_photo (struct tgl_photo *P); void tgls_free_message (struct tgl_message *M); +void tgls_clear_message (struct tgl_message *M); struct tgl_message *tglm_message_alloc (long long id); void tglm_message_insert_tree (struct tgl_message *M); diff --git a/tgl.h b/tgl.h index 8ccaf06..529dccf 100644 --- a/tgl.h +++ b/tgl.h @@ -103,6 +103,7 @@ struct tgl_net_methods { int (*read_in_lookup) (struct connection *c, void *data, int len); void (*flush_out) (struct connection *c); void (*incr_out_packet_num) (struct connection *c); + void (*free) (struct connection *c); struct tgl_dc *(*get_dc) (struct connection *c); struct tgl_session *(*get_session) (struct connection *c); @@ -324,4 +325,6 @@ struct paramed_type *tglf_extf_store (const char *data, int data_len); void tgl_do_send_extf (char *data, int data_len, void (*callback)(void *callback_extra, int success, char *data), void *callback_extra); char *tglf_extf_fetch (struct paramed_type *T); +void tgl_free_all (void); + #endif