diff --git a/loop.c b/loop.c index 9954b3d..61b0a5b 100644 --- a/loop.c +++ b/loop.c @@ -75,6 +75,7 @@ extern int queries_num; int unread_messages; void got_it (char *line, int len); void net_loop (int flags, int (*is_end)(void)) { + logprintf("starting net_loop()\n"); while (!is_end ()) { struct pollfd fds[101]; int cc = 0; @@ -84,11 +85,13 @@ void net_loop (int flags, int (*is_end)(void)) { cc ++; } + logprintf("writing_state_file()\n"); write_state_file (); int x = connections_make_poll_array (fds + cc, 101 - cc) + cc; double timer = next_timer_in (); if (timer > 1000) { timer = 1000; } if (poll (fds, x, timer) < 0) { + logprintf("poll returned -1, wait a little bit.\n"); work_timers (); continue; } @@ -109,7 +112,7 @@ void net_loop (int flags, int (*is_end)(void)) { lua_do_all (); #endif if (safe_quit && !queries_num) { - printf ("All done. Exit\n"); + logprintf ("All done. Exit\n"); rl_callback_handler_remove (); exit (0); } @@ -182,6 +185,11 @@ void write_dc (int auth_file_fd, struct dc *DC) { } int our_id; + +void store_config () { + write_auth_file(); +} + void write_auth_file (void) { if (binlog_enabled) { return; } int auth_file_fd = open (get_auth_key_filename (), O_CREAT | O_RDWR, 0600); @@ -220,9 +228,9 @@ void read_dc (int auth_file_fd, int id, unsigned ver) { assert (read (auth_file_fd, &DC->auth_key_id, 8) == 8); assert (read (auth_file_fd, &DC->auth_key, 256) == 256); assert (read (auth_file_fd, &DC->server_salt, 8) == 8); - printf("auth_key_id: %lli \n", DC->auth_key_id); - printf("auth_key_id: ?"); - printf("server_salt: %lli \n", DC->server_salt); + logprintf("auth_key_id: %lli \n", DC->auth_key_id); + logprintf("auth_key_id: ?"); + logprintf("server_salt: %lli \n", DC->server_salt); if (DC->auth_key_id) { DC->flags |= 1; } @@ -248,7 +256,10 @@ void read_auth_file (void) { empty_auth_file (); } assert (auth_file_fd >= 0); + + // amount of data centers unsigned x; + // magic number of file unsigned m; if (read (auth_file_fd, &m, 4) < 4 || (m != DC_SERIALIZED_MAGIC && m != DC_SERIALIZED_MAGIC_V2)) { close (auth_file_fd); @@ -463,7 +474,11 @@ int readline_active; int new_dc_num; int wait_dialog_list; -void init_loop (void) { +/** + * Discover the network and authorise with all data centers + */ +void network_connect (void) { + verbosity = 0; on_start (); if (binlog_enabled) { double t = get_double_time (); @@ -477,79 +492,141 @@ void init_loop (void) { } else { read_auth_file (); } - printf("update prompt()\n"); + logprintf("update prompt()\n"); update_prompt (); - printf("update prompt() done... \n"); + logprintf("update prompt() done... \n"); assert (DC_list[dc_working_num]); if (!DC_working || !DC_working->auth_key_id) { // if (auth_state == 0) { + logprintf("No working DC or not start_loopd.\n"); DC_working = DC_list[dc_working_num]; assert (!DC_working->auth_key_id); dc_authorize (DC_working); assert (DC_working->auth_key_id); auth_state = 100; write_auth_file (); + logprintf("Authorized DataCentre: auth_key_id: %lld \n", DC_working->auth_key_id); } if (verbosity) { logprintf ("Requesting info about DC...\n"); } do_help_get_config (); - printf("net_loop\n"); + logprintf("net_loop\n"); net_loop (0, mcs); - printf("net_loop done...\n"); + logprintf("net_loop done...\n"); if (verbosity) { logprintf ("DC_info: %d new DC got\n", new_dc_num); } int i; for (i = 0; i <= MAX_DC_NUM; i++) if (DC_list[i] && !DC_list[i]->auth_key_id) { + logprintf("DataCentre %d not start_loopd, authorizing...\n", i); dc_authorize (DC_list[i]); assert (DC_list[i]->auth_key_id); write_auth_file (); + logprintf("DataCentre start_loopd, key id: %lld\n", DC_list[i]->auth_key_id); } } +/** + * Return if the given phone is registered + */ +int network_phone_is_registered() { + int res = do_auth_check_phone (default_username); + assert(res >= 0); + return res; +} + + +/** + * Return if the current client is registered. + */ +int network_client_is_registered() { + return !(auth_state == 100 || !(DC_working->has_auth)); +} + +/** + * Request a verification for the given client, by sending + * a code to the current phone number + */ +char* network_request_registration () +{ + return do_send_code (default_username); +} + +/** + * Verify the phone, by providing the code and the real name + * + * NOTE: This should be called when the phone number was previously + * unknown to the telegram network. + */ +int network_verify_phone_registration(char* code, char *firstname, char *lastname) +{ + if (do_send_code_result_auth (code, firstname, lastname) >= 0) { + auth_state = 300; + return 1; + } + return 0; +} + +/** + * Verify the current client by providing the given code + */ +int network_verify_registration(const char *code, const char *sms_hash) +{ + logprintf("telegram: pointer - code: %p, hash: %p\n", code, sms_hash); + logprintf("telegram: string - code: %s, hash: %s\n", code, sms_hash); + if (do_send_code_result (code, sms_hash) >= 0) { + logprintf ("Authentication successfull, state = 300\n"); + auth_state = 300; + return 1; + } + return 0; +} + int start_loop (char* code, char* auth_mode) { - printf("Calling start_loop()\n"); - printf("auth_state %i\n", auth_state); + logprintf("Calling start_loop()\n"); + logprintf("auth_state %i\n", auth_state); if (auth_state == 100 || !(DC_working->has_auth)) { - printf("auth_state == 100 || !(DC_working->has_auth)"); + logprintf("auth_state == 100 || !(DC_working->has_auth)"); int res = do_auth_check_phone (default_username); assert (res >= 0); logprintf ("%s\n", res > 0 ? "phone registered" : "phone not registered"); if (res > 0 && !register_mode) { // Register Mode 1 - printf ("Register Mode 1\n"); + logprintf ("Register Mode 1\n"); if (code) { + /* if (do_send_code_result (code) >= 0) { - printf ("Authentication successfull, state = 300\n"); + logprintf ("Authentication successfull, state = 300\n"); auth_state = 300; } + */ } else { - printf("No code given, attempting to register\n"); + logprintf("No code given, attempting to register\n"); // Send Code - printf ("auth mode %s\n", auth_mode); + logprintf ("auth mode %s\n", auth_mode); /* if (strcmp(TELEGRAM_AUTH_MODE_SMS"sms", auth_mode)) { */ do_send_code (default_username); - printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); - printf("storing current state in auth file...\n"); + logprintf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); + logprintf("storing current state in auth file...\n"); write_auth_file (); - printf("exitting...\n"); + logprintf("exitting...\n"); return 0; /* } else { - printf ("You typed \"call\", switching to phone system.\n"); + logprintf ("You typed \"call\", switching to phone system.\n"); do_phone_call (default_username); - printf ("Calling you!"); + logprintf ("Calling you!"); } */ } } else { - printf ("User is not registered. Do you want to register? [Y/n] "); - printf ("ERROR THIS IS NOT POSSIBLE!\n"); + logprintf ("User is not registered. Do you want to register? [Y/n] "); + logprintf ("ERROR THIS IS NOT POSSIBLE!\n"); return 1; // Register Mode 2 // TODO: Requires first and last name, decide how to handle this. @@ -559,13 +636,13 @@ int start_loop (char* code, char* auth_mode) { /* size_t size; char *first_name; - printf ("First name: "); + logprintf ("First name: "); if (net_getline (&first_name, &size) == -1) { perror ("getline()"); exit (EXIT_FAILURE); } char *last_name; - printf ("Last name: "); + logprintf ("Last name: "); if (net_getline (&last_name, &size) == -1) { perror ("getline()"); exit (EXIT_FAILURE); @@ -583,17 +660,17 @@ int start_loop (char* code, char* auth_mode) { } else { if (strcmp(TELEGRAM_AUTH_MODE_SMS, auth_mode)) { do_send_code (default_username); - printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); + logprintf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); } else { - printf ("You typed \"call\", switching to phone system.\n"); + logprintf ("You typed \"call\", switching to phone system.\n"); do_phone_call (default_username); - printf ("Calling you! Code: "); + logprintf ("Calling you! Code: "); } } */ } } - printf("Authentication done\n"); + logprintf("Authentication done\n"); int i; for (i = 0; i <= MAX_DC_NUM; i++) if (DC_list[i] && !DC_list[i]->has_auth) { @@ -636,12 +713,12 @@ int start_loop (char* code, char* auth_mode) { * with 0. In all other cases exit with 1. */ int loop_auto(char *username, char *code, char* auth_mode) { - init_loop(); + network_connect(); set_default_username (username); return start_loop(code, auth_mode); } int loop (void) { - init_loop(); + network_connect(); return start_loop(NULL, NULL); } diff --git a/mtproto-client.c b/mtproto-client.c index cb598d3..442e4c2 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -225,6 +225,7 @@ int rpc_send_packet (struct connection *c) { } int rpc_send_message (struct connection *c, void *data, int len) { + logprintf("rpc_send_message(...)\n"); assert (len > 0 && !(len & 0xfc000003)); int total_len = len >> 2; if (total_len < 0x7f) { @@ -743,6 +744,7 @@ int aes_encrypt_message (struct dc *DC, struct encrypted_message *enc) { } long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful) { + logprintf("encrypt_send_message(...)\n"); struct dc *DC = GET_DC(c); struct session *S = c->session; assert (S); diff --git a/net.c b/net.c index 881f670..db2b474 100644 --- a/net.c +++ b/net.c @@ -634,6 +634,7 @@ struct dc *alloc_dc (int id, char *ip, int port UU) { } void dc_create_session (struct dc *DC) { + logprintf("dc_create_session(...)\n"); struct session *S = talloc0 (sizeof (*S)); assert (RAND_pseudo_bytes ((unsigned char *) &S->session_id, 8) >= 0); S->dc = DC; diff --git a/purple-plugin/Makefile b/purple-plugin/Makefile index 87b5aca..0651517 100755 --- a/purple-plugin/Makefile +++ b/purple-plugin/Makefile @@ -16,7 +16,7 @@ ifeq ($(ARCH),i686) else ifeq ($(ARCH),x86_64) ARCHFLAGS = -m64 else - ARCHFLAGS = + ARCHFLAGS = endif .PHONY: all @@ -83,4 +83,4 @@ clean: .PHONY: run run: all install - pidgin -d + pidgin -d | grep telegram diff --git a/purple-plugin/telegram-purple.c b/purple-plugin/telegram-purple.c index 2e417c2..ffab3d8 100644 --- a/purple-plugin/telegram-purple.c +++ b/purple-plugin/telegram-purple.c @@ -59,12 +59,9 @@ static PurplePlugin *_telegram_protocol = NULL; */ void tg_cli_log_cb(const char* format, va_list ap) { - // emulate libpurple logging function, because we cant pass va_list - // directly - time_t mtime = time(NULL); - const char *mdate = purple_utf8_strftime("%H:%M:%S", localtime(&mtime)); - printf("(%s) prpl-telegram: ", mdate); - vprintf(format, ap); + char buffer[256]; + vsnprintf(buffer, sizeof(buffer), format, ap); + purple_debug_info(PLUGIN_ID, "%s", buffer); } /** @@ -105,73 +102,79 @@ static void tgprpl_tooltip_text(PurpleBuddy * buddy, PurpleNotifyUserInfo * info static void tgprpl_login(PurpleAccount * acct) { purple_debug_info(PLUGIN_ID, "tgprpl_login()\n"); + PurpleConnection *gc = purple_account_get_connection(acct); - const char *username = purple_account_get_username(acct); - const char *code = purple_account_get_string(acct, "verification_key", NULL); - const char *hostname = purple_account_get_string(acct, "server", TELEGRAM_TEST_SERVER); - const char *verificationType = purple_account_get_string(acct, "verification_type", TELEGRAM_AUTH_MODE_SMS); - int port = purple_account_get_int(acct, "port", TELEGRAM_DEFAULT_PORT); + const char *username = purple_account_get_username(acct); + const char *code = purple_account_get_string(acct, "verification_key", NULL); + const char *hash = purple_account_get_string(acct, "verification_hash", NULL); + const char *hostname = purple_account_get_string(acct, "server", TELEGRAM_TEST_SERVER); + // const char *verificationType = purple_account_get_string(acct, "verification_type", TELEGRAM_AUTH_MODE_SMS); + // int port = purple_account_get_int(acct, "port", TELEGRAM_DEFAULT_PORT); - printf("username: %s\n", username); - printf("code: %s\n", code); - printf("hostname: %s\n", hostname); + purple_debug_info(PLUGIN_ID, "username: %s\n", username); + purple_debug_info(PLUGIN_ID, "code: %s\n", code); + purple_debug_info(PLUGIN_ID, "verification_hash: %s\n", hash); + purple_debug_info(PLUGIN_ID, "hostname: %s\n", hostname); + // ensure config-file exists an purple_debug_info(PLUGIN_ID, "running_for_first_time()\n"); running_for_first_time(); + + // load all settings: the known network topology, log and configuration file paths purple_debug_info(PLUGIN_ID, "parse_config()\n"); parse_config (); - purple_debug_info(PLUGIN_ID, "init_loop()\n"); - init_loop(); purple_debug_info(PLUGIN_ID, "set_default_username()\n"); set_default_username (username); - purple_debug_info(PLUGIN_ID, "start_loop() -> Authentication\n"); - start_loop (code, verificationType); - - - // TODO: Do proper input validation - /* - if (code && strcmp(code, "")) { - code = NULL; - } - */ - if (!code) { - purple_notify_message( - _telegram_protocol, - PURPLE_NOTIFY_MSG_INFO, - "Telegram Verification", - "Telegram needs to verify this phone number. You should receive a SMS with a code soon, please copy that code into the account option 'Verification Key'.", - NULL, - NULL, - NULL - ); - } - // tg_login(username, code, TELEGRAM_AUTH_MODE_SMS); - printf("Returned from tg_login...\n"); - /* - PurpleConnection *gc = purple_account_get_connection(acct); - purple_debug_info(PLUGIN_ID, "logging in %s\n", username); + // Connect to the network + purple_debug_info(PLUGIN_ID, "Connecting to the Telegram network...\n"); + network_connect(); - if (strcmp(sms_key[0], "")) { - purple_debug_info(PLUGIN_ID, "no sms key -> send sms key request\n"); - } + // Login + if (!network_phone_is_registered()) { + purple_debug_info(PLUGIN_ID, "Phone is not registered, registering...\n"); + } - purple_debug_info(PLUGIN_ID, "Connect\n"); - purple_connection_update_progress(gc, "Connecting", 0, 4); - telegram_conn *conn; - conn = g_new0(telegram_conn, 1); - conn->gc = gc; + if (!network_client_is_registered()) { + purple_debug_info(PLUGIN_ID, "Client is not registered\n"); + + if (code && hash) { + purple_debug_info(PLUGIN_ID, "SMS code provided, trying to verify \n"); + purple_debug_info(PLUGIN_ID, "pointer - code:%p hash:%p\n", code, hash); + purple_debug_info(PLUGIN_ID, "string - code%s hash:%s\n", code, hash); + int verified = network_verify_registration(code, hash); + if (verified) { + store_config(); + } else { + purple_connection_set_state(gc, PURPLE_DISCONNECTED); + purple_notify_message(_telegram_protocol, PURPLE_NOTIFY_MSG_INFO, "Verification Failed", + "Please make sure you entered the correct verification code.", NULL, NULL, NULL); + return; + } + } else { + // TODO: we should find a way to request the key + // only once. + purple_debug_info(PLUGIN_ID, "Device not registered, requesting new authentication code.\n"); + char *new_hash = network_request_registration(); + purple_debug_info(PLUGIN_ID, "Saving verification_hash: '%s'", new_hash); + purple_account_set_string(acct, "verification_hash", new_hash); + } + } + + // Our protocol data, that will be delivered to us + // through purple connection + telegram_conn *conn = g_new0(telegram_conn, 1); + conn->gc = gc; conn->account = acct; + purple_connection_set_protocol_data(gc, conn); - gc->proto_data = conn; - purple_connection_set_state(gc, PURPLE_CONNECTED); - - purple_debug_info(PLUGIN_ID, "Connected\n"); - */ + + // TODO: probably needs to be in callback after connection + purple_connection_set_state(gc, PURPLE_CONNECTED); + purple_debug_info(PLUGIN_ID, "Logged in...\n"); } - /** * This must be implemented. */ @@ -192,6 +195,7 @@ static void tgprpl_close(PurpleConnection * gc) static int tgprpl_send_im(PurpleConnection * gc, const char *who, const char *message, PurpleMessageFlags flags) { purple_debug_info(PLUGIN_ID, "tgprpl_send_im()\n"); + return -1; } @@ -241,7 +245,6 @@ static void tgprpl_add_buddies(PurpleConnection * gc, GList * buddies, GList * g static void tgprpl_remove_buddy(PurpleConnection * gc, PurpleBuddy * buddy, PurpleGroup * group) { purple_debug_info(PLUGIN_ID, "tgprpl_remove_buddy()\n"); - } static void tgprpl_remove_buddies(PurpleConnection * gc, GList * buddies, GList * groups) @@ -569,8 +572,13 @@ static void tgprpl_init(PurplePlugin *plugin) option = purple_account_option_list_new("Verification type", "verification_type", verification_values); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); - option = purple_account_option_string_new("Server", "server", TELEGRAM_TEST_SERVER); - option = purple_account_option_string_new("Verification key", "verification_key", NULL); + // option = purple_account_option_string_new("Server", "server", TELEGRAM_TEST_SERVER); + // prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + + option = purple_account_option_string_new("Verification key", "verification_key", NULL); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); + + option = purple_account_option_string_new("Verification hash", "verification_hash", NULL); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); // TODO: Path to public key (When you can change the server hostname, @@ -617,4 +625,5 @@ static PurplePluginInfo info = { NULL // reserved }; + PURPLE_INIT_PLUGIN(telegram, tgprpl_init, info) diff --git a/queries.c b/queries.c index 5087531..181f766 100644 --- a/queries.c +++ b/queries.c @@ -126,11 +126,13 @@ void query_restart (long long id) { } struct query *send_query (struct dc *DC, int ints, void *data, struct query_methods *methods, void *extra) { + logprintf("send_query(...)\n"); assert (DC); assert (DC->auth_key_id); if (!DC->sessions[0]) { dc_create_session (DC); } + logprintf("telegram: verbosity: %d\n", verbosity); if (verbosity) { logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port); } @@ -397,6 +399,7 @@ int send_code_on_answer (struct query *q UU) { tfree_str (phone_code_hash); } phone_code_hash = tstrndup (s, l); + logprintf("telegram: phone_code_hash: %s\n", phone_code_hash); fetch_int (); fetch_bool (); want_dc_num = -1; @@ -434,7 +437,7 @@ int config_got (void) { char *suser; extern int dc_working_num; -void do_send_code (const char *user) { +char* do_send_code (const char *user) { logprintf ("sending code\n"); suser = tstrdup (user); want_dc_num = 0; @@ -450,7 +453,7 @@ void do_send_code (const char *user) { logprintf ("send_code: dc_num = %d\n", dc_working_num); send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_code_methods, 0); net_loop (0, code_is_sent); - if (want_dc_num == -1) { return; } + if (want_dc_num == -1) { return phone_code_hash; } DC_working = DC_list[want_dc_num]; if (!DC_working->sessions[0]) { @@ -474,6 +477,8 @@ void do_send_code (const char *user) { send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_code_methods, 0); net_loop (0, code_is_sent); assert (want_dc_num == -1); + + return phone_code_hash; } @@ -626,12 +631,11 @@ int sign_in_on_answer (struct query *q UU) { fetch_user (&User); if (!our_id) { our_id = get_peer_id (User.id); - bl_do_set_our_id (our_id); } sign_in_ok = 1; if (verbosity) { - logprintf ( "authorized successfully: name = '%s %s', phone = '%s', expires = %d\n", User.first_name, User.last_name, User.phone, (int)(expires - get_double_time ())); + logprintf ( "telegram: authorized successfully: name = '%s %s', phone = '%s', expires = %d\n", User.first_name, User.last_name, User.phone, (int)(expires - get_double_time ())); } DC_working->has_auth = 1; @@ -643,7 +647,6 @@ int sign_in_on_answer (struct query *q UU) { int sign_in_on_error (struct query *q UU, int error_code, int l, char *error) { logprintf ( "error_code = %d, error = %.*s\n", error_code, l, error); sign_in_ok = -1; - assert (0); return 0; } @@ -652,11 +655,11 @@ struct query_methods sign_in_methods = { .on_error = sign_in_on_error }; -int do_send_code_result (const char *code) { +int do_send_code_result (const char *code, const char *sms_hash) { clear_packet (); out_int (CODE_auth_sign_in); out_string (suser); - out_string (phone_code_hash); + out_string(sms_hash); out_string (code); send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, 0); sign_in_ok = 0; @@ -698,27 +701,27 @@ int get_contacts_on_answer (struct query *q UU) { struct user *U = fetch_alloc_user (); print_start (); push_color (COLOR_YELLOW); - printf ("User #%d: ", get_peer_id (U->id)); + logprintf ("User #%d: ", get_peer_id (U->id)); print_user_name (U->id, (peer_t *)U); push_color (COLOR_GREEN); - printf (" ("); - printf ("%s", U->print_name); + logprintf (" ("); + logprintf ("%s", U->print_name); if (U->phone) { - printf (" "); - printf ("%s", U->phone); + logprintf (" "); + logprintf ("%s", U->phone); } - printf (") "); + logprintf (") "); pop_color (); if (U->status.online > 0) { - printf ("online\n"); + logprintf ("online\n"); } else { if (U->status.online < 0) { - printf ("offline. Was online "); + logprintf ("offline. Was online "); print_date_full (U->status.when); } else { - printf ("offline permanent"); + logprintf ("offline permanent"); } - printf ("\n"); + logprintf ("\n"); } pop_color (); print_end (); @@ -872,9 +875,9 @@ int msg_send_on_answer (struct query *q UU) { } print_start (); push_color (COLOR_YELLOW); - printf ("Link with user "); + logprintf ("Link with user "); print_user_name (U->id, (void *)U); - printf (" changed\n"); + logprintf (" changed\n"); pop_color (); print_end (); } @@ -1175,15 +1178,15 @@ int get_dialogs_on_answer (struct query *q UU) { switch (get_peer_type (plist[i])) { case PEER_USER: UC = user_chat_get (plist[i]); - printf ("User "); + logprintf ("User "); print_user_name (plist[i], UC); - printf (": %d unread\n", dlist[2 * i + 1]); + logprintf (": %d unread\n", dlist[2 * i + 1]); break; case PEER_CHAT: UC = user_chat_get (plist[i]); - printf ("Chat "); + logprintf ("Chat "); print_chat_name (plist[i], UC); - printf (": %d unread\n", dlist[2 * i + 1]); + logprintf (": %d unread\n", dlist[2 * i + 1]); break; } } @@ -1646,21 +1649,21 @@ void print_chat_info (struct chat *C) { peer_t *U = (void *)C; print_start (); push_color (COLOR_YELLOW); - printf ("Chat "); + logprintf ("Chat "); print_chat_name (U->id, U); - printf (" members:\n"); + logprintf (" members:\n"); int i; for (i = 0; i < C->user_list_size; i++) { - printf ("\t\t"); + logprintf ("\t\t"); print_user_name (MK_USER (C->user_list[i].user_id), user_chat_get (MK_USER (C->user_list[i].user_id))); - printf (" invited by "); + logprintf (" invited by "); print_user_name (MK_USER (C->user_list[i].inviter_id), user_chat_get (MK_USER (C->user_list[i].inviter_id))); - printf (" at "); + logprintf (" at "); print_date_full (C->user_list[i].date); if (C->user_list[i].user_id == C->admin_id) { - printf (" admin"); + logprintf (" admin"); } - printf ("\n"); + logprintf ("\n"); } pop_color (); print_end (); @@ -1700,17 +1703,17 @@ void print_user_info (struct user *U) { peer_t *C = (void *)U; print_start (); push_color (COLOR_YELLOW); - printf ("User "); + logprintf ("User "); print_user_name (U->id, C); - printf (":\n"); - printf ("\treal name: %s %s\n", U->real_first_name, U->real_last_name); - printf ("\tphone: %s\n", U->phone); + logprintf (":\n"); + logprintf ("\treal name: %s %s\n", U->real_first_name, U->real_last_name); + logprintf ("\tphone: %s\n", U->phone); if (U->status.online > 0) { - printf ("\tonline\n"); + logprintf ("\tonline\n"); } else { - printf ("\toffline (was online "); + logprintf ("\toffline (was online "); print_date_full (U->status.when); - printf (")\n"); + logprintf (")\n"); } pop_color (); print_end (); @@ -2127,27 +2130,27 @@ int add_contact_on_answer (struct query *q UU) { struct user *U = fetch_alloc_user (); print_start (); push_color (COLOR_YELLOW); - printf ("User #%d: ", get_peer_id (U->id)); + logprintf ("User #%d: ", get_peer_id (U->id)); print_user_name (U->id, (peer_t *)U); push_color (COLOR_GREEN); - printf (" ("); - printf ("%s", U->print_name); + logprintf (" ("); + logprintf ("%s", U->print_name); if (U->phone) { - printf (" "); - printf ("%s", U->phone); + logprintf (" "); + logprintf ("%s", U->phone); } - printf (") "); + logprintf (") "); pop_color (); if (U->status.online > 0) { - printf ("online\n"); + logprintf ("online\n"); } else { if (U->status.online < 0) { - printf ("offline. Was online "); + logprintf ("offline. Was online "); print_date_full (U->status.when); } else { - printf ("offline permanent"); + logprintf ("offline permanent"); } - printf ("\n"); + logprintf ("\n"); } pop_color (); print_end (); @@ -2223,11 +2226,11 @@ int contacts_search_on_answer (struct query *q UU) { push_color (COLOR_YELLOW); for (i = 0; i < n; i++) { struct user *U = fetch_alloc_user (); - printf ("User "); + logprintf ("User "); push_color (COLOR_RED); - printf ("%s %s", U->first_name, U->last_name); + logprintf ("%s %s", U->first_name, U->last_name); pop_color (); - printf (". Phone %s\n", U->phone); + logprintf (". Phone %s\n", U->phone); } pop_color (); print_end (); @@ -2254,17 +2257,17 @@ int send_encr_accept_on_answer (struct query *q UU) { if (E->state == sc_ok) { print_start (); push_color (COLOR_YELLOW); - printf ("Encrypted connection with "); + logprintf ("Encrypted connection with "); print_encr_chat_name (E->id, (void *)E); - printf (" established\n"); + logprintf (" established\n"); pop_color (); print_end (); } else { print_start (); push_color (COLOR_YELLOW); - printf ("Encrypted connection with "); + logprintf ("Encrypted connection with "); print_encr_chat_name (E->id, (void *)E); - printf (" failed\n"); + logprintf (" failed\n"); pop_color (); print_end (); } @@ -2276,17 +2279,17 @@ int send_encr_request_on_answer (struct query *q UU) { if (E->state == sc_deleted) { print_start (); push_color (COLOR_YELLOW); - printf ("Encrypted connection with "); + logprintf ("Encrypted connection with "); print_encr_chat_name (E->id, (void *)E); - printf (" can not be established\n"); + logprintf (" can not be established\n"); pop_color (); print_end (); } else { print_start (); push_color (COLOR_YELLOW); - printf ("Establishing connection with "); + logprintf ("Establishing connection with "); print_encr_chat_name (E->id, (void *)E); - printf ("\n"); + logprintf ("\n"); pop_color (); print_end (); @@ -2679,12 +2682,12 @@ void do_visualize_key (peer_id_t id) { for (j = 0; j < 4; j ++) { push_color (colors[x & 3]); push_color (COLOR_INVERSE); - printf (" "); + logprintf (" "); pop_color (); pop_color (); x = x >> 2; } - if (i & 1) { printf ("\n"); } + if (i & 1) { logprintf ("\n"); } } print_end (); } @@ -2713,7 +2716,7 @@ int get_suggested_on_answer (struct query *q UU) { peer_t *U = (void *)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]); + logprintf (" phone %s: %d mutual friends\n", U->user.phone, l[2 * i + 1]); } pop_color (); print_end (); diff --git a/queries.h b/queries.h index afcc64e..189f89d 100644 --- a/queries.h +++ b/queries.h @@ -63,9 +63,9 @@ void work_timers (void); extern struct query_methods help_get_config_methods; -void do_send_code (const char *user); +char* do_send_code (const char *user); void do_phone_call (const char *user); -int do_send_code_result (const char *code); +int do_send_code_result (const char *code, const char *sms_hash); double get_double_time (void); void do_update_contact_list (void); diff --git a/tg-cli.h b/tg-cli.h index 95b1156..128e69c 100755 --- a/tg-cli.h +++ b/tg-cli.h @@ -2,6 +2,39 @@ int tg_login (); +void running_for_first_time (); + +void parse_config (); +void store_config (); + +void read_auth_file (); + +/** + * Connect to the telegram network with the given configuration + */ +void network_connect (); + +/** + * Request a registration code + */ +char* network_request_registration(); + +/** + * Verify the registration with the given registration code + */ +int network_verify_registration(const char *code, const char *sms_hash); + +/** + * Retur if the current phone is registered in the given network. + */ +int network_phone_is_registered(); + +/** + * Return if the current client is registered. + */ +int network_client_is_registered(); + +void set_default_username (); // Settings #define AUTH_MODE_SMS "sms" #define AUTH_MODE_PHONE "phone"