Commit b12ca538 authored by Vysheng's avatar Vysheng

many updates

parent fe08f0c5
...@@ -18,7 +18,7 @@ DIR_LIST=${DEP} ${AUTO} ${EXE} ${OBJ} ${DEP}/auto ${OBJ}/auto ...@@ -18,7 +18,7 @@ DIR_LIST=${DEP} ${AUTO} ${EXE} ${OBJ} ${DEP}/auto ${OBJ}/auto
EXE_LIST=${EXE}/generate ${EXE}/tlc ${EXE}/telegram-cli EXE_LIST=${EXE}/generate ${EXE}/tlc ${EXE}/telegram-cli
TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/net.o ${OBJ}/mtproto-common.o ${OBJ}/mtproto-client.o ${OBJ}/queries.o ${OBJ}/structures.o ${OBJ}/binlog.o ${OBJ}/lua-tg.o ${OBJ}/auto/auto.o ${OBJ}/tgl.o TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/net.o ${OBJ}/mtproto-common.o ${OBJ}/mtproto-client.o ${OBJ}/queries.o ${OBJ}/structures.o ${OBJ}/binlog.o ${OBJ}/lua-tg.o ${OBJ}/auto/auto.o ${OBJ}/tgl.o ${OBJ}/updates.o
TLC_OBJECTS=${OBJ}/tlc.o ${OBJ}/tl-parser.o ${OBJ}/crc32.o TLC_OBJECTS=${OBJ}/tlc.o ${OBJ}/tl-parser.o ${OBJ}/crc32.o
GENERATE_OBJECTS=${OBJ}/generate.o GENERATE_OBJECTS=${OBJ}/generate.o
COMMON_OBJECTS=${OBJ}/tools.o COMMON_OBJECTS=${OBJ}/tools.o
...@@ -60,6 +60,7 @@ ${EXE}/generate: ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ...@@ -60,6 +60,7 @@ ${EXE}/generate: ${GENERATE_OBJECTS} ${COMMON_OBJECTS}
${CC} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${LINK_FLAGS} -o $@ ${CC} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${LINK_FLAGS} -o $@
${AUTO}/scheme.tlo: ${AUTO}/scheme.tl ${EXE}/tlc ${AUTO}/scheme.tlo: ${AUTO}/scheme.tl ${EXE}/tlc
${EXE}/tlc -e $@ ${AUTO}/scheme.tl ${EXE}/tlc -e $@ ${AUTO}/scheme.tl
${AUTO}/scheme.tl: ${srcdir}/scheme.tl ${srcdir}/binlog.tl ${srcdir}/append.tl ${AUTO}/scheme.tl: ${srcdir}/scheme.tl ${srcdir}/binlog.tl ${srcdir}/append.tl
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "loop.h" #include "loop.h"
#include "tgl.h" #include "tgl.h"
#include "auto.h"
#include <openssl/sha.h> #include <openssl/sha.h>
...@@ -80,7 +81,7 @@ static int fetch_comb_binlog_dc_option (void *extra) { ...@@ -80,7 +81,7 @@ static int fetch_comb_binlog_dc_option (void *extra) {
vlogprintf (E_NOTICE, "DC%d '%.*s' update: %.*s:%d\n", id, l1, name, l2, ip, port); vlogprintf (E_NOTICE, "DC%d '%.*s' update: %.*s:%d\n", id, l1, name, l2, ip, port);
alloc_dc (id, tstrndup (ip, l2), port); tglmp_alloc_dc (id, tstrndup (ip, l2), port);
return 0; return 0;
} }
......
...@@ -44,20 +44,11 @@ ...@@ -44,20 +44,11 @@
#include <fcntl.h> #include <fcntl.h>
#include "interface.h" #include "interface.h"
#include "net.h"
#include "mtproto-client.h"
#include "mtproto-common.h"
#include "queries.h"
#include "telegram.h" #include "telegram.h"
#include "loop.h" #include "loop.h"
#include "binlog.h"
#include "lua-tg.h" #include "lua-tg.h"
#include "structures.h"
#include "tgl.h" #include "tgl.h"
#include "auto.h"
extern char *default_username; extern char *default_username;
extern char *auth_token; extern char *auth_token;
void set_default_username (const char *s); void set_default_username (const char *s);
...@@ -80,7 +71,7 @@ void net_loop (int flags, int (*is_end)(void)) { ...@@ -80,7 +71,7 @@ void net_loop (int flags, int (*is_end)(void)) {
cc ++; cc ++;
} }
write_state_file (); //write_state_file ();
int x = connections_make_poll_array (fds + cc, 101 - cc) + cc; int x = connections_make_poll_array (fds + cc, 101 - cc) + cc;
double timer = next_timer_in (); double timer = next_timer_in ();
if (timer > 1000) { timer = 1000; } if (timer > 1000) { timer = 1000; }
...@@ -155,289 +146,6 @@ char *get_state_filename (void); ...@@ -155,289 +146,6 @@ char *get_state_filename (void);
char *get_secret_chat_filename (void); char *get_secret_chat_filename (void);
int zero[512]; int zero[512];
/*
void write_dc (int auth_file_fd, struct dc *DC) {
assert (write (auth_file_fd, &DC->port, 4) == 4);
int l = strlen (DC->ip);
assert (write (auth_file_fd, &l, 4) == 4);
assert (write (auth_file_fd, DC->ip, l) == l);
if (DC->flags & 1) {
assert (write (auth_file_fd, &DC->auth_key_id, 8) == 8);
assert (write (auth_file_fd, DC->auth_key, 256) == 256);
} else {
assert (write (auth_file_fd, zero, 256 + 8) == 256 + 8);
}
assert (write (auth_file_fd, &DC->server_salt, 8) == 8);
assert (write (auth_file_fd, &DC->has_auth, 4) == 4);
}
void write_auth_file (void) {
if (binlog_enabled) { return; }
int auth_file_fd = open (get_auth_key_filename (), O_CREAT | O_RDWR, 0600);
assert (auth_file_fd >= 0);
int x = DC_SERIALIZED_MAGIC_V2;
assert (write (auth_file_fd, &x, 4) == 4);
x = MAX_DC_ID;
assert (write (auth_file_fd, &x, 4) == 4);
assert (write (auth_file_fd, &dc_working_num, 4) == 4);
assert (write (auth_file_fd, &auth_state, 4) == 4);
int i;
for (i = 0; i <= MAX_DC_ID; i++) {
if (DC_list[i]) {
x = 1;
assert (write (auth_file_fd, &x, 4) == 4);
write_dc (auth_file_fd, DC_list[i]);
} else {
x = 0;
assert (write (auth_file_fd, &x, 4) == 4);
}
}
assert (write (auth_file_fd, &tgl_state.our_id, 4) == 4);
close (auth_file_fd);
}
void read_dc (int auth_file_fd, int id, unsigned ver) {
int port = 0;
assert (read (auth_file_fd, &port, 4) == 4);
int l = 0;
assert (read (auth_file_fd, &l, 4) == 4);
assert (l >= 0);
char *ip = talloc (l + 1);
assert (read (auth_file_fd, ip, l) == l);
ip[l] = 0;
struct dc *DC = alloc_dc (id, ip, port);
assert (read (auth_file_fd, &DC->auth_key_id, 8) == 8);
assert (read (auth_file_fd, &DC->auth_key, 256) == 256);
assert (read (auth_file_fd, &DC->server_salt, 8) == 8);
if (DC->auth_key_id) {
DC->flags |= 1;
}
if (ver != DC_SERIALIZED_MAGIC) {
assert (read (auth_file_fd, &DC->has_auth, 4) == 4);
} else {
DC->has_auth = 0;
}
}
void empty_auth_file (void) {
alloc_dc (1, tstrdup (tgl_state.test_mode ? TG_SERVER_TEST : TG_SERVER), 443);
dc_working_num = 1;
auth_state = 0;
write_auth_file ();
}
int need_dc_list_update;
void read_auth_file (void) {
if (binlog_enabled) { return; }
int auth_file_fd = open (get_auth_key_filename (), O_CREAT | O_RDWR, 0600);
if (auth_file_fd < 0) {
empty_auth_file ();
}
assert (auth_file_fd >= 0);
unsigned x;
unsigned m;
if (read (auth_file_fd, &m, 4) < 4 || (m != DC_SERIALIZED_MAGIC && m != DC_SERIALIZED_MAGIC_V2)) {
close (auth_file_fd);
empty_auth_file ();
return;
}
assert (read (auth_file_fd, &x, 4) == 4);
assert (x <= MAX_DC_ID);
assert (read (auth_file_fd, &dc_working_num, 4) == 4);
assert (read (auth_file_fd, &auth_state, 4) == 4);
if (m == DC_SERIALIZED_MAGIC) {
auth_state = 700;
}
int i;
for (i = 0; i <= (int)x; i++) {
int y;
assert (read (auth_file_fd, &y, 4) == 4);
if (y) {
read_dc (auth_file_fd, i, m);
}
}
int l = read (auth_file_fd, &tgl_state.our_id, 4);
if (l < 4) {
assert (!l);
}
close (auth_file_fd);
DC_working = DC_list[dc_working_num];
if (m == DC_SERIALIZED_MAGIC) {
DC_working->has_auth = 1;
}
}
int pts, qts, seq, last_date;
void read_state_file (void) {
if (binlog_enabled) { return; }
int state_file_fd = open (get_state_filename (), O_CREAT | O_RDWR, 0600);
if (state_file_fd < 0) {
return;
}
int version, magic;
if (read (state_file_fd, &magic, 4) < 4) { close (state_file_fd); return; }
if (magic != (int)STATE_FILE_MAGIC) { close (state_file_fd); return; }
if (read (state_file_fd, &version, 4) < 4) { close (state_file_fd); return; }
assert (version >= 0);
int x[4];
if (read (state_file_fd, x, 16) < 16) {
close (state_file_fd);
return;
}
pts = x[0];
qts = x[1];
seq = x[2];
last_date = x[3];
close (state_file_fd);
}
void write_state_file (void) {
if (binlog_enabled) { return; }
static int wseq;
static int wpts;
static int wqts;
static int wdate;
if (wseq >= seq && wpts >= pts && wqts >= qts && wdate >= last_date) { return; }
int state_file_fd = open (get_state_filename (), O_CREAT | O_RDWR, 0600);
if (state_file_fd < 0) {
return;
}
int x[6];
x[0] = STATE_FILE_MAGIC;
x[1] = 0;
x[2] = pts;
x[3] = qts;
x[4] = seq;
x[5] = last_date;
assert (write (state_file_fd, x, 24) == 24);
close (state_file_fd);
wseq = seq; wpts = pts; wqts = qts; wdate = last_date;
}
extern tgl_peer_t *Peers[];
extern int peer_num;
extern int encr_root;
extern unsigned char *encr_prime;
extern int encr_param_version;
extern int dialog_list_got;
void read_secret_chat_file (void) {
if (binlog_enabled) { return; }
int fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
if (fd < 0) {
return;
}
int x[2];
if (read (fd, x, 8) < 8) {
close (fd); return;
}
if (x[0] != (int)SECRET_CHAT_FILE_MAGIC) { close (fd); return; }
int version = x[1];
assert (version >= 0);
int cc;
assert (read (fd, &cc, 4) == 4);
int i;
for (i = 0; i < cc; i++) {
tgl_peer_t *P = talloc0 (sizeof (*P));
struct tgl_secret_chat *E = &P->encr_chat;
int t;
assert (read (fd, &t, 4) == 4);
P->id = TGL_MK_ENCR_CHAT (t);
assert (read (fd, &P->flags, 4) == 4);
assert (read (fd, &t, 4) == 4);
assert (t > 0);
P->print_name = talloc (t + 1);
assert (read (fd, P->print_name, t) == t);
P->print_name[t] = 0;
tglp_peer_insert_name (P);
assert (read (fd, &E->state, 4) == 4);
assert (read (fd, &E->user_id, 4) == 4);
assert (read (fd, &E->admin_id, 4) == 4);
assert (read (fd, &E->ttl, 4) == 4);
assert (read (fd, &E->access_hash, 8) == 8);
if (E->state != sc_waiting) {
E->g_key = talloc (256);
assert (read (fd, E->g_key, 256) == 256);
E->nonce = talloc (256);
assert (read (fd, E->nonce, 256) == 256);
}
assert (read (fd, E->key, 256) == 256);
assert (read (fd, &E->key_fingerprint, 8) == 8);
tglp_insert_encrypted_chat (P);
}
if (version >= 1) {
assert (read (fd, &encr_root, 4) == 4);
if (encr_root) {
assert (read (fd, &encr_param_version, 4) == 4);
encr_prime = talloc (256);
assert (read (fd, encr_prime, 256) == 256);
}
}
close (fd);
}
void count_encr_peer (tgl_peer_t *P, void *cc) {
if (tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT && P->encr_chat.state != sc_none && P->encr_chat.state != sc_deleted) {
(*(int *)cc) ++;
}
}
void write_encr_peer (tgl_peer_t *P, void *pfd) {
int fd = *(int *)pfd;
if (tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT && P->encr_chat.state != sc_none && P->encr_chat.state != sc_deleted) {
int t = tgl_get_peer_id (P->id);
assert (write (fd, &t, 4) == 4);
t = P->flags;
assert (write (fd, &t, 4) == 4);
t = strlen (P->print_name);
assert (write (fd, &t, 4) == 4);
assert (write (fd, P->print_name, t) == t);
assert (write (fd, &P->encr_chat.state, 4) == 4);
assert (write (fd, &P->encr_chat.user_id, 4) == 4);
assert (write (fd, &P->encr_chat.admin_id, 4) == 4);
assert (write (fd, &P->encr_chat.ttl, 4) == 4);
assert (write (fd, &P->encr_chat.access_hash, 8) == 8);
if (P->encr_chat.state != sc_waiting) {
assert (write (fd, P->encr_chat.g_key, 256) == 256);
}
if (P->encr_chat.state != sc_waiting) {
assert (write (fd, P->encr_chat.nonce, 256) == 256);
}
assert (write (fd, P->encr_chat.key, 256) == 256);
assert (write (fd, &P->encr_chat.key_fingerprint, 8) == 8);
}
}
void write_secret_chat_file (void) {
if (binlog_enabled) { return; }
int fd = open (get_secret_chat_filename (), O_CREAT | O_RDWR, 0600);
if (fd < 0) {
return;
}
int x[2];
x[0] = SECRET_CHAT_FILE_MAGIC;
x[1] = 1;
assert (write (fd, x, 8) == 8);
int cc = 0;
tgl_peer_iterator_ex (count_encr_peer, &cc);
tgl_peer_iterator_ex (write_encr_peer, &fd);
assert (write (fd, &encr_root, 4) == 4);
if (encr_root) {
assert (write (fd, &encr_param_version, 4) == 4);
assert (write (fd, encr_prime, 256) == 256);
}
close (fd);
}*/
extern int max_chat_size; extern int max_chat_size;
int mcs (void) { int mcs (void) {
return max_chat_size; return max_chat_size;
...@@ -456,19 +164,17 @@ int new_dc_num; ...@@ -456,19 +164,17 @@ int new_dc_num;
int wait_dialog_list; int wait_dialog_list;
int loop (void) { int loop (void) {
on_start (); //on_start ();
if (binlog_enabled) { tgl_init ();
double t = get_double_time ();
logprintf ("replay log start\n"); double t = get_double_time ();
tgl_replay_log (); logprintf ("replay log start\n");
logprintf ("replay log end in %lf seconds\n", get_double_time () - t); tgl_replay_log ();
tgl_reopen_binlog_for_writing (); logprintf ("replay log end in %lf seconds\n", get_double_time () - t);
#ifdef USE_LUA tgl_reopen_binlog_for_writing ();
lua_binlog_end (); #ifdef USE_LUA
#endif lua_binlog_end ();
} else { #endif
read_auth_file ();
}
update_prompt (); update_prompt ();
assert (DC_list[dc_working_num]); assert (DC_list[dc_working_num]);
......
...@@ -386,8 +386,8 @@ void usage (void) { ...@@ -386,8 +386,8 @@ void usage (void) {
exit (1); exit (1);
} }
extern char *rsa_public_key_name; //extern char *rsa_public_key_name;
extern int default_dc_num; //extern int default_dc_num;
char *log_net_file; char *log_net_file;
FILE *log_net_f; FILE *log_net_f;
...@@ -406,7 +406,8 @@ void args_parse (int argc, char **argv) { ...@@ -406,7 +406,8 @@ void args_parse (int argc, char **argv) {
set_default_username (optarg); set_default_username (optarg);
break; break;
case 'k': case 'k':
rsa_public_key_name = tstrdup (optarg); //rsa_public_key_name = tstrdup (optarg);
tgl_set_rsa_key (optarg);
break; break;
case 'v': case 'v':
tgl_incr_verbosity (); tgl_incr_verbosity ();
......
This diff is collapsed.
...@@ -19,15 +19,76 @@ ...@@ -19,15 +19,76 @@
*/ */
#ifndef __MTPROTO_CLIENT_H__ #ifndef __MTPROTO_CLIENT_H__
#define __MTPROTO_CLIENT_H__ #define __MTPROTO_CLIENT_H__
#include "net.h" //#include "net.h"
#include <openssl/bn.h> #include <openssl/bn.h>
void on_start (void); //void on_start (void);
long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful); //..long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful);
void dc_authorize (struct dc *DC); //void dc_authorize (struct dc *DC);
void work_update (struct connection *c, long long msg_id); //void work_update (struct connection *c, long long msg_id);
void work_update_binlog (void); //void work_update_binlog (void);
int check_g (unsigned char p[256], BIGNUM *g); //int check_g (unsigned char p[256], BIGNUM *g);
int check_g_bn (BIGNUM *p, BIGNUM *g); //int check_g_bn (BIGNUM *p, BIGNUM *g);
int check_DH_params (BIGNUM *p, int g); //int check_DH_params (BIGNUM *p, int g);
void secure_random (void *s, int l); //void secure_random (void *s, int l);
struct connection;
struct dc;
//#include "queries.h"
#define TG_SERVER "173.240.5.1"
#define TG_SERVER_TEST "173.240.5.253"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define ACK_TIMEOUT 1
#define MAX_DC_ID 10
struct connection;
enum dc_state {
st_init,
st_reqpq_sent,
st_reqdh_sent,
st_client_dh_sent,
st_authorized,
st_error
};
#define MAX_DC_SESSIONS 3
struct session {
struct dc *dc;
long long session_id;
int seq_no;
struct connection *c;
struct tree_long *ack_tree;
struct event *ev;
//struct event_timer ev;
};
struct dc {
int id;
int port;
int flags;
enum dc_state state;
char *ip;
char *user;
struct session *sessions[MAX_DC_SESSIONS];
char auth_key[256];
long long auth_key_id;
long long server_salt;
int server_time_delta;
double server_time_udelta;
int has_auth;
};
long long tglmp_encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful);
void tglmp_dc_create_session (struct dc *DC);
int tglmp_check_g (unsigned char p[256], BIGNUM *g);
int tglmp_check_DH_params (BIGNUM *p, int g);
struct dc *tglmp_alloc_dc (int id, char *ip, int port);
void tgln_insert_msg_id (struct session *S, long long id);
void tglmp_on_start (const char *key);
void tgl_dc_authorize (struct dc *DC);
#endif #endif
...@@ -53,9 +53,9 @@ int *packet_buffer = __packet_buffer + 16; ...@@ -53,9 +53,9 @@ int *packet_buffer = __packet_buffer + 16;
long long rsa_encrypted_chunks, rsa_decrypted_chunks; long long rsa_encrypted_chunks, rsa_decrypted_chunks;
BN_CTX *BN_ctx; BN_CTX *BN_ctx;
int verbosity; //int verbosity;
int get_random_bytes (unsigned char *buf, int n) { static int get_random_bytes (unsigned char *buf, int n) {
int r = 0, h = open ("/dev/random", O_RDONLY | O_NONBLOCK); int r = 0, h = open ("/dev/random", O_RDONLY | O_NONBLOCK);
if (h >= 0) { if (h >= 0) {
r = read (h, buf, n); r = read (h, buf, n);
...@@ -87,20 +87,6 @@ int get_random_bytes (unsigned char *buf, int n) { ...@@ -87,20 +87,6 @@ int get_random_bytes (unsigned char *buf, int n) {
return r; return r;
} }
void my_clock_gettime (int clock_id UU, struct timespec *T) {
#ifdef __MACH__
// We are ignoring MONOTONIC and hope time doesn't go back too often
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
T->tv_sec = mts.tv_sec;
T->tv_nsec = mts.tv_nsec;
#else
assert (clock_gettime(clock_id, T) >= 0);
#endif
}
/* RDTSC */ /* RDTSC */
#if defined(__i386__) #if defined(__i386__)
......
...@@ -25,12 +25,14 @@ ...@@ -25,12 +25,14 @@
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/aes.h> #include <openssl/aes.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h>
//#include "interface.h" //#include "interface.h"
#include "tools.h" #include "tools.h"
#include "auto/constants.h" #include "auto/constants.h"
#include "tgl.h" #include "tgl.h"
#include "tgl-inner.h"
/* DH key exchange protocol data structures */ /* DH key exchange protocol data structures */
#define CODE_req_pq 0x60469778 #define CODE_req_pq 0x60469778
#define CODE_resPQ 0x05162463 #define CODE_resPQ 0x05162463
...@@ -157,10 +159,10 @@ static inline void out_bignum (BIGNUM *n) { ...@@ -157,10 +159,10 @@ static inline void out_bignum (BIGNUM *n) {
extern int *in_ptr, *in_end; extern int *in_ptr, *in_end;
void fetch_pts (void); //void fetch_pts (void);
void fetch_qts (void); //void fetch_qts (void);
void fetch_date (void); //void fetch_date (void);
void fetch_seq (void); //void fetch_seq (void);
static inline int prefetch_strlen (void) { static inline int prefetch_strlen (void) {
if (in_ptr >= in_end) { if (in_ptr >= in_end) {
return -1; return -1;
...@@ -331,7 +333,7 @@ static inline void fetch256 (void *buf) { ...@@ -331,7 +333,7 @@ static inline void fetch256 (void *buf) {
} }
} }
int get_random_bytes (unsigned char *buf, int n); //int get_random_bytes (unsigned char *buf, int n);
int pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *E); int pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *E);
int pad_rsa_decrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *D); int pad_rsa_decrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *D);
......
This diff is collapsed.
...@@ -20,59 +20,6 @@ ...@@ -20,59 +20,6 @@
#define __NET_H__ #define __NET_H__
#include <poll.h> #include <poll.h>
struct dc;
#include "queries.h"
#define TG_SERVER "173.240.5.1"
#define TG_SERVER_TEST "173.240.5.253"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define ACK_TIMEOUT 1
#define MAX_DC_ID 10
enum dc_state {
st_init,
st_reqpq_sent,
st_reqdh_sent,
st_client_dh_sent,
st_authorized,
st_error
} ;
struct connection;
struct connection_methods {
int (*ready) (struct connection *c);
int (*close) (struct connection *c);
int (*execute) (struct connection *c, int op, int len);
};
#define MAX_DC_SESSIONS 3
struct session {
struct dc *dc;
long long session_id;
int seq_no;
struct connection *c;
struct tree_long *ack_tree;
struct event_timer ev;
};
struct dc {
int id;
int port;
int flags;
char *ip;
char *user;
struct session *sessions[MAX_DC_SESSIONS];
char auth_key[256];
long long auth_key_id;
long long server_salt;
int server_time_delta;
double server_time_udelta;
int has_auth;
};
#define DC_SERIALIZED_MAGIC 0x64582faa #define DC_SERIALIZED_MAGIC 0x64582faa
#define DC_SERIALIZED_MAGIC_V2 0x94032abb #define DC_SERIALIZED_MAGIC_V2 0x94032abb
...@@ -122,27 +69,32 @@ struct connection { ...@@ -122,27 +69,32 @@ struct connection {
int out_packet_num; int out_packet_num;
int last_connect_time; int last_connect_time;
int in_fail_timer; int in_fail_timer;
struct connection_methods *methods; struct mtproto_methods *methods;
struct session *session; struct session *session;
void *extra; void *extra;
struct event_timer ev; struct event *ping_ev;
struct event *fail_ev;
struct event *read_ev;
struct event *write_ev;
double last_receive_time; double last_receive_time;
}; };
extern struct connection *Connections[]; //extern struct connection *Connections[];
int tgln_write_out (struct connection *c, const void *data, int len);
void tgln_flush_out (struct connection *c);
int tgln_read_in (struct connection *c, void *data, int len);
int tgln_read_in_lookup (struct connection *c, void *data, int len);
void tgln_insert_msg_id (struct session *S, long long id);
int write_out (struct connection *c, const void *data, int len);
void flush_out (struct connection *c);
int read_in (struct connection *c, void *data, int len);
void create_all_outbound_connections (void); //void create_all_outbound_connections (void);
struct connection *create_connection (const char *host, int port, struct session *session, struct connection_methods *methods); //struct connection *create_connection (const char *host, int port, struct session *session, struct connection_methods *methods);
int connections_make_poll_array (struct pollfd *fds, int max); struct dc *tgln_alloc_dc (int id, char *ip, int port);
void connections_poll_result (struct pollfd *fds, int max); void tgln_dc_create_session (struct dc *DC, struct mtproto_methods *methods);
void dc_create_session (struct dc *DC); struct connection *tgln_create_connection (const char *host, int port, struct session *session, struct mtproto_methods *methods);
void insert_msg_id (struct session *S, long long id);
struct dc *alloc_dc (int id, char *ip, int port);
#define GET_DC(c) (c->session->dc) #define GET_DC(c) (c->session->dc)
#endif #endif
This diff is collapsed.
...@@ -16,13 +16,15 @@ ...@@ -16,13 +16,15 @@
Copyright Vitaly Valtman 2013 Copyright Vitaly Valtman 2013
*/ */
#include "net.h" //#include "net.h"
#ifndef __QUERIES_H__ #ifndef __QUERIES_H__
#define __QUERIES_H__ #define __QUERIES_H__
#include "structures.h" #include "structures.h"
#include "auto.h" #include "auto.h"
#include "tgl-layout.h" #include "tgl-layout.h"
struct event;
#define QUERY_ACK_RECEIVED 1 #define QUERY_ACK_RECEIVED 1
struct query; struct query;
...@@ -33,12 +35,6 @@ struct query_methods { ...@@ -33,12 +35,6 @@ struct query_methods {
struct paramed_type *type; struct paramed_type *type;
}; };
struct event_timer {
double timeout;
int (*alarm)(void *self);
void *self;
};
struct query { struct query {
long long msg_id; long long msg_id;
int data_len; int data_len;
...@@ -46,7 +42,7 @@ struct query { ...@@ -46,7 +42,7 @@ struct query {
int seq_no; int seq_no;
void *data; void *data;
struct query_methods *methods; struct query_methods *methods;
struct event_timer ev; struct event *ev;
struct dc *DC; struct dc *DC;
struct session *session; struct session *session;
void *extra; void *extra;
...@@ -55,14 +51,12 @@ struct query { ...@@ -55,14 +51,12 @@ struct query {
}; };
struct query *send_query (struct dc *DC, int len, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra); struct query *tglq_send_query (struct dc *DC, int len, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra);
void query_ack (long long id); void tglq_query_ack (long long id);
void query_error (long long id); void tglq_query_error (long long id);
void query_result (long long id); void tglq_query_result (long long id);
void query_restart (long long id); void tglq_query_restart (long long id);
void insert_event_timer (struct event_timer *ev);
void remove_event_timer (struct event_timer *ev);
double next_timer_in (void); double next_timer_in (void);
void work_timers (void); void work_timers (void);
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <openssl/sha.h> #include <openssl/sha.h>
#include "queries.h" #include "queries.h"
#include "binlog.h" #include "binlog.h"
#include "updates.h"
#include "tgl.h" #include "tgl.h"
...@@ -497,7 +498,7 @@ void tglf_fetch_photo_size (struct tgl_photo_size *S) { ...@@ -497,7 +498,7 @@ void tglf_fetch_photo_size (struct tgl_photo_size *S) {
} }
} }
void fetch_geo (struct tgl_geo *G) { void tglf_fetch_geo (struct tgl_geo *G) {
unsigned x = fetch_int (); unsigned x = fetch_int ();
if (x == CODE_geo_point) { if (x == CODE_geo_point) {
G->longitude = fetch_double (); G->longitude = fetch_double ();
...@@ -519,7 +520,7 @@ void tglf_fetch_photo (struct tgl_photo *P) { ...@@ -519,7 +520,7 @@ void tglf_fetch_photo (struct tgl_photo *P) {
P->user_id = fetch_int (); P->user_id = fetch_int ();
P->date = fetch_int (); P->date = fetch_int ();
P->caption = fetch_str_dup (); P->caption = fetch_str_dup ();
fetch_geo (&P->geo); tglf_fetch_geo (&P->geo);
assert (fetch_int () == CODE_vector); assert (fetch_int () == CODE_vector);
P->sizes_num = fetch_int (); P->sizes_num = fetch_int ();
P->sizes = talloc (sizeof (struct tgl_photo_size) * P->sizes_num); P->sizes = talloc (sizeof (struct tgl_photo_size) * P->sizes_num);
...@@ -630,10 +631,10 @@ void tglf_fetch_message_short (struct tgl_message *M) { ...@@ -630,10 +631,10 @@ void tglf_fetch_message_short (struct tgl_message *M) {
int l = prefetch_strlen (); int l = prefetch_strlen ();
char *s = fetch_str (l); char *s = fetch_str (l);
fetch_pts (); tglu_fetch_pts ();
int date = fetch_int (); int date = fetch_int ();
fetch_seq (); tglu_fetch_seq ();
bl_do_create_message_text (id, from_id, TGL_PEER_USER, to_id, date, l, s); bl_do_create_message_text (id, from_id, TGL_PEER_USER, to_id, date, l, s);
} else { } else {
...@@ -642,9 +643,9 @@ void tglf_fetch_message_short (struct tgl_message *M) { ...@@ -642,9 +643,9 @@ void tglf_fetch_message_short (struct tgl_message *M) {
int l = prefetch_strlen (); int l = prefetch_strlen ();
fetch_str (l); // text fetch_str (l); // text
fetch_pts (); tglu_fetch_pts ();
fetch_int (); fetch_int ();
fetch_seq (); tglu_fetch_seq ();
} }
} }
...@@ -658,10 +659,10 @@ void tglf_fetch_message_short_chat (struct tgl_message *M) { ...@@ -658,10 +659,10 @@ void tglf_fetch_message_short_chat (struct tgl_message *M) {
int l = prefetch_strlen (); int l = prefetch_strlen ();
char *s = fetch_str (l); char *s = fetch_str (l);
fetch_pts (); tglu_fetch_pts ();
int date = fetch_int (); int date = fetch_int ();
fetch_seq (); tglu_fetch_seq ();
bl_do_create_message_text (id, from_id, TGL_PEER_CHAT, to_id, date, l, s); bl_do_create_message_text (id, from_id, TGL_PEER_CHAT, to_id, date, l, s);
} else { } else {
...@@ -671,9 +672,9 @@ void tglf_fetch_message_short_chat (struct tgl_message *M) { ...@@ -671,9 +672,9 @@ void tglf_fetch_message_short_chat (struct tgl_message *M) {
int l = prefetch_strlen (); int l = prefetch_strlen ();
fetch_str (l); // text fetch_str (l); // text
fetch_pts (); tglu_fetch_pts ();
fetch_int (); fetch_int ();
fetch_seq (); tglu_fetch_seq ();
} }
} }
...@@ -697,7 +698,7 @@ void tglf_fetch_message_media (struct tgl_message_media *M) { ...@@ -697,7 +698,7 @@ void tglf_fetch_message_media (struct tgl_message_media *M) {
tglf_fetch_document (&M->document); tglf_fetch_document (&M->document);
break; break;
case CODE_message_media_geo: case CODE_message_media_geo:
fetch_geo (&M->geo); tglf_fetch_geo (&M->geo);
break; break;
case CODE_message_media_contact: case CODE_message_media_contact:
M->phone = fetch_str_dup (); M->phone = fetch_str_dup ();
...@@ -995,7 +996,7 @@ void tglf_fetch_message (struct tgl_message *M) { ...@@ -995,7 +996,7 @@ void tglf_fetch_message (struct tgl_message *M) {
bl_do_set_unread (M, unread); bl_do_set_unread (M, unread);
} }
void tglf_fetch_geo_message (struct tgl_message *M) { void tglf_tglf_fetch_geo_message (struct tgl_message *M) {
memset (M, 0, sizeof (*M)); memset (M, 0, sizeof (*M));
unsigned x = fetch_int (); unsigned x = fetch_int ();
assert (x == CODE_geo_chat_message_empty || x == CODE_geo_chat_message || x == CODE_geo_chat_message_service); assert (x == CODE_geo_chat_message_empty || x == CODE_geo_chat_message || x == CODE_geo_chat_message_service);
...@@ -1254,7 +1255,7 @@ struct tgl_message *tglf_fetch_alloc_message (void) { ...@@ -1254,7 +1255,7 @@ struct tgl_message *tglf_fetch_alloc_message (void) {
struct tgl_message *tglf_fetch_alloc_geo_message (void) { struct tgl_message *tglf_fetch_alloc_geo_message (void) {
struct tgl_message *M = talloc (sizeof (*M)); struct tgl_message *M = talloc (sizeof (*M));
tglf_fetch_geo_message (M); tglf_tglf_fetch_geo_message (M);
struct tgl_message *M1 = tree_lookup_message (message_tree, M); struct tgl_message *M1 = tree_lookup_message (message_tree, M);
messages_allocated ++; messages_allocated ++;
if (M1) { if (M1) {
......
#ifndef __TGL_INNER_H__
#define __TGL_INNER_H__
#define vlogprintf(verbosity_level,...) \
do { \
if (tgl_state.verbosity >= verbosity_level) { \
tgl_state.callback.logprintf (__VA_ARGS__); \
} \
} while (0)
#endif
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
#endif #endif
#include "tgl.h" #include "tgl.h"
#include "tools.h"
#include "mtproto-client.h"
#include <event2/event.h>
struct tgl_state tgl_state; struct tgl_state tgl_state;
...@@ -21,3 +25,16 @@ void tgl_set_auth_file_path (const char *path) { ...@@ -21,3 +25,16 @@ void tgl_set_auth_file_path (const char *path) {
void tgl_set_download_directory (const char *path) { void tgl_set_download_directory (const char *path) {
tgl_state.downloads_directory = tstrdup (path); tgl_state.downloads_directory = tstrdup (path);
} }
void tgl_set_callback (struct tgl_update_callback *cb) {
tgl_state.callback = *cb;
}
void tgl_set_rsa_key (const char *key) {
tgl_state.rsa_key = tstrdup (key);
}
void tgl_init (void) {
tgl_state.ev_base = event_base_new ();
tglmp_on_start (tgl_state.rsa_key);
}
...@@ -10,22 +10,37 @@ ...@@ -10,22 +10,37 @@
#define TGL_VERSION "0.9-beta" #define TGL_VERSION "0.9-beta"
// Do not modify this structure, unless you know what you do // Do not modify this structure, unless you know what you do
struct connection;
struct mtproto_methods;
struct session;
struct dc;
struct tgl_update_callback { struct tgl_update_callback {
void (*new_msg)(struct tgl_message *M); void (*new_msg)(struct tgl_message *M);
void (*marked_read)(int num, struct tgl_message *list[]); void (*marked_read)(int num, struct tgl_message *list[]);
void (*logprintf)(const char *format, ...) __attribute__ ((format (printf, 1, 2))); void (*logprintf)(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void (*type_notification)(tgl_peer_id_t id, struct tgl_user *U); void (*type_notification)(struct tgl_user *U);
void (*type_in_chat_notification)(tgl_peer_id_t id, struct tgl_user *U, tgl_peer_id_t chat_id, struct tgl_chat *C); void (*type_in_chat_notification)(struct tgl_user *U, struct tgl_chat *C);
void (*type_in_secret_chat_notification)(struct tgl_secret_chat *E);
void (*status_notification)(struct tgl_user *U); void (*status_notification)(struct tgl_user *U);
void (*user_registered)(struct tgl_user *U); void (*user_registered)(struct tgl_user *U);
void (*user_activated)(struct tgl_user *U);
void (*new_authorization)(const char *device, const char *location);
void (*secret_chat_request)(struct tgl_secret_chat *E);
void (*secret_chat_established)(struct tgl_secret_chat *E);
void (*secret_chat_deleted)(struct tgl_secret_chat *E);
}; };
#define vlogprintf(verbosity_level,...) \ struct tgl_net_methods {
do { \ int (*write_out) (struct connection *c, void *data, int len);
if (tgl_state.verbosity >= verbosity_level) { \ int (*read_in) (struct connection *c, void *data, int len);
tgl_state.callback.logprintf (__VA_ARGS__); \ int (*read_in_lookup) (struct connection *c, void *data, int len);
} \ int (*flush_out) (struct connection *c);
} while (0) void (*incr_out_packet_num) (struct connection *c);
struct dc *(*get_dc) (struct connection *c);
struct session *(*get_session) (struct connection *c);
struct connection *(*create_connection) (const char *host, int port, struct dc *dc, struct session *session, struct mtproto_methods *methods);
};
#define E_ERROR 0 #define E_ERROR 0
...@@ -61,6 +76,10 @@ struct tgl_state { ...@@ -61,6 +76,10 @@ struct tgl_state {
char *downloads_directory; char *downloads_directory;
struct tgl_update_callback callback; struct tgl_update_callback callback;
struct tgl_net_methods *net_methods;
struct event_base *ev_base;
char *rsa_key;
}; };
extern struct tgl_state tgl_state; extern struct tgl_state tgl_state;
...@@ -94,6 +113,8 @@ void tgl_set_binlog_mode (int mode); ...@@ -94,6 +113,8 @@ void tgl_set_binlog_mode (int mode);
void tgl_set_binlog_path (const char *path); void tgl_set_binlog_path (const char *path);
void tgl_set_auth_file_path (const char *path); void tgl_set_auth_file_path (const char *path);
void tgl_set_download_directory (const char *path); void tgl_set_download_directory (const char *path);
void tgl_set_callback (struct tgl_update_callback *cb);
void tgl_set_rsa_key (const char *key);
static inline int tgl_get_peer_type (tgl_peer_id_t id) { static inline int tgl_get_peer_type (tgl_peer_id_t id) {
...@@ -127,6 +148,10 @@ static inline void tgl_set_test_mode (void) { ...@@ -127,6 +148,10 @@ static inline void tgl_set_test_mode (void) {
tgl_state.test_mode ++; tgl_state.test_mode ++;
} }
struct pollfd;
int tgl_connections_make_poll_array (struct pollfd *fds, int max);
void tgl_connections_poll_result (struct pollfd *fds, int max);
void tgl_do_help_get_config (void (*callback)(void *callback_extra, int success), void *callback_extra); void tgl_do_help_get_config (void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_send_code (const char *user, void (*callback)(void *callback_extra, int success, int registered, const char *hash), void *callback_extra); void tgl_do_send_code (const char *user, void (*callback)(void *callback_extra, int success, int registered, const char *hash), void *callback_extra);
void tgl_do_phone_call (const char *user, void (*callback)(void *callback_extra, int success), void *callback_extra); void tgl_do_phone_call (const char *user, void (*callback)(void *callback_extra, int success), void *callback_extra);
...@@ -168,8 +193,19 @@ void tgl_do_update_status (int online, void (*callback)(void *callback_extra, in ...@@ -168,8 +193,19 @@ void tgl_do_update_status (int online, void (*callback)(void *callback_extra, in
void tgl_do_visualize_key (tgl_peer_id_t id, unsigned char buf[16]); void tgl_do_visualize_key (tgl_peer_id_t id, unsigned char buf[16]);
void tgl_do_send_ping (struct connection *c);
//void tgl_do_get_suggested (void); //void tgl_do_get_suggested (void);
void tgl_do_create_keys_end (struct tgl_secret_chat *U); void tgl_do_create_keys_end (struct tgl_secret_chat *U);
void tgl_do_send_encr_chat_layer (struct tgl_secret_chat *E); void tgl_do_send_encr_chat_layer (struct tgl_secret_chat *E);
struct mtproto_methods {
int (*ready) (struct connection *c);
int (*close) (struct connection *c);
int (*execute) (struct connection *c, int op, int len);
};
void tgl_init (void);
void tgl_dc_authorize (struct dc *DC);
#endif #endif
...@@ -28,9 +28,12 @@ ...@@ -28,9 +28,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/rand.h>
#include <zlib.h> #include <zlib.h>
#include <time.h>
#include <sys/time.h>
#include "interface.h" //#include "interface.h"
#include "tools.h" #include "tools.h"
#ifdef DEBUG #ifdef DEBUG
...@@ -43,6 +46,15 @@ int used_blocks; ...@@ -43,6 +46,15 @@ int used_blocks;
int free_blocks_cnt; int free_blocks_cnt;
#endif #endif
void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2), weak));
void logprintf (const char *format, ...) {
va_list ap;
va_start (ap, format);
vfprintf (stdout, format, ap);
va_end (ap);
}
extern int verbosity; extern int verbosity;
long long total_allocated_bytes; long long total_allocated_bytes;
...@@ -269,3 +281,35 @@ void texists (void *ptr, int size) { ...@@ -269,3 +281,35 @@ void texists (void *ptr, int size) {
assert (block_num < used_blocks); assert (block_num < used_blocks);
} }
#endif #endif
void my_clock_gettime (int clock_id, struct timespec *T) {
#ifdef __MACH__
// We are ignoring MONOTONIC and hope time doesn't go back too often
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
T->tv_sec = mts.tv_sec;
T->tv_nsec = mts.tv_nsec;
#else
assert (clock_gettime(clock_id, T) >= 0);
#endif
}
double get_double_time (void) {
struct timespec tv;
my_clock_gettime (CLOCK_REALTIME, &tv);
return tv.tv_sec + 1e-9 * tv.tv_nsec;
}
void tglt_secure_random (void *s, int l) {
if (RAND_bytes (s, l) < 0) {
/*if (allow_weak_random) {
RAND_pseudo_bytes (s, l);
} else {*/
assert (0 && "End of random. If you want, you can start with -w");
//}
}
}
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#ifndef __TOOLS_H__ #ifndef __TOOLS_H__
#define __TOOLS_H__ #define __TOOLS_H__
double get_double_time (void);
void *talloc (size_t size); void *talloc (size_t size);
void *trealloc (void *ptr, size_t old_size, size_t size); void *trealloc (void *ptr, size_t old_size, size_t size);
void *talloc0 (size_t size); void *talloc0 (size_t size);
...@@ -37,6 +39,8 @@ void tfree_secure (void *ptr, int size); ...@@ -37,6 +39,8 @@ void tfree_secure (void *ptr, int size);
int tsnprintf (char *buf, int len, const char *format, ...) __attribute__ ((format (printf, 3, 4))); int tsnprintf (char *buf, int len, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
int tasprintf (char **res, const char *format, ...) __attribute__ ((format (printf, 2, 3))); int tasprintf (char **res, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
void tglt_secure_random (void *s, int l);
#ifdef DEBUG #ifdef DEBUG
void tcheck (void); void tcheck (void);
void texists (void *ptr, int size); void texists (void *ptr, int size);
......
...@@ -32,7 +32,7 @@ struct tree_ ## X_NAME { \ ...@@ -32,7 +32,7 @@ struct tree_ ## X_NAME { \
int y;\ int y;\
};\ };\
\ \
struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\ static inline struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
struct tree_ ## X_NAME *T = talloc (sizeof (*T));\ struct tree_ ## X_NAME *T = talloc (sizeof (*T));\
T->x = x;\ T->x = x;\
T->y = y;\ T->y = y;\
...@@ -40,11 +40,11 @@ struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\ ...@@ -40,11 +40,11 @@ struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
return T;\ return T;\
}\ }\
\ \
void delete_tree_node_ ## X_NAME (struct tree_ ## X_NAME *T) {\ static inline void delete_tree_node_ ## X_NAME (struct tree_ ## X_NAME *T) {\
tfree (T, sizeof (*T));\ tfree (T, sizeof (*T));\
}\ }\
\ \
void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## X_NAME **L, struct tree_ ## X_NAME **R) {\ static inline void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## X_NAME **L, struct tree_ ## X_NAME **R) {\
if (!T) {\ if (!T) {\
*L = *R = 0;\ *L = *R = 0;\
} else {\ } else {\
...@@ -59,8 +59,8 @@ void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## ...@@ -59,8 +59,8 @@ void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ##
}\ }\
}\ }\
\ \
struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) __attribute__ ((warn_unused_result));\ static inline struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) __attribute__ ((warn_unused_result));\
struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) {\ static inline struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) {\
if (!T) {\ if (!T) {\
return new_tree_node_ ## X_NAME (x, y);\ return new_tree_node_ ## X_NAME (x, y);\
} else {\ } else {\
...@@ -81,7 +81,7 @@ struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP ...@@ -81,7 +81,7 @@ struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP
}\ }\
}\ }\
\ \
struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct tree_ ## X_NAME *R) {\ static inline struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct tree_ ## X_NAME *R) {\
if (!L || !R) {\ if (!L || !R) {\
return L ? L : R;\ return L ? L : R;\
} else {\ } else {\
...@@ -95,8 +95,8 @@ struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct ...@@ -95,8 +95,8 @@ struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct
}\ }\
}\ }\
\ \
struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((warn_unused_result));\ static inline struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((warn_unused_result));\
struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\ static inline struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
assert (T);\ assert (T);\
int c = X_CMP (x, T->x);\ int c = X_CMP (x, T->x);\
if (!c) {\ if (!c) {\
...@@ -113,13 +113,13 @@ struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP ...@@ -113,13 +113,13 @@ struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP
}\ }\
}\ }\
\ \
X_TYPE tree_get_min_ ## X_NAME (struct tree_ ## X_NAME *T) {\ static inline X_TYPE tree_get_min_ ## X_NAME (struct tree_ ## X_NAME *T) {\
if (!T) { return X_UNSET; } \ if (!T) { return X_UNSET; } \
while (T->left) { T = T->left; }\ while (T->left) { T = T->left; }\
return T->x; \ return T->x; \
} \ } \
\ \
X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\ static inline X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
int c;\ int c;\
while (T && (c = X_CMP (x, T->x))) {\ while (T && (c = X_CMP (x, T->x))) {\
T = (c < 0 ? T->left : T->right);\ T = (c < 0 ? T->left : T->right);\
...@@ -127,25 +127,25 @@ X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\ ...@@ -127,25 +127,25 @@ X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
return T ? T->x : X_UNSET;\ return T ? T->x : X_UNSET;\
}\ }\
\ \
void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) {\ static inline void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) {\
if (!T) { return; } \ if (!T) { return; } \
tree_act_ ## X_NAME (T->left, act); \ tree_act_ ## X_NAME (T->left, act); \
act (T->x); \ act (T->x); \
tree_act_ ## X_NAME (T->right, act); \ tree_act_ ## X_NAME (T->right, act); \
}\ }\
\ \
void tree_act_ex_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE, void *), void *extra) {\ static inline void tree_act_ex_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE, void *), void *extra) {\
if (!T) { return; } \ if (!T) { return; } \
tree_act_ex_ ## X_NAME (T->left, act, extra); \ tree_act_ex_ ## X_NAME (T->left, act, extra); \
act (T->x, extra); \ act (T->x, extra); \
tree_act_ex_ ## X_NAME (T->right, act, extra); \ tree_act_ex_ ## X_NAME (T->right, act, extra); \
}\ }\
\ \
int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) { \ static inline int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return 0; }\ if (!T) { return 0; }\
return 1 + tree_count_ ## X_NAME (T->left) + tree_count_ ## X_NAME (T->right); \ return 1 + tree_count_ ## X_NAME (T->left) + tree_count_ ## X_NAME (T->right); \
}\ }\
void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \ static inline void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return; }\ if (!T) { return; }\
if (T->left) { \ if (T->left) { \
assert (T->left->y <= T->y);\ assert (T->left->y <= T->y);\
...@@ -158,7 +158,7 @@ void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \ ...@@ -158,7 +158,7 @@ void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \
tree_check_ ## X_NAME (T->left); \ tree_check_ ## X_NAME (T->left); \
tree_check_ ## X_NAME (T->right); \ tree_check_ ## X_NAME (T->right); \
}\ }\
struct tree_ ## X_NAME *tree_clear_ ## X_NAME (struct tree_ ## X_NAME *T) { \ static inline struct tree_ ## X_NAME *tree_clear_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return 0; }\ if (!T) { return 0; }\
tree_clear_ ## X_NAME (T->left); \ tree_clear_ ## X_NAME (T->left); \
tree_clear_ ## X_NAME (T->right); \ tree_clear_ ## X_NAME (T->right); \
......
This diff is collapsed.
#ifndef __UPDATES_H__
#define __UPDATES_H__
struct connection;
void tglu_work_update (struct connection *c, long long msg_id);
void tglu_work_updates_to_long (struct connection *c, long long msg_id);
void tglu_work_update_short_chat_message (struct connection *c, long long msg_id);
void tglu_work_update_short_message (struct connection *c, long long msg_id);
void tglu_work_update_short (struct connection *c, long long msg_id);
void tglu_work_updates (struct connection *c, long long msg_id);
void tglu_fetch_pts (void);
void tglu_fetch_qts (void);
void tglu_fetch_seq (void);
void tglu_fetch_date (void);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment