support for secret chats file in no-binlog mode

This commit is contained in:
vvaltman 2014-08-31 18:18:19 +04:00
parent 0d2046a70f
commit f5e6e3aa6b
5 changed files with 173 additions and 1 deletions

View File

@ -430,6 +430,22 @@ static int fetch_comb_binlog_encr_chat_set_date (void *extra) {
return 0;
}
static int fetch_comb_binlog_encr_chat_set_ttl (void *extra) {
tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ());
tgl_peer_t *U = tgl_peer_get (id);
assert (U);
U->encr_chat.ttl = fetch_int ();
return 0;
}
static int fetch_comb_binlog_encr_chat_set_layer (void *extra) {
tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ());
tgl_peer_t *U = tgl_peer_get (id);
assert (U);
U->encr_chat.layer = fetch_int ();
return 0;
}
static int fetch_comb_binlog_encr_chat_set_state (void *extra) {
tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ());
tgl_peer_t *U = tgl_peer_get (id);
@ -498,6 +514,24 @@ static int fetch_comb_binlog_encr_chat_init (void *extra) {
return 0;
}
static int fetch_comb_binlog_encr_chat_create (void *extra) {
tgl_peer_t *P = talloc0 (sizeof (*P));
P->id = TGL_MK_ENCR_CHAT (fetch_int ());
assert (!tgl_peer_get (P->id));
P->encr_chat.user_id = fetch_int ();
P->encr_chat.admin_id = fetch_int ();
tglp_insert_encrypted_chat (P);
P->print_name = fetch_str_dup ();
tglp_peer_insert_name (P);
P->flags |= FLAG_CREATED;
if (tgl_state.callback.secret_chat_update) {
tgl_state.callback.secret_chat_update ((void *)P, TGL_UPDATE_CREATED);
}
return 0;
}
static int fetch_comb_binlog_chat_create (void *extra) {
tgl_peer_id_t id = TGL_MK_CHAT (fetch_int ());
tgl_peer_t *_C = tgl_peer_get (id);
@ -1160,10 +1194,13 @@ static void replay_log_event (void) {
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_requested)
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_access_hash)
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_date)
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_ttl)
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_layer)
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_state)
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_accepted)
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_set_key)
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_init)
FETCH_COMBINATOR_FUNCTION (binlog_encr_chat_create)
FETCH_COMBINATOR_FUNCTION (binlog_chat_create)
FETCH_COMBINATOR_FUNCTION (binlog_chat_change_flags)
@ -1530,6 +1567,24 @@ void bl_do_encr_chat_set_date (struct tgl_secret_chat *U, int date) {
add_log_event (ev, 12);
}
void bl_do_encr_chat_set_ttl (struct tgl_secret_chat *U, int ttl) {
if (U->ttl == ttl) { return; }
int *ev = alloc_log_event (12);
ev[0] = CODE_binlog_encr_chat_set_ttl;
ev[1] = tgl_get_peer_id (U->id);
ev[2] = ttl;
add_log_event (ev, 12);
}
void bl_do_encr_chat_set_layer (struct tgl_secret_chat *U, int layer) {
if (U->layer == layer) { return; }
int *ev = alloc_log_event (12);
ev[0] = CODE_binlog_encr_chat_set_layer;
ev[1] = tgl_get_peer_id (U->id);
ev[2] = layer;
add_log_event (ev, 12);
}
void bl_do_encr_chat_set_state (struct tgl_secret_chat *U, enum tgl_secret_chat_state state) {
if (U->state == state) { return; }
int *ev = alloc_log_event (12);
@ -1550,6 +1605,16 @@ void bl_do_encr_chat_accepted (struct tgl_secret_chat *U, const unsigned char g_
add_log_event (ev, 528);
}
void bl_do_encr_chat_create (int id, int user_id, int admin_id, char *name, int name_len) {
clear_packet ();
out_int (CODE_binlog_encr_chat_create);
out_int (id);
out_int (user_id);
out_int (admin_id);
out_cstring (name, name_len);
add_log_event (packet_buffer, 4 * (packet_ptr - packet_buffer));
}
void bl_do_encr_chat_set_key (struct tgl_secret_chat *E, unsigned char key[], long long key_fingerprint) {
int *ev = alloc_log_event (272);
ev[0] = CODE_binlog_encr_chat_set_key;

View File

@ -41,9 +41,12 @@ void bl_do_user_set_real_name (struct tgl_user *U, const char *f, int fl, const
void bl_do_encr_chat_delete (struct tgl_secret_chat *U);
void bl_do_encr_chat_requested (struct tgl_secret_chat *U, long long access_hash, int date, int admin_id, int user_id, unsigned char g_key[], unsigned char nonce[]);
void bl_do_encr_chat_create (int id, int user_id, int admin_id, char *name, int name_len);
void bl_do_encr_chat_set_access_hash (struct tgl_secret_chat *U, long long access_hash);
void bl_do_encr_chat_set_date (struct tgl_secret_chat *U, int date);
void bl_do_encr_chat_set_state (struct tgl_secret_chat *U, enum tgl_secret_chat_state state);
void bl_do_encr_chat_set_ttl (struct tgl_secret_chat *U, int ttl);
void bl_do_encr_chat_set_layer (struct tgl_secret_chat *U, int layer);
void bl_do_encr_chat_accepted (struct tgl_secret_chat *U, const unsigned char g_key[], const unsigned char nonce[], long long key_fingerprint);
void bl_do_encr_chat_set_key (struct tgl_secret_chat *E, unsigned char key[], long long key_fingerprint);
void bl_do_encr_chat_init (int id, int user_id, unsigned char random[], unsigned char g_a[]);

View File

@ -32,9 +32,12 @@ binlog.encrChatDelete id:int = binlog.Update;
binlog.encrChatRequested id:int hash:long date:int admin:int user:int key:64*[int] nonce:64*[int] = binlog.Update;
binlog.encrChatAccepted id:int key:64*[int] nonce:64*[int] fingerprint:long = binlog.Update;
binlog.encrChatInit id:int user:int key:64*[int] g_key:64*[int] = binlog.Update;
binlog.encrChatCreate id:int user_id:int admin_id:int name:string = binlog.Update;
binlog.encrChatSetAccessHash id:int hash:long = binlog.Update;
binlog.encrChatSetDate id:int date:int = binlog.Update;
binlog.encrChatSetTtl id:int ttl:int = binlog.Update;
binlog.encrChatSetLayer id:int layer:int = binlog.Update;
binlog.encrChatSetState id:int state:int = binlog.Update;
binlog.encrChatSetKey id:int key:64*[int] fingerprint:long = binlog.Update;

View File

@ -54,6 +54,7 @@
//#include "mtproto-common.h"
#include "tgl.h"
#include "loop.h"
#ifndef PATH_MAX
#define PATH_MAX 4096
@ -961,6 +962,9 @@ void secret_chat_update_gw (struct tgl_secret_chat *U, unsigned flags) {
if (!binlog_read) { return; }
if ((flags & TGL_UPDATE_WORKING) || (flags & TGL_UPDATE_DELETED)) {
write_secret_chat_file ();
}
if ((flags & TGL_UPDATE_REQUESTED) && !disable_auto_accept) {
tgl_do_accept_encr_chat_request (U, 0, 0);
}

99
loop.c
View File

@ -313,9 +313,11 @@ extern struct tgl_update_callback upd_cb;
#define DC_SERIALIZED_MAGIC 0x868aa81d
#define STATE_FILE_MAGIC 0x28949a93
#define SECRET_FILE_MAGIX 0x37a1988a
#define SECRET_CHAT_FILE_MAGIC 0x37a1988a
char *get_auth_key_filename (void);
char *get_state_filename (void);
char *get_secret_chat_filename (void);
void read_state_file (void) {
if (binlog_enabled) { return; }
@ -405,6 +407,52 @@ void write_auth_file (void) {
close (auth_file_fd);
}
void write_secret_chat (tgl_peer_t *_P, void *extra) {
struct tgl_secret_chat *P = (void *)_P;
if (tgl_get_peer_type (P->id) != TGL_PEER_ENCR_CHAT) { return; }
if (P->state != sc_ok) { return; }
int *a = extra;
int fd = a[0];
a[1] ++;
int id = tgl_get_peer_id (P->id);
assert (write (fd, &id, 4) == 4);
//assert (write (fd, &P->flags, 4) == 4);
int l = strlen (P->print_name);
assert (write (fd, &l, 4) == 4);
assert (write (fd, P->print_name, l) == l);
assert (write (fd, &P->user_id, 4) == 4);
assert (write (fd, &P->admin_id, 4) == 4);
assert (write (fd, &P->date, 4) == 4);
assert (write (fd, &P->ttl, 4) == 4);
assert (write (fd, &P->layer, 4) == 4);
assert (write (fd, &P->access_hash, 8) == 8);
assert (write (fd, &P->state, 4) == 4);
assert (write (fd, &P->key_fingerprint, 8) == 8);
assert (write (fd, &P->key, 256) == 256);
}
void write_secret_chat_file (void) {
if (binlog_enabled) { return; }
int secret_chat_fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
assert (secret_chat_fd >= 0);
int x = SECRET_CHAT_FILE_MAGIC;
assert (write (secret_chat_fd, &x, 4) == 4);
x = 0;
assert (write (secret_chat_fd, &x, 4) == 4); // version
assert (write (secret_chat_fd, &x, 4) == 4); // num
int y[2];
y[0] = secret_chat_fd;
y[1] = 0;
tgl_peer_iterator_ex (write_secret_chat, y);
lseek (secret_chat_fd, 8, SEEK_SET);
assert (write (secret_chat_fd, &y[1], 4) == 4);
close (secret_chat_fd);
}
void read_dc (int auth_file_fd, int id, unsigned ver) {
int port = 0;
assert (read (auth_file_fd, &port, 4) == 4);
@ -473,6 +521,54 @@ void read_auth_file (void) {
close (auth_file_fd);
}
void read_secret_chat (int fd) {
int id, l, user_id, admin_id, date, ttl, layer, state;
long long access_hash, key_fingerprint;
static char s[1000];
static unsigned char key[256];
assert (read (fd, &id, 4) == 4);
//assert (read (fd, &flags, 4) == 4);
assert (read (fd, &l, 4) == 4);
assert (l > 0 && l < 1000);
assert (read (fd, s, l) == l);
assert (read (fd, &user_id, 4) == 4);
assert (read (fd, &admin_id, 4) == 4);
assert (read (fd, &date, 4) == 4);
assert (read (fd, &ttl, 4) == 4);
assert (read (fd, &layer, 4) == 4);
assert (read (fd, &access_hash, 8) == 8);
assert (read (fd, &state, 4) == 4);
assert (read (fd, &key_fingerprint, 8) == 8);
assert (read (fd, &key, 256) == 256);
bl_do_encr_chat_create (id, user_id, admin_id, s, l);
struct tgl_secret_chat *P = (void *)tgl_peer_get (TGL_MK_ENCR_CHAT (id));
assert (P && (P->flags & FLAG_CREATED));
bl_do_encr_chat_set_date (P, date);
bl_do_encr_chat_set_ttl (P, ttl);
bl_do_encr_chat_set_layer (P, layer);
bl_do_encr_chat_set_access_hash (P, access_hash);
bl_do_encr_chat_set_state (P, state);
bl_do_encr_chat_set_key (P, key, key_fingerprint);
}
void read_secret_chat_file (void) {
if (binlog_enabled) { return; }
int secret_chat_fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
assert (secret_chat_fd >= 0);
int x;
assert (read (secret_chat_fd, &x, 4) == 4);
assert (x == SECRET_CHAT_FILE_MAGIC);
assert (read (secret_chat_fd, &x, 4) == 4);
assert (!x); // version
assert (read (secret_chat_fd, &x, 4) == 4);
assert (x >= 0);
while (x --> 0) {
read_secret_chat (secret_chat_fd);
}
close (secret_chat_fd);
}
void dlist_cb (void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[]) {
d_got_ok = 1;
}
@ -495,6 +591,7 @@ int loop (void) {
} else {
read_auth_file ();
read_state_file ();
read_secret_chat_file ();
}
binlog_read = 1;
#ifdef USE_LUA