Commit fe08f0c5 authored by vysheng's avatar vysheng

more code

parent bf86f756
......@@ -1126,9 +1126,7 @@ static void replay_log_event (void) {
assert (rptr < wptr);
int op = *rptr;
if (verbosity >= 2) {
logprintf ("log_pos %lld, op 0x%08x\n", binlog_pos, op);
}
vlogprintf (E_DEBUG, "replay_log_event: log_pos=%lld, op=0x%08x\n", binlog_pos, op);
in_ptr = rptr;
in_end = wptr;
......@@ -1201,7 +1199,7 @@ static void replay_log_event (void) {
FETCH_COMBINATOR_FUNCTION (binlog_set_msg_id)
FETCH_COMBINATOR_FUNCTION (binlog_delete_msg)
default:
logprintf ("Unknown op 0x%08x\n", op);
vlogprintf (E_ERROR, "Unknown op 0x%08x\n", op);
assert (0);
}
assert (ok >= 0);
......@@ -1287,9 +1285,7 @@ void tgl_reopen_binlog_for_writing (void) {
}
static void add_log_event (const int *data, int len) {
if (verbosity) {
logprintf ("Add log event: magic = 0x%08x, len = %d\n", data[0], len);
}
vlogprintf (E_DEBUG, "Add log event: magic = 0x%08x, len = %d\n", data[0], len);
assert (!(len & 3));
rptr = (void *)data;
wptr = rptr + (len / 4);
......@@ -1297,7 +1293,7 @@ static void add_log_event (const int *data, int len) {
int *end = in_end;
replay_log_event ();
if (rptr != wptr) {
logprintf ("Unread %lld ints. Len = %d\n", (long long)(wptr - rptr), len);
vlogprintf (E_ERROR, "Unread %lld ints. Len = %d\n", (long long)(wptr - rptr), len);
assert (rptr == wptr);
}
if (tgl_state.binlog_enabled) {
......
......@@ -34,11 +34,6 @@
#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);
......
......@@ -155,7 +155,7 @@ char *get_state_filename (void);
char *get_secret_chat_filename (void);
int zero[512];
/*
void write_dc (int auth_file_fd, struct dc *DC) {
assert (write (auth_file_fd, &DC->port, 4) == 4);
int l = strlen (DC->ip);
......@@ -436,7 +436,7 @@ void write_secret_chat_file (void) {
assert (write (fd, encr_prime, 256) == 256);
}
close (fd);
}
}*/
extern int max_chat_size;
int mcs (void) {
......
......@@ -49,7 +49,6 @@
#include "telegram.h"
#include "loop.h"
#include "mtproto-client.h"
#include "interface.h"
#include "tools.h"
......@@ -59,8 +58,8 @@
#include "tgl.h"
#define PROGNAME "telegram-client"
#define VERSION "0.01"
#define PROGNAME "telegram-cli"
#define VERSION "0.07"
#define CONFIG_DIRECTORY "." PROG_NAME
#define CONFIG_FILE "config"
......@@ -319,14 +318,21 @@ void parse_config (void) {
config_directory = make_full_path (config_directory);
parse_config_val (&conf, &auth_file_name, "auth_file", AUTH_KEY_FILE, config_directory);
parse_config_val (&conf, &state_file_name, "state_file", STATE_FILE, config_directory);
parse_config_val (&conf, &secret_chat_file_name, "secret", SECRET_CHAT_FILE, config_directory);
parse_config_val (&conf, &downloads_directory, "downloads", DOWNLOADS_DIRECTORY, config_directory);
parse_config_val (&conf, &binlog_file_name, "binlog", BINLOG_FILE, config_directory);
strcpy (buf + l, "binlog_enabled");
config_lookup_bool (&conf, buf, &binlog_enabled);
if (binlog_enabled) {
tgl_set_binlog_mode (1);
tgl_set_binlog_path (binlog_file_name);
} else {
tgl_set_binlog_mode (0);
tgl_set_auth_file_path (auth_file_name);
}
tgl_set_download_directory (downloads_directory);
if (!mkdir (config_directory, CONFIG_DIRECTORY_MODE)) {
printf ("[%s] created\n", config_directory);
}
......@@ -338,10 +344,17 @@ void parse_config (void) {
void parse_config (void) {
printf ("libconfig not enabled\n");
tasprintf (&auth_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, AUTH_KEY_FILE);
tasprintf (&state_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, STATE_FILE);
tasprintf (&secret_chat_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, SECRET_CHAT_FILE);
tasprintf (&downloads_directory, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, DOWNLOADS_DIRECTORY);
tasprintf (&binlog_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, BINLOG_FILE);
if (binlog_enabled) {
tgl_set_binlog_mode (1);
tgl_set_binlog_path (binlog_file_name);
} else {
tgl_set_binlog_mode (0);
tgl_set_auth_file_path (auth_file_name;
}
tgl_set_download_directory (downloads_directory);
}
#endif
......@@ -488,7 +501,7 @@ int main (int argc, char **argv) {
args_parse (argc, argv);
printf (
"Telegram-client version " TG_VERSION ", Copyright (C) 2013 Vitaly Valtman\n"
"Telegram-client version " TGL_VERSION ", Copyright (C) 2013 Vitaly Valtman\n"
"Telegram-client comes with ABSOLUTELY NO WARRANTY; for details type `show_license'.\n"
"This is free software, and you are welcome to redistribute it\n"
"under certain conditions; type `show_license' for details.\n"
......
......@@ -50,7 +50,6 @@
#include "include.h"
#include "queries.h"
#include "loop.h"
#include "interface.h"
#include "structures.h"
#include "binlog.h"
#include "auto.h"
......@@ -142,18 +141,18 @@ static int rsa_load_public_key (const char *public_key_name) {
pubKey = NULL;
FILE *f = fopen (public_key_name, "r");
if (f == NULL) {
logprintf ( "Couldn't open public key file: %s\n", public_key_name);
vlogprintf (E_WARNING, "Couldn't open public key file: %s\n", public_key_name);
return -1;
}
pubKey = PEM_read_RSAPublicKey (f, NULL, NULL, NULL);
fclose (f);
if (pubKey == NULL) {
logprintf ( "PEM_read_RSAPublicKey returns NULL.\n");
vlogprintf (E_WARNING, "PEM_read_RSAPublicKey returns NULL.\n");
return -1;
}
if (verbosity) {
logprintf ( "public key '%s' loaded successfully\n", rsa_public_key_name);
vlogprintf (E_WARNING, "public key '%s' loaded successfully\n", rsa_public_key_name);
}
return 0;
......@@ -267,9 +266,7 @@ unsigned p1, p2;
int process_respq_answer (struct connection *c, char *packet, int len) {
int i;
if (verbosity) {
logprintf ( "process_respq_answer(), len=%d\n", len);
}
vlogprintf (E_DEBUG, "process_respq_answer(), len=%d\n", len);
assert (len >= 76);
assert (!*(long long *) packet);
assert (*(int *) (packet + 16) == len - 20);
......@@ -289,10 +286,6 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
p1 = 0, p2 = 0;
if (verbosity >= 2) {
logprintf ( "%lld received\n", what);
}
int it = 0;
unsigned long long g = 0;
for (i = 0; i < 3 || it < 1000; i++) {
......@@ -337,10 +330,6 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
}
if (verbosity) {
logprintf ( "p1 = %d, p2 = %d, %d iterations\n", p1, p2, it);
}
/// ++p1; ///
assert (*(int *) (from) == CODE_vector);
......@@ -354,7 +343,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
}
}
if (i == fingerprints_num) {
logprintf ( "fatal: don't have any matching keys (%016llx expected)\n", pk_fingerprint);
vlogprintf (E_ERROR, "fatal: don't have any matching keys (%016llx expected)\n", pk_fingerprint);
exit (2);
}
// create inner part (P_Q_inner_data)
......@@ -519,7 +508,7 @@ int check_g (unsigned char p[256], BIGNUM *g) {
ok = 1;
break;
} else if (s[i] > p[i]) {
logprintf ("i = %d (%d %d)\n", i, (int)s[i], (int)p[i]);
vlogprintf (E_WARNING, "i = %d (%d %d)\n", i, (int)s[i], (int)p[i]);
return -1;
}
}
......@@ -536,11 +525,9 @@ int check_g_bn (BIGNUM *p, BIGNUM *g) {
}
int process_dh_answer (struct connection *c, char *packet, int len) {
if (verbosity) {
logprintf ( "process_dh_answer(), len=%d\n", len);
}
vlogprintf (E_DEBUG, "process_dh_answer(), len=%d\n", len);
if (len < 116) {
logprintf ( "%u * %u = %llu", p1, p2, what);
vlogprintf (E_ERROR, "%u * %u = %llu", p1, p2, what);
}
assert (len >= 116);
assert (!*(long long *) packet);
......@@ -636,9 +623,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
int process_auth_complete (struct connection *c UU, char *packet, int len) {
if (verbosity) {
logprintf ( "process_dh_answer(), len=%d\n", len);
}
vlogprintf (E_DEBUG, "process_dh_answer(), len=%d\n", len);
assert (len == 72);
assert (!*(long long *) packet);
assert (*(int *) (packet + 16) == len - 20);
......@@ -659,9 +644,6 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
assert (!memcmp (packet + 56, sha1_buffer + 4, 16));
GET_DC(c)->server_salt = *(long long *)server_nonce ^ *(long long *)new_nonce;
if (verbosity >= 3) {
logprintf ( "auth_key_id=%016llx\n", GET_DC(c)->auth_key_id);
}
//kprintf ("OK\n");
//c->status = conn_error;
......@@ -669,9 +651,7 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
c_state = st_authorized;
//return 1;
if (verbosity) {
logprintf ( "Auth success\n");
}
vlogprintf (E_DEBUG, "Auth success\n");
auth_success ++;
GET_DC(c)->flags |= 1;
write_auth_file ();
......@@ -735,9 +715,7 @@ int aes_encrypt_message (struct dc *DC, struct encrypted_message *enc) {
assert (enc->msg_len >= 0 && enc->msg_len <= MAX_MESSAGE_INTS * 4 - 16 && !(enc->msg_len & 3));
sha1 ((unsigned char *) &enc->server_salt, enc_len, sha1_buffer);
//printf ("enc_len is %d\n", enc_len);
if (verbosity >= 2) {
logprintf ( "sending message with sha1 %08x\n", *(int *)sha1_buffer);
}
vlogprintf (E_DEBUG, "sending message with sha1 %08x\n", *(int *)sha1_buffer);
memcpy (enc->msg_key, sha1_buffer + 4, 16);
init_aes_auth (DC->auth_key, enc->msg_key, AES_ENCRYPT);
//hexdump ((char *)enc, (char *)enc + enc_len + 24);
......@@ -831,7 +809,7 @@ void fetch_date (void) {
void fetch_seq (void) {
int x = fetch_int ();
if (x > seq + 1) {
logprintf ("Hole in seq: seq = %d, x = %d\n", seq, x);
vlogprintf (E_NOTICE, "Hole in seq: seq = %d, x = %d\n", seq, x);
//tgl_do_get_difference ();
//seq = x;
} else if (x == seq + 1) {
......@@ -911,9 +889,11 @@ void work_update (struct connection *c UU, long long msg_id UU) {
struct tgl_message *M = tglf_fetch_alloc_message ();
assert (M);
fetch_pts ();
unread_messages ++;
print_message (M);
update_prompt ();
tgl_state.callback.new_msg (M);
//unread_messages ++;
//print_message (M);
//update_prompt ();
break;
};
case CODE_update_message_i_d:
......@@ -930,30 +910,38 @@ void work_update (struct connection *c UU, long long msg_id UU) {
{
assert (fetch_int () == (int)CODE_vector);
int n = fetch_int ();
struct tgl_message **ML = talloc (n * sizeof (void *));
int p = 0;
int i;
for (i = 0; i < n; i++) {
int id = fetch_int ();
struct tgl_message *M = tgl_message_get (id);
if (M) {
bl_do_set_unread (M, 0);
ML[p ++] = M;
}
}
fetch_pts ();
if (log_level >= 1) {
tgl_state.callback.marked_read (p, ML);
tfree (ML, sizeof (void *) * n);
/*if (log_level >= 1) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" %d messages marked as read\n", n);
pop_color ();
print_end ();
}
}*/
}
break;
case CODE_update_user_typing:
{
tgl_peer_id_t id = TGL_MK_USER (fetch_int ());
tgl_peer_t *U = tgl_peer_get (id);
if (log_level >= 2) {
tgl_state.callback.type_notification (id, (void *)U);
/*if (log_level >= 2) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
......@@ -962,7 +950,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf (" is typing....\n");
pop_color ();
print_end ();
}
}*/
}
break;
case CODE_update_chat_user_typing:
......@@ -971,7 +959,9 @@ void work_update (struct connection *c UU, long long msg_id UU) {
tgl_peer_id_t id = TGL_MK_USER (fetch_int ());
tgl_peer_t *C = tgl_peer_get (chat_id);
tgl_peer_t *U = tgl_peer_get (id);
if (log_level >= 2) {
tgl_state.callback.type_in_chat_notification (id, (void *)U, chat_id, (void *)C);
/*if (log_level >= 2) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
......@@ -982,7 +972,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf ("....\n");
pop_color ();
print_end ();
}
}*/
}
break;
case CODE_update_user_status:
......@@ -991,7 +981,8 @@ void work_update (struct connection *c UU, long long msg_id UU) {
tgl_peer_t *U = tgl_peer_get (user_id);
if (U) {
tglf_fetch_user_status (&U->user.status);
if (log_level >= 3) {
tgl_state.callback.status_notification ((void *)U);
/*if (log_level >= 3) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
......@@ -1001,7 +992,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf ("%s\n", (U->user.status.online > 0) ? "online" : "offline");
pop_color ();
print_end ();
}
}*/
} else {
struct tgl_user_status t;
tglf_fetch_user_status (&t);
......@@ -1019,7 +1010,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
char *l = fetch_str (l2);
struct tgl_user *U = &UC->user;
bl_do_user_set_real_name (U, f, l1, l, l2);
print_start ();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
......@@ -1028,7 +1019,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
print_user_name (user_id, UC);
printf ("\n");
pop_color ();
print_end ();
print_end ();*/
} else {
fetch_skip_str ();
fetch_skip_str ();
......@@ -1060,14 +1051,14 @@ void work_update (struct connection *c UU, long long msg_id UU) {
}
bl_do_set_user_profile_photo (U, photo_id, &big, &small);
print_start ();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, UC);
printf (" updated profile photo\n");
pop_color ();
print_end ();
print_end ();*/
} else {
struct tgl_file_location t;
unsigned y = fetch_int ();
......@@ -1086,12 +1077,12 @@ void work_update (struct connection *c UU, long long msg_id UU) {
{
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
print_start ();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Restored %d messages\n", n);
pop_color ();
print_end ();
print_end ();*/
fetch_skip (n);
fetch_pts ();
}
......@@ -1100,12 +1091,12 @@ void work_update (struct connection *c UU, long long msg_id UU) {
{
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
print_start ();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Deleted %d messages\n", n);
pop_color ();
print_end ();
print_end ();*/
fetch_skip (n);
fetch_pts ();
}
......@@ -1142,7 +1133,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
fetch_int (); // version
}
}
print_start ();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Chat ");
......@@ -1153,7 +1144,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf (" changed list, but we are forbidden to know about it (Why this update even was sent to us?\n");
}
pop_color ();
print_end ();
print_end ();*/
}
break;
case CODE_update_contact_registered:
......@@ -1161,28 +1152,29 @@ void work_update (struct connection *c UU, long long msg_id UU) {
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *U = tgl_peer_get (user_id);
fetch_int (); // date
print_start ();
tgl_state.callback.user_registered (U);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, U);
printf (" registered\n");
pop_color ();
print_end ();
print_end ();*/
}
break;
case CODE_update_contact_link:
{
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *U = tgl_peer_get (user_id);
print_start ();
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Updated link with user ");
print_user_name (user_id, U);
printf ("\n");
pop_color ();
print_end ();
print_end ();*/
unsigned t = fetch_int ();
assert (t == CODE_contacts_my_link_empty || t == CODE_contacts_my_link_requested || t == CODE_contacts_my_link_contact);
if (t == CODE_contacts_my_link_requested) {
......@@ -1246,9 +1238,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
case CODE_update_encryption:
{
struct tgl_secret_chat *E = tglf_fetch_alloc_encrypted_chat ();
if (verbosity >= 2) {
logprintf ("Secret chat state = %d\n", E->state);
}
vlogprintf (E_DEBUG, "Secret chat state = %d\n", E->state);
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
......@@ -1415,7 +1405,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
}
break;
default:
logprintf ("Unknown update type %08x\n", op);
vlogprintf (E_ERROR, "Unknown update type %08x\n", op);
;
}
}
......@@ -1476,9 +1466,7 @@ void work_update_short_chat_message (struct connection *c UU, long long msg_id U
}
void work_container (struct connection *c, long long msg_id UU) {
if (verbosity) {
logprintf ( "work_container: msg_id = %lld\n", msg_id);
}
vlogprintf (E_DEBUG, "work_container: msg_id = %lld\n", msg_id);
assert (fetch_int () == CODE_msg_container);
int n = fetch_int ();
int i;
......@@ -1499,9 +1487,7 @@ void work_container (struct connection *c, long long msg_id UU) {
}
void work_new_session_created (struct connection *c, long long msg_id UU) {
if (verbosity) {
logprintf ( "work_new_session_created: msg_id = %lld\n", msg_id);
}
vlogprintf (E_DEBUG, "work_new_session_created: msg_id = %lld\n", msg_id);
assert (fetch_int () == (int)CODE_new_session_created);
fetch_long (); // first message id
//DC->session_id = fetch_long ();
......@@ -1511,26 +1497,20 @@ void work_new_session_created (struct connection *c, long long msg_id UU) {
}
void work_msgs_ack (struct connection *c UU, long long msg_id UU) {
if (verbosity) {
logprintf ( "work_msgs_ack: msg_id = %lld\n", msg_id);
}
vlogprintf (E_DEBUG, "work_msgs_ack: msg_id = %lld\n", msg_id);
assert (fetch_int () == CODE_msgs_ack);
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
int i;
for (i = 0; i < n; i++) {
long long id = fetch_long ();
if (verbosity) {
logprintf ("ack for %lld\n", id);
}
vlogprintf (E_DEBUG + 1, "ack for %lld\n", id);
query_ack (id);
}
}
void work_rpc_result (struct connection *c UU, long long msg_id UU) {
if (verbosity) {
logprintf ( "work_rpc_result: msg_id = %lld\n", msg_id);
}
vlogprintf (E_DEBUG, "work_rpc_result: msg_id = %lld\n", msg_id);
assert (fetch_int () == (int)CODE_rpc_result);
long long id = fetch_long ();
int op = prefetch_int ();
......@@ -1558,10 +1538,6 @@ void work_packed (struct connection *c, long long msg_id) {
//assert (total_out % 4 == 0);
in_ptr = buf;
in_end = in_ptr + total_out / 4;
if (verbosity >= 4) {
logprintf ( "Unzipped data: ");
hexdump_in ();
}
rpc_execute_answer (c, msg_id);
in_ptr = end;
in_end = eend;
......@@ -1601,7 +1577,7 @@ void work_new_detailed_info (struct connection *c UU, long long msg_id UU) {
void work_updates_to_long (struct connection *c UU, long long msg_id UU) {
assert (fetch_int () == (int)CODE_updates_too_long);
logprintf ("updates to long... Getting difference\n");
vlogprintf (E_NOTICE, "updates to long... Getting difference\n");
tgl_do_get_difference ();
}
......@@ -1610,14 +1586,10 @@ void work_bad_msg_notification (struct connection *c UU, long long msg_id UU) {
long long m1 = fetch_long ();
int s = fetch_int ();
int e = fetch_int ();
logprintf ("bad_msg_notification: msg_id = %lld, seq = %d, error = %d\n", m1, s, e);
vlogprintf (E_NOTICE, "bad_msg_notification: msg_id = %lld, seq = %d, error = %d\n", m1, s, e);
}
void rpc_execute_answer (struct connection *c, long long msg_id UU) {
if (verbosity >= 5) {
logprintf ("rpc_execute_answer: fd=%d\n", c->fd);
hexdump_in ();
}
int op = prefetch_int ();
switch (op) {
case CODE_msg_container:
......@@ -1666,17 +1638,14 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
work_bad_msg_notification (c, msg_id);
return;
}
logprintf ( "Unknown message: \n");
hexdump_in ();
vlogprintf (E_WARNING, "Unknown message: %08x\n", op);
in_ptr = in_end; // Will not fail due to assertion in_ptr == in_end
}
int process_rpc_message (struct connection *c UU, struct encrypted_message *enc, int len) {
const int MINSZ = offsetof (struct encrypted_message, message);
const int UNENCSZ = offsetof (struct encrypted_message, server_salt);
if (verbosity) {
logprintf ( "process_rpc_message(), len=%d\n", len);
}
vlogprintf (E_DEBUG, "process_rpc_message(), len=%d\n", len);
assert (len >= MINSZ && (len & 15) == (UNENCSZ & 15));
struct dc *DC = GET_DC(c);
assert (enc->auth_key_id == DC->auth_key_id);
......@@ -1702,10 +1671,9 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
}
double st = get_server_time (DC);
if (this_server_time < st - 300 || this_server_time > st + 30) {
logprintf ("salt = %lld, session_id = %lld, msg_id = %lld, seq_no = %d, st = %lf, now = %lf\n", enc->server_salt, enc->session_id, enc->msg_id, enc->seq_no, st, get_utime (CLOCK_REALTIME));
vlogprintf (E_WARNING, "salt = %lld, session_id = %lld, msg_id = %lld, seq_no = %d, st = %lf, now = %lf\n", enc->server_salt, enc->session_id, enc->msg_id, enc->seq_no, st, get_utime (CLOCK_REALTIME));
in_ptr = enc->message;
in_end = in_ptr + (enc->msg_len / 4);
hexdump_in ();
}
assert (this_server_time >= st - 300 && this_server_time <= st + 30);
......
......@@ -39,7 +39,6 @@
#include <openssl/sha.h>
#include "mtproto-common.h"
#include "interface.h"
#include "include.h"
#ifdef __MACH__
......@@ -61,9 +60,7 @@ int get_random_bytes (unsigned char *buf, int n) {
if (h >= 0) {
r = read (h, buf, n);
if (r > 0) {
if (verbosity >= 3) {
logprintf ( "added %d bytes of real entropy to secure random numbers seed\n", r);
}
vlogprintf (E_DEBUG, "added %d bytes of real entropy to secure random numbers seed\n", r);
} else {
r = 0;
}
......@@ -143,16 +140,14 @@ void prng_seed (const char *password_filename, int password_length) {
if (password_filename && password_length > 0) {
int fd = open (password_filename, O_RDONLY);
if (fd < 0) {
logprintf ( "Warning: fail to open password file - \"%s\", %m.\n", password_filename);
vlogprintf (E_WARNING, "Warning: fail to open password file - \"%s\", %m.\n", password_filename);
} else {
unsigned char *a = talloc0 (password_length);
int l = read (fd, a, password_length);
if (l < 0) {
logprintf ( "Warning: fail to read password file - \"%s\", %m.\n", password_filename);
vlogprintf (E_WARNING, "Warning: fail to read password file - \"%s\", %m.\n", password_filename);
} else {
if (verbosity > 0) {
logprintf ( "read %d bytes from password file.\n", l);
}
vlogprintf (E_DEBUG, "read %d bytes from password file.\n", l);
RAND_add (a, l, l);
}
close (fd);
......
......@@ -26,9 +26,11 @@
#include <openssl/aes.h>
#include <stdio.h>
#include "interface.h"
//#include "interface.h"
#include "tools.h"
#include "auto/constants.h"
#include "tgl.h"
/* DH key exchange protocol data structures */
#define CODE_req_pq 0x60469778
#define CODE_resPQ 0x05162463
......@@ -178,9 +180,7 @@ static inline int prefetch_strlen (void) {
extern int verbosity;
static inline char *fetch_str (int len) {
assert (len >= 0);
if (verbosity > 6) {
logprintf ("fetch_string: len = %d\n", len);
}
vlogprintf (E_DEBUG + 3, "fetch_string: len = %d\n", len);
if (len < 254) {
char *str = (char *) in_ptr + 1;
in_ptr += 1 + (len >> 2);
......@@ -272,16 +272,12 @@ int fetch_bignum (BIGNUM *x);
static inline int fetch_int (void) {
assert (in_ptr + 1 <= in_end);
if (verbosity > 6) {
logprintf ("fetch_int: 0x%08x (%d)\n", *in_ptr, *in_ptr);
}
vlogprintf (E_DEBUG + 3, "fetch_int: 0x%08x (%d)\n", *in_ptr, *in_ptr);
return *(in_ptr ++);
}
static inline int fetch_bool (void) {
if (verbosity > 6) {
logprintf ("fetch_bool: 0x%08x (%d)\n", *in_ptr, *in_ptr);
}
vlogprintf (E_DEBUG + 3, "fetch_bool: 0x%08x (%d)\n", *in_ptr, *in_ptr);
assert (in_ptr + 1 <= in_end);
assert (*(in_ptr) == (int)CODE_bool_true || *(in_ptr) == (int)CODE_bool_false);
return *(in_ptr ++) == (int)CODE_bool_true;
......@@ -349,14 +345,14 @@ void init_aes_unauth (const char server_nonce[16], const char hidden_client_nonc
void init_aes_auth (char auth_key[192], char msg_key[16], int encrypt);
int pad_aes_encrypt (char *from, int from_len, char *to, int size);
int pad_aes_decrypt (char *from, int from_len, char *to, int size);
/*
static inline void hexdump_in (void) {
hexdump (in_ptr, in_end);
}
static inline void hexdump_out (void) {
hexdump (packet_buffer, packet_ptr);
}
}*/
#ifdef __MACH__
#define CLOCK_REALTIME 0
......
......@@ -26,9 +26,6 @@ struct dc;
#define TG_SERVER_TEST "173.240.5.253"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define TG_BUILD "209"
#define TG_VERSION "0.01-beta"
#define ACK_TIMEOUT 1
#define MAX_DC_ID 10
......
......@@ -43,7 +43,7 @@
#include "telegram.h"
#include "loop.h"
#include "structures.h"
#include "interface.h"
//#include "interface.h"
#include "net.h"
#include <openssl/bn.h>
#include <openssl/rand.h>
......@@ -64,21 +64,21 @@
#define OPEN_BIN "xdg-open %s"
#endif
int want_dc_num;
char *get_downloads_directory (void);
int verbosity;
extern int offline_mode;
//extern int offline_mode;
long long cur_uploading_bytes;
long long cur_uploaded_bytes;
long long cur_downloading_bytes;
long long cur_downloaded_bytes;
//long long cur_uploading_bytes;
//long long cur_uploaded_bytes;
//long long cur_downloading_bytes;
//long long cur_downloaded_bytes;
extern int binlog_enabled;
extern int sync_from_start;
//extern int binlog_enabled;
//extern int sync_from_start;
int queries_num;
static int queries_num;
void out_peer_id (tgl_peer_id_t id);
static void out_peer_id (tgl_peer_id_t id);
#define QUERY_TIMEOUT 6.0
#define memcmp8(a,b) memcmp ((a), (b), 8)
......@@ -97,9 +97,7 @@ struct query *query_get (long long id) {
int alarm_query (struct query *q) {
assert (q);
if (verbosity >= 1) {
logprintf ("Alarm query %lld\n", q->msg_id);
}
vlogprintf (E_DEBUG, "Alarm query %lld\n", q->msg_id);
q->ev.timeout = get_double_time () + QUERY_TIMEOUT;
insert_event_timer (&q->ev);
......@@ -127,15 +125,13 @@ void query_restart (long long id) {
}
}
struct query *send_query (struct dc *DC, int ints, void *data, struct query_methods *methods, void *extra) {
struct query *send_query (struct dc *DC, int ints, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra) {
assert (DC);
assert (DC->auth_key_id);
if (!DC->sessions[0]) {
dc_create_session (DC);
}
if (verbosity) {
logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port);
}
vlogprintf (E_DEBUG, "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port);
struct query *q = talloc0 (sizeof (*q));
q->data_len = ints;
q->data = talloc (4 * ints);
......@@ -143,15 +139,11 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
q->msg_id = encrypt_send_message (DC->sessions[0]->c, data, ints, 1);
q->session = DC->sessions[0];
q->seq_no = DC->sessions[0]->seq_no - 1;
if (verbosity) {
logprintf ( "Msg_id is %lld %p\n", q->msg_id, q);
}
vlogprintf (E_DEBUG, "Msg_id is %lld %p\n", q->msg_id, q);
q->methods = methods;
q->DC = DC;
if (queries_tree) {
if (verbosity >= 2) {
logprintf ( "%lld %lld\n", q->msg_id, queries_tree->x->msg_id);
}
vlogprintf (E_DEBUG + 2, "%lld %lld\n", q->msg_id, queries_tree->x->msg_id);
}
queries_tree = tree_insert_query (queries_tree, q, lrand48 ());
......@@ -161,10 +153,18 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
insert_event_timer (&q->ev);
q->extra = extra;
q->callback = callback;
q->callback_extra = callback_extra;
queries_num ++;
return q;
}
static int fail_on_error (struct query *q UU, int error_code UU, int l UU, char *error UU) {
fprintf (stderr, "error #%d: %.*s\n", error_code, l, error);
assert (0);
return 0;
}
void query_ack (long long id) {
struct query *q = query_get (id);
if (q && !(q->flags & QUERY_ACK_RECEIVED)) {
......@@ -179,14 +179,10 @@ void query_error (long long id) {
int error_code = fetch_int ();
int error_len = prefetch_strlen ();
char *error = fetch_str (error_len);
if (verbosity) {
logprintf ( "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
}
vlogprintf (E_WARNING, "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
struct query *q = query_get (id);
if (!q) {
if (verbosity) {
logprintf ( "No such query\n");
}
vlogprintf (E_WARNING, "No such query\n");
} else {
if (!(q->flags & QUERY_ACK_RECEIVED)) {
remove_event_timer (&q->ev);
......@@ -195,7 +191,7 @@ void query_error (long long id) {
if (q->methods && q->methods->on_error) {
q->methods->on_error (q, error_code, error_len, error);
} else {
logprintf ( "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
vlogprintf ( E_WARNING, "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
}
tfree (q->data, q->data_len * 4);
tfree (q, sizeof (*q));
......@@ -207,13 +203,11 @@ void query_error (long long id) {
static int packed_buffer[MAX_PACKED_SIZE / 4];
void query_result (long long id UU) {
if (verbosity) {
logprintf ( "result for query #%lld\n", id);
}
if (verbosity >= 4) {
vlogprintf (E_DEBUG, "result for query #%lld\n", id);
/*if (verbosity >= 4) {
logprintf ( "result: ");
hexdump_in ();
}
}*/
int op = prefetch_int ();
int *end = 0;
int *eend = 0;
......@@ -227,16 +221,17 @@ void query_result (long long id UU) {
//assert (total_out % 4 == 0);
in_ptr = packed_buffer;
in_end = in_ptr + total_out / 4;
if (verbosity >= 4) {
/*if (verbosity >= 4) {
logprintf ( "Unzipped data: ");
hexdump_in ();
}
}*/
}
struct query *q = query_get (id);
if (!q) {
if (verbosity) {
logprintf ( "No such query\n");
}
//if (verbosity) {
// logprintf ( "No such query\n");
//}
vlogprintf (E_WARNING, "No such query\n");
in_ptr = in_end;
} else {
if (!(q->flags & QUERY_ACK_RECEIVED)) {
......@@ -247,7 +242,7 @@ void query_result (long long id UU) {
if (q->methods->type) {
int *save = in_ptr;
if (skip_type_any (q->methods->type) < 0) {
logprintf ("Skipped %ld int out of %ld (type %s)\n", in_ptr - save, in_end - save, q->methods->type->type->id);
vlogprintf (E_ERROR, "Skipped %ld int out of %ld (type %s)\n", in_ptr - save, in_end - save, q->methods->type->type->id);
assert (0);
}
......@@ -272,16 +267,12 @@ DEFINE_TREE (timer, struct event_timer *, event_timer_cmp, 0)
struct tree_timer *timer_tree;
void insert_event_timer (struct event_timer *ev) {
if (verbosity > 2) {
logprintf ( "INSERT: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
}
vlogprintf (E_DEBUG + 2, "INSERT: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
timer_tree = tree_insert_timer (timer_tree, ev, lrand48 ());
}
void remove_event_timer (struct event_timer *ev) {
if (verbosity > 2) {
logprintf ( "REMOVE: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
}
vlogprintf (E_DEBUG + 2, "REMOVE: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
timer_tree = tree_delete_timer (timer_tree, ev);
}
......@@ -298,21 +289,19 @@ void work_timers (void) {
if (ev->timeout > t) { break; }
remove_event_timer (ev);
assert (ev->alarm);
if (verbosity) {
logprintf ("Alarm\n");
}
vlogprintf (E_DEBUG, "Alarm\n");
ev->alarm (ev->self);
}
}
int max_chat_size;
int max_bcast_size;
int want_dc_num;
int new_dc_num;
//int want_dc_num;
//int new_dc_num;
extern struct dc *DC_list[];
extern struct dc *DC_working;
void out_random (int n) {
static void out_random (int n) {
assert (n <= 32);
static char buf[32];
secure_random (buf, n);
......@@ -331,19 +320,19 @@ void tgl_do_insert_header (void) {
static char buf[4096];
tsnprintf (buf, sizeof (buf), "%.999s %.999s %.999s\n", st.sysname, st.release, st.version);
out_string (buf);
out_string (TG_VERSION " (build " TG_BUILD ")");
out_string (TGL_VERSION " (build " TGL_BUILD ")");
out_string ("En");
} else {
out_string ("x86");
out_string ("Linux");
out_string (TG_VERSION);
out_string (TGL_VERSION);
out_string ("en");
}
}
/* {{{ Get config */
void fetch_dc_option (void) {
static void fetch_dc_option (void) {
assert (fetch_int () == CODE_dc_option);
int id = fetch_int ();
int l1 = prefetch_strlen ();
......@@ -351,14 +340,12 @@ void fetch_dc_option (void) {
int l2 = prefetch_strlen ();
char *ip = fetch_str (l2);
int port = fetch_int ();
if (verbosity) {
logprintf ( "id = %d, name = %.*s ip = %.*s port = %d\n", id, l1, name, l2, ip, port);
}
vlogprintf (E_DEBUG, "id = %d, name = %.*s ip = %.*s port = %d\n", id, l1, name, l2, ip, port);
bl_do_dc_option (id, l1, name, l2, ip, port);
}
int help_get_config_on_answer (struct query *q UU) {
static int help_get_config_on_answer (struct query *q UU) {
unsigned op = fetch_int ();
assert (op == CODE_config || op == CODE_config_old);
fetch_int ();
......@@ -367,9 +354,7 @@ int help_get_config_on_answer (struct query *q UU) {
assert (test_mode == CODE_bool_true || test_mode == CODE_bool_false);
assert (test_mode == CODE_bool_false || test_mode == CODE_bool_true);
int this_dc = fetch_int ();
if (verbosity) {
logprintf ( "this_dc = %d\n", this_dc);
}
vlogprintf (E_DEBUG, "this_dc = %d\n", this_dc);
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
assert (n <= 10);
......@@ -381,30 +366,32 @@ int help_get_config_on_answer (struct query *q UU) {
if (op == CODE_config) {
max_bcast_size = fetch_int ();
}
if (verbosity >= 2) {
logprintf ( "chat_size = %d\n", max_chat_size);
vlogprintf (E_DEBUG, "chat_size = %d\n", max_chat_size);
if (q->callback) {
((void (*)(void *, int))(q->callback))(q->callback_extra, 1);
}
return 0;
}
struct query_methods help_get_config_methods = {
static struct query_methods help_get_config_methods = {
.on_answer = help_get_config_on_answer,
.type = TYPE_TO_PARAM(config)
};
void tgl_do_help_get_config (void) {
void tgl_do_help_get_config (void (*callback)(void *, int), void *callback_extra) {
clear_packet ();
tgl_do_insert_header ();
out_int (CODE_help_get_config);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &help_get_config_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &help_get_config_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Send code */
char *phone_code_hash;
int send_code_on_answer (struct query *q UU) {
static char *phone_code_hash;
static int send_code_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_auth_sent_code);
fetch_bool ();
int registered = fetch_bool ();
int l = prefetch_strlen ();
char *s = fetch_str (l);
if (phone_code_hash) {
......@@ -414,10 +401,13 @@ int send_code_on_answer (struct query *q UU) {
fetch_int ();
fetch_bool ();
want_dc_num = -1;
if (q->callback) {
((void (*)(void *, int, int, const char *))(q->callback)) (q->callback_extra, 1, registered, phone_code_hash);
}
return 0;
}
int send_code_on_error (struct query *q UU, int error_code, int l, char *error) {
static int send_code_on_error (struct query *q UU, int error_code, int l, char *error) {
int s = strlen ("PHONE_MIGRATE_");
int s2 = strlen ("NETWORK_MIGRATE_");
if (l >= s && !memcmp (error, "PHONE_MIGRATE_", s)) {
......@@ -427,55 +417,26 @@ int send_code_on_error (struct query *q UU, int error_code, int l, char *error)
int i = error[s2] - '0';
want_dc_num = i;
} else {
logprintf ( "error_code = %d, error = %.*s\n", error_code, l, error);
vlogprintf (E_ERROR, "error_code = %d, error = %.*s\n", error_code, l, error);
assert (0);
}
if (q->callback) {
((void (*)(void *, int, int, const char *))(q->callback)) (q->callback_extra, 0, 0, 0);
}
return 0;
}
struct query_methods send_code_methods = {
static struct query_methods send_code_methods = {
.on_answer = send_code_on_answer,
.on_error = send_code_on_error,
.type = TYPE_TO_PARAM(auth_sent_code)
};
int code_is_sent (void) {
return want_dc_num;
}
int config_got (void) {
return DC_list[want_dc_num] != 0;
}
char *suser;
//char *suser;
extern int dc_working_num;
void tgl_do_send_code (const char *user) {
logprintf ("sending code\n");
suser = tstrdup (user);
want_dc_num = 0;
clear_packet ();
tgl_do_insert_header ();
out_int (CODE_auth_send_code);
out_string (user);
out_int (0);
out_int (TG_APP_ID);
out_string (TG_APP_HASH);
out_string ("en");
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; }
DC_working = DC_list[want_dc_num];
if (!DC_working->sessions[0]) {
dc_create_session (DC_working);
}
dc_working_num = want_dc_num;
bl_do_set_working_dc (dc_working_num);
logprintf ("send_code: dc_num = %d\n", dc_working_num);
void tgl_do_send_code (const char *user, void (*callback)(void *callback_extra, int success, int registered, const char *hash), void *callback_extra) {
vlogprintf (E_DEBUG, "sending code to dc %d\n", dc_working_num);
//suser = tstrdup (user);
want_dc_num = 0;
clear_packet ();
tgl_do_insert_header ();
......@@ -486,32 +447,26 @@ void tgl_do_send_code (const char *user) {
out_string (TG_APP_HASH);
out_string ("en");
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);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_code_methods, 0, callback, callback_extra);
}
int phone_call_on_answer (struct query *q UU) {
static int phone_call_on_answer (struct query *q UU) {
fetch_bool ();
if (q->callback) {
((void (*)(void *, int))(q->callback))(q->callback_extra, 1);
}
return 0;
}
int phone_call_on_error (struct query *q UU, int error_code, int l, char *error) {
logprintf ( "error_code = %d, error = %.*s\n", error_code, l, error);
assert (0);
return 0;
}
struct query_methods phone_call_methods = {
static struct query_methods phone_call_methods = {
.on_answer = phone_call_on_answer,
.on_error = phone_call_on_error,
.type = TYPE_TO_PARAM(bool)
};
void tgl_do_phone_call (const char *user) {
logprintf ("calling user\n");
suser = tstrdup (user);
void tgl_do_phone_call (const char *user, void (*callback)(void *callback_extra, int success), void *callback_extra) {
vlogprintf (E_DEBUG, "calling user\n");
//suser = tstrdup (user);
want_dc_num = 0;
clear_packet ();
tgl_do_insert_header ();
......@@ -519,13 +474,12 @@ void tgl_do_phone_call (const char *user) {
out_string (user);
out_string (phone_code_hash);
logprintf ("tgl_do_phone_call: dc_num = %d\n", dc_working_num);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &phone_call_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &phone_call_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Check phone */
int check_phone_result;
/*int check_phone_result;
int cr_f (void) {
return check_phone_result >= 0;
}
......@@ -586,11 +540,11 @@ int tgl_do_auth_check_phone (const char *user) {
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &check_phone_methods, 0);
net_loop (0, cr_f);
return check_phone_result;
}
}*/
/* }}} */
/* {{{ Nearest DC */
int nearest_dc_num;
/*int nearest_dc_num;
int nr_f (void) {
return nearest_dc_num >= 0;
}
......@@ -607,12 +561,6 @@ int nearest_dc_on_answer (struct query *q UU) {
return 0;
}
int fail_on_error (struct query *q UU, int error_code UU, int l UU, char *error UU) {
fprintf (stderr, "error #%d: %.*s\n", error_code, l, error);
assert (0);
return 0;
}
struct query_methods nearest_dc_methods = {
.on_answer = nearest_dc_on_answer,
.on_error = fail_on_error,
......@@ -626,79 +574,58 @@ int tgl_do_get_nearest_dc (void) {
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &nearest_dc_methods, 0);
net_loop (0, nr_f);
return nearest_dc_num;
}
}*/
/* }}} */
/* {{{ Sign in / Sign up */
int sign_in_ok;
int sign_in_is_ok (void) {
return sign_in_ok;
}
struct tgl_user User;
int sign_in_on_answer (struct query *q UU) {
static int sign_in_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_auth_authorization);
int expires = fetch_int ();
tglf_fetch_user (&User);
if (!tgl_state.our_id) {
bl_do_set_our_id (tgl_get_peer_id (User.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 ()));
}
vlogprintf (E_DEBUG, "Expires in %d\n", expires);
struct tgl_user *U = tglf_fetch_alloc_user ();
DC_working->has_auth = 1;
bl_do_dc_signed (DC_working->id);
return 0;
}
if (q->callback) {
((void (*)(void *, int, struct tgl_user *))q->callback) (q->callback_extra, 1, U);
}
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;
}
struct query_methods sign_in_methods = {
static struct query_methods sign_in_methods = {
.on_answer = sign_in_on_answer,
.on_error = sign_in_on_error,
.type = TYPE_TO_PARAM(auth_authorization)
};
int tgl_do_send_code_result (const char *code) {
int tgl_do_send_code_result (const char *user, const char *code, void (*callback)(void *callback_extra, int success, struct tgl_user *Self), void *callback_extra) {
clear_packet ();
out_int (CODE_auth_sign_in);
out_string (suser);
out_string (user);
out_string (phone_code_hash);
out_string (code);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, 0);
sign_in_ok = 0;
net_loop (0, sign_in_is_ok);
return sign_in_ok;
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, 0, callback, callback_extra);
return 0;
}
int tgl_do_send_code_result_auth (const char *code, const char *first_name, const char *last_name) {
int tgl_do_send_code_result_auth (const char *user, const char *code, const char *first_name, const char *last_name, void (*callback)(void *callback_extra, int success, struct tgl_user *Self), void *callback_extra) {
clear_packet ();
out_int (CODE_auth_sign_up);
out_string (suser);
out_string (user);
out_string (phone_code_hash);
out_string (code);
out_string (first_name);
out_string (last_name);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, 0);
sign_in_ok = 0;
net_loop (0, sign_in_is_ok);
return sign_in_ok;
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, 0, callback, callback_extra);
return 0;
}
/* }}} */
/* {{{ Get contacts */
extern char *user_list[];
int get_contacts_on_answer (struct query *q UU) {
static int get_contacts_on_answer (struct query *q UU) {
int i;
assert (fetch_int () == (int)CODE_contacts_contacts);
......@@ -711,7 +638,15 @@ int get_contacts_on_answer (struct query *q UU) {
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
struct tgl_user **list = talloc (sizeof (void *) * n);
for (i = 0; i < n; i++) {
list[i] = tglf_fetch_alloc_user ();
}
if (q->callback) {
((void (*)(void *, int, int, struct tgl_user **))q->callback) (q->callback_extra, 1, n, list);
}
tfree (list, sizeof (void *) * n);
/* for (i = 0; i < n; i++) {
struct tgl_user *U = tglf_fetch_alloc_user ();
print_start ();
push_color (COLOR_YELLOW);
......@@ -739,30 +674,30 @@ int get_contacts_on_answer (struct query *q UU) {
}
pop_color ();
print_end ();
}
}*/
return 0;
}
struct query_methods get_contacts_methods = {
static struct query_methods get_contacts_methods = {
.on_answer = get_contacts_on_answer,
.type = TYPE_TO_PARAM(contacts_contacts)
};
void tgl_do_update_contact_list (void) {
void tgl_do_update_contact_list (void (*callback) (void *callback_extra, int success, int size, struct tgl_user *contacts[]), void *callback_extra) {
clear_packet ();
out_int (CODE_contacts_get_contacts);
out_string ("");
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_contacts_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_contacts_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Encrypt decrypted */
int *encr_extra;
int *encr_ptr;
int *encr_end;
static int *encr_extra;
static int *encr_ptr;
static int *encr_end;
char *encrypt_decrypted_message (struct tgl_secret_chat *E) {
static char *encrypt_decrypted_message (struct tgl_secret_chat *E) {
static int msg_key[4];
static unsigned char sha1a_buffer[20];
static unsigned char sha1b_buffer[20];
......@@ -848,22 +783,25 @@ void tgl_do_send_encr_chat_layer (struct tgl_secret_chat *E) {
struct tgl_message *M = tgl_message_get (t);
assert (M);
tgl_do_send_msg (M);
print_message (M);
tgl_do_send_msg (M, 0, 0);
//print_message (M);
}
/* {{{ Seng msg (plain text) */
int msg_send_encr_on_answer (struct query *q UU) {
static int msg_send_encr_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_messages_sent_encrypted_message);
rprintf ("Sent\n");
struct tgl_message *M = q->extra;
//M->date = fetch_int ();
fetch_int ();
bl_do_set_message_sent (M);
if (q->callback) {
((void (*)(void *, int, struct tgl_message *))q->callback) (q->callback_extra, 1, M);
}
return 0;
}
int msg_send_on_answer (struct query *q UU) {
static int msg_send_on_answer (struct query *q UU) {
unsigned x = fetch_int ();
assert (x == CODE_messages_sent_message || x == CODE_messages_sent_message_link);
int id = fetch_int (); // id
......@@ -873,6 +811,9 @@ int msg_send_on_answer (struct query *q UU) {
fetch_pts ();
fetch_seq ();
if (x == CODE_messages_sent_message_link) {
assert (skip_type_any (TYPE_TO_PARAM_1 (vector, TYPE_TO_PARAM (contacts_link))) >= 0);
}
/*if (x == CODE_messages_sent_message_link) {
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
int i;
......@@ -910,35 +851,46 @@ int msg_send_on_answer (struct query *q UU) {
pop_color ();
print_end ();
}
}
rprintf ("Sent: id = %d\n", id);
}*/
bl_do_set_message_sent (M);
if (q->callback) {
((void (*)(void *, int, struct tgl_message *))q->callback) (q->callback_extra, 1, M);
}
return 0;
}
int msg_send_on_error (struct query *q, int error_code, int error_len, char *error) {
logprintf ( "error for query #%lld: #%d :%.*s\n", q->msg_id, error_code, error_len, error);
static int msg_send_on_error (struct query *q, int error_code, int error_len, char *error) {
vlogprintf (E_WARNING, "error for query #%lld: #%d :%.*s\n", q->msg_id, error_code, error_len, error);
struct tgl_message *M = q->extra;
if (q->callback) {
((void (*)(void *, int, struct tgl_message *))q->callback) (q->callback_extra, 0, M);
}
bl_do_delete_msg (M);
return 0;
}
struct query_methods msg_send_methods = {
static struct query_methods msg_send_methods = {
.on_answer = msg_send_on_answer,
.on_error = msg_send_on_error,
.type = TYPE_TO_PARAM(messages_sent_message)
};
struct query_methods msg_send_encr_methods = {
static struct query_methods msg_send_encr_methods = {
.on_answer = msg_send_encr_on_answer,
.type = TYPE_TO_PARAM(messages_sent_encrypted_message)
};
int out_message_num;
//int out_message_num;
void tgl_do_send_encr_msg_action (struct tgl_message *M) {
void tgl_do_send_encr_msg_action (struct tgl_message *M, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
tgl_peer_t *P = tgl_peer_get (M->to_id);
if (!P || P->encr_chat.state != sc_ok) { return; }
if (!P || P->encr_chat.state != sc_ok) {
vlogprintf (E_WARNING, "Unknown encrypted chat\n");
if (callback) {
((void (*)(void *, int, struct tgl_message *))callback) (callback_extra, 0, M);
}
return;
}
clear_packet ();
out_int (CODE_messages_send_encrypted_service);
......@@ -963,16 +915,22 @@ void tgl_do_send_encr_msg_action (struct tgl_message *M) {
}
encr_finish (&P->encr_chat);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_encr_methods, M);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_encr_methods, M, callback, callback_extra);
}
void tgl_do_send_encr_msg (struct tgl_message *M) {
void tgl_do_send_encr_msg (struct tgl_message *M, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
if (M->service) {
tgl_do_send_encr_msg_action (M);
tgl_do_send_encr_msg_action (M, callback, callback_extra);
return;
}
tgl_peer_t *P = tgl_peer_get (M->to_id);
if (!P || P->encr_chat.state != sc_ok) { return; }
if (!P || P->encr_chat.state != sc_ok) {
vlogprintf (E_WARNING, "Unknown encrypted chat\n");
if (callback) {
((void (*)(void *, int, struct tgl_message *))callback) (callback_extra, 0, M);
}
return;
}
clear_packet ();
out_int (CODE_messages_send_encrypted);
......@@ -990,12 +948,12 @@ void tgl_do_send_encr_msg (struct tgl_message *M) {
out_int (CODE_decrypted_message_media_empty);
encr_finish (&P->encr_chat);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_encr_methods, M);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_encr_methods, M, callback, callback_extra);
}
void tgl_do_send_msg (struct tgl_message *M) {
void tgl_do_send_msg (struct tgl_message *M, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
if (tgl_get_peer_type (M->to_id) == TGL_PEER_ENCR_CHAT) {
tgl_do_send_encr_msg (M);
tgl_do_send_encr_msg (M, callback, callback_extra);
return;
}
clear_packet ();
......@@ -1003,50 +961,60 @@ void tgl_do_send_msg (struct tgl_message *M) {
out_peer_id (M->to_id);
out_cstring (M->message, M->message_len);
out_long (M->id);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_methods, M);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_methods, M, callback, callback_extra);
}
void tgl_do_send_message (tgl_peer_id_t id, const char *msg, int len) {
void tgl_do_send_message (tgl_peer_id_t id, const char *msg, int len, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT) {
tgl_peer_t *P = tgl_peer_get (id);
if (!P) {
logprintf ("Can not send to unknown encrypted chat\n");
vlogprintf (E_WARNING, "Unknown encrypted chat\n");
if (callback) {
((void (*)(void *, int, struct tgl_message *))callback) (callback_extra, 0, 0);
}
return;
}
if (P->encr_chat.state != sc_ok) {
logprintf ("Chat is not yet initialized\n");
vlogprintf (E_WARNING, "Chat is not yet initialized\n");
if (callback) {
((void (*)(void *, int, struct tgl_message *))callback) (callback_extra, 0, 0);
}
return;
}
}
long long t;
secure_random (&t, 8);
logprintf ("t = %lld, len = %d\n", t, len);
vlogprintf (E_DEBUG, "t = %lld, len = %d\n", t, len);
bl_do_send_message_text (t, tgl_state.our_id, tgl_get_peer_type (id), tgl_get_peer_id (id), time (0), len, msg);
struct tgl_message *M = tgl_message_get (t);
assert (M);
tgl_do_send_msg (M);
print_message (M);
tgl_do_send_msg (M, callback, callback_extra);
//print_message (M);
}
/* }}} */
/* {{{ Send text file */
void tgl_do_send_text (tgl_peer_id_t id, char *file_name) {
void tgl_do_send_text (tgl_peer_id_t id, char *file_name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
int fd = open (file_name, O_RDONLY);
if (fd < 0) {
rprintf ("No such file '%s'\n", file_name);
tfree_str (file_name);
vlogprintf (E_WARNING, "No such file '%s'\n", file_name);
if (callback) {
((void (*)(void *, int, struct tgl_message *))callback) (callback_extra, 0, 0);
}
return;
}
static char buf[(1 << 20) + 1];
int x = read (fd, buf, (1 << 20) + 1);
assert (x >= 0);
if (x == (1 << 20) + 1) {
rprintf ("Too big file '%s'\n", file_name);
tfree_str (file_name);
vlogprintf (E_WARNING, "Too big file '%s'\n", file_name);
close (fd);
if (callback) {
((void (*)(void *, int, struct tgl_message *))callback) (callback_extra, 0, 0);
}
} else {
buf[x] = 0;
tgl_do_send_message (id, buf, x);
tgl_do_send_message (id, buf, x, callback, callback_extra);
tfree_str (file_name);
close (fd);
}
......@@ -1054,96 +1022,93 @@ void tgl_do_send_text (tgl_peer_id_t id, char *file_name) {
/* }}} */
/* {{{ Mark read */
int mark_read_on_receive (struct query *q UU) {
static int mark_read_on_receive (struct query *q UU) {
assert (fetch_int () == (int)CODE_messages_affected_history);
fetch_pts ();
fetch_seq ();
fetch_int (); // offset
if (q->callback) {
((void (*)(void *, int))q->callback)(q->callback_extra, 1);
}
return 0;
}
int mark_read_encr_on_receive (struct query *q UU) {
static int mark_read_encr_on_receive (struct query *q UU) {
fetch_bool ();
if (q->callback) {
((void (*)(void *, int))q->callback)(q->callback_extra, 1);
}
return 0;
}
struct query_methods mark_read_methods = {
static struct query_methods mark_read_methods = {
.on_answer = mark_read_on_receive,
.type = TYPE_TO_PARAM(messages_affected_history)
};
struct query_methods mark_read_encr_methods = {
static struct query_methods mark_read_encr_methods = {
.on_answer = mark_read_encr_on_receive,
.type = TYPE_TO_PARAM(bool)
};
void tgl_do_messages_mark_read (tgl_peer_id_t id, int max_id) {
void tgl_do_messages_mark_read (tgl_peer_id_t id, int max_id, void (*callback)(void *callback_extra, int), void *callback_extra) {
clear_packet ();
out_int (CODE_messages_read_history);
out_peer_id (id);
out_int (max_id);
out_int (0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &mark_read_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &mark_read_methods, 0, callback, callback_extra);
}
void tgl_do_messages_mark_read_encr (tgl_peer_id_t id, long long access_hash, int last_time) {
void tgl_do_messages_mark_read_encr (tgl_peer_id_t id, long long access_hash, int last_time, void (*callback)(void *callback_extra, int), void *callback_extra) {
clear_packet ();
out_int (CODE_messages_read_encrypted_history);
out_int (CODE_input_encrypted_chat);
out_int (tgl_get_peer_id (id));
out_long (access_hash);
out_int (last_time);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &mark_read_encr_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &mark_read_encr_methods, 0, callback, callback_extra);
}
void tgl_do_mark_read (tgl_peer_id_t id) {
void tgl_do_mark_read (tgl_peer_id_t id, void (*callback)(void *callback_extra, int success), void *callback_extra) {
tgl_peer_t *P = tgl_peer_get (id);
if (!P) {
rprintf ("Unknown peer\n");
vlogprintf (E_WARNING, "Unknown peer\n");
callback (callback_extra, 0);
return;
}
if (tgl_get_peer_type (id) == TGL_PEER_USER || tgl_get_peer_type (id) == TGL_PEER_CHAT) {
if (!P->last) {
rprintf ("Unknown last peer message\n");
vlogprintf (E_WARNING, "Unknown last peer message\n");
callback (callback_extra, 0);
return;
}
tgl_do_messages_mark_read (id, P->last->id);
tgl_do_messages_mark_read (id, P->last->id, callback, callback_extra);
return;
}
assert (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT);
if (P->last) {
tgl_do_messages_mark_read_encr (id, P->encr_chat.access_hash, P->last->date);
tgl_do_messages_mark_read_encr (id, P->encr_chat.access_hash, P->last->date, callback, callback_extra);
} else {
tgl_do_messages_mark_read_encr (id, P->encr_chat.access_hash, time (0) - 10);
tgl_do_messages_mark_read_encr (id, P->encr_chat.access_hash, time (0) - 10, callback, callback_extra);
}
}
/* }}} */
/* {{{ Get history */
int get_history_on_answer (struct query *q UU) {
static struct tgl_message *ML[10000];
static int get_history_on_answer (struct query *q UU) {
int i;
int x = fetch_int ();
if (x == (int)CODE_messages_messages_slice) {
fetch_int ();
rprintf ("...\n");
} else {
assert (x == (int)CODE_messages_messages);
}
assert (x == (int)CODE_messages_messages_slice || x == (int)CODE_messages_messages);
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
struct tgl_message **ML = talloc (sizeof (void *) * n);
for (i = 0; i < n; i++) {
struct tgl_message *M = tglf_fetch_alloc_message ();
if (i <= 9999) {
ML[i] = M;
ML[i] = tglf_fetch_alloc_message ();
}
}
if (n > 10000) { n = 10000; }
int sn = n;
for (i = n - 1; i >= 0; i--) {
print_message (ML[i]);
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
for (i = 0; i < n; i++) {
......@@ -1154,20 +1119,32 @@ int get_history_on_answer (struct query *q UU) {
for (i = 0; i < n; i++) {
tglf_fetch_alloc_user ();
}
if (q->callback) {
((void (*)(void *, int, int, struct tgl_message **))q->callback) (q->callback_extra, 1, sn, ML);
}
tfree (ML, sizeof (void *) * n);
/*for (i = n - 1; i >= 0; i--) {
print_message (ML[i]);
}*/
if (sn > 0 && q->extra) {
tgl_do_messages_mark_read (*(tgl_peer_id_t *)&(q->extra), ML[0]->id);
tgl_do_messages_mark_read (*(tgl_peer_id_t *)&(q->extra), ML[0]->id, 0, 0);
}
return 0;
}
struct query_methods get_history_methods = {
static struct query_methods get_history_methods = {
.on_answer = get_history_on_answer,
.type = TYPE_TO_PARAM(messages_messages)
};
void tgl_do_get_local_history (tgl_peer_id_t id, int limit) {
void tgl_do_get_local_history (tgl_peer_id_t id, int limit, void (*callback)(void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) {
tgl_peer_t *P = tgl_peer_get (id);
if (!P || !P->last) { return; }
if (!P || !P->last) {
callback (callback_extra, 0, 0, 0);
return;
}
struct tgl_message *M = P->last;
int count = 1;
assert (!M->prev);
......@@ -1175,16 +1152,23 @@ void tgl_do_get_local_history (tgl_peer_id_t id, int limit) {
M = M->next;
count ++;
}
while (M) {
print_message (M);
M = M->prev;
struct tgl_message **ML = talloc (sizeof (void *) * count);
M = P->last;
ML[0] = M;
count = 1;
while (count < limit && M->next) {
M = M->next;
ML[count ++] = M->next;
}
callback (callback_extra, 1, count, ML);
tfree (ML, sizeof (void *) * count);
}
void tgl_do_get_history (tgl_peer_id_t id, int limit) {
void tgl_do_get_history (tgl_peer_id_t id, int limit, int offline_mode, void (*callback)(void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) {
if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT || offline_mode) {
tgl_do_get_local_history (id, limit);
tgl_do_mark_read (id);
tgl_do_get_local_history (id, limit, callback, callback_extra);
tgl_do_mark_read (id, 0, 0);
return;
}
clear_packet ();
......@@ -1193,13 +1177,12 @@ void tgl_do_get_history (tgl_peer_id_t id, int limit) {
out_int (0);
out_int (0);
out_int (limit);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_history_methods, (void *)*(long *)&id);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_history_methods, (void *)*(long *)&id, callback, callback_extra);
}
/* }}} */
/* {{{ Get dialogs */
int dialog_list_got;
int get_dialogs_on_answer (struct query *q UU) {
static int get_dialogs_on_answer (struct query *q UU) {
unsigned x = fetch_int ();
assert (x == CODE_messages_dialogs || x == CODE_messages_dialogs_slice);
if (x == CODE_messages_dialogs_slice) {
......@@ -1208,20 +1191,16 @@ int get_dialogs_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_vector);
int n, i;
n = fetch_int ();
static int dlist[2 * 100];
static tgl_peer_id_t plist[100];
int dl_size = n;
tgl_peer_id_t *PL = talloc0 (sizeof (tgl_peer_id_t) * n);
int *UC = talloc0 (4 * n);
int *LM = talloc0 (4 * n);
for (i = 0; i < n; i++) {
assert (fetch_int () == (int)CODE_dialog);
if (i < 100) {
plist[i] = tglf_fetch_peer_id ();
dlist[2 * i + 0] = fetch_int ();
dlist[2 * i + 1] = fetch_int ();
} else {
tglf_fetch_peer_id ();
fetch_int ();
fetch_int ();
}
PL[i] = tglf_fetch_peer_id ();
LM[i] = fetch_int ();
UC[i] = fetch_int ();
assert (skip_type_any (TYPE_TO_PARAM (peer_notify_settings)) >= 0);
}
assert (fetch_int () == CODE_vector);
......@@ -1239,7 +1218,7 @@ int get_dialogs_on_answer (struct query *q UU) {
for (i = 0; i < n; i++) {
tglf_fetch_alloc_user ();
}
print_start ();
/*print_start ();
push_color (COLOR_YELLOW);
for (i = dl_size - 1; i >= 0; i--) {
tgl_peer_t *UC;
......@@ -1261,23 +1240,31 @@ int get_dialogs_on_answer (struct query *q UU) {
pop_color ();
print_end ();
dialog_list_got = 1;
dialog_list_got = 1;*/
if (q->callback) {
((void (*)(void *, int, int, tgl_peer_id_t *, int *, int *))q->callback) (q->callback_extra, 1, dl_size, PL, LM, UC);
}
tfree (PL, sizeof (tgl_peer_id_t) * dl_size);
tfree (UC, 4 * dl_size);
tfree (LM, 4 * dl_size);
return 0;
}
struct query_methods get_dialogs_methods = {
static struct query_methods get_dialogs_methods = {
.on_answer = get_dialogs_on_answer,
.type = TYPE_TO_PARAM(messages_dialogs)
};
void tgl_do_get_dialog_list (void) {
void tgl_do_get_dialog_list (void (*callback)(void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[]), void *callback_extra) {
clear_packet ();
out_int (CODE_messages_get_dialogs);
out_int (0);
out_int (0);
out_int (1000);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dialogs_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dialogs_methods, 0, callback, callback_extra);
}
/* }}} */
......@@ -1301,7 +1288,7 @@ struct send_file {
unsigned char *key;
};
void out_peer_id (tgl_peer_id_t id) {
static void out_peer_id (tgl_peer_id_t id) {
tgl_peer_t *U;
switch (tgl_get_peer_type (id)) {
case TGL_PEER_CHAT:
......@@ -1324,14 +1311,14 @@ void out_peer_id (tgl_peer_id_t id) {
}
}
void send_part (struct send_file *f);
int send_file_part_on_answer (struct query *q) {
static void send_part (struct send_file *f, void *callback, void *callback_extra);
static int send_file_part_on_answer (struct query *q) {
assert (fetch_int () == (int)CODE_bool_true);
send_part (q->extra);
send_part (q->extra, q->callback, q->callback_extra);
return 0;
}
int send_file_on_answer (struct query *q UU) {
static int send_file_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_messages_stated_message);
struct tgl_message *M = tglf_fetch_alloc_message ();
assert (fetch_int () == CODE_vector);
......@@ -1347,14 +1334,15 @@ int send_file_on_answer (struct query *q UU) {
}
fetch_pts ();
fetch_seq ();
print_message (M);
if (q->callback) {
((void (*)(void *, int, struct tgl_message *))q->callback)(q->callback_extra, 1, M);
}
//print_message (M);
return 0;
}
int send_encr_file_on_answer (struct query *q UU) {
if (prefetch_int () != (int)CODE_messages_sent_encrypted_file) {
hexdump_in ();
}
static int send_encr_file_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_messages_sent_encrypted_file);
struct tgl_message *M = q->extra;
M->date = fetch_int ();
......@@ -1365,30 +1353,34 @@ int send_encr_file_on_answer (struct query *q UU) {
fetch_int ();
M->media.encr_photo.dc_id = fetch_int ();
assert (fetch_int () == M->media.encr_photo.key_fingerprint);
print_message (M);
//print_message (M);
tglm_message_insert (M);
if (q->callback) {
((void (*)(void *, int, struct tgl_message *))q->callback)(q->callback_extra, 1, M);
}
return 0;
}
struct query_methods send_file_part_methods = {
static struct query_methods send_file_part_methods = {
.on_answer = send_file_part_on_answer,
.type = TYPE_TO_PARAM(bool)
};
struct query_methods send_file_methods = {
static struct query_methods send_file_methods = {
.on_answer = send_file_on_answer,
.type = TYPE_TO_PARAM(messages_stated_message)
};
struct query_methods send_encr_file_methods = {
static struct query_methods send_encr_file_methods = {
.on_answer = send_encr_file_on_answer,
.type = TYPE_TO_PARAM(messages_sent_encrypted_message)
};
void send_part (struct send_file *f) {
static void send_part (struct send_file *f, void *callback, void *callback_extra) {
if (f->fd >= 0) {
if (!f->part_num) {
cur_uploading_bytes += f->size;
tgl_state.cur_uploading_bytes += f->size;
}
clear_packet ();
if (f->size < (16 << 20)) {
......@@ -1405,7 +1397,7 @@ void send_part (struct send_file *f) {
int x = read (f->fd, buf, f->part_size);
assert (x > 0);
f->offset += x;
cur_uploaded_bytes += x;
tgl_state.cur_uploaded_bytes += x;
if (f->encr) {
if (x & 15) {
......@@ -1420,21 +1412,19 @@ void send_part (struct send_file *f) {
memset (&aes_key, 0, sizeof (aes_key));
}
out_cstring (buf, x);
if (verbosity >= 2) {
logprintf ("offset=%lld size=%lld\n", f->offset, f->size);
}
vlogprintf (E_DEBUG, "offset=%lld size=%lld\n", f->offset, f->size);
if (f->offset == f->size) {
close (f->fd);
f->fd = -1;
} else {
assert (f->part_size == x);
}
update_prompt ();
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f);
//update_prompt ();
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f, callback, callback_extra);
} else {
cur_uploaded_bytes -= f->size;
cur_uploading_bytes -= f->size;
update_prompt ();
tgl_state.cur_uploaded_bytes -= f->size;
tgl_state.cur_uploading_bytes -= f->size;
//update_prompt ();
clear_packet ();
assert (f->media_type == CODE_input_media_uploaded_photo || f->media_type == CODE_input_media_uploaded_video || f->media_type == CODE_input_media_uploaded_thumb_video || f->media_type == CODE_input_media_uploaded_audio || f->media_type == CODE_input_media_uploaded_document || f->media_type == CODE_input_media_uploaded_thumb_document);
if (!f->encr) {
......@@ -1477,7 +1467,7 @@ void send_part (struct send_file *f) {
}
out_long (-lrand48 () * (1ll << 32) - lrand48 ());
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_methods, 0, callback, callback_extra);
} else {
struct tgl_message *M = talloc0 (sizeof (*M));
......@@ -1568,38 +1558,37 @@ void send_part (struct send_file *f) {
M->id = r;
M->date = time (0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_file_methods, M);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_file_methods, M, callback, callback_extra);
}
tfree_str (f->file_name);
tfree (f, sizeof (*f));
}
}
void send_file_thumb (struct send_file *f) {
/*void send_file_thumb (struct send_file *f, void *callback, void *callback_extra) {
clear_packet ();
f->thumb_id = lrand48 () * (1ll << 32) + lrand48 ();
out_int (CODE_upload_save_file_part);
out_long (f->thumb_id);
out_int (0);
out_cstring ((void *)thumb_file, thumb_file_size);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f);
}
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f, callback, callback_extra);
}*/
void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name) {
void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
int fd = open (file_name, O_RDONLY);
if (fd < 0) {
rprintf ("No such file '%s'\n", file_name);
tfree_str (file_name);
vlogprintf (E_WARNING, "No such file '%s'\n", file_name);
callback (callback_extra, 0, 0);
return;
}
struct stat buf;
fstat (fd, &buf);
long long size = buf.st_size;
if (size <= 0) {
rprintf ("File has zero length\n");
tfree_str (file_name);
vlogprintf (E_WARNING, "File has zero length\n");
close (fd);
callback (callback_extra, 0, 0);
return;
}
struct send_file *f = talloc0 (sizeof (*f));
......@@ -1615,16 +1604,16 @@ void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name) {
if (f->part_size > (512 << 10)) {
close (fd);
rprintf ("Too big file. Maximal supported size is %d.\n", (512 << 10) * 1000);
vlogprintf (E_WARNING, "Too big file. Maximal supported size is %d.\n", (512 << 10) * 1000);
tfree (f, sizeof (*f));
tfree_str (file_name);
callback (callback_extra, 0, 0);
return;
}
f->id = lrand48 () * (1ll << 32) + lrand48 ();
f->to_id = to_id;
f->media_type = type;
f->file_name = file_name;
f->file_name = tstrdup (file_name);
if (tgl_get_peer_type (f->to_id) == TGL_PEER_ENCR_CHAT) {
f->encr = 1;
f->iv = talloc (32);
......@@ -1643,12 +1632,12 @@ void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name) {
} else {
send_part (f);
}*/
send_part (f);
send_part (f, callback, callback_extra);
}
/* }}} */
/* {{{ Forward */
int fwd_msg_on_answer (struct query *q UU) {
static int fwd_msg_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_messages_stated_message);
struct tgl_message *M = tglf_fetch_alloc_message ();
assert (fetch_int () == CODE_vector);
......@@ -1664,18 +1653,22 @@ int fwd_msg_on_answer (struct query *q UU) {
}
fetch_pts ();
fetch_seq ();
print_message (M);
//print_message (M);
if (q->callback) {
((void (*)(void *, int, struct tgl_message *))q->callback) (q->callback_extra, 1, M);
}
return 0;
}
struct query_methods fwd_msg_methods = {
static struct query_methods fwd_msg_methods = {
.on_answer = fwd_msg_on_answer,
.type = TYPE_TO_PARAM(messages_stated_message)
};
void tgl_do_forward_message (tgl_peer_id_t id, int n) {
void tgl_do_forward_message (tgl_peer_id_t id, int n, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT) {
rprintf ("Can not forward messages from secret chat\n");
vlogprintf (E_WARNING, "Can not forward messages from secret chat\n");
callback (callback_extra, 0, 0);
return;
}
clear_packet ();
......@@ -1683,12 +1676,12 @@ void tgl_do_forward_message (tgl_peer_id_t id, int n) {
out_peer_id (id);
out_int (n);
out_long (lrand48 () * (1ll << 32) + lrand48 ());
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &fwd_msg_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &fwd_msg_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Rename chat */
int rename_chat_on_answer (struct query *q UU) {
static int rename_chat_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_messages_stated_message);
struct tgl_message *M = tglf_fetch_alloc_message ();
assert (fetch_int () == CODE_vector);
......@@ -1704,27 +1697,30 @@ int rename_chat_on_answer (struct query *q UU) {
}
fetch_pts ();
fetch_seq ();
print_message (M);
//print_message (M);
if (q->callback) {
((void (*)(void *, int, struct tgl_message *))q->callback) (q->callback_extra, 1, M);
}
return 0;
}
struct query_methods rename_chat_methods = {
static struct query_methods rename_chat_methods = {
.on_answer = rename_chat_on_answer,
.type = TYPE_TO_PARAM(messages_stated_message)
};
void tgl_do_rename_chat (tgl_peer_id_t id, char *name UU) {
void tgl_do_rename_chat (tgl_peer_id_t id, char *name UU, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
clear_packet ();
out_int (CODE_messages_edit_chat_title);
assert (tgl_get_peer_type (id) == TGL_PEER_CHAT);
out_int (tgl_get_peer_id (id));
out_string (name);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &rename_chat_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &rename_chat_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Chat info */
void print_chat_info (struct tgl_chat *C) {
/*void print_chat_info (struct tgl_chat *C) {
tgl_peer_t *U = (void *)C;
print_start ();
push_color (COLOR_YELLOW);
......@@ -1746,26 +1742,31 @@ void print_chat_info (struct tgl_chat *C) {
}
pop_color ();
print_end ();
}
}*/
int chat_info_on_answer (struct query *q UU) {
static int chat_info_on_answer (struct query *q UU) {
struct tgl_chat *C = tglf_fetch_alloc_chat_full ();
print_chat_info (C);
//print_chat_info (C);
if (q->callback) {
((void (*)(void *, int, struct tgl_chat *))q->callback) (q->callback_extra, 0, C);
}
return 0;
}
struct query_methods chat_info_methods = {
static struct query_methods chat_info_methods = {
.on_answer = chat_info_on_answer,
.type = TYPE_TO_PARAM(messages_chat_full)
};
void tgl_do_get_chat_info (tgl_peer_id_t id) {
void tgl_do_get_chat_info (tgl_peer_id_t id, int offline_mode, void (*callback)(void *callback_extra, int success, struct tgl_chat *C), void *callback_extra) {
if (offline_mode) {
tgl_peer_t *C = tgl_peer_get (id);
if (!C) {
rprintf ("No such chat\n");
vlogprintf (E_WARNING, "No such chat\n");
callback (callback_extra, 0, 0);
} else {
print_chat_info (&C->chat);
//print_chat_info (&C->chat);
callback (callback_extra, 1, &C->chat);
}
return;
}
......@@ -1773,13 +1774,13 @@ void tgl_do_get_chat_info (tgl_peer_id_t id) {
out_int (CODE_messages_get_full_chat);
assert (tgl_get_peer_type (id) == TGL_PEER_CHAT);
out_int (tgl_get_peer_id (id));
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &chat_info_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &chat_info_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ User info */
void print_user_info (struct tgl_user *U) {
/*void print_user_info (struct tgl_user *U) {
tgl_peer_t *C = (void *)U;
print_start ();
push_color (COLOR_YELLOW);
......@@ -1797,26 +1798,29 @@ void print_user_info (struct tgl_user *U) {
}
pop_color ();
print_end ();
}
}*/
int user_info_on_answer (struct query *q UU) {
static int user_info_on_answer (struct query *q UU) {
struct tgl_user *U = tglf_fetch_alloc_user_full ();
print_user_info (U);
if (q->callback) {
((void (*)(void *, int, struct tgl_user *))q->callback) (q->callback_extra, 0, U);
}
return 0;
}
struct query_methods user_info_methods = {
static struct query_methods user_info_methods = {
.on_answer = user_info_on_answer,
.type = TYPE_TO_PARAM(user_full)
};
void tgl_do_get_user_info (tgl_peer_id_t id) {
void tgl_do_get_user_info (tgl_peer_id_t id, int offline_mode, void (*callback)(void *callback_extra, int success, struct tgl_user *U), void *callback_extra) {
if (offline_mode) {
tgl_peer_t *C = tgl_peer_get (id);
if (!C) {
rprintf ("No such user\n");
vlogprintf (E_WARNING, "No such user\n");
callback (callback_extra, 0, 0);
} else {
print_user_info (&C->user);
callback (callback_extra, 1, &C->user);
}
return;
}
......@@ -1832,12 +1836,12 @@ void tgl_do_get_user_info (tgl_peer_id_t id) {
out_int (CODE_input_user_contact);
out_int (tgl_get_peer_id (id));
}
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &user_info_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &user_info_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Get user info silently */
int user_list_info_silent_on_answer (struct query *q UU) {
/*int user_list_info_silent_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
int i;
......@@ -1864,7 +1868,7 @@ void tgl_do_get_user_list_info_silent (int num, int *list) {
//out_long (0);
}
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &user_list_info_silent_methods, 0);
}
}*/
/* }}} */
/* {{{ Load photo/video */
......@@ -1886,12 +1890,12 @@ struct download {
};
void end_load (struct download *D) {
cur_downloading_bytes -= D->size;
cur_downloaded_bytes -= D->size;
update_prompt ();
static void end_load (struct download *D, void *callback, void *callback_extra) {
tgl_state.cur_downloading_bytes -= D->size;
tgl_state.cur_downloaded_bytes -= D->size;
//update_prompt ();
close (D->fd);
if (D->next == 1) {
/*if (D->next == 1) {
logprintf ("Done: %s\n", D->name);
} else if (D->next == 2) {
static char buf[PATH_MAX];
......@@ -1904,7 +1908,12 @@ void end_load (struct download *D) {
logprintf ("Image is at %s\n", D->name);
}
}
}*/
if (callback) {
((void (*)(void *, int, char *))callback) (callback_extra, 1, D->name);
}
if (D->iv) {
tfree_secure (D->iv, 32);
}
......@@ -1912,8 +1921,8 @@ void end_load (struct download *D) {
tfree (D, sizeof (*D));
}
void load_next_part (struct download *D);
int download_on_answer (struct query *q) {
static void load_next_part (struct download *D, void *callback, void *callback_extra);
static int download_on_answer (struct query *q) {
assert (fetch_int () == (int)CODE_upload_file);
unsigned x = fetch_int ();
assert (x);
......@@ -1924,8 +1933,8 @@ int download_on_answer (struct query *q) {
fetch_int (); // mtime
int len = prefetch_strlen ();
assert (len >= 0);
cur_downloaded_bytes += len;
update_prompt ();
tgl_state.cur_downloaded_bytes += len;
//update_prompt ();
if (D->iv) {
unsigned char *ptr = (void *)fetch_str (len);
assert (!(len & 15));
......@@ -1942,20 +1951,20 @@ int download_on_answer (struct query *q) {
}
D->offset += len;
if (D->offset < D->size) {
load_next_part (D);
load_next_part (D, q->callback, q->callback_extra);
return 0;
} else {
end_load (D);
end_load (D, q->callback, q->callback_extra);
return 0;
}
}
struct query_methods download_methods = {
static struct query_methods download_methods = {
.on_answer = download_on_answer,
.type = TYPE_TO_PARAM(upload_file)
};
void load_next_part (struct download *D) {
static void load_next_part (struct download *D, void *callback, void *callback_extra) {
if (!D->offset) {
static char buf[PATH_MAX];
int l;
......@@ -1965,7 +1974,7 @@ void load_next_part (struct download *D) {
l = tsnprintf (buf, sizeof (buf), "%s/download_%lld", get_downloads_directory (), D->id);
}
if (l >= (int) sizeof (buf)) {
logprintf ("Download filename is too long");
vlogprintf (E_ERROR, "Download filename is too long");
exit (1);
}
D->name = tstrdup (buf);
......@@ -1973,17 +1982,17 @@ void load_next_part (struct download *D) {
if (stat (buf, &st) >= 0) {
D->offset = st.st_size;
if (D->offset >= D->size) {
cur_downloading_bytes += D->size;
cur_downloaded_bytes += D->offset;
rprintf ("Already downloaded\n");
end_load (D);
tgl_state.cur_downloading_bytes += D->size;
tgl_state.cur_downloaded_bytes += D->offset;
vlogprintf (E_NOTICE, "Already downloaded\n");
end_load (D, callback, callback_extra);
return;
}
}
cur_downloading_bytes += D->size;
cur_downloaded_bytes += D->offset;
update_prompt ();
tgl_state.cur_downloading_bytes += D->size;
tgl_state.cur_downloaded_bytes += D->offset;
//update_prompt ();
}
clear_packet ();
out_int (CODE_upload_get_file);
......@@ -2003,18 +2012,18 @@ void load_next_part (struct download *D) {
}
out_int (D->offset);
out_int (1 << 14);
send_query (DC_list[D->dc], packet_ptr - packet_buffer, packet_buffer, &download_methods, D);
send_query (DC_list[D->dc], packet_ptr - packet_buffer, packet_buffer, &download_methods, D, callback, callback_extra);
//send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &download_methods, D);
}
void tgl_do_load_photo_size (struct tgl_photo_size *P, int next) {
void tgl_do_load_photo_size (struct tgl_photo_size *P, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra) {
if (!P->loc.dc) {
rprintf ("Bad video thumb\n");
vlogprintf (E_WARNING, "Bad video thumb\n");
callback (callback_extra, 0, 0);
return;
}
assert (P);
assert (next);
struct download *D = talloc0 (sizeof (*D));
D->id = 0;
D->offset = 0;
......@@ -2023,14 +2032,17 @@ void tgl_do_load_photo_size (struct tgl_photo_size *P, int next) {
D->dc = P->loc.dc;
D->local_id = P->loc.local_id;
D->secret = P->loc.secret;
D->next = next;
D->name = 0;
D->fd = -1;
load_next_part (D);
load_next_part (D, callback, callback_extra);
}
void tgl_do_load_photo (struct tgl_photo *photo, int next) {
if (!photo->sizes_num) { return; }
void tgl_do_load_photo (struct tgl_photo *photo, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra) {
if (!photo->sizes_num) {
vlogprintf (E_WARNING, "No sizes\n");
callback (callback_extra, 0, 0);
return;
}
int max = -1;
int maxi = 0;
int i;
......@@ -2040,81 +2052,73 @@ void tgl_do_load_photo (struct tgl_photo *photo, int next) {
maxi = i;
}
}
tgl_do_load_photo_size (&photo->sizes[maxi], next);
tgl_do_load_photo_size (&photo->sizes[maxi], callback, callback_extra);
}
void tgl_do_load_video_thumb (struct tgl_video *video, int next) {
tgl_do_load_photo_size (&video->thumb, next);
void tgl_do_load_video_thumb (struct tgl_video *video, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra) {
tgl_do_load_photo_size (&video->thumb, callback, callback_extra);
}
void tgl_do_load_document_thumb (struct tgl_document *video, int next) {
tgl_do_load_photo_size (&video->thumb, next);
void tgl_do_load_document_thumb (struct tgl_document *video, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra) {
tgl_do_load_photo_size (&video->thumb, callback, callback_extra);
}
void tgl_do_load_video (struct tgl_video *V, int next) {
void tgl_do_load_video (struct tgl_video *V, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra) {
assert (V);
assert (next);
struct download *D = talloc0 (sizeof (*D));
D->offset = 0;
D->size = V->size;
D->id = V->id;
D->access_hash = V->access_hash;
D->dc = V->dc_id;
D->next = next;
D->name = 0;
D->fd = -1;
D->type = CODE_input_video_file_location;
load_next_part (D);
load_next_part (D, callback, callback_extra);
}
void tgl_do_load_audio (struct tgl_video *V, int next) {
void tgl_do_load_audio (struct tgl_video *V, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra) {
assert (V);
assert (next);
struct download *D = talloc0 (sizeof (*D));
D->offset = 0;
D->size = V->size;
D->id = V->id;
D->access_hash = V->access_hash;
D->dc = V->dc_id;
D->next = next;
D->name = 0;
D->fd = -1;
D->type = CODE_input_audio_file_location;
load_next_part (D);
load_next_part (D, callback, callback_extra);
}
void tgl_do_load_document (struct tgl_document *V, int next) {
void tgl_do_load_document (struct tgl_document *V, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra) {
assert (V);
assert (next);
struct download *D = talloc0 (sizeof (*D));
D->offset = 0;
D->size = V->size;
D->id = V->id;
D->access_hash = V->access_hash;
D->dc = V->dc_id;
D->next = next;
D->name = 0;
D->fd = -1;
D->type = CODE_input_document_file_location;
load_next_part (D);
load_next_part (D, callback, callback_extra);
}
void tgl_do_load_encr_video (struct tgl_encr_video *V, int next) {
void tgl_do_load_encr_video (struct tgl_encr_video *V, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra) {
assert (V);
assert (next);
struct download *D = talloc0 (sizeof (*D));
D->offset = 0;
D->size = V->size;
D->id = V->id;
D->access_hash = V->access_hash;
D->dc = V->dc_id;
D->next = next;
D->name = 0;
D->fd = -1;
D->key = V->key;
D->iv = talloc (32);
memcpy (D->iv, V->iv, 32);
load_next_part (D);
load_next_part (D, callback, callback_extra);
unsigned char md5[16];
unsigned char str[64];
......@@ -2126,78 +2130,64 @@ void tgl_do_load_encr_video (struct tgl_encr_video *V, int next) {
/* }}} */
/* {{{ Export auth */
char *export_auth_str;
int export_auth_str_len;
int is_export_auth_str (void) {
return export_auth_str != 0;
}
int isn_export_auth_str (void) {
return export_auth_str == 0;
static int import_auth_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_auth_authorization);
fetch_int (); // expires
tglf_fetch_alloc_user ();
if (q->callback) {
((void (*)(void *, int))q->callback) (q->callback_extra, 1);
}
return 0;
}
int export_auth_on_answer (struct query *q UU) {
static struct query_methods import_auth_methods = {
.on_answer = import_auth_on_answer,
.on_error = fail_on_error,
.type = TYPE_TO_PARAM(auth_authorization)
};
static int export_auth_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_auth_exported_authorization);
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;
export_auth_str = s;
clear_packet ();
tgl_do_insert_header ();
out_int (CODE_auth_import_authorization);
out_int (tgl_state.our_id);
out_cstring (s, l);
send_query (q->extra, packet_ptr - packet_buffer, packet_buffer, &import_auth_methods, 0, q->callback, q->callback_extra);
tfree (s, l);
return 0;
}
struct query_methods export_auth_methods = {
static struct query_methods export_auth_methods = {
.on_answer = export_auth_on_answer,
.on_error = fail_on_error,
.type = TYPE_TO_PARAM(auth_exported_authorization)
};
void tgl_do_export_auth (int num) {
export_auth_str = 0;
void tgl_do_export_auth (int num, void (*callback) (void *callback_extra, int success), void *callback_extra) {
clear_packet ();
out_int (CODE_auth_export_authorization);
out_int (num);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &export_auth_methods, 0);
net_loop (0, is_export_auth_str);
}
/* }}} */
/* {{{ Import auth */
int import_auth_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_auth_authorization);
fetch_int (); // expires
tglf_fetch_alloc_user ();
tfree (export_auth_str, export_auth_str_len);
export_auth_str = 0;
return 0;
}
struct query_methods import_auth_methods = {
.on_answer = import_auth_on_answer,
.on_error = fail_on_error,
.type = TYPE_TO_PARAM(auth_authorization)
};
void tgl_do_import_auth (int num) {
clear_packet ();
tgl_do_insert_header ();
out_int (CODE_auth_import_authorization);
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);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &export_auth_methods, DC_list[num], callback, callback_extra);
}
/* }}} */
/* {{{ Add contact */
int add_contact_on_answer (struct query *q UU) {
static int add_contact_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_contacts_imported_contacts);
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
if (n > 0) {
logprintf ("Added successfully");
vlogprintf (E_DEBUG, "Added successfully");
} else {
logprintf ("Not added");
vlogprintf (E_DEBUG, "Not added");
}
int i;
for (i = 0; i < n ; i++) {
......@@ -2209,11 +2199,16 @@ int add_contact_on_answer (struct query *q UU) {
n = fetch_int ();
for (i = 0; i < n; i++) {
long long id = fetch_long ();
logprintf ("contact #%lld not added. Please retry\n", id);
vlogprintf (E_NOTICE, "contact #%lld not added. Please retry\n", id);
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
for (i = 0; i < n ; i++) {
struct tgl_user **UL = talloc (n * sizeof (void *));
for (i = 0; i < n; i++) {
UL[i] = tglf_fetch_alloc_user ();
}
/*for (i = 0; i < n ; i++) {
struct tgl_user *U = tglf_fetch_alloc_user ();
print_start ();
push_color (COLOR_YELLOW);
......@@ -2242,16 +2237,21 @@ int add_contact_on_answer (struct query *q UU) {
pop_color ();
print_end ();
}*/
if (q->callback) {
((void (*)(void *, int, int, struct tgl_user **))q->callback) (q->callback_extra, 1, n, UL);
}
tfree (UL, n * sizeof (void *));
return 0;
}
struct query_methods add_contact_methods = {
static struct query_methods add_contact_methods = {
.on_answer = add_contact_on_answer,
.type = TYPE_TO_PARAM(contacts_imported_contacts)
};
void tgl_do_add_contact (const char *phone, int phone_len, const char *first_name, int first_name_len, const char *last_name, int last_name_len, int force) {
void tgl_do_add_contact (const char *phone, int phone_len, const char *first_name, int first_name_len, const char *last_name, int last_name_len, int force, void (*callback)(void *callback_extra, int success, int size, struct tgl_user *users[]), void *callback_extra) {
clear_packet ();
out_int (CODE_contacts_import_contacts);
out_int (CODE_vector);
......@@ -2262,23 +2262,26 @@ void tgl_do_add_contact (const char *phone, int phone_len, const char *first_nam
out_cstring (first_name, first_name_len);
out_cstring (last_name, last_name_len);
out_int (force ? CODE_bool_true : CODE_bool_false);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &add_contact_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &add_contact_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Msg search */
int msg_search_on_answer (struct query *q UU) {
static int msg_search_on_answer (struct query *q UU) {
return get_history_on_answer (q);
}
struct query_methods msg_search_methods = {
static struct query_methods msg_search_methods = {
.on_answer = msg_search_on_answer,
.type = TYPE_TO_PARAM(messages_messages)
};
void tgl_do_msg_search (tgl_peer_id_t id, int from, int to, int limit, const char *s) {
void tgl_do_msg_search (tgl_peer_id_t id, int from, int to, int limit, const char *s, void (*callback)(void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) {
if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT) {
rprintf ("Can not search in secure chat\n");
vlogprintf (E_WARNING, "Can not search in secure chat\n");
if (callback) {
callback (callback_extra, 0, 0, 0);
}
return;
}
clear_packet ();
......@@ -2295,12 +2298,12 @@ void tgl_do_msg_search (tgl_peer_id_t id, int from, int to, int limit, const cha
out_int (0); // offset
out_int (0); // max_id
out_int (limit);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_search_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_search_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Contacts search */
int contacts_search_on_answer (struct query *q UU) {
static int contacts_search_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_contacts_found);
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
......@@ -2311,7 +2314,12 @@ int contacts_search_on_answer (struct query *q UU) {
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
print_start ();
struct tgl_user **UL = talloc (sizeof (void *) * n);
for (i = 0; i < n; i++) {
UL[i] = tglf_fetch_alloc_user ();
}
/*print_start ();
push_color (COLOR_YELLOW);
for (i = 0; i < n; i++) {
struct tgl_user *U = tglf_fetch_alloc_user ();
......@@ -2322,29 +2330,33 @@ int contacts_search_on_answer (struct query *q UU) {
printf (". Phone %s\n", U->phone);
}
pop_color ();
print_end ();
print_end ();*/
if (q->callback) {
((void (*)(void *, int, int, struct tgl_user **))q->callback) (q->callback_extra, 1, n, UL);
}
tfree (UL, sizeof (void *) * n);
return 0;
}
struct query_methods contacts_search_methods = {
static struct query_methods contacts_search_methods = {
.on_answer = contacts_search_on_answer,
.type = TYPE_TO_PARAM(contacts_found)
};
void tgl_do_contacts_search (int limit, const char *s) {
void tgl_do_contacts_search (int limit, const char *s, void (*callback) (void *callback_extra, int success, int size, struct tgl_user *users[]), void *callback_extra) {
clear_packet ();
out_int (CODE_contacts_search);
out_string (s);
out_int (limit);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &contacts_search_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &contacts_search_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Encr accept */
int send_encr_accept_on_answer (struct query *q UU) {
static int send_encr_accept_on_answer (struct query *q UU) {
struct tgl_secret_chat *E = tglf_fetch_alloc_encrypted_chat ();
if (E->state == sc_ok) {
/*if (E->state == sc_ok) {
print_start ();
push_color (COLOR_YELLOW);
printf ("Encrypted connection with ");
......@@ -2360,13 +2372,17 @@ int send_encr_accept_on_answer (struct query *q UU) {
printf (" failed\n");
pop_color ();
print_end ();
}*/
if (q->callback) {
((void (*)(void *, int, struct tgl_secret_chat *))q->callback) (q->callback_extra, E->state == sc_ok, E);
}
return 0;
}
int send_encr_request_on_answer (struct query *q UU) {
static int send_encr_request_on_answer (struct query *q UU) {
struct tgl_secret_chat *E = tglf_fetch_alloc_encrypted_chat ();
if (E->state == sc_deleted) {
/*if (E->state == sc_deleted) {
print_start ();
push_color (COLOR_YELLOW);
printf ("Encrypted connection with ");
......@@ -2384,26 +2400,30 @@ int send_encr_request_on_answer (struct query *q UU) {
print_end ();
assert (E->state == sc_waiting);
}*/
if (q->callback) {
((void (*)(void *, int, struct tgl_secret_chat *))q->callback) (q->callback_extra, E->state != sc_deleted, E);
}
return 0;
}
struct query_methods send_encr_accept_methods = {
static struct query_methods send_encr_accept_methods = {
.on_answer = send_encr_accept_on_answer,
.type = TYPE_TO_PARAM(encrypted_chat)
};
struct query_methods send_encr_request_methods = {
static struct query_methods send_encr_request_methods = {
.on_answer = send_encr_request_on_answer,
.type = TYPE_TO_PARAM(encrypted_chat)
};
int encr_root;
unsigned char *encr_prime;
int encr_param_version;
BN_CTX *ctx;
//int encr_root;
//unsigned char *encr_prime;
//int encr_param_version;
static BN_CTX *ctx;
void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *random) {
void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *random, void (*callback)(void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) {
int i;
int ok = 0;
for (i = 0; i < 64; i++) {
......@@ -2412,7 +2432,10 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
break;
}
}
if (ok) { return; } // Already generated key for this chat
if (ok) {
callback (callback_extra, 1, E);
return;
} // Already generated key for this chat
unsigned char random_here[256];
secure_random (random_here, 256);
for (i = 0; i < 256; i++) {
......@@ -2422,12 +2445,12 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
ensure_ptr (b);
BIGNUM *g_a = BN_bin2bn (E->g_key, 256, 0);
ensure_ptr (g_a);
assert (check_g (encr_prime, g_a) >= 0);
assert (check_g (tgl_state.encr_prime, g_a) >= 0);
if (!ctx) {
ctx = BN_CTX_new ();
ensure_ptr (ctx);
}
BIGNUM *p = BN_bin2bn (encr_prime, 256, 0);
BIGNUM *p = BN_bin2bn (tgl_state.encr_prime, 256, 0);
ensure_ptr (p);
BIGNUM *r = BN_new ();
ensure_ptr (r);
......@@ -2449,7 +2472,7 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
out_int (tgl_get_peer_id (E->id));
out_long (E->access_hash);
ensure (BN_set_word (g_a, encr_root));
ensure (BN_set_word (g_a, tgl_state.encr_root));
ensure (BN_mod_exp (r, g_a, b, p, ctx));
static unsigned char buf[256];
memset (buf, 0, sizeof (buf));
......@@ -2462,19 +2485,19 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
BN_clear_free (p);
BN_clear_free (r);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_accept_methods, E);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_accept_methods, E, callback, callback_extra);
}
void tgl_do_create_keys_end (struct tgl_secret_chat *U) {
assert (encr_prime);
assert (tgl_state.encr_prime);
BIGNUM *g_b = BN_bin2bn (U->g_key, 256, 0);
ensure_ptr (g_b);
assert (check_g (encr_prime, g_b) >= 0);
assert (check_g (tgl_state.encr_prime, g_b) >= 0);
if (!ctx) {
ctx = BN_CTX_new ();
ensure_ptr (ctx);
}
BIGNUM *p = BN_bin2bn (encr_prime, 256, 0);
BIGNUM *p = BN_bin2bn (tgl_state.encr_prime, 256, 0);
ensure_ptr (p);
BIGNUM *r = BN_new ();
ensure_ptr (r);
......@@ -2496,13 +2519,7 @@ void tgl_do_create_keys_end (struct tgl_secret_chat *U) {
sha1 ((void *)U->key, 256, sha_buffer);
long long k = *(long long *)(sha_buffer + 12);
if (k != U->key_fingerprint) {
logprintf ("version = %d\n", encr_param_version);
hexdump ((void *)U->nonce, (void *)(U->nonce + 256));
hexdump ((void *)U->g_key, (void *)(U->g_key + 256));
hexdump ((void *)U->key, (void *)(U->key + 64));
hexdump ((void *)t, (void *)(t + 256));
hexdump ((void *)sha_buffer, (void *)(sha_buffer + 20));
logprintf ("!!Key fingerprint mismatch (my 0x%llx 0x%llx)\n", (unsigned long long)k, (unsigned long long)U->key_fingerprint);
vlogprintf (E_WARNING, "Key fingerprint mismatch (my 0x%llx 0x%llx)\n", (unsigned long long)k, (unsigned long long)U->key_fingerprint);
U->state = sc_deleted;
}
......@@ -2514,7 +2531,7 @@ void tgl_do_create_keys_end (struct tgl_secret_chat *U) {
BN_clear_free (a);
}
void tgl_do_send_create_encr_chat (void *x, unsigned char *random) {
void tgl_do_send_create_encr_chat (void *x, unsigned char *random, void (*callback)(void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) {
int user_id = (long)x;
int i;
unsigned char random_here[256];
......@@ -2528,13 +2545,13 @@ void tgl_do_send_create_encr_chat (void *x, unsigned char *random) {
}
BIGNUM *a = BN_bin2bn (random, 256, 0);
ensure_ptr (a);
BIGNUM *p = BN_bin2bn (encr_prime, 256, 0);
BIGNUM *p = BN_bin2bn (tgl_state.encr_prime, 256, 0);
ensure_ptr (p);
BIGNUM *g = BN_new ();
ensure_ptr (g);
ensure (BN_set_word (g, encr_root));
ensure (BN_set_word (g, tgl_state.encr_root));
BIGNUM *r = BN_new ();
ensure_ptr (r);
......@@ -2578,10 +2595,10 @@ void tgl_do_send_create_encr_chat (void *x, unsigned char *random) {
BN_clear_free (p);
BN_clear_free (r);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_request_methods, E);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_request_methods, E, callback, callback_extra);
}
int get_dh_config_on_answer (struct query *q UU) {
static int get_dh_config_on_answer (struct query *q UU) {
unsigned x = fetch_int ();
assert (x == CODE_messages_dh_config || x == CODE_messages_dh_config_not_modified);
if (x == CODE_messages_dh_config) {
......@@ -2603,7 +2620,7 @@ int get_dh_config_on_answer (struct query *q UU) {
memcpy (random, fetch_str (256), 256);
if (q->extra) {
void **x = q->extra;
((void (*)(void *, void *))(*x))(x[1], random);
((void (*)(void *, void *, void *, void *))(*x))(x[1], random, q->callback, q->callback_extra);
tfree (x, 2 * sizeof (void *));
tfree_secure (random, 256);
} else {
......@@ -2612,81 +2629,84 @@ int get_dh_config_on_answer (struct query *q UU) {
return 0;
}
struct query_methods get_dh_config_methods = {
static struct query_methods get_dh_config_methods = {
.on_answer = get_dh_config_on_answer,
.type = TYPE_TO_PARAM(messages_dh_config)
};
void tgl_do_accept_encr_chat_request (struct tgl_secret_chat *E) {
void tgl_do_accept_encr_chat_request (struct tgl_secret_chat *E, void (*callback)(void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) {
assert (E->state == sc_request);
clear_packet ();
out_int (CODE_messages_get_dh_config);
out_int (encr_param_version);
out_int (tgl_state.encr_param_version);
out_int (256);
void **x = talloc (2 * sizeof (void *));
x[0] = tgl_do_send_accept_encr_chat;
x[1] = E;
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dh_config_methods, x);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dh_config_methods, x, callback, callback_extra);
}
void tgl_do_create_encr_chat_request (int user_id) {
void tgl_do_create_encr_chat_request (int user_id, void (*callback)(void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) {
clear_packet ();
out_int (CODE_messages_get_dh_config);
out_int (encr_param_version);
out_int (tgl_state.encr_param_version);
out_int (256);
void **x = talloc (2 * sizeof (void *));
x[0] = tgl_do_send_create_encr_chat;
x[1] = (void *)(long)(user_id);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dh_config_methods, x);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dh_config_methods, x, callback, callback_extra);
}
/* }}} */
/* {{{ Get difference */
int unread_messages;
int difference_got;
int seq, pts, qts, last_date;
int get_state_on_answer (struct query *q UU) {
//int unread_messages;
//int difference_got;
//int seq, pts, qts, last_date;
static int get_state_on_answer (struct query *q UU) {
assert (fetch_int () == (int)CODE_updates_state);
bl_do_set_pts (fetch_int ());
bl_do_set_qts (fetch_int ());
bl_do_set_date (fetch_int ());
bl_do_set_seq (fetch_int ());
unread_messages = fetch_int ();
write_state_file ();
difference_got = 1;
//unread_messages = fetch_int ();
fetch_int ();
//write_state_file ();
//difference_got = 1;
if (q->callback) {
((void (*)(void *, int))q->callback) (q->callback_extra, 1);
}
return 0;
}
int get_difference_active;
int get_difference_on_answer (struct query *q UU) {
get_difference_active = 0;
//int get_difference_active;
static int get_difference_on_answer (struct query *q UU) {
//get_difference_active = 0;
unsigned x = fetch_int ();
if (x == CODE_updates_difference_empty) {
bl_do_set_date (fetch_int ());
bl_do_set_seq (fetch_int ());
difference_got = 1;
//difference_got = 1;
if (q->callback) {
((void (*)(void *, int))q->callback) (q->callback_extra, 1);
}
} else if (x == CODE_updates_difference || x == CODE_updates_difference_slice) {
int n, i;
assert (fetch_int () == CODE_vector);
n = fetch_int ();
static struct tgl_message *ML[10000];
struct tgl_message **ML = talloc (n * sizeof (void *));
int ml_pos = 0;
for (i = 0; i < n; i++) {
if (ml_pos < 10000) {
ML[ml_pos ++] = tglf_fetch_alloc_message ();
} else {
tglf_fetch_alloc_message ();
}
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
struct tgl_message **EL = talloc (n * sizeof (void *));
int el_pos = 0;
for (i = 0; i < n; i++) {
if (ml_pos < 10000) {
ML[ml_pos ++] = tglf_fetch_alloc_encrypted_message ();
} else {
tglf_fetch_alloc_encrypted_message ();
}
EL[el_pos ++] = tglf_fetch_alloc_encrypted_message ();
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
......@@ -2708,15 +2728,28 @@ int get_difference_on_answer (struct query *q UU) {
bl_do_set_qts (fetch_int ());
bl_do_set_date (fetch_int ());
bl_do_set_seq (fetch_int ());
unread_messages = fetch_int ();
write_state_file ();
for (i = 0; i < ml_pos; i++) {
//unread_messages = fetch_int ();
fetch_int ();
//write_state_file ();
/*for (i = 0; i < ml_pos; i++) {
print_message (ML[i]);
}*/
for (i = 0; i < ml_pos; i++) {
tgl_state.callback.new_msg (ML[i]);
}
for (i = 0; i < el_pos; i++) {
tgl_state.callback.new_msg (EL[i]);
}
tfree (ML, ml_pos * sizeof (void *));
tfree (EL, el_pos * sizeof (void *));
if (x == CODE_updates_difference_slice) {
tgl_do_get_difference ();
tgl_do_get_difference (0, q->callback, q->callback_extra);
} else {
difference_got = 1;
//difference_got = 1;
if (q->callback) {
((void (*)(void *, int))q->callback) (q->callback_extra, 1);
}
}
} else {
assert (0);
......@@ -2724,39 +2757,39 @@ int get_difference_on_answer (struct query *q UU) {
return 0;
}
struct query_methods get_state_methods = {
static struct query_methods get_state_methods = {
.on_answer = get_state_on_answer,
.type = TYPE_TO_PARAM(updates_state)
};
struct query_methods get_difference_methods = {
static struct query_methods get_difference_methods = {
.on_answer = get_difference_on_answer,
.type = TYPE_TO_PARAM(updates_difference)
};
void tgl_do_get_difference (void) {
get_difference_active = 1;
difference_got = 0;
void tgl_do_get_difference (int sync_from_start, void (*callback)(void *callback_extra, int success), void *callback_extra) {
//get_difference_active = 1;
//difference_got = 0;
clear_packet ();
tgl_do_insert_header ();
if (seq > 0 || sync_from_start) {
if (pts == 0) { pts = 1; }
if (qts == 0) { qts = 1; }
if (last_date == 0) { last_date = 1; }
if (tgl_state.seq > 0 || sync_from_start) {
if (tgl_state.pts == 0) { tgl_state.pts = 1; }
if (tgl_state.qts == 0) { tgl_state.qts = 1; }
if (tgl_state.date == 0) { tgl_state.date = 1; }
out_int (CODE_updates_get_difference);
out_int (pts);
out_int (last_date);
out_int (qts);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_difference_methods, 0);
out_int (tgl_state.pts);
out_int (tgl_state.date);
out_int (tgl_state.qts);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_difference_methods, 0, callback, callback_extra);
} else {
out_int (CODE_updates_get_state);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_state_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_state_methods, 0, callback, callback_extra);
}
}
/* }}} */
/* {{{ Visualize key */
char *colors[4] = {COLOR_GREY, COLOR_CYAN, COLOR_BLUE, COLOR_GREEN};
/*char *colors[4] = {COLOR_GREY, COLOR_CYAN, COLOR_BLUE, COLOR_GREEN};
void tgl_do_visualize_key (tgl_peer_id_t id) {
assert (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT);
......@@ -2784,11 +2817,24 @@ void tgl_do_visualize_key (tgl_peer_id_t id) {
if (i & 1) { printf ("\n"); }
}
print_end ();
}*/
void tgl_do_visualize_key (tgl_peer_id_t id, unsigned char buf[16]) {
assert (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT);
tgl_peer_t *P = tgl_peer_get (id);
assert (P);
if (P->encr_chat.state != sc_ok) {
vlogprintf (E_WARNING, "Chat is not initialized yet\n");
return;
}
unsigned char res[20];
SHA1 ((void *)P->encr_chat.key, 256, res);
memcpy (buf, res, 16);
}
/* }}} */
/* {{{ Get suggested */
int get_suggested_on_answer (struct query *q UU) {
/*int get_suggested_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_contacts_suggested);
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
......@@ -2827,17 +2873,17 @@ void tgl_do_get_suggested (void) {
out_int (CODE_contacts_get_suggested);
out_int (100);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_suggested_methods, 0);
}
}*/
/* }}} */
/* {{{ Add user to chat */
struct query_methods add_user_to_chat_methods = {
static struct query_methods add_user_to_chat_methods = {
.on_answer = fwd_msg_on_answer,
.type = TYPE_TO_PARAM(message_action)
};
void tgl_do_add_user_to_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, int limit) {
void tgl_do_add_user_to_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, int limit, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
clear_packet ();
out_int (CODE_messages_add_chat_user);
out_int (tgl_get_peer_id (chat_id));
......@@ -2853,10 +2899,10 @@ void tgl_do_add_user_to_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, int limit
out_int (tgl_get_peer_id (id));
}
out_int (limit);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &add_user_to_chat_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &add_user_to_chat_methods, 0, callback, callback_extra);
}
void tgl_do_del_user_from_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id) {
void tgl_do_del_user_from_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
clear_packet ();
out_int (CODE_messages_delete_chat_user);
out_int (tgl_get_peer_id (chat_id));
......@@ -2871,36 +2917,36 @@ void tgl_do_del_user_from_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id) {
out_int (CODE_input_user_contact);
out_int (tgl_get_peer_id (id));
}
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &add_user_to_chat_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &add_user_to_chat_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Create secret chat */
char *create_print_name (tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
//char *create_print_name (tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
void tgl_do_create_secret_chat (tgl_peer_id_t id) {
void tgl_do_create_secret_chat (tgl_peer_id_t id, void (*callback)(void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) {
assert (tgl_get_peer_type (id) == TGL_PEER_USER);
tgl_peer_t *U = tgl_peer_get (id);
if (!U) {
rprintf ("Can not create chat with unknown user\n");
vlogprintf (E_WARNING, "Can not create chat with unknown user\n");
return;
}
tgl_do_create_encr_chat_request (tgl_get_peer_id (id));
tgl_do_create_encr_chat_request (tgl_get_peer_id (id), callback, callback_extra);
}
/* }}} */
/* {{{ Create group chat */
struct query_methods create_group_chat_methods = {
static struct query_methods create_group_chat_methods = {
.on_answer = fwd_msg_on_answer,
.type = TYPE_TO_PARAM(message_action)
};
void tgl_do_create_group_chat (tgl_peer_id_t id, char *chat_topic) {
void tgl_do_create_group_chat (tgl_peer_id_t id, char *chat_topic, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) {
assert (tgl_get_peer_type (id) == TGL_PEER_USER);
tgl_peer_t *U = tgl_peer_get (id);
if (!U) {
rprintf ("Can not create chat with unknown user\n");
vlogprintf (E_WARNING, "Can not create chat with unknown user\n");
return;
}
clear_packet ();
......@@ -2916,62 +2962,74 @@ void tgl_do_create_group_chat (tgl_peer_id_t id, char *chat_topic) {
out_int (tgl_get_peer_id (id));
}
out_string (chat_topic);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &create_group_chat_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &create_group_chat_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Delete msg */
int delete_msg_on_answer (struct query *q UU) {
static int delete_msg_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
fetch_skip (n);
logprintf ("Deleted %d messages\n", n);
if (q->callback) {
((void (*)(void *, int))q->callback) (q->callback_extra, 1);
}
return 0;
}
struct query_methods delete_msg_methods = {
static struct query_methods delete_msg_methods = {
.on_answer = delete_msg_on_answer,
.type = TYPE_TO_PARAM_1(vector, TYPE_TO_PARAM (bare_int))
};
void tgl_do_delete_msg (long long id) {
void tgl_do_delete_msg (long long id, void (*callback)(void *callback_extra, int success), void *callback_extra) {
clear_packet ();
out_int (CODE_messages_delete_messages);
out_int (CODE_vector);
out_int (1);
out_int (id);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &delete_msg_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &delete_msg_methods, 0, callback, callback_extra);
}
/* }}} */
/* {{{ Restore msg */
int restore_msg_on_answer (struct query *q UU) {
static int restore_msg_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
fetch_skip (n);
logprintf ("Restored %d messages\n", n);
//logprintf ("Restored %d messages\n", n);
if (q->callback) {
((void (*)(void *, int))q->callback) (q->callback_extra, 1);
}
return 0;
}
struct query_methods restore_msg_methods = {
static struct query_methods restore_msg_methods = {
.on_answer = restore_msg_on_answer,
.type = TYPE_TO_PARAM_1(vector, TYPE_TO_PARAM (bare_int))
};
void tgl_do_restore_msg (long long id) {
void tgl_do_restore_msg (long long id, void (*callback)(void *callback_extra, int success), void *callback_extra) {
clear_packet ();
out_int (CODE_messages_restore_messages);
out_int (CODE_vector);
out_int (1);
out_int (id);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &restore_msg_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &restore_msg_methods, 0, callback, callback_extra);
}
/* }}} */
int update_status_on_answer (struct query *q UU) {
fetch_bool ();
if (q->callback) {
((void (*)(void *, int))q->callback) (q->callback_extra, 1);
}
return 0;
}
......@@ -2980,9 +3038,9 @@ struct query_methods update_status_methods = {
.type = TYPE_TO_PARAM(bool)
};
void tgl_do_update_status (int online UU) {
void tgl_do_update_status (int online UU, void (*callback)(void *callback_extra, int success), void *callback_extra) {
clear_packet ();
out_int (CODE_account_update_status);
out_int (online ? CODE_bool_false : CODE_bool_true);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &update_status_methods, 0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &update_status_methods, 0, callback, callback_extra);
}
......@@ -50,10 +50,12 @@ struct query {
struct dc *DC;
struct session *session;
void *extra;
void *callback;
void *callback_extra;
};
struct query *send_query (struct dc *DC, int len, void *data, struct query_methods *methods, void *extra);
struct query *send_query (struct dc *DC, int len, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra);
void query_ack (long long id);
void query_error (long long id);
void query_result (long long id);
......@@ -64,13 +66,13 @@ void remove_event_timer (struct event_timer *ev);
double next_timer_in (void);
void work_timers (void);
extern struct query_methods help_get_config_methods;
//extern struct query_methods help_get_config_methods;
double get_double_time (void);
// For binlog
int get_dh_config_on_answer (struct query *q);
void fetch_dc_option (void);
//int get_dh_config_on_answer (struct query *q);
//void fetch_dc_option (void);
#endif
......@@ -1628,9 +1628,9 @@ void tglm_message_remove_unsent (struct tgl_message *M) {
static void __send_msg (struct tgl_message *M) {
vlogprintf (E_NOTICE, "Resending message...\n");
print_message (M);
//print_message (M);
tgl_do_send_msg (M);
tgl_do_send_msg (M, 0, 0);
}
void tglm_send_all_unsent (void ) {
......
......@@ -5,3 +5,19 @@
#include "tgl.h"
struct tgl_state tgl_state;
void tgl_set_binlog_mode (int mode) {
tgl_state.binlog_enabled = mode;
}
void tgl_set_binlog_path (const char *path) {
tgl_state.binlog_name = tstrdup (path);
}
void tgl_set_auth_file_path (const char *path) {
tgl_state.auth_file = tstrdup (path);
}
void tgl_set_download_directory (const char *path) {
tgl_state.downloads_directory = tstrdup (path);
}
......@@ -6,7 +6,33 @@
#define TGL_MAX_DC_NUM 100
#define TGL_BUILD "1828"
#define TGL_VERSION "0.9-beta"
// Do not modify this structure, unless you know what you do
struct tgl_update_callback {
void (*new_msg)(struct tgl_message *M);
void (*marked_read)(int num, struct tgl_message *list[]);
void (*logprintf)(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void (*type_notification)(tgl_peer_id_t id, struct tgl_user *U);
void (*type_in_chat_notification)(tgl_peer_id_t id, struct tgl_user *U, tgl_peer_id_t chat_id, struct tgl_chat *C);
void (*status_notification)(struct tgl_user *U);
void (*user_registered)(struct tgl_user *U);
};
#define vlogprintf(verbosity_level,...) \
do { \
if (tgl_state.verbosity >= verbosity_level) { \
tgl_state.callback.logprintf (__VA_ARGS__); \
} \
} while (0)
#define E_ERROR 0
#define E_WARNING 1
#define E_NOTICE 2
#define E_DEBUG 3
struct tgl_state {
int our_id; // ID of logged in user
int encr_root;
......@@ -29,6 +55,12 @@ struct tgl_state {
long long cur_uploaded_bytes;
long long cur_downloading_bytes;
long long cur_downloaded_bytes;
char *binlog_name;
char *auth_file;
char *downloads_directory;
struct tgl_update_callback callback;
};
extern struct tgl_state tgl_state;
......@@ -58,6 +90,12 @@ int tgl_complete_peer_list (int index, const char *text, int len, char **R);
#define TGL_MK_GEO_CHAT(id) tgl_set_peer_id (TGL_PEER_GEO_CHAT,id)
#define TGL_MK_ENCR_CHAT(id) tgl_set_peer_id (TGL_PEER_ENCR_CHAT,id)
void tgl_set_binlog_mode (int mode);
void tgl_set_binlog_path (const char *path);
void tgl_set_auth_file_path (const char *path);
void tgl_set_download_directory (const char *path);
static inline int tgl_get_peer_type (tgl_peer_id_t id) {
return id.type;
}
......@@ -89,52 +127,49 @@ static inline void tgl_set_test_mode (void) {
tgl_state.test_mode ++;
}
void tgl_do_send_code (const char *user);
void tgl_do_phone_call (const char *user);
int tgl_do_send_code_result (const char *code);
void tgl_do_update_contact_list (void);
void tgl_do_send_message (tgl_peer_id_t id, const char *msg, int len);
void tgl_do_send_text (tgl_peer_id_t id, char *file);
void tgl_do_get_history (tgl_peer_id_t id, int limit);
void tgl_do_get_dialog_list (void);
void tgl_do_get_dialog_list_ex (void);
void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name);
void tgl_do_get_chat_info (tgl_peer_id_t id);
void tgl_do_get_user_list_info_silent (int num, int *list);
void tgl_do_get_user_info (tgl_peer_id_t id);
void tgl_do_forward_message (tgl_peer_id_t id, int n);
void tgl_do_rename_chat (tgl_peer_id_t id, char *name);
void tgl_do_load_encr_video (struct tgl_encr_video *V, int next);
void tgl_do_create_encr_chat_request (int user_id);
void tgl_do_create_secret_chat (tgl_peer_id_t id);
void tgl_do_create_group_chat (tgl_peer_id_t id, char *chat_topic);
void tgl_do_get_suggested (void);
void tgl_do_load_photo (struct tgl_photo *photo, int next);
void tgl_do_load_video_thumb (struct tgl_video *video, int next);
void tgl_do_load_audio (struct tgl_video *V, int next);
void tgl_do_load_video (struct tgl_video *V, int next);
void tgl_do_load_document (struct tgl_document *V, int next);
void tgl_do_load_document_thumb (struct tgl_document *video, int next);
void tgl_do_help_get_config (void);
int tgl_do_auth_check_phone (const char *user);
int tgl_do_get_nearest_dc (void);
int tgl_do_send_code_result_auth (const char *code, const char *first_name, const char *last_name);
void tgl_do_import_auth (int num);
void tgl_do_export_auth (int num);
void tgl_do_add_contact (const char *phone, int phone_len, const char *first_name, int first_name_len, const char *last_name, int last_name_len, int force);
void tgl_do_msg_search (tgl_peer_id_t id, int from, int to, int limit, const char *s);
void tgl_do_accept_encr_chat_request (struct tgl_secret_chat *E);
void tgl_do_get_difference (void);
void tgl_do_mark_read (tgl_peer_id_t id);
void tgl_do_visualize_key (tgl_peer_id_t id);
void tgl_do_help_get_config (void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_send_code (const char *user, void (*callback)(void *callback_extra, int success, int registered, const char *hash), void *callback_extra);
void tgl_do_phone_call (const char *user, void (*callback)(void *callback_extra, int success), void *callback_extra);
int tgl_do_send_code_result (const char *user, const char *code, void (*callback)(void *callback_extra, int success, struct tgl_user *Self), void *callback_extra) ;
int tgl_do_send_code_result_auth (const char *user, const char *code, const char *first_name, const char *last_name, void (*callback)(void *callback_extra, int success, struct tgl_user *Self), void *callback_extra);
void tgl_do_update_contact_list (void (*callback) (void *callback_extra, int success, int size, struct tgl_user *contacts[]), void *callback_extra);
void tgl_do_send_message (tgl_peer_id_t id, const char *msg, int len, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_send_msg (struct tgl_message *M, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_send_text (tgl_peer_id_t id, char *file, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_mark_read (tgl_peer_id_t id, void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_get_history (tgl_peer_id_t id, int limit, int offline_mode, void (*callback)(void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra);
void tgl_do_get_dialog_list (void (*callback)(void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[]), void *callback_extra);
void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_forward_message (tgl_peer_id_t id, int n, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_rename_chat (tgl_peer_id_t id, char *name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_get_chat_info (tgl_peer_id_t id, int offline_mode, void (*callback)(void *callback_extra, int success, struct tgl_chat *C), void *callback_extra);
void tgl_do_get_user_info (tgl_peer_id_t id, int offline_mode, void (*callback)(void *callback_extra, int success, struct tgl_user *U), void *callback_extra);
void tgl_do_load_photo (struct tgl_photo *photo, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra);
void tgl_do_load_video_thumb (struct tgl_video *video, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra);
void tgl_do_load_audio (struct tgl_video *V, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra);
void tgl_do_load_video (struct tgl_video *V, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra);
void tgl_do_load_document (struct tgl_document *V, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra);
void tgl_do_load_document_thumb (struct tgl_document *video, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra);
void tgl_do_load_encr_video (struct tgl_encr_video *V, void (*callback)(void *callback_extra, int success, char *filename), void *callback_extra);
void tgl_do_export_auth (int num, void (*callback) (void *callback_extra, int success), void *callback_extra);
void tgl_do_add_contact (const char *phone, int phone_len, const char *first_name, int first_name_len, const char *last_name, int last_name_len, int force, void (*callback)(void *callback_extra, int success, int size, struct tgl_user *users[]), void *callback_extra);
void tgl_do_msg_search (tgl_peer_id_t id, int from, int to, int limit, const char *s, void (*callback)(void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra);
void tgl_do_contacts_search (int limit, const char *s, void (*callback) (void *callback_extra, int success, int size, struct tgl_user *users[]), void *callback_extra);
void tgl_do_create_encr_chat_request (int user_id, void (*callback)(void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra);
void tgl_do_create_secret_chat (tgl_peer_id_t id, void (*callback)(void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra);
void tgl_do_accept_encr_chat_request (struct tgl_secret_chat *E, void (*callback)(void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra);
void tgl_do_get_difference (int sync_from_start, void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_add_user_to_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, int limit, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_del_user_from_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_create_group_chat (tgl_peer_id_t id, char *chat_topic, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_delete_msg (long long id, void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_restore_msg (long long id, void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_update_status (int online, void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_visualize_key (tgl_peer_id_t id, unsigned char buf[16]);
//void tgl_do_get_suggested (void);
void tgl_do_create_keys_end (struct tgl_secret_chat *U);
void tgl_do_add_user_to_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, int limit);
void tgl_do_del_user_from_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id);
void tgl_do_update_status (int online);
void tgl_do_contacts_search (int limit, const char *s);
void tgl_do_send_msg (struct tgl_message *M);
void tgl_do_delete_msg (long long id);
void tgl_do_restore_msg (long long id);
void tgl_do_send_encr_chat_layer (struct tgl_secret_chat *E);
#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