Commit c03d91a5 authored by Vysheng's avatar Vysheng

Fixed small memory leaks. Added functions to clear most part of data

parent 3984078f
......@@ -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;
}
......
......@@ -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 <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 <peer> <phone> <first-name> <last-name>\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, ""}
};
......
......@@ -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) {
......
......@@ -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));
}
......@@ -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
......@@ -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
};
......@@ -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"
......
......@@ -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);
......
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment