Commit 923845d6 authored by vysheng's avatar vysheng

Partial support for encrypted chats.

parent 9dd3627a
...@@ -48,9 +48,8 @@ long long cur_downloading_bytes; ...@@ -48,9 +48,8 @@ long long cur_downloading_bytes;
long long cur_downloaded_bytes; long long cur_downloaded_bytes;
char *line_ptr; char *line_ptr;
extern int user_num;
extern int chat_num;
extern peer_t *Peers[]; extern peer_t *Peers[];
extern int peer_num;
int is_same_word (const char *s, size_t l, const char *word) { int is_same_word (const char *s, size_t l, const char *word) {
return s && word && strlen (word) == l && !memcmp (s, word, l); return s && word && strlen (word) == l && !memcmp (s, word, l);
...@@ -106,10 +105,10 @@ peer_id_t next_token_user (void) { ...@@ -106,10 +105,10 @@ peer_id_t next_token_user (void) {
} }
int index = 0; int index = 0;
while (index < user_num + chat_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_USER)) { while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_USER)) {
index ++; index ++;
} }
if (index < user_num + chat_num) { if (index < peer_num) {
return Peers[index]->id; return Peers[index]->id;
} else { } else {
return PEER_NOT_FOUND; return PEER_NOT_FOUND;
...@@ -130,10 +129,10 @@ peer_id_t next_token_chat (void) { ...@@ -130,10 +129,10 @@ peer_id_t next_token_chat (void) {
} }
int index = 0; int index = 0;
while (index < user_num + chat_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_CHAT)) { while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name) || get_peer_type (Peers[index]->id) != PEER_CHAT)) {
index ++; index ++;
} }
if (index < user_num + chat_num) { if (index < peer_num) {
return Peers[index]->id; return Peers[index]->id;
} else { } else {
return PEER_NOT_FOUND; return PEER_NOT_FOUND;
...@@ -161,10 +160,10 @@ peer_id_t next_token_peer (void) { ...@@ -161,10 +160,10 @@ peer_id_t next_token_peer (void) {
} }
int index = 0; int index = 0;
while (index < user_num + chat_num && (!is_same_word (s, l, Peers[index]->print_name))) { while (index < peer_num && (!is_same_word (s, l, Peers[index]->print_name))) {
index ++; index ++;
} }
if (index < user_num + chat_num) { if (index < peer_num) {
return Peers[index]->id; return Peers[index]->id;
} else { } else {
return PEER_NOT_FOUND; return PEER_NOT_FOUND;
...@@ -232,6 +231,7 @@ char *commands[] = { ...@@ -232,6 +231,7 @@ char *commands[] = {
"rename_contact", "rename_contact",
"show_license", "show_license",
"search", "search",
"mark_read",
0 }; 0 };
int commands_flags[] = { int commands_flags[] = {
...@@ -258,6 +258,7 @@ int commands_flags[] = { ...@@ -258,6 +258,7 @@ int commands_flags[] = {
071, 071,
07, 07,
072, 072,
072,
}; };
int get_complete_mode (void) { int get_complete_mode (void) {
...@@ -297,10 +298,10 @@ int get_complete_mode (void) { ...@@ -297,10 +298,10 @@ int get_complete_mode (void) {
int complete_user_list (int index, const char *text, int len, char **R) { int complete_user_list (int index, const char *text, int len, char **R) {
index ++; index ++;
while (index < user_num + chat_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_USER)) { while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_USER)) {
index ++; index ++;
} }
if (index < user_num + chat_num) { if (index < peer_num) {
*R = strdup (Peers[index]->print_name); *R = strdup (Peers[index]->print_name);
return index; return index;
} else { } else {
...@@ -310,10 +311,10 @@ int complete_user_list (int index, const char *text, int len, char **R) { ...@@ -310,10 +311,10 @@ int complete_user_list (int index, const char *text, int len, char **R) {
int complete_chat_list (int index, const char *text, int len, char **R) { int complete_chat_list (int index, const char *text, int len, char **R) {
index ++; index ++;
while (index < user_num + chat_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_CHAT)) { while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len) || get_peer_type (Peers[index]->id) != PEER_CHAT)) {
index ++; index ++;
} }
if (index < user_num + chat_num) { if (index < peer_num) {
*R = strdup (Peers[index]->print_name); *R = strdup (Peers[index]->print_name);
return index; return index;
} else { } else {
...@@ -323,10 +324,10 @@ int complete_chat_list (int index, const char *text, int len, char **R) { ...@@ -323,10 +324,10 @@ int complete_chat_list (int index, const char *text, int len, char **R) {
int complete_user_chat_list (int index, const char *text, int len, char **R) { int complete_user_chat_list (int index, const char *text, int len, char **R) {
index ++; index ++;
while (index < user_num + chat_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) { while (index < peer_num && (!Peers[index]->print_name || strncmp (Peers[index]->print_name, text, len))) {
index ++; index ++;
} }
if (index < user_num + chat_num) { if (index < peer_num) {
*R = strdup (Peers[index]->print_name); *R = strdup (Peers[index]->print_name);
return index; return index;
} else { } else {
...@@ -663,6 +664,8 @@ void interpreter (char *line UU) { ...@@ -663,6 +664,8 @@ void interpreter (char *line UU) {
"load_photo/load_video/load_video_thumb <msg-seqno> - loads photo/video to download dir\n" "load_photo/load_video/load_video_thumb <msg-seqno> - loads photo/video to download dir\n"
"view_photo/view_video/view_video_thumb <msg-seqno> - loads photo/video to download dir and starts system default viewer\n" "view_photo/view_video/view_video_thumb <msg-seqno> - loads photo/video to download dir and starts system default viewer\n"
"show_license - prints contents of GPLv2\n" "show_license - prints contents of GPLv2\n"
"search <peer> pattern - searches pattern in messages with peer\n"
"mark_read <peer> - mark read all received messages with peer\n"
); );
pop_color (); pop_color ();
rl_on_new_line (); rl_on_new_line ();
...@@ -685,6 +688,9 @@ void interpreter (char *line UU) { ...@@ -685,6 +688,9 @@ void interpreter (char *line UU) {
RET; RET;
} }
do_msg_search (id, from, to, limit, s); do_msg_search (id, from, to, limit, s);
} else if (IS_WORD ("mark_read")) {
GET_PEER;
do_mark_read (id);
} }
#undef IS_WORD #undef IS_WORD
#undef RET #undef RET
...@@ -796,30 +802,6 @@ void logprintf (const char *format, ...) { ...@@ -796,30 +802,6 @@ void logprintf (const char *format, ...) {
} }
} }
const char *message_media_type_str (struct message_media *M) {
static char buf[1000];
switch (M->type) {
case CODE_message_media_empty:
return "";
case CODE_message_media_photo:
return "[photo]";
case CODE_message_media_video:
return "[video]";
case CODE_message_media_geo:
sprintf (buf, "[geo] https://maps.google.com/maps?ll=%.6lf,%.6lf", M->geo.latitude, M->geo.longitude);
return buf;
case CODE_message_media_contact:
snprintf (buf, 999, "[contact] " COLOR_RED "%s %s" COLOR_NORMAL " %s", M->first_name, M->last_name, M->phone);
return buf;
case CODE_message_media_unsupported:
return "[unsupported]";
default:
assert (0);
return "";
}
}
int color_stack_pos; int color_stack_pos;
const char *color_stack[10]; const char *color_stack[10];
...@@ -853,6 +835,12 @@ void print_media (struct message_media *M) { ...@@ -853,6 +835,12 @@ void print_media (struct message_media *M) {
case CODE_message_media_video: case CODE_message_media_video:
printf ("[video]"); printf ("[video]");
return; return;
case CODE_decrypted_message_media_photo:
printf ("[photo]");
return;
case CODE_decrypted_message_media_video:
printf ("[video]");
return;
case CODE_message_media_geo: case CODE_message_media_geo:
printf ("[geo] https://maps.google.com/?q=%.6lf,%.6lf", M->geo.latitude, M->geo.longitude); printf ("[geo] https://maps.google.com/?q=%.6lf,%.6lf", M->geo.latitude, M->geo.longitude);
return; return;
...@@ -1009,6 +997,9 @@ peer_id_t last_from_id; ...@@ -1009,6 +997,9 @@ peer_id_t last_from_id;
peer_id_t last_to_id; peer_id_t last_to_id;
void print_message (struct message *M) { void print_message (struct message *M) {
if (M->flags & (FLAG_EMPTY | FLAG_DELETED)) {
return;
}
if (M->service) { if (M->service) {
print_service_message (M); print_service_message (M);
return; return;
...@@ -1050,7 +1041,42 @@ void print_message (struct message *M) { ...@@ -1050,7 +1041,42 @@ void print_message (struct message *M) {
printf (" »»» "); printf (" »»» ");
} }
} }
} else if (get_peer_type (M->to_id) == PEER_ENCR_CHAT) {
peer_t *P = user_chat_get (M->to_id);
assert (P);
if (M->out) {
push_color (COLOR_GREEN);
if (msg_num_mode) {
printf ("%lld ", M->id);
}
print_date (M->date);
printf (" ");
push_color (COLOR_CYAN);
printf (" %s", P->print_name);
pop_color ();
if (M->unread) {
printf (" <<< ");
} else {
printf (" ««« ");
}
} else {
push_color (COLOR_BLUE);
if (msg_num_mode) {
printf ("%lld ", M->id);
}
print_date (M->date);
push_color (COLOR_CYAN);
printf (" %s", P->print_name);
pop_color ();
if (M->unread) {
printf (" >>> ");
} else {
printf (" »»» ");
}
}
} else { } else {
assert (get_peer_type (M->to_id) == PEER_CHAT);
push_color (COLOR_MAGENTA); push_color (COLOR_MAGENTA);
if (msg_num_mode) { if (msg_num_mode) {
printf ("%lld ", M->id); printf ("%lld ", M->id);
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define COLOR_YELLOW "\033[33;1m" #define COLOR_YELLOW "\033[33;1m"
#define COLOR_BLUE "\033[34;1m" #define COLOR_BLUE "\033[34;1m"
#define COLOR_MAGENTA "\033[35;1m" #define COLOR_MAGENTA "\033[35;1m"
#define COLOR_CYAN "\033[36;1m"
char *get_default_prompt (void); char *get_default_prompt (void);
char *complete_none (const char *text, int state); char *complete_none (const char *text, int state);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "mtproto-common.h" #include "mtproto-common.h"
#include "queries.h" #include "queries.h"
#include "telegram.h" #include "telegram.h"
#include "loop.h"
extern char *default_username; extern char *default_username;
extern char *auth_token; extern char *auth_token;
...@@ -59,6 +60,7 @@ void net_loop (int flags, int (*is_end)(void)) { ...@@ -59,6 +60,7 @@ void net_loop (int flags, int (*is_end)(void)) {
cc ++; cc ++;
} }
write_state_file ();
int x = connections_make_poll_array (fds + cc, 101 - cc) + cc; int x = connections_make_poll_array (fds + cc, 101 - cc) + cc;
double timer = next_timer_in (); double timer = next_timer_in ();
if (timer > 1000) { timer = 1000; } if (timer > 1000) { timer = 1000; }
...@@ -116,6 +118,8 @@ struct dc *DC_working; ...@@ -116,6 +118,8 @@ struct dc *DC_working;
int dc_working_num; int dc_working_num;
int auth_state; int auth_state;
char *get_auth_key_filename (void); char *get_auth_key_filename (void);
char *get_state_filename (void);
char *get_secret_chat_filename (void);
int zero[512]; int zero[512];
...@@ -231,11 +235,157 @@ void read_auth_file (void) { ...@@ -231,11 +235,157 @@ void read_auth_file (void) {
} }
} }
int pts, qts, seq, last_date;
void read_state_file (void) {
int state_file_fd = open (get_state_filename (), O_CREAT | O_RDWR, 0600);
if (state_file_fd < 0) {
return;
}
int version, magic;
if (read (state_file_fd, &magic, 4) < 4) { close (state_file_fd); return; }
if (magic != (int)STATE_FILE_MAGIC) { close (state_file_fd); return; }
if (read (state_file_fd, &version, 4) < 4) { close (state_file_fd); return; }
assert (version >= 0);
int x[4];
if (read (state_file_fd, x, 16) < 16) {
close (state_file_fd);
return;
}
pts = x[0];
qts = x[1];
seq = x[2];
last_date = x[3];
close (state_file_fd);
}
void write_state_file (void) {
static int wseq;
static int wpts;
static int wqts;
static int wdate;
if (wseq >= seq && wpts >= pts && wqts >= qts && wdate >= last_date) { return; }
int state_file_fd = open (get_state_filename (), O_CREAT | O_RDWR, 0600);
if (state_file_fd < 0) {
return;
}
int x[6];
x[0] = STATE_FILE_MAGIC;
x[1] = 0;
x[2] = pts;
x[3] = qts;
x[4] = seq;
x[5] = last_date;
assert (write (state_file_fd, x, 24) == 24);
close (state_file_fd);
wseq = seq; wpts = pts; wqts = qts; wdate = last_date;
}
extern peer_t *Peers[];
extern int peer_num;
void read_secret_chat_file (void) {
int fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
if (fd < 0) {
return;
}
int x[2];
if (read (fd, x, 8) < 8) {
close (fd); return;
}
if (x[0] != (int)SECRET_CHAT_FILE_MAGIC) { close (fd); return; }
int version = x[1];
assert (version >= 0);
int cc;
assert (read (fd, &cc, 4) == 4);
int i;
for (i = 0; i < cc; i++) {
peer_t *P = malloc (sizeof (*P));
memset (P, 0, sizeof (*P));
struct secret_chat *E = &P->encr_chat;
int t;
assert (read (fd, &t, 4) == 4);
P->id = MK_ENCR_CHAT (t);
assert (read (fd, &P->flags, 4) == 4);
assert (read (fd, &t, 4) == 4);
assert (t > 0);
P->print_name = malloc (t + 1);
assert (read (fd, P->print_name, t) == t);
P->print_name[t] = 0;
assert (read (fd, &E->state, 4) == 4);
assert (read (fd, &E->user_id, 4) == 4);
assert (read (fd, &E->admin_id, 4) == 4);
assert (read (fd, &E->ttl, 4) == 4);
assert (read (fd, &E->access_hash, 8) == 8);
if (E->state != sc_waiting) {
E->g_key = malloc (256);
assert (read (fd, E->g_key, 256) == 256);
}
E->nonce = malloc (256);
assert (read (fd, E->nonce, 256) == 256);
assert (read (fd, E->key, 256) == 256);
assert (read (fd, &E->key_fingerprint, 8) == 8);
insert_encrypted_chat (P);
}
close (fd);
}
void write_secret_chat_file (void) {
int fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
if (fd < 0) {
return;
}
int x[2];
x[0] = SECRET_CHAT_FILE_MAGIC;
x[1] = 0;
assert (write (fd, x, 8) == 8);
int i;
int cc = 0;
for (i = 0; i < peer_num; i++) if (get_peer_type (Peers[i]->id) == PEER_ENCR_CHAT) {
if (Peers[i]->encr_chat.state != sc_none && Peers[i]->encr_chat.state != sc_deleted) {
cc ++;
}
}
assert (write (fd, &cc, 4) == 4);
for (i = 0; i < peer_num; i++) if (get_peer_type (Peers[i]->id) == PEER_ENCR_CHAT) {
if (Peers[i]->encr_chat.state != sc_none && Peers[i]->encr_chat.state != sc_deleted) {
int t = get_peer_id (Peers[i]->id);
assert (write (fd, &t, 4) == 4);
t = Peers[i]->flags;
assert (write (fd, &t, 4) == 4);
t = strlen (Peers[i]->print_name);
assert (write (fd, &t, 4) == 4);
assert (write (fd, Peers[i]->print_name, t) == t);
assert (write (fd, &Peers[i]->encr_chat.state, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.user_id, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.admin_id, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.ttl, 4) == 4);
assert (write (fd, &Peers[i]->encr_chat.access_hash, 8) == 8);
if (Peers[i]->encr_chat.state != sc_waiting) {
assert (write (fd, Peers[i]->encr_chat.g_key, 256) == 256);
}
assert (write (fd, Peers[i]->encr_chat.nonce, 256) == 256);
assert (write (fd, Peers[i]->encr_chat.key, 256) == 256);
assert (write (fd, &Peers[i]->encr_chat.key_fingerprint, 8) == 8);
}
}
close (fd);
}
extern int max_chat_size; extern int max_chat_size;
int mcs (void) { int mcs (void) {
return max_chat_size; return max_chat_size;
} }
extern int difference_got;
int dgot (void) {
return !difference_got;
}
int readline_active; int readline_active;
int new_dc_num; int new_dc_num;
int loop (void) { int loop (void) {
...@@ -368,7 +518,11 @@ int loop (void) { ...@@ -368,7 +518,11 @@ int loop (void) {
rl_attempted_completion_function = (CPPFunction *) complete_text; rl_attempted_completion_function = (CPPFunction *) complete_text;
rl_completion_entry_function = complete_none; rl_completion_entry_function = complete_none;
do_get_dialog_list_ex (); read_state_file ();
read_secret_chat_file ();
do_get_difference ();
net_loop (0, dgot);
do_get_dialog_list ();
return main_loop (); return main_loop ();
} }
......
...@@ -21,4 +21,6 @@ ...@@ -21,4 +21,6 @@
int loop (void); int loop (void);
void net_loop (int flags, int (*end)(void)); void net_loop (int flags, int (*end)(void));
void write_auth_file (void); void write_auth_file (void);
void write_state_file (void);
void write_secret_chat_file (void);
#endif #endif
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#define CONFIG_DIRECTORY ".telegram/" #define CONFIG_DIRECTORY ".telegram/"
#define CONFIG_FILE CONFIG_DIRECTORY "config" #define CONFIG_FILE CONFIG_DIRECTORY "config"
#define AUTH_KEY_FILE CONFIG_DIRECTORY "auth" #define AUTH_KEY_FILE CONFIG_DIRECTORY "auth"
#define STATE_FILE CONFIG_DIRECTORY "state"
#define SECRET_CHAT_FILE CONFIG_DIRECTORY "secret"
#define DOWNLOADS_DIRECTORY "downloads/" #define DOWNLOADS_DIRECTORY "downloads/"
#define CONFIG_DIRECTORY_MODE 0700 #define CONFIG_DIRECTORY_MODE 0700
...@@ -130,6 +132,24 @@ char *get_auth_key_filename (void) { ...@@ -130,6 +132,24 @@ char *get_auth_key_filename (void) {
return auth_key_filename; return auth_key_filename;
} }
char *get_state_filename (void) {
char *state_filename;
int length = strlen (get_home_directory ()) + strlen (STATE_FILE) + 2;
state_filename = (char *) calloc (length, sizeof (char));
sprintf (state_filename, "%s/" STATE_FILE, get_home_directory ());
return state_filename;
}
char *get_secret_chat_filename (void) {
char *secret_chat_filename;
int length = strlen (get_home_directory ()) + strlen (SECRET_CHAT_FILE) + 2;
secret_chat_filename = (char *) calloc (length, sizeof (char));
sprintf (secret_chat_filename, "%s/" SECRET_CHAT_FILE, get_home_directory ());
return secret_chat_filename;
}
char *get_downloads_directory (void) char *get_downloads_directory (void)
{ {
char *downloads_directory; char *downloads_directory;
......
...@@ -637,14 +637,18 @@ int unread_messages; ...@@ -637,14 +637,18 @@ int unread_messages;
int our_id; int our_id;
int pts; int pts;
int qts; int qts;
int last_date;
int seq;
void fetch_pts (void) { void fetch_pts (void) {
int p = fetch_int (); int p = fetch_int ();
if (p <= pts) { return; }
if (p != pts + 1) { if (p != pts + 1) {
if (pts) { if (pts) {
logprintf ("Hole in pts p = %d, pts = %d\n", p, pts); //logprintf ("Hole in pts p = %d, pts = %d\n", p, pts);
// get difference should be here // get difference should be here
pts = p;
} else { } else {
pts = p; pts = p;
} }
...@@ -655,10 +659,12 @@ void fetch_pts (void) { ...@@ -655,10 +659,12 @@ void fetch_pts (void) {
void fetch_qts (void) { void fetch_qts (void) {
int p = fetch_int (); int p = fetch_int ();
if (p <= qts) { return; }
if (p != qts + 1) { if (p != qts + 1) {
if (qts) { if (qts) {
logprintf ("Hole in qts\n"); //logprintf ("Hole in qts\n");
// get difference should be here // get difference should be here
qts = p;
} else { } else {
qts = p; qts = p;
} }
...@@ -667,6 +673,24 @@ void fetch_qts (void) { ...@@ -667,6 +673,24 @@ void fetch_qts (void) {
} }
} }
void fetch_date (void) {
int p = fetch_int ();
if (p > last_date) {
last_date = p;
}
}
void fetch_seq (void) {
int x = fetch_int ();
if (x > seq + 1) {
logprintf ("Hole in seq: seq = %d, x = %d\n", seq, x);
//do_get_difference ();
seq = x;
} else if (x >= seq + 1) {
seq = x;
}
}
void work_update (struct connection *c UU, long long msg_id UU) { void work_update (struct connection *c UU, long long msg_id UU) {
unsigned op = fetch_int (); unsigned op = fetch_int ();
switch (op) { switch (op) {
...@@ -993,9 +1017,11 @@ void work_update (struct connection *c UU, long long msg_id UU) { ...@@ -993,9 +1017,11 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf (" is now in deleted state\n"); printf (" is now in deleted state\n");
break; break;
} }
/*if (E->state == state_requested) { pop_color ();
print_end ();
if (E->state == sc_request) {
do_accept_encr_chat_request (E); do_accept_encr_chat_request (E);
}*/ }
fetch_int (); // date fetch_int (); // date
} }
break; break;
...@@ -1041,7 +1067,7 @@ void work_update (struct connection *c UU, long long msg_id UU) { ...@@ -1041,7 +1067,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
void work_update_short (struct connection *c, long long msg_id) { void work_update_short (struct connection *c, long long msg_id) {
assert (fetch_int () == CODE_update_short); assert (fetch_int () == CODE_update_short);
work_update (c, msg_id); work_update (c, msg_id);
fetch_int (); // date fetch_date ();
} }
void work_updates (struct connection *c, long long msg_id) { void work_updates (struct connection *c, long long msg_id) {
...@@ -1062,9 +1088,8 @@ void work_updates (struct connection *c, long long msg_id) { ...@@ -1062,9 +1088,8 @@ void work_updates (struct connection *c, long long msg_id) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
fetch_alloc_chat (); fetch_alloc_chat ();
} }
fetch_int (); // date fetch_date (); // date
fetch_int (); // seq fetch_seq (); // seq
} }
void work_update_short_message (struct connection *c UU, long long msg_id UU) { void work_update_short_message (struct connection *c UU, long long msg_id UU) {
...@@ -1073,6 +1098,9 @@ void work_update_short_message (struct connection *c UU, long long msg_id UU) { ...@@ -1073,6 +1098,9 @@ void work_update_short_message (struct connection *c UU, long long msg_id UU) {
unread_messages ++; unread_messages ++;
print_message (M); print_message (M);
update_prompt (); update_prompt ();
if (M->date > last_date) {
last_date = M->date;
}
} }
void work_update_short_chat_message (struct connection *c UU, long long msg_id UU) { void work_update_short_chat_message (struct connection *c UU, long long msg_id UU) {
...@@ -1081,6 +1109,9 @@ void work_update_short_chat_message (struct connection *c UU, long long msg_id U ...@@ -1081,6 +1109,9 @@ void work_update_short_chat_message (struct connection *c UU, long long msg_id U
unread_messages ++; unread_messages ++;
print_message (M); print_message (M);
update_prompt (); update_prompt ();
if (M->date > last_date) {
last_date = M->date;
}
} }
void work_container (struct connection *c, long long msg_id UU) { void work_container (struct connection *c, long long msg_id UU) {
...@@ -1211,6 +1242,10 @@ void work_detained_info (struct connection *c UU, long long msg_id UU) { ...@@ -1211,6 +1242,10 @@ void work_detained_info (struct connection *c UU, long long msg_id UU) {
fetch_int (); // status fetch_int (); // status
} }
void work_updates_to_long (struct connection *c UU, long long msg_id UU) {
assert (fetch_int () == (int)CODE_updates_too_long);
do_get_difference ();
}
void rpc_execute_answer (struct connection *c, long long msg_id UU) { void rpc_execute_answer (struct connection *c, long long msg_id UU) {
if (verbosity >= 5) { if (verbosity >= 5) {
logprintf ("rpc_execute_answer: fd=%d\n", c->fd); logprintf ("rpc_execute_answer: fd=%d\n", c->fd);
...@@ -1254,6 +1289,9 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) { ...@@ -1254,6 +1289,9 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
case CODE_msg_detained_info: case CODE_msg_detained_info:
work_detained_info (c, msg_id); work_detained_info (c, msg_id);
return; return;
case CODE_updates_too_long:
work_updates_to_long (c, msg_id);
return;
} }
logprintf ( "Unknown message: \n"); logprintf ( "Unknown message: \n");
hexdump_in (); hexdump_in ();
......
...@@ -23,4 +23,5 @@ ...@@ -23,4 +23,5 @@
void on_start (void); void on_start (void);
long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful); long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful);
void dc_authorize (struct dc *DC); void dc_authorize (struct dc *DC);
void work_update (struct connection *c, long long msg_id);
#endif #endif
...@@ -37,6 +37,9 @@ ...@@ -37,6 +37,9 @@
#include "mtproto-common.h" #include "mtproto-common.h"
#include "interface.h" #include "interface.h"
int __packet_buffer[PACKET_BUFFER_SIZE], *packet_ptr;
int *packet_buffer = __packet_buffer + 16;
long long rsa_encrypted_chunks, rsa_decrypted_chunks; long long rsa_encrypted_chunks, rsa_decrypted_chunks;
BN_CTX *BN_ctx; BN_CTX *BN_ctx;
......
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
#define MAX_MESSAGE_INTS 1048576 #define MAX_MESSAGE_INTS 1048576
#define MAX_PROTO_MESSAGE_INTS 1048576 #define MAX_PROTO_MESSAGE_INTS 1048576
#define PACKET_BUFFER_SIZE (16384 * 100 + 16) // temp fix
#pragma pack(push,4) #pragma pack(push,4)
struct encrypted_message { struct encrypted_message {
// unencrypted header // unencrypted header
...@@ -219,8 +220,8 @@ void prng_seed (const char *password_filename, int password_length); ...@@ -219,8 +220,8 @@ void prng_seed (const char *password_filename, int password_length);
int serialize_bignum (BIGNUM *b, char *buffer, int maxlen); int serialize_bignum (BIGNUM *b, char *buffer, int maxlen);
long long compute_rsa_key_fingerprint (RSA *key); long long compute_rsa_key_fingerprint (RSA *key);
#define PACKET_BUFFER_SIZE (16384 * 100) // temp fix extern int *packet_buffer;
int packet_buffer[PACKET_BUFFER_SIZE], *packet_ptr; extern int *packet_ptr;
static inline void out_ints (int *what, int len) { static inline void out_ints (int *what, int len) {
assert (packet_ptr + len <= packet_buffer + PACKET_BUFFER_SIZE); assert (packet_ptr + len <= packet_buffer + PACKET_BUFFER_SIZE);
...@@ -262,6 +263,9 @@ static inline void out_bignum (BIGNUM *n) { ...@@ -262,6 +263,9 @@ static inline void out_bignum (BIGNUM *n) {
extern int *in_ptr, *in_end; extern int *in_ptr, *in_end;
void fetch_pts (void); void fetch_pts (void);
void fetch_qts (void);
void fetch_date (void);
void fetch_seq (void);
static inline int prefetch_strlen (void) { static inline int prefetch_strlen (void) {
if (in_ptr >= in_end) { if (in_ptr >= in_end) {
return -1; return -1;
......
...@@ -26,7 +26,7 @@ struct dc; ...@@ -26,7 +26,7 @@ struct dc;
//#define TG_SERVER "95.142.192.66" //#define TG_SERVER "95.142.192.66"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74" #define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899 #define TG_APP_ID 2899
#define TG_BUILD "200" #define TG_BUILD "203"
#define TG_VERSION "0.01-beta" #define TG_VERSION "0.01-beta"
...@@ -79,6 +79,9 @@ struct dc { ...@@ -79,6 +79,9 @@ struct dc {
#define DC_SERIALIZED_MAGIC 0x64582faa #define DC_SERIALIZED_MAGIC 0x64582faa
#define DC_SERIALIZED_MAGIC_V2 0x94032abb #define DC_SERIALIZED_MAGIC_V2 0x94032abb
#define STATE_FILE_MAGIC 0x84217a0d
#define SECRET_CHAT_FILE_MAGIC 0xa9840add
struct dc_serialized { struct dc_serialized {
int magic; int magic;
int port; int port;
......
This diff is collapsed.
...@@ -94,5 +94,8 @@ void do_import_auth (int num); ...@@ -94,5 +94,8 @@ void do_import_auth (int num);
void do_export_auth (int num); void do_export_auth (int num);
void 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 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 do_msg_search (peer_id_t id, int from, int to, int limit, const char *s); void do_msg_search (peer_id_t id, int from, int to, int limit, const char *s);
void do_accept_encr_chat_request (struct secret_chat *E);
void do_get_difference (void);
void do_mark_read (peer_id_t id);
#endif #endif
This diff is collapsed.
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#define __STRUCTURES_H__ #define __STRUCTURES_H__
#include <assert.h> #include <assert.h>
typedef struct { int id; } peer_id_t; typedef struct { int type; int id; } peer_id_t;
#define FLAG_EMPTY 1 #define FLAG_EMPTY 1
#define FLAG_DELETED 2 #define FLAG_DELETED 2
...@@ -111,6 +111,7 @@ struct user_status { ...@@ -111,6 +111,7 @@ struct user_status {
struct user { struct user {
peer_id_t id; peer_id_t id;
int flags; int flags;
struct message *last;
char *print_name; char *print_name;
struct file_location photo_big; struct file_location photo_big;
struct file_location photo_small; struct file_location photo_small;
...@@ -134,6 +135,7 @@ struct chat_user { ...@@ -134,6 +135,7 @@ struct chat_user {
struct chat { struct chat {
peer_id_t id; peer_id_t id;
int flags; int flags;
struct message *last;
char *print_title; char *print_title;
struct file_location photo_big; struct file_location photo_big;
struct file_location photo_small; struct file_location photo_small;
...@@ -157,6 +159,7 @@ enum secret_chat_state { ...@@ -157,6 +159,7 @@ enum secret_chat_state {
struct secret_chat { struct secret_chat {
peer_id_t id; peer_id_t id;
int flags; int flags;
struct message *last;
char *print_name; char *print_name;
struct file_location photo_big; struct file_location photo_big;
struct file_location photo_small; struct file_location photo_small;
...@@ -178,6 +181,7 @@ typedef union peer { ...@@ -178,6 +181,7 @@ typedef union peer {
struct { struct {
peer_id_t id; peer_id_t id;
int flags; int flags;
struct message *last;
char *print_name; char *print_name;
struct file_location photo_big; struct file_location photo_big;
struct file_location photo_small; struct file_location photo_small;
...@@ -237,6 +241,7 @@ struct message_media { ...@@ -237,6 +241,7 @@ struct message_media {
struct message { struct message {
struct message *next_use, *prev_use; struct message *next_use, *prev_use;
struct message *next, *prev;
long long id; long long id;
int flags; int flags;
peer_id_t fwd_from_id; peer_id_t fwd_from_id;
...@@ -283,6 +288,7 @@ void update_message_id (struct message *M, long long id); ...@@ -283,6 +288,7 @@ void update_message_id (struct message *M, long long id);
void message_insert (struct message *M); void message_insert (struct message *M);
void free_photo (struct photo *P); void free_photo (struct photo *P);
void fetch_photo (struct photo *P); void fetch_photo (struct photo *P);
void insert_encrypted_chat (peer_t *P);
#define PEER_USER 1 #define PEER_USER 1
#define PEER_CHAT 2 #define PEER_CHAT 2
...@@ -296,55 +302,18 @@ void fetch_photo (struct photo *P); ...@@ -296,55 +302,18 @@ void fetch_photo (struct photo *P);
#define MK_ENCR_CHAT(id) set_peer_id (PEER_ENCR_CHAT,id) #define MK_ENCR_CHAT(id) set_peer_id (PEER_ENCR_CHAT,id)
static inline int get_peer_type (peer_id_t id) { static inline int get_peer_type (peer_id_t id) {
if (id.id > 1000000000) { return id.type;
return PEER_ENCR_CHAT;
}
if (id.id > 0) {
return PEER_USER;
}
if (id.id < -1000000000) {
return PEER_GEO_CHAT;
}
if (id.id < 0) {
return PEER_CHAT;
}
return PEER_UNKNOWN;
} }
static inline int get_peer_id (peer_id_t id) { static inline int get_peer_id (peer_id_t id) {
switch (get_peer_type (id)) {
case PEER_USER:
return id.id; return id.id;
case PEER_CHAT:
return -id.id;
case PEER_GEO_CHAT:
return -id.id - 1000000000;
case PEER_ENCR_CHAT:
return id.id - 1000000000;
default:
return 0;
}
} }
static inline peer_id_t set_peer_id (int type, int id) { static inline peer_id_t set_peer_id (int type, int id) {
peer_id_t ID; peer_id_t ID;
switch (type) {
case PEER_USER:
ID.id = id; ID.id = id;
ID.type = type;
return ID; return ID;
case PEER_CHAT:
ID.id = -id;
return ID;
case PEER_GEO_CHAT:
ID.id = -id - 1000000000;
return ID;
case PEER_ENCR_CHAT:
ID.id = id + 1000000000;
return ID;
default:
assert (0);
return ID;
}
} }
static inline int cmp_peer_id (peer_id_t a, peer_id_t b) { static inline int cmp_peer_id (peer_id_t a, peer_id_t b) {
......
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