Manty fixes. Mostly binlog for messages
This commit is contained in:
parent
d095e607c2
commit
725c6669a7
466
binlog.c
466
binlog.c
@ -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));
|
||||
}
|
||||
|
25
binlog.h
25
binlog.h
@ -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
|
||||
|
@ -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
5
loop.c
@ -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 ();
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
119
queries.c
119
queries.c
@ -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,86 +849,62 @@ 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) {
|
||||
peer_t *P = user_chat_get (id);
|
||||
if (!P) {
|
||||
logprintf ("Can not send to unknown encrypted chat\n");
|
||||
return;
|
||||
}
|
||||
if (P->encr_chat.state != sc_ok) {
|
||||
logprintf ("Chat is not yet initialized\n");
|
||||
return;
|
||||
}
|
||||
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 (id));
|
||||
out_int (get_peer_id (M->to_id));
|
||||
out_long (P->encr_chat.access_hash);
|
||||
if (!out_message_num) {
|
||||
out_message_num = -lrand48 ();
|
||||
}
|
||||
out_long ((--out_message_num) - (4ll << 32));
|
||||
out_long (M->id);
|
||||
encr_start ();
|
||||
//out_int (CODE_decrypted_message_layer);
|
||||
//out_int (8);
|
||||
out_int (CODE_decrypted_message);
|
||||
out_long ((out_message_num) - (4ll << 32));
|
||||
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 *)msg, len);
|
||||
out_cstring ((void *)M->message, M->message_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_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) {
|
||||
do_send_encr_message (id, msg, len);
|
||||
return;
|
||||
peer_t *P = user_chat_get (id);
|
||||
if (!P) {
|
||||
logprintf ("Can not send to unknown encrypted chat\n");
|
||||
return;
|
||||
}
|
||||
if (P->encr_chat.state != sc_ok) {
|
||||
logprintf ("Chat is not yet initialized\n");
|
||||
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 ++;
|
||||
@ -2295,6 +2273,9 @@ void do_create_keys_end (struct secret_chat *U) {
|
||||
BIGNUM *a = BN_bin2bn ((void *)U->key, 256, 0);
|
||||
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);
|
||||
@ -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);
|
||||
|
@ -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
|
||||
|
631
structures.c
631
structures.c
@ -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 --;
|
||||
}
|
||||
}
|
||||
sprintf (s + fl, "#%d", 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 ();
|
||||
fetch_pts ();
|
||||
M->date = fetch_int ();
|
||||
fetch_seq ();
|
||||
M->media.type = CODE_message_media_empty;
|
||||
M->unread = 1;
|
||||
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 ();
|
||||
|
||||
int date = fetch_int ();
|
||||
fetch_seq ();
|
||||
|
||||
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 ();
|
||||
fetch_pts ();
|
||||
M->date = fetch_int ();
|
||||
fetch_seq ();
|
||||
M->media.type = CODE_message_media_empty;
|
||||
M->unread = 1;
|
||||
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 ();
|
||||
|
||||
int date = fetch_int ();
|
||||
fetch_seq ();
|
||||
|
||||
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,30 +1233,54 @@ 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 {
|
||||
bl_do_create_message_service (id, from_id, get_peer_type (to_id), get_peer_id (to_id), date, start, (in_ptr - start));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
M->message = fetch_str_dup ();
|
||||
fetch_message_media (&M->media);
|
||||
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) {
|
||||
@ -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;
|
||||
P->last = M;
|
||||
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);
|
||||
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;
|
||||
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 ++;
|
||||
}
|
||||
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);
|
||||
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;
|
||||
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 ++;
|
||||
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);
|
||||
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;
|
||||
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 ++;
|
||||
}
|
||||
fetch_message_short (M);
|
||||
return M;
|
||||
}
|
||||
|
||||
struct message *fetch_alloc_message_short_chat (void) {
|
||||
struct message *M = malloc (sizeof (*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 ++;
|
||||
}
|
||||
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);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
15
structures.h
15
structures.h
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user