Manty fixes. Mostly binlog for messages

This commit is contained in:
Vysheng 2013-11-30 01:43:56 +04:00
parent d095e607c2
commit 725c6669a7
11 changed files with 1040 additions and 237 deletions

466
binlog.c
View File

@ -38,6 +38,7 @@ extern int binlog_enabled;
extern int encr_root;
extern unsigned char *encr_prime;
extern int encr_param_version;
extern int messages_allocated;
int in_replay_log;
@ -53,11 +54,12 @@ 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);
}
in_ptr = rptr;
in_end = wptr;
if (verbosity >= 2) {
logprintf ("event = 0x%08x. pos = %lld\n", op, binlog_pos);
}
switch (op) {
case LOG_START:
rptr ++;
@ -703,6 +705,319 @@ void replay_log_event (void) {
C->user_list_version = version;
}
break;
case CODE_binlog_create_message_text:
case CODE_binlog_send_message_text:
in_ptr ++;
{
long long id;
if (op == CODE_binlog_create_message_text) {
id = fetch_int ();
} else {
id = fetch_long ();
}
struct message *M = message_get (id);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
M->flags |= FLAG_CREATED;
M->from_id = MK_USER (fetch_int ());
int t = fetch_int ();
if (t == PEER_ENCR_CHAT) {
M->flags |= FLAG_ENCRYPTED;
}
M->to_id = set_peer_id (t, fetch_int ());
M->date = fetch_int ();
int l = prefetch_strlen ();
M->message = malloc (l + 1);
memcpy (M->message, fetch_str (l), l);
M->message[l] = 0;
M->message_len = l;
if (t == PEER_ENCR_CHAT) {
M->media.type = CODE_decrypted_message_media_empty;
} else {
M->media.type = CODE_message_media_empty;
}
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
message_insert (M);
if (op == CODE_binlog_send_message_text) {
message_insert_unsent (M);
M->flags |= FLAG_PENDING;
}
}
rptr = in_ptr;
break;
case CODE_binlog_create_message_text_fwd:
in_ptr ++;
{
int id = fetch_int ();
struct message *M = message_get (id);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
M->flags |= FLAG_CREATED;
M->from_id = MK_USER (fetch_int ());
int t = fetch_int ();
M->to_id = set_peer_id (t, fetch_int ());
M->date = fetch_int ();
M->fwd_from_id = MK_USER (fetch_int ());
M->fwd_date = fetch_int ();
int l = prefetch_strlen ();
M->message = malloc (l + 1);
memcpy (M->message, fetch_str (l), l);
M->message[l] = 0;
M->message_len = l;
M->media.type = CODE_message_media_empty;
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
message_insert (M);
}
rptr = in_ptr;
break;
case CODE_binlog_create_message_media:
in_ptr ++;
{
int id = fetch_int ();
struct message *M = message_get (id);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
M->flags |= FLAG_CREATED;
M->from_id = MK_USER (fetch_int ());
int t = fetch_int ();
M->to_id = set_peer_id (t, fetch_int ());
M->date = fetch_int ();
int l = prefetch_strlen ();
M->message = malloc (l + 1);
memcpy (M->message, fetch_str (l), l);
M->message[l] = 0;
M->message_len = l;
fetch_message_media (&M->media);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
message_insert (M);
}
rptr = in_ptr;
break;
case CODE_binlog_create_message_media_encr:
in_ptr ++;
{
long long id = fetch_long ();
struct message *M = message_get (id);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
M->flags |= FLAG_CREATED | FLAG_ENCRYPTED;
M->from_id = MK_USER (fetch_int ());
int t = fetch_int ();
M->to_id = set_peer_id (t, fetch_int ());
M->date = fetch_int ();
int l = prefetch_strlen ();
M->message = malloc (l + 1);
memcpy (M->message, fetch_str (l), l);
M->message[l] = 0;
M->message_len = l;
fetch_message_media_encrypted (&M->media);
fetch_encrypted_message_file (&M->media);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
message_insert (M);
}
rptr = in_ptr;
break;
case CODE_binlog_create_message_media_fwd:
in_ptr ++;
{
int id = fetch_int ();
struct message *M = message_get (id);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
M->flags |= FLAG_CREATED;
M->from_id = MK_USER (fetch_int ());
int t = fetch_int ();
M->to_id = set_peer_id (t, fetch_int ());
M->date = fetch_int ();
M->fwd_from_id = MK_USER (fetch_int ());
M->fwd_date = fetch_int ();
int l = prefetch_strlen ();
M->message = malloc (l + 1);
memcpy (M->message, fetch_str (l), l);
M->message[l] = 0;
M->message_len = l;
fetch_message_media (&M->media);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
message_insert (M);
}
rptr = in_ptr;
break;
case CODE_binlog_create_message_service:
in_ptr ++;
{
int id = fetch_int ();
struct message *M = message_get (id);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
M->flags |= FLAG_CREATED;
M->from_id = MK_USER (fetch_int ());
int t = fetch_int ();
M->to_id = set_peer_id (t, fetch_int ());
M->date = fetch_int ();
fetch_message_action (&M->action);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->service = 1;
message_insert (M);
}
rptr = in_ptr;
break;
case CODE_binlog_create_message_service_encr:
in_ptr ++;
{
long long id = fetch_long ();
struct message *M = message_get (id);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
M->flags |= FLAG_CREATED | FLAG_ENCRYPTED;
M->from_id = MK_USER (fetch_int ());
int t = fetch_int ();
M->to_id = set_peer_id (t, fetch_int ());
M->date = fetch_int ();
fetch_message_action_encrypted (&M->action);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->service = 1;
message_insert (M);
}
rptr = in_ptr;
break;
case CODE_binlog_create_message_service_fwd:
in_ptr ++;
{
int id = fetch_int ();
struct message *M = message_get (id);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = id;
message_insert_tree (M);
messages_allocated ++;
} else {
assert (!(M->flags & FLAG_CREATED));
}
M->flags |= FLAG_CREATED;
M->from_id = MK_USER (fetch_int ());
int t = fetch_int ();
M->to_id = set_peer_id (t, fetch_int ());
M->date = fetch_int ();
M->fwd_from_id = MK_USER (fetch_int ());
M->fwd_date = fetch_int ();
fetch_message_action (&M->action);
M->unread = 1;
M->out = get_peer_id (M->from_id) == our_id;
M->service = 1;
message_insert (M);
}
rptr = in_ptr;
break;
case CODE_binlog_set_unread:
rptr ++;
{
struct message *M = message_get (*(rptr ++));
assert (M);
M->unread = 0;
}
break;
case CODE_binlog_set_message_sent:
rptr ++;
{
struct message *M = message_get (*(long long *)rptr);
rptr += 2;
assert (M);
message_remove_unsent (M);
M->flags &= ~FLAG_PENDING;
}
break;
case CODE_binlog_set_msg_id:
rptr ++;
{
struct message *M = message_get (*(long long *)rptr);
rptr += 2;
assert (M);
message_remove_tree (M);
message_del_peer (M);
M->id = *(rptr ++);
message_insert_tree (M);
message_add_peer (M);
}
break;
case CODE_update_user_photo:
case CODE_update_user_name:
work_update_binlog ();
@ -807,6 +1122,7 @@ void add_log_event (const int *data, int len) {
assert (rptr == wptr);
}
if (binlog_enabled) {
assert (binlog_fd > 0);
assert (write (binlog_fd, data, len) == len);
}
in_ptr = in;
@ -1009,6 +1325,7 @@ void bl_do_encr_chat_delete (struct secret_chat *U) {
}
void bl_do_encr_chat_requested (struct secret_chat *U, long long access_hash, int date, int admin_id, int user_id, unsigned char g_key[], unsigned char nonce[]) {
if (U->state != sc_none) { return; }
int *ev = alloc_log_event (540);
ev[0] = CODE_binlog_encr_chat_requested;
ev[1] = get_peer_id (U->id);
@ -1258,3 +1575,146 @@ void bl_do_chat_del_user (struct chat *C, int version, int user) {
ev[3] = user;
add_log_event (ev, 16);
}
void bl_do_create_message_text (int msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s) {
clear_packet ();
out_int (CODE_binlog_create_message_text);
out_int (msg_id);
out_int (from_id);
out_int (to_type);
out_int (to_id);
out_int (date);
out_cstring (s, l);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_send_message_text (long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s) {
clear_packet ();
out_int (CODE_binlog_send_message_text);
out_long (msg_id);
out_int (from_id);
out_int (to_type);
out_int (to_id);
out_int (date);
out_cstring (s, l);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_create_message_text_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int l, const char *s) {
clear_packet ();
out_int (CODE_binlog_create_message_text_fwd);
out_int (msg_id);
out_int (from_id);
out_int (to_type);
out_int (to_id);
out_int (date);
out_int (fwd);
out_int (fwd_date);
out_cstring (s, l);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_create_message_media (int msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len) {
clear_packet ();
out_int (CODE_binlog_create_message_media);
out_int (msg_id);
out_int (from_id);
out_int (to_type);
out_int (to_id);
out_int (date);
out_cstring (s, l);
out_ints (data, len);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_create_message_media_encr (long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len, const int *data2, int len2) {
clear_packet ();
out_int (CODE_binlog_create_message_media_encr);
out_long (msg_id);
out_int (from_id);
out_int (to_type);
out_int (to_id);
out_int (date);
out_cstring (s, l);
out_ints (data, len);
out_ints (data2, len2);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_create_message_media_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int l, const char *s, const int *data, int len) {
clear_packet ();
out_int (CODE_binlog_create_message_media_fwd);
out_int (msg_id);
out_int (from_id);
out_int (to_type);
out_int (to_id);
out_int (date);
out_int (fwd);
out_int (fwd_date);
out_cstring (s, l);
out_ints (data, len);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_create_message_service (int msg_id, int from_id, int to_type, int to_id, int date, const int *data, int len) {
clear_packet ();
out_int (CODE_binlog_create_message_service);
out_int (msg_id);
out_int (from_id);
out_int (to_type);
out_int (to_id);
out_int (date);
out_ints (data, len);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_create_message_service_encr (long long msg_id, int from_id, int to_type, int to_id, int date, const int *data, int len) {
clear_packet ();
out_int (CODE_binlog_create_message_service_encr);
out_long (msg_id);
out_int (from_id);
out_int (to_type);
out_int (to_id);
out_int (date);
out_ints (data, len);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_create_message_service_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, const int *data, int len) {
clear_packet ();
out_int (CODE_binlog_create_message_service_fwd);
out_int (msg_id);
out_int (from_id);
out_int (to_type);
out_int (to_id);
out_int (date);
out_int (fwd);
out_int (fwd_date);
out_ints (data, len);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_set_unread (struct message *M, int unread) {
if (unread || !M->unread) { return; }
clear_packet ();
out_int (CODE_binlog_set_unread);
out_int (M->id);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_set_message_sent (struct message *M) {
if (!(M->flags & FLAG_PENDING)) { return; }
clear_packet ();
out_int (CODE_binlog_set_message_sent);
out_long (M->id);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_set_msg_id (struct message *M, int id) {
if (M->id == id) { return; }
clear_packet ();
out_int (CODE_binlog_set_msg_id);
out_long (M->id);
out_int (id);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}

View File

@ -51,6 +51,18 @@
#define CODE_binlog_chat_full_photo 0x6cca6629
#define CODE_binlog_add_chat_participant 0x63345108
#define CODE_binlog_del_chat_participant 0x82d1f0ee
#define CODE_binlog_create_message_text 0x269acd5b
#define CODE_binlog_create_message_text_fwd 0xa3d864cd
#define CODE_binlog_create_message_service 0xbbe5e94b
#define CODE_binlog_create_message_service_fwd 0xea9c57ae
#define CODE_binlog_create_message_media 0x62a92d19
#define CODE_binlog_create_message_media_fwd 0xbefdc462
#define CODE_binlog_send_message_text 0x31cfd652
#define CODE_binlog_set_unread 0x21d4c909
#define CODE_binlog_set_message_sent 0xc335282b
#define CODE_binlog_set_msg_id 0xf3285b6a
#define CODE_binlog_create_message_media_encr 0x19cd7c9d
#define CODE_binlog_create_message_service_encr 0x8b4b9395
void *alloc_log_event (int l);
void replay_log (void);
@ -102,4 +114,17 @@ void bl_do_set_chat_participants (struct chat *C, int version, int user_num, str
void bl_do_set_chat_full_photo (struct chat *U, const int *start, int len);
void bl_do_chat_add_user (struct chat *C, int version, int user, int inviter, int date);
void bl_do_chat_del_user (struct chat *C, int version, int user);
void bl_do_create_message_text (int msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s);
void bl_do_create_message_text_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int l, const char *s);
void bl_do_create_message_service (int msg_id, int from_id, int to_type, int to_id, int date, const int *data, int len);
void bl_do_create_message_service_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, const int *data, int len);
void bl_do_create_message_media (int msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len);
void bl_do_create_message_media_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int l, const char *s, const int *data, int len);
void bl_do_create_message_media_encr (long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len, const int *data2, int len2);
void bl_do_create_message_service_encr (long long msg_id, int from_id, int to_type, int to_id, int date, const int *data, int len);
void bl_do_send_message_text (long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s);
void bl_do_set_unread (struct message *M, int unread);
void bl_do_set_message_sent (struct message *M);
void bl_do_set_msg_id (struct message *M, int id);
#endif

View File

@ -43,7 +43,7 @@
#include "mtproto-common.h"
//#define ALLOW_MULT 1
#define ALLOW_MULT 1
char *default_prompt = "> ";
int unread_messages;
@ -1096,6 +1096,7 @@ void pop_color (void) {
void print_media (struct message_media *M) {
switch (M->type) {
case CODE_message_media_empty:
case CODE_decrypted_message_media_empty:
return;
case CODE_message_media_photo:
if (M->photo.caption && strlen (M->photo.caption)) {

5
loop.c
View File

@ -436,7 +436,10 @@ int new_dc_num;
int loop (void) {
on_start ();
if (binlog_enabled) {
double t = get_double_time ();
logprintf ("replay log start\n");
replay_log ();
logprintf ("replay log end in %lf seconds\n", get_double_time () - t);
write_binlog ();
} else {
read_auth_file ();
@ -571,6 +574,8 @@ int loop (void) {
do_get_difference ();
net_loop (0, dgot);
send_all_unsent ();
do_get_dialog_list ();
return main_loop ();

View File

@ -789,7 +789,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
int new = fetch_long (); // random_id
struct message *M = message_get (new);
if (M) {
update_message_id (M, id);
bl_do_set_msg_id (M, id);
}
}
break;
@ -802,7 +802,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
int id = fetch_int ();
struct message *M = message_get (id);
if (M) {
M->unread = 0;
bl_do_set_unread (M, 0);
}
}
fetch_pts ();
@ -885,7 +885,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
int l2 = prefetch_strlen ();
char *l = fetch_str (l2);
struct user *U = &UC->user;
bl_do_set_user_name (U, f, l1, l, l2);
bl_do_set_user_real_name (U, f, l1, l, l2);
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));

View File

@ -226,7 +226,7 @@ long long compute_rsa_key_fingerprint (RSA *key);
extern int *packet_buffer;
extern int *packet_ptr;
static inline void out_ints (int *what, int len) {
static inline void out_ints (const int *what, int len) {
assert (packet_ptr + len <= packet_buffer + PACKET_BUFFER_SIZE);
memcpy (packet_ptr, what, len * 4);
packet_ptr += len;

141
queries.c
View File

@ -779,8 +779,9 @@ int msg_send_encr_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_messages_sent_encrypted_message);
rprintf ("Sent\n");
struct message *M = q->extra;
M->date = fetch_int ();
message_insert (M);
//M->date = fetch_int ();
fetch_int ();
bl_do_set_message_sent (M);
return 0;
}
@ -788,12 +789,11 @@ 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
struct message *M = q->extra;
bl_do_set_msg_id (M, id);
fetch_date ();
fetch_pts ();
fetch_seq ();
struct message *M = q->extra;
M->id = id;
message_insert (M);
if (x == CODE_messages_sent_message_link) {
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
@ -834,6 +834,7 @@ int msg_send_on_answer (struct query *q UU) {
}
}
rprintf ("Sent: id = %d\n", id);
bl_do_set_message_sent (M);
return 0;
}
@ -848,7 +849,47 @@ struct query_methods msg_send_encr_methods = {
int out_message_num;
int our_id;
void do_send_encr_message (peer_id_t id, const char *msg, int len) {
void do_send_encr_msg (struct message *M) {
peer_t *P = user_chat_get (M->to_id);
if (!P || P->encr_chat.state != sc_ok) { return; }
clear_packet ();
out_int (CODE_messages_send_encrypted);
out_int (CODE_input_encrypted_chat);
out_int (get_peer_id (M->to_id));
out_long (P->encr_chat.access_hash);
out_long (M->id);
encr_start ();
out_int (CODE_decrypted_message);
out_long (M->id);
static int buf[4];
int i;
for (i = 0; i < 3; i++) {
buf[i] = mrand48 ();
}
out_cstring ((void *)buf, 16);
out_cstring ((void *)M->message, M->message_len);
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);
}
void do_send_msg (struct message *M) {
if (get_peer_type (M->to_id) == PEER_ENCR_CHAT) {
do_send_encr_msg (M);
return;
}
clear_packet ();
out_int (CODE_messages_send_message);
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);
}
void do_send_message (peer_id_t id, const char *msg, int len) {
if (get_peer_type (id) == PEER_ENCR_CHAT) {
peer_t *P = user_chat_get (id);
if (!P) {
logprintf ("Can not send to unknown encrypted chat\n");
@ -858,76 +899,12 @@ void do_send_encr_message (peer_id_t id, const char *msg, int len) {
logprintf ("Chat is not yet initialized\n");
return;
}
clear_packet ();
out_int (CODE_messages_send_encrypted);
out_int (CODE_input_encrypted_chat);
out_int (get_peer_id (id));
out_long (P->encr_chat.access_hash);
if (!out_message_num) {
out_message_num = -lrand48 ();
}
out_long ((--out_message_num) - (4ll << 32));
encr_start ();
//out_int (CODE_decrypted_message_layer);
//out_int (8);
out_int (CODE_decrypted_message);
out_long ((out_message_num) - (4ll << 32));
static int buf[4];
int i;
for (i = 0; i < 3; i++) {
buf[i] = mrand48 ();
}
out_cstring ((void *)buf, 16);
out_cstring ((void *)msg, len);
out_int (CODE_decrypted_message_media_empty);
encr_finish (&P->encr_chat);
struct message *M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->flags = FLAG_ENCRYPTED;
M->from_id = MK_USER (our_id);
M->to_id = id;
M->unread = 1;
M->message = malloc (len + 1);
memcpy (M->message, msg, len);
M->message[len] = 0;
M->message_len = len;
M->out = 1;
M->media.type = CODE_message_media_empty;
M->id = (out_message_num) - (4ll << 32);
M->date = time (0);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_encr_methods, M);
print_message (M);
}
void do_send_message (peer_id_t id, const char *msg, int len) {
if (get_peer_type (id) == PEER_ENCR_CHAT) {
do_send_encr_message (id, msg, len);
return;
}
if (!out_message_num) {
out_message_num = -lrand48 ();
}
clear_packet ();
out_int (CODE_messages_send_message);
struct message *M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->from_id = MK_USER (our_id);
M->to_id = id;
M->unread = 1;
out_peer_id (id);
M->message = malloc (len + 1);
memcpy (M->message, msg, len);
M->message[len] = 0;
M->message_len = len;
M->out = 1;
M->media.type = CODE_message_media_empty;
M->id = out_message_num;
M->date = time (0);
out_cstring (msg, len);
out_long ((--out_message_num) - (1ll << 32));
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_methods, M);
long long t = -lrand48 () * (1ll << 32) - lrand48 ();
bl_do_send_message_text (t, our_id, get_peer_type (id), get_peer_id (id), time (0), len, msg);
struct message *M = message_get (t);
assert (M);
do_send_msg (M);
print_message (M);
}
/* }}} */
@ -1070,6 +1047,7 @@ void do_get_local_history (peer_id_t id, int limit) {
if (!P || !P->last) { return; }
struct message *M = P->last;
int count = 1;
assert (!M->prev);
while (count < limit && M->next) {
M = M->next;
count ++;
@ -2296,6 +2274,9 @@ void do_create_keys_end (struct secret_chat *U) {
BN_init (r);
BN_mod_exp (r, g_b, a, p, ctx);
void *t = malloc (256);
memcpy (t, U->key, 256);
memset (U->key, 0, sizeof (U->key));
BN_bn2bin (r, (void *)U->key);
int i;
@ -2306,7 +2287,15 @@ void do_create_keys_end (struct secret_chat *U) {
static unsigned char sha_buffer[20];
sha1 ((void *)U->key, 256, sha_buffer);
long long k = *(long long *)(sha_buffer + 12);
assert (k == U->key_fingerprint);
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));
logprintf ("!!Key fingerprint mismatch\n");
U->state = sc_deleted;
}
BN_clear_free (p);
BN_clear_free (g_b);

View File

@ -107,6 +107,7 @@ void do_add_user_to_chat (peer_id_t chat_id, peer_id_t id, int limit);
void do_del_user_from_chat (peer_id_t chat_id, peer_id_t id);
void do_update_status (int online);
void do_contacts_search (int limit, const char *s);
void do_send_msg (struct message *M);
// For binlog

View File

@ -47,6 +47,7 @@ struct message message_list = {
struct tree_peer *peer_tree;
struct tree_message *message_tree;
struct tree_message *message_unsent_tree;
int users_allocated;
int chats_allocated;
@ -121,6 +122,7 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha
const char *d[4];
d[0] = a1; d[1] = a2; d[2] = a3; d[3] = a4;
static char buf[10000];
buf[0] = 0;
int i;
int p = 0;
for (i = 0; i < 4; i++) {
@ -141,6 +143,7 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha
int ok = 1;
int i;
for (i = 0; i < peer_num; i++) {
assert (Peers[i]);
if (cmp_peer_id (Peers[i]->id, id) && Peers[i]->print_name && !strcmp (Peers[i]->print_name, s)) {
ok = 0;
break;
@ -151,24 +154,7 @@ char *create_print_name (peer_id_t id, const char *a1, const char *a2, const cha
}
cc ++;
assert (cc <= 9999);
if (cc == 1) {
int l = strlen (s);
s[l + 2] = 0;
s[l] = '#';
s[l + 1] = '1';
} else if (cc == 10 || cc == 100 || cc == 1000) {
// int l = strlen (s);
sprintf (s + fl, "#%d", cc);
} else {
int l = strlen (s);
s[l - 1] ++;
int cc = l - 1;
while (s[cc] > '9') {
s[cc] = '0';
s[cc - 1] ++;
cc --;
}
}
}
return strdup (s);
}
@ -320,6 +306,7 @@ void fetch_encrypted_chat (struct secret_chat *U) {
int l = prefetch_strlen ();
char *s = fetch_str (l);
if (l != 256) { logprintf ("l = %d\n", l); }
if (l < 256) {
memcpy (g_key + 256 - l, s, l);
} else {
@ -328,6 +315,7 @@ void fetch_encrypted_chat (struct secret_chat *U) {
l = prefetch_strlen ();
s = fetch_str (l);
if (l != 256) { logprintf ("l = %d\n", l); }
if (l < 256) {
memcpy (nonce + 256 - l, s, l);
} else {
@ -369,6 +357,7 @@ void fetch_encrypted_chat (struct secret_chat *U) {
int l = prefetch_strlen ();
char *s = fetch_str (l);
if (l != 256) { logprintf ("l = %d\n", l); }
if (l < 256) {
memcpy (g_key + 256 - l, s, l);
} else {
@ -377,6 +366,7 @@ void fetch_encrypted_chat (struct secret_chat *U) {
l = prefetch_strlen ();
s = fetch_str (l);
if (l != 256) { logprintf ("l = %d\n", l); }
if (l < 256) {
memcpy (nonce + 256 - l, s, l);
} else {
@ -635,7 +625,7 @@ void fetch_skip_geo (void) {
unsigned x = fetch_int ();
assert (x == CODE_geo_point || x == CODE_geo_point_empty);
if (x == CODE_geo_point) {
in_ptr += 2;
in_ptr += 4;
}
}
@ -693,6 +683,18 @@ void fetch_video (struct video *V) {
V->h = fetch_int ();
}
void fetch_skip_video (void) {
unsigned x = fetch_int ();
fetch_long ();
if (x == CODE_video_empty) { return; }
fetch_skip (4);
int l = prefetch_strlen ();
fetch_str (l);
fetch_skip (2);
fetch_skip_photo_size ();
fetch_skip (3);
}
void fetch_audio (struct audio *V) {
memset (V, 0, sizeof (*V));
unsigned x = fetch_int ();
@ -706,6 +708,13 @@ void fetch_audio (struct audio *V) {
V->dc_id = fetch_int ();
}
void fetch_skip_audio (void) {
unsigned x = fetch_int ();
fetch_skip (2);
if (x == CODE_audio_empty) { return; }
fetch_skip (7);
}
void fetch_document (struct document *V) {
memset (V, 0, sizeof (*V));
unsigned x = fetch_int ();
@ -721,6 +730,20 @@ void fetch_document (struct document *V) {
V->dc_id = fetch_int ();
}
void fetch_skip_document (void) {
unsigned x = fetch_int ();
fetch_skip (2);
if (x == CODE_document_empty) { return; }
fetch_skip (4);
int l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
fetch_skip (1);
fetch_skip_photo_size ();
fetch_skip (1);
}
void fetch_message_action (struct message_action *M) {
memset (M, 0, sizeof (*M));
unsigned x = fetch_int ();
@ -765,30 +788,104 @@ void fetch_message_action (struct message_action *M) {
}
}
void fetch_skip_message_action (void) {
unsigned x = fetch_int ();
int l;
switch (x) {
case CODE_message_action_empty:
break;
case CODE_message_action_geo_chat_create:
{
l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
}
break;
case CODE_message_action_geo_chat_checkin:
break;
case CODE_message_action_chat_create:
l = prefetch_strlen ();
fetch_str (l);
assert (fetch_int () == (int)CODE_vector);
l = fetch_int ();
fetch_skip (l);
break;
case CODE_message_action_chat_edit_title:
l = prefetch_strlen ();
fetch_str (l);
break;
case CODE_message_action_chat_edit_photo:
fetch_skip_photo ();
break;
case CODE_message_action_chat_delete_photo:
break;
case CODE_message_action_chat_add_user:
fetch_int ();
break;
case CODE_message_action_chat_delete_user:
fetch_int ();
break;
default:
assert (0);
}
}
void fetch_message_short (struct message *M) {
memset (M, 0, sizeof (*M));
M->id = fetch_int ();
M->to_id = MK_USER (our_id);
M->from_id = MK_USER (fetch_int ());
M->message = fetch_str_dup ();
int new = !(M->flags & FLAG_CREATED);
if (new) {
int id = fetch_int ();
int from_id = fetch_int ();
int to_id = our_id;
int l = prefetch_strlen ();
char *s = fetch_str (l);
fetch_pts ();
M->date = fetch_int ();
int date = fetch_int ();
fetch_seq ();
M->media.type = CODE_message_media_empty;
M->unread = 1;
bl_do_create_message_text (id, from_id, PEER_USER, to_id, date, l, s);
} else {
fetch_int (); // id
fetch_int (); // from_id
int l = prefetch_strlen ();
fetch_str (l); // text
fetch_pts ();
fetch_int ();
fetch_seq ();
}
}
void fetch_message_short_chat (struct message *M) {
memset (M, 0, sizeof (*M));
M->id = fetch_int ();
M->from_id = MK_USER (fetch_int ());
M->to_id = MK_CHAT (fetch_int ());
M->message = fetch_str_dup ();
int new = !(M->flags & FLAG_CREATED);
if (new) {
int id = fetch_int ();
int from_id = fetch_int ();
int to_id = fetch_int ();
int l = prefetch_strlen ();
char *s = fetch_str (l);
fetch_pts ();
M->date = fetch_int ();
int date = fetch_int ();
fetch_seq ();
M->media.type = CODE_message_media_empty;
M->unread = 1;
bl_do_create_message_text (id, from_id, PEER_CHAT, to_id, date, l, s);
} else {
fetch_int (); // id
fetch_int (); // from_id
fetch_int (); // to_id
int l = prefetch_strlen ();
fetch_str (l); // text
fetch_pts ();
fetch_int ();
fetch_seq ();
}
}
@ -828,6 +925,124 @@ void fetch_message_media (struct message_media *M) {
}
}
void fetch_skip_message_media (void) {
unsigned x = fetch_int ();
switch (x) {
case CODE_message_media_empty:
break;
case CODE_message_media_photo:
fetch_skip_photo ();
break;
case CODE_message_media_video:
fetch_skip_video ();
break;
case CODE_message_media_audio:
fetch_skip_audio ();
break;
case CODE_message_media_document:
fetch_skip_document ();
break;
case CODE_message_media_geo:
fetch_skip_geo ();
break;
case CODE_message_media_contact:
{
int l;
l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
fetch_int ();
}
break;
case CODE_message_media_unsupported:
{
int l = prefetch_strlen ();
fetch_str (l);
}
break;
default:
logprintf ("type = 0x%08x\n", x);
assert (0);
}
}
void fetch_skip_message_media_encrypted (void) {
unsigned x = fetch_int ();
int l;
switch (x) {
case CODE_decrypted_message_media_empty:
break;
case CODE_decrypted_message_media_photo:
l = prefetch_strlen ();
fetch_str (l); // thumb
fetch_skip (5);
l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
break;
case CODE_decrypted_message_media_video:
l = prefetch_strlen ();
fetch_str (l); // thumb
fetch_skip (6);
l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
break;
case CODE_decrypted_message_media_audio:
fetch_skip (2);
l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
break;
case CODE_decrypted_message_media_document:
l = prefetch_strlen ();
fetch_str (l); // thumb
fetch_skip (2);
l = prefetch_strlen ();
fetch_str (l); // thumb
l = prefetch_strlen ();
fetch_str (l); // thumb
fetch_skip (1);
l = prefetch_strlen ();
fetch_str (l);
l = prefetch_strlen ();
fetch_str (l);
break;
case CODE_decrypted_message_media_geo_point:
fetch_skip (4);
break;
case CODE_decrypted_message_media_contact:
l = prefetch_strlen ();
fetch_str (l); // thumb
l = prefetch_strlen ();
fetch_str (l); // thumb
l = prefetch_strlen ();
fetch_str (l); // thumb
fetch_skip (1);
break;
default:
logprintf ("type = 0x%08x\n", x);
assert (0);
}
}
void fetch_message_media_encrypted (struct message_media *M) {
memset (M, 0, sizeof (*M));
unsigned x = fetch_int ();
@ -977,7 +1192,32 @@ void fetch_message_media_encrypted (struct message_media *M) {
M->user_id = fetch_int ();
break;
default:
logprintf ("type = 0x%08x\n", M->type);
logprintf ("type = 0x%08x\n", x);
assert (0);
}
}
void fetch_skip_message_action_encrypted (void) {
unsigned x = fetch_int ();
switch (x) {
case CODE_decrypted_message_action_set_message_t_t_l:
fetch_skip (1);
break;
default:
logprintf ("x = 0x%08x\n", x);
assert (0);
}
}
void fetch_message_action_encrypted (struct message_action *M) {
unsigned x = fetch_int ();
switch (x) {
case CODE_decrypted_message_action_set_message_t_t_l:
M->type = x;
M->ttl = fetch_int ();
break;
default:
logprintf ("x = 0x%08x\n", x);
assert (0);
}
}
@ -993,31 +1233,55 @@ peer_id_t fetch_peer_id (void) {
}
void fetch_message (struct message *M) {
memset (M, 0, sizeof (*M));
unsigned x = fetch_int ();
assert (x == CODE_message_empty || x == CODE_message || x == CODE_message_forwarded || x == CODE_message_service);
M->id = fetch_int ();
int id = fetch_int ();
assert (M->id == id);
if (x == CODE_message_empty) {
M->flags |= 1;
return;
}
int fwd_from_id = 0;
int fwd_date = 0;
if (x == CODE_message_forwarded) {
M->fwd_from_id = MK_USER (fetch_int ());
M->fwd_date = fetch_int ();
fwd_from_id = fetch_int ();
fwd_date = fetch_int ();
}
M->from_id = MK_USER (fetch_int ());
M->to_id = fetch_peer_id ();
M->out = fetch_bool ();
M->unread = fetch_bool ();
M->date = fetch_int ();
int from_id = fetch_int ();
peer_id_t to_id = fetch_peer_id ();
fetch_bool (); // out.
int unread = fetch_bool ();
int date = fetch_int ();
int new = !(M->flags & FLAG_CREATED);
if (x == CODE_message_service) {
M->service = 1;
fetch_message_action (&M->action);
int *start = in_ptr;
fetch_skip_message_action ();
if (new) {
if (fwd_from_id) {
bl_do_create_message_service_fwd (id, from_id, get_peer_type (to_id), get_peer_id (to_id), date, fwd_from_id, fwd_date, start, (in_ptr - start));
} else {
M->message = fetch_str_dup ();
fetch_message_media (&M->media);
bl_do_create_message_service (id, from_id, get_peer_type (to_id), get_peer_id (to_id), date, start, (in_ptr - start));
}
}
} else {
int l = prefetch_strlen ();
char *s = fetch_str (l);
int *start = in_ptr;
fetch_skip_message_media ();
if (new) {
if (fwd_from_id) {
bl_do_create_message_media_fwd (id, from_id, get_peer_type (to_id), get_peer_id (to_id), date, fwd_from_id, fwd_date, l, s, start, in_ptr - start);
} else {
bl_do_create_message_media (id, from_id, get_peer_type (to_id), get_peer_id (to_id), date, l, s, start, in_ptr - start);
}
}
}
bl_do_set_unread (M, unread);
}
void fetch_geo_message (struct message *M) {
memset (M, 0, sizeof (*M));
@ -1100,29 +1364,26 @@ int decrypt_encrypted_message (struct secret_chat *E) {
}
void fetch_encrypted_message (struct message *M) {
memset (M, 0, sizeof (*M));
unsigned x = fetch_int ();
assert (x == CODE_encrypted_message || x == CODE_encrypted_message_service);
unsigned sx = x;
M->id = fetch_long ();
peer_id_t chat = MK_ENCR_CHAT (fetch_int ());
M->from_id = MK_USER (our_id);
M->to_id = chat;
int new = !(M->flags & FLAG_CREATED);
long long id = fetch_long ();
int to_id = fetch_int ();
peer_id_t chat = MK_ENCR_CHAT (to_id);
int date = fetch_int ();
peer_t *P = user_chat_get (chat);
M->flags &= ~(FLAG_MESSAGE_EMPTY | FLAG_DELETED);
M->flags |= FLAG_ENCRYPTED;
if (!P) {
logprintf ("Encrypted message to unknown chat. Dropping\n");
M->flags |= FLAG_MESSAGE_EMPTY;
}
M->date = fetch_int ();
int len = prefetch_strlen ();
assert ((len & 15) == 8);
decr_ptr = (void *)fetch_str (len);
decr_end = decr_ptr + (len / 4);
M->flags |= FLAG_ENCRYPTED;
int ok = 0;
if (P) {
if (*(long long *)decr_ptr != P->encr_chat.key_fingerprint) {
@ -1131,32 +1392,39 @@ void fetch_encrypted_message (struct message *M) {
}
decr_ptr += 2;
}
if (P && decrypt_encrypted_message (&P->encr_chat) >= 0) {
int l = 0;
char *s = 0;
int *start = 0;
int *end = 0;
x = 0;
if (P && decrypt_encrypted_message (&P->encr_chat) >= 0 && new) {
ok = 1;
int *save_in_ptr = in_ptr;
int *save_in_end = in_end;
in_ptr = decr_ptr;
int l = fetch_int ();
in_end = in_ptr + l;
unsigned x = fetch_int ();
int ll = fetch_int ();
in_end = in_ptr + ll;
x = fetch_int ();
if (x == CODE_decrypted_message_layer) {
int layer = fetch_int ();
assert (layer >= 0);
x = fetch_int ();
}
assert (x == CODE_decrypted_message || x == CODE_decrypted_message_service);
assert (M->id = fetch_long ());
l = prefetch_strlen ();
fetch_str (l); // random_bytes
//assert (id == fetch_long ());
fetch_long ();
ll = prefetch_strlen ();
fetch_str (ll); // random_bytes
if (x == CODE_decrypted_message) {
M->message = fetch_str_dup ();
fetch_message_media_encrypted (&M->media);
l = prefetch_strlen ();
s = fetch_str (l);
start = in_ptr;
fetch_skip_message_media_encrypted ();
end = in_ptr;
} else {
assert (fetch_int () == (int)CODE_decrypted_message_action_set_message_t_t_l);
M->action.type = CODE_decrypted_message_action_set_message_t_t_l;
P->encr_chat.ttl = fetch_int ();
M->action.ttl = P->encr_chat.ttl;
M->service = 1;
start = in_ptr;
fetch_skip_message_action_encrypted ();
end = in_ptr;
}
in_ptr = save_in_ptr;
in_end = save_in_end;
@ -1164,7 +1432,11 @@ void fetch_encrypted_message (struct message *M) {
if (sx == CODE_encrypted_message) {
if (ok) {
fetch_encrypted_message_file (&M->media);
int *start_file = in_ptr;
fetch_skip_encrypted_message_file ();
if (x == CODE_decrypted_message) {
bl_do_create_message_media_encr (id, P->encr_chat.user_id, PEER_ENCR_CHAT, to_id, date, l, s, start, end - start, start_file, in_ptr - start_file);
}
} else {
x = fetch_int ();
if (x == CODE_encrypted_file) {
@ -1174,6 +1446,10 @@ void fetch_encrypted_message (struct message *M) {
}
M->media.type = CODE_message_media_empty;
}
} else {
if (ok && x == CODE_decrypted_message_service) {
bl_do_create_message_service_encr (id, P->encr_chat.user_id, PEER_ENCR_CHAT, to_id, date, start, end - start);
}
}
}
@ -1195,6 +1471,15 @@ void fetch_encrypted_message_file (struct message_media *M) {
}
}
void fetch_skip_encrypted_message_file (void) {
unsigned x = fetch_int ();
assert (x == CODE_encrypted_file || x == CODE_encrypted_file_empty);
if (x == CODE_encrypted_file_empty) {
} else {
fetch_skip (7);
}
}
static int id_cmp (struct message *M1, struct message *M2) {
if (M1->id < M2->id) { return -1; }
else if (M1->id > M2->id) { return 1; }
@ -1424,10 +1709,33 @@ void message_add_peer (struct message *M) {
peer_tree = tree_insert_peer (peer_tree, P, lrand48 ());
Peers[peer_num ++] = P;
}
M->next = P->last;
if (M->next) { M->next->prev = M; }
M->prev = 0;
if (!P->last) {
P->last = M;
M->prev = M->next = 0;
} else {
if (get_peer_type (P->id) != PEER_ENCR_CHAT) {
struct message *N = P->last;
struct message *NP = 0;
while (N && N->id > M->id) {
NP = N;
N = N->next;
}
if (N) { assert (N->id < M->id); }
M->next = N;
M->prev = NP;
if (N) { N->prev = M; }
if (NP) { NP->next = M; }
else { P->last = M; }
} else {
struct message *N = P->last;
struct message *NP = 0;
M->next = N;
M->prev = NP;
if (N) { N->prev = M; }
if (NP) { NP->next = M; }
else { P->last = M; }
}
}
}
void message_del_peer (struct message *M) {
@ -1450,26 +1758,19 @@ void message_del_peer (struct message *M) {
}
struct message *fetch_alloc_message (void) {
struct message *M = malloc (sizeof (*M));
fetch_message (M);
struct message *M1 = tree_lookup_message (message_tree, M);
int data[2];
prefetch_data (data, 8);
struct message *M = message_get (data[1]);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = data[1];
message_insert_tree (M);
messages_allocated ++;
if (M1) {
message_del_use (M1);
message_del_peer (M1);
free_message (M1);
memcpy (M1, M, sizeof (*M));
free (M);
message_add_use (M1);
message_add_peer (M1);
messages_allocated --;
return M1;
} else {
message_add_use (M);
message_add_peer (M);
message_tree = tree_insert_message (message_tree, M, lrand48 ());
return M;
}
fetch_message (M);
return M;
}
struct message *fetch_alloc_geo_message (void) {
@ -1496,75 +1797,53 @@ struct message *fetch_alloc_geo_message (void) {
}
struct message *fetch_alloc_encrypted_message (void) {
struct message *M = malloc (sizeof (*M));
fetch_encrypted_message (M);
struct message *M1 = tree_lookup_message (message_tree, M);
int data[3];
prefetch_data (data, 12);
struct message *M = message_get (*(long long *)(data + 1));
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = *(long long *)(data + 1);
message_insert_tree (M);
messages_allocated ++;
if (M1) {
message_del_use (M1);
message_del_peer (M1);
free_message (M1);
memcpy (M1, M, sizeof (*M));
free (M);
message_add_use (M1);
message_add_peer (M1);
messages_allocated --;
return M1;
} else {
message_add_use (M);
message_add_peer (M);
message_tree = tree_insert_message (message_tree, M, lrand48 ());
return M;
assert (message_get (M->id) == M);
logprintf ("id = %lld\n", M->id);
}
fetch_encrypted_message (M);
return M;
}
struct message *fetch_alloc_message_short (void) {
struct message *M = malloc (sizeof (*M));
fetch_message_short (M);
struct message *M1 = tree_lookup_message (message_tree, M);
int data[1];
prefetch_data (data, 4);
struct message *M = message_get (data[0]);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = data[0];
message_insert_tree (M);
messages_allocated ++;
if (M1) {
message_del_use (M1);
message_del_peer (M1);
free_message (M1);
memcpy (M1, M, sizeof (*M));
free (M);
message_add_use (M1);
message_add_peer (M1);
messages_allocated --;
return M1;
} else {
message_add_use (M);
message_add_peer (M);
message_tree = tree_insert_message (message_tree, M, lrand48 ());
return M;
}
fetch_message_short (M);
return M;
}
struct message *fetch_alloc_message_short_chat (void) {
struct message *M = malloc (sizeof (*M));
fetch_message_short_chat (M);
if (verbosity >= 2) {
logprintf ("Read message with id %lld\n", M->id);
}
struct message *M1 = tree_lookup_message (message_tree, M);
int data[1];
prefetch_data (data, 4);
struct message *M = message_get (data[0]);
if (!M) {
M = malloc (sizeof (*M));
memset (M, 0, sizeof (*M));
M->id = data[0];
message_insert_tree (M);
messages_allocated ++;
if (M1) {
message_del_use (M1);
message_del_peer (M1);
free_message (M1);
memcpy (M1, M, sizeof (*M));
free (M);
message_add_use (M1);
message_add_peer (M1);
messages_allocated --;
return M1;
} else {
message_add_use (M);
message_add_peer (M);
message_tree = tree_insert_message (message_tree, M, lrand48 ());
return M;
}
fetch_message_short_chat (M);
return M;
}
struct chat *fetch_alloc_chat (void) {
@ -1640,8 +1919,36 @@ void update_message_id (struct message *M, long long id) {
message_tree = tree_insert_message (message_tree, M, lrand48 ());
}
void message_insert_tree (struct message *M) {
assert (M->id);
message_tree = tree_insert_message (message_tree, M, lrand48 ());
}
void message_remove_tree (struct message *M) {
assert (M->id);
message_tree = tree_delete_message (message_tree, M);
}
void message_insert (struct message *M) {
message_add_use (M);
message_add_peer (M);
message_tree = tree_insert_message (message_tree, M, lrand48 ());
}
void message_insert_unsent (struct message *M) {
message_unsent_tree = tree_insert_message (message_unsent_tree, M, lrand48 ());
}
void message_remove_unsent (struct message *M) {
message_unsent_tree = tree_delete_message (message_unsent_tree, M);
}
void __send_msg (struct message *M) {
logprintf ("Resending message...\n");
print_message (M);
do_send_msg (M);
}
void send_all_unsent (void ) {
tree_act_message (message_unsent_tree, __send_msg);
}

View File

@ -38,6 +38,7 @@ typedef struct { int type; int id; } peer_id_t;
#define FLAG_CHAT_IN_CHAT 128
#define FLAG_ENCRYPTED 4096
#define FLAG_PENDING 8192
struct file_location {
int dc;
@ -337,8 +338,16 @@ struct message *fetch_alloc_message_short (void);
struct message *fetch_alloc_message_short_chat (void);
struct message *fetch_alloc_encrypted_message (void);
void fetch_encrypted_message_file (struct message_media *M);
void fetch_skip_encrypted_message_file (void);
void fetch_encrypted_message_file (struct message_media *M);
void fetch_message_action_encrypted (struct message_action *M);
peer_id_t fetch_peer_id (void);
void fetch_message_media (struct message_media *M);
void fetch_message_media_encrypted (struct message_media *M);
void fetch_message_action (struct message_action *M);
void message_insert_tree (struct message *M);
void free_user (struct user *U);
void free_chat (struct chat *U);
@ -356,6 +365,12 @@ void insert_user (peer_t *P);
void insert_chat (peer_t *P);
void fetch_photo (struct photo *P);
void free_photo (struct photo *P);
void message_insert_unsent (struct message *M);
void message_remove_unsent (struct message *M);
void send_all_unsent (void);
void message_remove_tree (struct message *M);
void message_add_peer (struct message *M);
void message_del_peer (struct message *M);
#define PEER_USER 1
#define PEER_CHAT 2

View File

@ -17,5 +17,5 @@
Copyright Vitaly Valtman 2013
*/
#define MAX_DC_NUM 9
#define MAX_USER_NUM 1000
#define MAX_CHAT_NUM 1000
#define MAX_USER_NUM 100000
#define MAX_CHAT_NUM 100000