Many fixes. Now (maybe) works authorization and get contact list query
This commit is contained in:
parent
3243c29a8c
commit
bf291df34a
1
Makefile
1
Makefile
@ -6,6 +6,7 @@ LD=cc
|
|||||||
SRC=main.c loop.c interface.c net.c mtproto-common.c mtproto-client.c queries.c structures.c
|
SRC=main.c loop.c interface.c net.c mtproto-common.c mtproto-client.c queries.c structures.c
|
||||||
OBJ=$(SRC:.c=.o)
|
OBJ=$(SRC:.c=.o)
|
||||||
EXE=telegram
|
EXE=telegram
|
||||||
|
HDRS=include.h interface.h loop.h mtproto-client.h mtproto-common.h net.h queries.h structures.h telegram.h tree.h
|
||||||
|
|
||||||
all: $(SRC) $(EXE)
|
all: $(SRC) $(EXE)
|
||||||
|
|
||||||
|
114
interface.c
114
interface.c
@ -9,6 +9,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "include.h"
|
#include "include.h"
|
||||||
#include "queries.h"
|
#include "queries.h"
|
||||||
|
|
||||||
|
#include "interface.h"
|
||||||
|
#include "telegram.h"
|
||||||
|
#include "structures.h"
|
||||||
char *default_prompt = ">";
|
char *default_prompt = ">";
|
||||||
|
|
||||||
char *get_default_prompt (void) {
|
char *get_default_prompt (void) {
|
||||||
@ -23,16 +27,18 @@ char *commands[] = {
|
|||||||
"help",
|
"help",
|
||||||
"msg",
|
"msg",
|
||||||
"contact_list",
|
"contact_list",
|
||||||
|
"stats",
|
||||||
0 };
|
0 };
|
||||||
|
|
||||||
int commands_flags[] = {
|
int commands_flags[] = {
|
||||||
070,
|
070,
|
||||||
072,
|
072,
|
||||||
00,
|
07,
|
||||||
|
07,
|
||||||
};
|
};
|
||||||
|
|
||||||
char *a = 0;
|
char *a = 0;
|
||||||
char **user_list = &a;
|
char *user_list[MAX_USER_NUM + 1];
|
||||||
char **chat_list = &a;
|
char **chat_list = &a;
|
||||||
|
|
||||||
int init_token (char **q) {
|
int init_token (char **q) {
|
||||||
@ -91,12 +97,27 @@ int get_complete_mode (void) {
|
|||||||
int s = 0;
|
int s = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
get_token (&q, &l);
|
get_token (&q, &l);
|
||||||
if (!*q) { return flags & 7; }
|
if (!*q) { return flags ? flags & 7 : 7; }
|
||||||
s ++;
|
s ++;
|
||||||
if (s <= 4) { flags >>= 3; }
|
if (s <= 4) { flags >>= 3; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int user_num;
|
||||||
|
extern struct user *Users[];
|
||||||
|
int complete_user_list (int index, const char *text, int len, char **R) {
|
||||||
|
index ++;
|
||||||
|
while (index < user_num && (!Users[index]->print_name || strncmp (Users[index]->print_name, text, len))) {
|
||||||
|
index ++;
|
||||||
|
}
|
||||||
|
if (index < user_num) {
|
||||||
|
*R = strdup (Users[index]->print_name);
|
||||||
|
return index;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int complete_string_list (char **list, int index, const char *text, int len, char **R) {
|
int complete_string_list (char **list, int index, const char *text, int len, char **R) {
|
||||||
index ++;
|
index ++;
|
||||||
while (list[index] && strncmp (list[index], text, len)) {
|
while (list[index] && strncmp (list[index], text, len)) {
|
||||||
@ -137,7 +158,7 @@ char *command_generator (const char *text, int state) {
|
|||||||
index = complete_string_list (commands, index, text, len, &R);
|
index = complete_string_list (commands, index, text, len, &R);
|
||||||
return R;
|
return R;
|
||||||
case 1:
|
case 1:
|
||||||
index = complete_string_list (user_list, index, text, len, &R);
|
index = complete_user_list (index, text, len, &R);
|
||||||
return R;
|
return R;
|
||||||
case 2:
|
case 2:
|
||||||
index = complete_string_list (chat_list, index, text, len, &R);
|
index = complete_string_list (chat_list, index, text, len, &R);
|
||||||
@ -154,27 +175,90 @@ char **complete_text (char *text, int start UU, int end UU) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void interpreter (char *line UU) {
|
void interpreter (char *line UU) {
|
||||||
|
if (line && *line) {
|
||||||
|
add_history (line);
|
||||||
|
}
|
||||||
if (!memcmp (line, "contact_list", 12)) {
|
if (!memcmp (line, "contact_list", 12)) {
|
||||||
do_update_contact_list ();
|
do_update_contact_list ();
|
||||||
|
} else if (!memcmp (line, "stats", 5)) {
|
||||||
|
static char stat_buf[1 << 15];
|
||||||
|
print_stat (stat_buf, (1 << 15) - 1);
|
||||||
|
printf ("%s\n", stat_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int readline_active;
|
||||||
void rprintf (const char *format, ...) {
|
void rprintf (const char *format, ...) {
|
||||||
|
int saved_point = 0;
|
||||||
int saved_point = rl_point;
|
char *saved_line = 0;
|
||||||
char *saved_line = rl_copy_text(0, rl_end);
|
if (readline_active) {
|
||||||
rl_save_prompt();
|
saved_point = rl_point;
|
||||||
rl_replace_line("", 0);
|
saved_line = rl_copy_text(0, rl_end);
|
||||||
rl_redisplay();
|
rl_save_prompt();
|
||||||
|
rl_replace_line("", 0);
|
||||||
|
rl_redisplay();
|
||||||
|
}
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, format);
|
va_start (ap, format);
|
||||||
vfprintf (stdout, format, ap);
|
vfprintf (stdout, format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
rl_restore_prompt();
|
if (readline_active) {
|
||||||
rl_replace_line(saved_line, 0);
|
rl_restore_prompt();
|
||||||
rl_point = saved_point;
|
rl_replace_line(saved_line, 0);
|
||||||
rl_redisplay();
|
rl_point = saved_point;
|
||||||
free(saved_line);
|
rl_redisplay();
|
||||||
|
free(saved_line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hexdump (int *in_ptr, int *in_end) {
|
||||||
|
int saved_point = 0;
|
||||||
|
char *saved_line = 0;
|
||||||
|
if (readline_active) {
|
||||||
|
saved_point = rl_point;
|
||||||
|
saved_line = rl_copy_text(0, rl_end);
|
||||||
|
rl_save_prompt();
|
||||||
|
rl_replace_line("", 0);
|
||||||
|
rl_redisplay();
|
||||||
|
}
|
||||||
|
int *ptr = in_ptr;
|
||||||
|
while (ptr < in_end) { fprintf (stdout, " %08x", *(ptr ++)); }
|
||||||
|
fprintf (stdout, "\n");
|
||||||
|
|
||||||
|
if (readline_active) {
|
||||||
|
rl_restore_prompt();
|
||||||
|
rl_replace_line(saved_line, 0);
|
||||||
|
rl_point = saved_point;
|
||||||
|
rl_redisplay();
|
||||||
|
free(saved_line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void logprintf (const char *format, ...) {
|
||||||
|
int saved_point = 0;
|
||||||
|
char *saved_line = 0;
|
||||||
|
if (readline_active) {
|
||||||
|
saved_point = rl_point;
|
||||||
|
saved_line = rl_copy_text(0, rl_end);
|
||||||
|
rl_save_prompt();
|
||||||
|
rl_replace_line("", 0);
|
||||||
|
rl_redisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf (COLOR_GREY " *** ");
|
||||||
|
va_list ap;
|
||||||
|
va_start (ap, format);
|
||||||
|
vfprintf (stdout, format, ap);
|
||||||
|
va_end (ap);
|
||||||
|
printf (COLOR_NORMAL);
|
||||||
|
|
||||||
|
if (readline_active) {
|
||||||
|
rl_restore_prompt();
|
||||||
|
rl_replace_line(saved_line, 0);
|
||||||
|
rl_point = saved_point;
|
||||||
|
rl_redisplay();
|
||||||
|
free(saved_line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
10
interface.h
10
interface.h
@ -1,9 +1,19 @@
|
|||||||
#ifndef __INTERFACE_H__
|
#ifndef __INTERFACE_H__
|
||||||
#define __INTERFACE_H__
|
#define __INTERFACE_H__
|
||||||
|
|
||||||
|
#define COLOR_RED "\033[31;1m"
|
||||||
|
#define COLOR_NORMAL "\033[0m"
|
||||||
|
#define COLOR_GREEN "\033[32;1m"
|
||||||
|
#define COLOR_GREY "\033[37;1m"
|
||||||
|
|
||||||
|
|
||||||
char *get_default_prompt (void);
|
char *get_default_prompt (void);
|
||||||
char *complete_none (const char *text, int state);
|
char *complete_none (const char *text, int state);
|
||||||
char **complete_text (char *text, int start, int end);
|
char **complete_text (char *text, int start, int end);
|
||||||
void interpreter (char *line);
|
void interpreter (char *line);
|
||||||
|
|
||||||
void rprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
void rprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||||
|
void iprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||||
|
void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||||
|
void hexdump (int *in_ptr, int *in_end);
|
||||||
#endif
|
#endif
|
||||||
|
2
loop.c
2
loop.c
@ -167,6 +167,7 @@ void read_auth_file (void) {
|
|||||||
close (auth_file_fd);
|
close (auth_file_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int readline_active;
|
||||||
int loop (void) {
|
int loop (void) {
|
||||||
on_start ();
|
on_start ();
|
||||||
read_auth_file ();
|
read_auth_file ();
|
||||||
@ -216,6 +217,7 @@ int loop (void) {
|
|||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
fflush (stderr);
|
fflush (stderr);
|
||||||
|
|
||||||
|
readline_active = 1;
|
||||||
rl_callback_handler_install (get_default_prompt (), interpreter);
|
rl_callback_handler_install (get_default_prompt (), interpreter);
|
||||||
rl_attempted_completion_function = (CPPFunction *) complete_text;
|
rl_attempted_completion_function = (CPPFunction *) complete_text;
|
||||||
rl_completion_entry_function = complete_none;
|
rl_completion_entry_function = complete_none;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "include.h"
|
#include "include.h"
|
||||||
#include "queries.h"
|
#include "queries.h"
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
#define sha1 SHA1
|
#define sha1 SHA1
|
||||||
|
|
||||||
@ -89,13 +90,13 @@ static int rsa_load_public_key (const char *public_key_name) {
|
|||||||
pubKey = NULL;
|
pubKey = NULL;
|
||||||
FILE *f = fopen (public_key_name, "r");
|
FILE *f = fopen (public_key_name, "r");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
fprintf (stderr, "Couldn't open public key file: %s\n", public_key_name);
|
logprintf ( "Couldn't open public key file: %s\n", public_key_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pubKey = PEM_read_RSAPublicKey (f, NULL, NULL, NULL);
|
pubKey = PEM_read_RSAPublicKey (f, NULL, NULL, NULL);
|
||||||
fclose (f);
|
fclose (f);
|
||||||
if (pubKey == NULL) {
|
if (pubKey == NULL) {
|
||||||
fprintf (stderr, "PEM_read_RSAPublicKey returns NULL.\n");
|
logprintf ( "PEM_read_RSAPublicKey returns NULL.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +206,7 @@ unsigned p1, p2;
|
|||||||
int process_respq_answer (struct connection *c, char *packet, int len) {
|
int process_respq_answer (struct connection *c, char *packet, int len) {
|
||||||
int i;
|
int i;
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "process_respq_answer(), len=%d\n", len);
|
logprintf ( "process_respq_answer(), len=%d\n", len);
|
||||||
}
|
}
|
||||||
assert (len >= 76);
|
assert (len >= 76);
|
||||||
assert (!*(long long *) packet);
|
assert (!*(long long *) packet);
|
||||||
@ -227,7 +228,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
|
|||||||
p1 = 0, p2 = 0;
|
p1 = 0, p2 = 0;
|
||||||
|
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
fprintf (stderr, "%lld received\n", what);
|
logprintf ( "%lld received\n", what);
|
||||||
}
|
}
|
||||||
|
|
||||||
int it = 0;
|
int it = 0;
|
||||||
@ -275,7 +276,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
|
|||||||
|
|
||||||
|
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "p1 = %d, p2 = %d, %d iterations\n", p1, p2, it);
|
logprintf ( "p1 = %d, p2 = %d, %d iterations\n", p1, p2, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ++p1; ///
|
/// ++p1; ///
|
||||||
@ -286,12 +287,12 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
|
|||||||
long long *fingerprints = (long long *) (from + 8);
|
long long *fingerprints = (long long *) (from + 8);
|
||||||
for (i = 0; i < fingerprints_num; i++) {
|
for (i = 0; i < fingerprints_num; i++) {
|
||||||
if (fingerprints[i] == pk_fingerprint) {
|
if (fingerprints[i] == pk_fingerprint) {
|
||||||
//fprintf (stderr, "found our public key at position %d\n", i);
|
//logprintf ( "found our public key at position %d\n", i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == fingerprints_num) {
|
if (i == fingerprints_num) {
|
||||||
fprintf (stderr, "fatal: don't have any matching keys (%016llx expected)\n", pk_fingerprint);
|
logprintf ( "fatal: don't have any matching keys (%016llx expected)\n", pk_fingerprint);
|
||||||
exit (2);
|
exit (2);
|
||||||
}
|
}
|
||||||
// create inner part (P_Q_inner_data)
|
// create inner part (P_Q_inner_data)
|
||||||
@ -378,10 +379,10 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
|
|||||||
|
|
||||||
int process_dh_answer (struct connection *c, char *packet, int len) {
|
int process_dh_answer (struct connection *c, char *packet, int len) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "process_dh_answer(), len=%d\n", len);
|
logprintf ( "process_dh_answer(), len=%d\n", len);
|
||||||
}
|
}
|
||||||
if (len < 116) {
|
if (len < 116) {
|
||||||
fprintf (stderr, "%u * %u = %llu", p1, p2, what);
|
logprintf ( "%u * %u = %llu", p1, p2, what);
|
||||||
}
|
}
|
||||||
assert (len >= 116);
|
assert (len >= 116);
|
||||||
assert (!*(long long *) packet);
|
assert (!*(long long *) packet);
|
||||||
@ -418,7 +419,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
|
|||||||
|
|
||||||
GET_DC(c)->server_time_delta = server_time - time (0);
|
GET_DC(c)->server_time_delta = server_time - time (0);
|
||||||
GET_DC(c)->server_time_udelta = server_time - get_utime (CLOCK_MONOTONIC);
|
GET_DC(c)->server_time_udelta = server_time - get_utime (CLOCK_MONOTONIC);
|
||||||
//fprintf (stderr, "server time is %d, delta = %d\n", server_time, server_time_delta);
|
//logprintf ( "server time is %d, delta = %d\n", server_time, server_time_delta);
|
||||||
|
|
||||||
// Build set_client_DH_params answer
|
// Build set_client_DH_params answer
|
||||||
clear_packet ();
|
clear_packet ();
|
||||||
@ -474,7 +475,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
|
|||||||
|
|
||||||
int process_auth_complete (struct connection *c UU, char *packet, int len) {
|
int process_auth_complete (struct connection *c UU, char *packet, int len) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "process_dh_answer(), len=%d\n", len);
|
logprintf ( "process_dh_answer(), len=%d\n", len);
|
||||||
}
|
}
|
||||||
assert (len == 72);
|
assert (len == 72);
|
||||||
assert (!*(long long *) packet);
|
assert (!*(long long *) packet);
|
||||||
@ -493,7 +494,7 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
|
|||||||
assert (!memcmp (packet + 56, sha1_buffer + 4, 16));
|
assert (!memcmp (packet + 56, sha1_buffer + 4, 16));
|
||||||
GET_DC(c)->server_salt = *(long long *)server_nonce ^ *(long long *)new_nonce;
|
GET_DC(c)->server_salt = *(long long *)server_nonce ^ *(long long *)new_nonce;
|
||||||
if (verbosity >= 3) {
|
if (verbosity >= 3) {
|
||||||
fprintf (stderr, "auth_key_id=%016llx\n", GET_DC(c)->auth_key_id);
|
logprintf ( "auth_key_id=%016llx\n", GET_DC(c)->auth_key_id);
|
||||||
}
|
}
|
||||||
//kprintf ("OK\n");
|
//kprintf ("OK\n");
|
||||||
|
|
||||||
@ -503,7 +504,7 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
|
|||||||
c_state = st_authorized;
|
c_state = st_authorized;
|
||||||
//return 1;
|
//return 1;
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "Auth success\n");
|
logprintf ( "Auth success\n");
|
||||||
}
|
}
|
||||||
auth_success ++;
|
auth_success ++;
|
||||||
GET_DC(c)->flags |= 1;
|
GET_DC(c)->flags |= 1;
|
||||||
@ -568,7 +569,7 @@ int aes_encrypt_message (struct dc *DC, struct encrypted_message *enc) {
|
|||||||
sha1 ((unsigned char *) &enc->server_salt, enc_len, sha1_buffer);
|
sha1 ((unsigned char *) &enc->server_salt, enc_len, sha1_buffer);
|
||||||
//printf ("enc_len is %d\n", enc_len);
|
//printf ("enc_len is %d\n", enc_len);
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
fprintf (stderr, "sending message with sha1 %08x\n", *(int *)sha1_buffer);
|
logprintf ( "sending message with sha1 %08x\n", *(int *)sha1_buffer);
|
||||||
}
|
}
|
||||||
memcpy (enc->msg_key, sha1_buffer + 4, 16);
|
memcpy (enc->msg_key, sha1_buffer + 4, 16);
|
||||||
init_aes_auth (DC->auth_key, enc->msg_key, AES_ENCRYPT);
|
init_aes_auth (DC->auth_key, enc->msg_key, AES_ENCRYPT);
|
||||||
@ -612,7 +613,7 @@ int auth_work_start (struct connection *c UU) {
|
|||||||
void rpc_execute_answer (struct connection *c, long long msg_id UU);
|
void rpc_execute_answer (struct connection *c, long long msg_id UU);
|
||||||
void work_container (struct connection *c, long long msg_id UU) {
|
void work_container (struct connection *c, long long msg_id UU) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "work_container: msg_id = %lld\n", msg_id);
|
logprintf ( "work_container: msg_id = %lld\n", msg_id);
|
||||||
}
|
}
|
||||||
assert (fetch_int () == CODE_msg_container);
|
assert (fetch_int () == CODE_msg_container);
|
||||||
int n = fetch_int ();
|
int n = fetch_int ();
|
||||||
@ -632,7 +633,7 @@ void work_container (struct connection *c, long long msg_id UU) {
|
|||||||
|
|
||||||
void work_new_session_created (struct connection *c, long long msg_id UU) {
|
void work_new_session_created (struct connection *c, long long msg_id UU) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "work_new_session_created: msg_id = %lld\n", msg_id);
|
logprintf ( "work_new_session_created: msg_id = %lld\n", msg_id);
|
||||||
}
|
}
|
||||||
assert (fetch_int () == (int)CODE_new_session_created);
|
assert (fetch_int () == (int)CODE_new_session_created);
|
||||||
fetch_long (); // first message id
|
fetch_long (); // first message id
|
||||||
@ -643,7 +644,7 @@ void work_new_session_created (struct connection *c, long long msg_id UU) {
|
|||||||
|
|
||||||
void work_msgs_ack (struct connection *c UU, long long msg_id UU) {
|
void work_msgs_ack (struct connection *c UU, long long msg_id UU) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "work_msgs_ack: msg_id = %lld\n", msg_id);
|
logprintf ( "work_msgs_ack: msg_id = %lld\n", msg_id);
|
||||||
}
|
}
|
||||||
assert (fetch_int () == CODE_msgs_ack);
|
assert (fetch_int () == CODE_msgs_ack);
|
||||||
assert (fetch_int () == CODE_vector);
|
assert (fetch_int () == CODE_vector);
|
||||||
@ -657,7 +658,7 @@ void work_msgs_ack (struct connection *c UU, long long msg_id UU) {
|
|||||||
|
|
||||||
void work_rpc_result (struct connection *c UU, long long msg_id UU) {
|
void work_rpc_result (struct connection *c UU, long long msg_id UU) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "work_rpc_result: msg_id = %lld\n", msg_id);
|
logprintf ( "work_rpc_result: msg_id = %lld\n", msg_id);
|
||||||
}
|
}
|
||||||
assert (fetch_int () == (int)CODE_rpc_result);
|
assert (fetch_int () == (int)CODE_rpc_result);
|
||||||
long long id = fetch_long ();
|
long long id = fetch_long ();
|
||||||
@ -685,7 +686,7 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
|
|||||||
work_rpc_result (c, msg_id);
|
work_rpc_result (c, msg_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fprintf (stderr, "Unknown message: \n");
|
logprintf ( "Unknown message: \n");
|
||||||
hexdump_in ();
|
hexdump_in ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +694,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
|
|||||||
const int MINSZ = offsetof (struct encrypted_message, message);
|
const int MINSZ = offsetof (struct encrypted_message, message);
|
||||||
const int UNENCSZ = offsetof (struct encrypted_message, server_salt);
|
const int UNENCSZ = offsetof (struct encrypted_message, server_salt);
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "process_rpc_message(), len=%d\n", len);
|
logprintf ( "process_rpc_message(), len=%d\n", len);
|
||||||
}
|
}
|
||||||
assert (len >= MINSZ && (len & 15) == (UNENCSZ & 15));
|
assert (len >= MINSZ && (len & 15) == (UNENCSZ & 15));
|
||||||
struct dc *DC = GET_DC(c);
|
struct dc *DC = GET_DC(c);
|
||||||
@ -717,7 +718,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
|
|||||||
assert (this_server_time >= st - 300 && this_server_time <= st + 30);
|
assert (this_server_time >= st - 300 && this_server_time <= st + 30);
|
||||||
//assert (enc->msg_id > server_last_msg_id && (enc->msg_id & 3) == 1);
|
//assert (enc->msg_id > server_last_msg_id && (enc->msg_id & 3) == 1);
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
fprintf (stderr, "received mesage id %016llx\n", enc->msg_id);
|
logprintf ( "received mesage id %016llx\n", enc->msg_id);
|
||||||
}
|
}
|
||||||
server_last_msg_id = enc->msg_id;
|
server_last_msg_id = enc->msg_id;
|
||||||
|
|
||||||
@ -727,7 +728,7 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
|
|||||||
assert (l >= (MINSZ - UNENCSZ) + 8);
|
assert (l >= (MINSZ - UNENCSZ) + 8);
|
||||||
//assert (enc->message[0] == CODE_rpc_result && *(long long *)(enc->message + 1) == client_last_msg_id);
|
//assert (enc->message[0] == CODE_rpc_result && *(long long *)(enc->message + 1) == client_last_msg_id);
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
fprintf (stderr, "OK, message is good!\n");
|
logprintf ( "OK, message is good!\n");
|
||||||
}
|
}
|
||||||
++good_messages;
|
++good_messages;
|
||||||
|
|
||||||
@ -745,11 +746,11 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
|
|||||||
|
|
||||||
int rpc_execute (struct connection *c, int op, int len) {
|
int rpc_execute (struct connection *c, int op, int len) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "outbound rpc connection #%d : received rpc answer %d with %d content bytes\n", c->fd, op, len);
|
logprintf ( "outbound rpc connection #%d : received rpc answer %d with %d content bytes\n", c->fd, op, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len >= MAX_RESPONSE_SIZE/* - 12*/ || len < 0/*12*/) {
|
if (len >= MAX_RESPONSE_SIZE/* - 12*/ || len < 0/*12*/) {
|
||||||
fprintf (stderr, "answer too long (%d bytes), skipping\n", len);
|
logprintf ( "answer too long (%d bytes), skipping\n", len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -758,7 +759,7 @@ int rpc_execute (struct connection *c, int op, int len) {
|
|||||||
assert (read_in (c, Response, Response_len) == Response_len);
|
assert (read_in (c, Response, Response_len) == Response_len);
|
||||||
Response[Response_len] = 0;
|
Response[Response_len] = 0;
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
fprintf (stderr, "have %d Response bytes\n", Response_len);
|
logprintf ( "have %d Response bytes\n", Response_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
|
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
|
||||||
@ -782,7 +783,7 @@ int rpc_execute (struct connection *c, int op, int len) {
|
|||||||
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
|
setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
fprintf (stderr, "fatal: cannot receive answer in state %d\n", c_state);
|
logprintf ( "fatal: cannot receive answer in state %d\n", c_state);
|
||||||
exit (2);
|
exit (2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -792,14 +793,14 @@ int rpc_execute (struct connection *c, int op, int len) {
|
|||||||
|
|
||||||
int tc_close (struct connection *c, int who) {
|
int tc_close (struct connection *c, int who) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "outbound http connection #%d : closing by %d\n", c->fd, who);
|
logprintf ( "outbound http connection #%d : closing by %d\n", c->fd, who);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tc_becomes_ready (struct connection *c) {
|
int tc_becomes_ready (struct connection *c) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "outbound connection #%d becomes ready\n", c->fd);
|
logprintf ( "outbound connection #%d becomes ready\n", c->fd);
|
||||||
}
|
}
|
||||||
char byte = 0xef;
|
char byte = 0xef;
|
||||||
assert (write_out (c, &byte, 1) == 1);
|
assert (write_out (c, &byte, 1) == 1);
|
||||||
@ -816,7 +817,7 @@ int tc_becomes_ready (struct connection *c) {
|
|||||||
auth_work_start (c);
|
auth_work_start (c);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf (stderr, "c_state = %d\n", c_state);
|
logprintf ( "c_state = %d\n", c_state);
|
||||||
assert (0);
|
assert (0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -842,7 +843,7 @@ void on_start (void) {
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "public key '%s' loaded successfully\n", rsa_public_key_name);
|
logprintf ( "public key '%s' loaded successfully\n", rsa_public_key_name);
|
||||||
}
|
}
|
||||||
pk_fingerprint = compute_rsa_key_fingerprint (pubKey);
|
pk_fingerprint = compute_rsa_key_fingerprint (pubKey);
|
||||||
}
|
}
|
||||||
@ -858,7 +859,7 @@ void dc_authorize (struct dc *DC) {
|
|||||||
dc_create_session (DC);
|
dc_create_session (DC);
|
||||||
}
|
}
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "Starting authorization for DC #%d: %s:%d\n", DC->id, DC->ip, DC->port);
|
logprintf ( "Starting authorization for DC #%d: %s:%d\n", DC->id, DC->ip, DC->port);
|
||||||
}
|
}
|
||||||
net_loop (0, auth_ok);
|
net_loop (0, auth_ok);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
#include "mtproto-common.h"
|
#include "mtproto-common.h"
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
long long rsa_encrypted_chunks, rsa_decrypted_chunks;
|
long long rsa_encrypted_chunks, rsa_decrypted_chunks;
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ int get_random_bytes (void *buf, int n) {
|
|||||||
r = read (h, buf, n);
|
r = read (h, buf, n);
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
if (verbosity >= 3) {
|
if (verbosity >= 3) {
|
||||||
fprintf (stderr, "added %d bytes of real entropy to secure random numbers seed\n", r);
|
logprintf ( "added %d bytes of real entropy to secure random numbers seed\n", r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close (h);
|
close (h);
|
||||||
@ -71,14 +72,14 @@ void prng_seed (const char *password_filename, int password_length) {
|
|||||||
if (password_filename) {
|
if (password_filename) {
|
||||||
int fd = open (password_filename, O_RDONLY);
|
int fd = open (password_filename, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf (stderr, "Warning: fail to open password file - \"%s\", %m.\n", password_filename);
|
logprintf ( "Warning: fail to open password file - \"%s\", %m.\n", password_filename);
|
||||||
} else {
|
} else {
|
||||||
int l = read (fd, a + s, password_length);
|
int l = read (fd, a + s, password_length);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
fprintf (stderr, "Warning: fail to read password file - \"%s\", %m.\n", password_filename);
|
logprintf ( "Warning: fail to read password file - \"%s\", %m.\n", password_filename);
|
||||||
} else {
|
} else {
|
||||||
if (verbosity > 0) {
|
if (verbosity > 0) {
|
||||||
fprintf (stderr, "read %d bytes from password file.\n", l);
|
logprintf ( "read %d bytes from password file.\n", l);
|
||||||
}
|
}
|
||||||
s += l;
|
s += l;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <openssl/aes.h>
|
#include <openssl/aes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "interface.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
|
||||||
@ -409,8 +410,6 @@ int pad_aes_encrypt (char *from, int from_len, char *to, int size);
|
|||||||
int pad_aes_decrypt (char *from, int from_len, char *to, int size);
|
int pad_aes_decrypt (char *from, int from_len, char *to, int size);
|
||||||
|
|
||||||
static inline void hexdump_in (void) {
|
static inline void hexdump_in (void) {
|
||||||
int *ptr = in_ptr;
|
hexdump (in_ptr, in_end);
|
||||||
while (ptr < in_end) { fprintf (stderr, " %08x", *(ptr ++)); }
|
|
||||||
fprintf (stderr, "\n");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
27
net.c
27
net.c
@ -17,6 +17,7 @@
|
|||||||
#include "mtproto-client.h"
|
#include "mtproto-client.h"
|
||||||
#include "mtproto-common.h"
|
#include "mtproto-common.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
DEFINE_TREE(int,int,int_cmp,0)
|
DEFINE_TREE(int,int,int_cmp,0)
|
||||||
|
|
||||||
@ -156,7 +157,7 @@ struct connection *create_connection (const char *host, int port, struct session
|
|||||||
|
|
||||||
if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
|
if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
|
||||||
if (errno != EINPROGRESS) {
|
if (errno != EINPROGRESS) {
|
||||||
fprintf (stderr, "Can not connect to %s:%d %m\n", host, port);
|
logprintf ( "Can not connect to %s:%d %m\n", host, port);
|
||||||
close (fd);
|
close (fd);
|
||||||
free (c);
|
free (c);
|
||||||
return 0;
|
return 0;
|
||||||
@ -183,7 +184,7 @@ struct connection *create_connection (const char *host, int port, struct session
|
|||||||
assert (!Connections[fd]);
|
assert (!Connections[fd]);
|
||||||
Connections[fd] = c;
|
Connections[fd] = c;
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "connect to %s:%d successful\n", host, port);
|
logprintf ( "connect to %s:%d successful\n", host, port);
|
||||||
}
|
}
|
||||||
if (c->methods->ready) {
|
if (c->methods->ready) {
|
||||||
c->methods->ready (c);
|
c->methods->ready (c);
|
||||||
@ -211,7 +212,7 @@ void fail_connection (struct connection *c) {
|
|||||||
|
|
||||||
void try_write (struct connection *c) {
|
void try_write (struct connection *c) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "try write: fd = %d\n", c->fd);
|
logprintf ( "try write: fd = %d\n", c->fd);
|
||||||
}
|
}
|
||||||
int x = 0;
|
int x = 0;
|
||||||
while (c->out_head) {
|
while (c->out_head) {
|
||||||
@ -238,12 +239,12 @@ void try_write (struct connection *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "Sent %d bytes to %d\n", x, c->fd);
|
logprintf ( "Sent %d bytes to %d\n", x, c->fd);
|
||||||
}
|
}
|
||||||
c->out_bytes -= x;
|
c->out_bytes -= x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hexdump (struct connection_buffer *b) {
|
void hexdump_buf (struct connection_buffer *b) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int rem = 8;
|
int rem = 8;
|
||||||
while (b) {
|
while (b) {
|
||||||
@ -270,7 +271,7 @@ void hexdump (struct connection_buffer *b) {
|
|||||||
void try_rpc_read (struct connection *c) {
|
void try_rpc_read (struct connection *c) {
|
||||||
assert (c->in_head);
|
assert (c->in_head);
|
||||||
if (verbosity >= 4) {
|
if (verbosity >= 4) {
|
||||||
hexdump (c->in_head);
|
hexdump_buf (c->in_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -307,7 +308,7 @@ void try_rpc_read (struct connection *c) {
|
|||||||
|
|
||||||
void try_read (struct connection *c) {
|
void try_read (struct connection *c) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "try read: fd = %d\n", c->fd);
|
logprintf ( "try read: fd = %d\n", c->fd);
|
||||||
}
|
}
|
||||||
if (!c->in_tail) {
|
if (!c->in_tail) {
|
||||||
c->in_head = c->in_tail = new_connection_buffer (1 << 20);
|
c->in_head = c->in_tail = new_connection_buffer (1 << 20);
|
||||||
@ -334,7 +335,7 @@ void try_read (struct connection *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "Received %d bytes from %d\n", x, c->fd);
|
logprintf ( "Received %d bytes from %d\n", x, c->fd);
|
||||||
}
|
}
|
||||||
c->in_bytes += x;
|
c->in_bytes += x;
|
||||||
if (x) {
|
if (x) {
|
||||||
@ -356,15 +357,15 @@ int connections_make_poll_array (struct pollfd *fds, int max) {
|
|||||||
fds ++;
|
fds ++;
|
||||||
max --;
|
max --;
|
||||||
}
|
}
|
||||||
if (verbosity >= 3) {
|
if (verbosity >= 10) {
|
||||||
fprintf (stderr, "%d connections in poll\n", _max - max);
|
logprintf ( "%d connections in poll\n", _max - max);
|
||||||
}
|
}
|
||||||
return _max - max;
|
return _max - max;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connections_poll_result (struct pollfd *fds, int max) {
|
void connections_poll_result (struct pollfd *fds, int max) {
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 10) {
|
||||||
fprintf (stderr, "connections_poll_result: max = %d\n", max);
|
logprintf ( "connections_poll_result: max = %d\n", max);
|
||||||
}
|
}
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < max; i++) {
|
for (i = 0; i < max; i++) {
|
||||||
@ -374,7 +375,7 @@ void connections_poll_result (struct pollfd *fds, int max) {
|
|||||||
}
|
}
|
||||||
if (fds[i].revents & (POLLHUP | POLLERR | POLLRDHUP)) {
|
if (fds[i].revents & (POLLHUP | POLLERR | POLLRDHUP)) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "fail connection\n");
|
logprintf ( "fail connection\n");
|
||||||
}
|
}
|
||||||
fail_connection (c);
|
fail_connection (c);
|
||||||
} else if (fds[i].revents & POLLOUT) {
|
} else if (fds[i].revents & POLLOUT) {
|
||||||
|
53
queries.c
53
queries.c
@ -43,7 +43,7 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
|
|||||||
dc_create_session (DC);
|
dc_create_session (DC);
|
||||||
}
|
}
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port);
|
logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port);
|
||||||
}
|
}
|
||||||
struct query *q = malloc (sizeof (*q));
|
struct query *q = malloc (sizeof (*q));
|
||||||
q->data_len = ints;
|
q->data_len = ints;
|
||||||
@ -51,11 +51,11 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
|
|||||||
memcpy (q->data, data, 4 * ints);
|
memcpy (q->data, data, 4 * ints);
|
||||||
q->msg_id = encrypt_send_message (DC->sessions[0]->c, data, ints, 1);
|
q->msg_id = encrypt_send_message (DC->sessions[0]->c, data, ints, 1);
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "Msg_id is %lld\n", q->msg_id);
|
logprintf ( "Msg_id is %lld\n", q->msg_id);
|
||||||
}
|
}
|
||||||
q->methods = methods;
|
q->methods = methods;
|
||||||
if (queries_tree) {
|
if (queries_tree) {
|
||||||
fprintf (stderr, "%lld %lld\n", q->msg_id, queries_tree->x->msg_id);
|
logprintf ( "%lld %lld\n", q->msg_id, queries_tree->x->msg_id);
|
||||||
}
|
}
|
||||||
queries_tree = tree_insert_query (queries_tree, q, lrand48 ());
|
queries_tree = tree_insert_query (queries_tree, q, lrand48 ());
|
||||||
|
|
||||||
@ -77,12 +77,12 @@ void query_error (long long id) {
|
|||||||
int error_len = prefetch_strlen ();
|
int error_len = prefetch_strlen ();
|
||||||
char *error = fetch_str (error_len);
|
char *error = fetch_str (error_len);
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
|
logprintf ( "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error);
|
||||||
}
|
}
|
||||||
struct query *q = query_get (id);
|
struct query *q = query_get (id);
|
||||||
if (!q) {
|
if (!q) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "No such query\n");
|
logprintf ( "No such query\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
remove_event_timer (&q->ev);
|
remove_event_timer (&q->ev);
|
||||||
@ -100,10 +100,10 @@ static int packed_buffer[MAX_PACKED_SIZE / 4];
|
|||||||
|
|
||||||
void query_result (long long id UU) {
|
void query_result (long long id UU) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "result for query #%lld\n", id);
|
logprintf ( "result for query #%lld\n", id);
|
||||||
}
|
}
|
||||||
if (verbosity >= 4) {
|
if (verbosity >= 4) {
|
||||||
fprintf (stderr, "result: ");
|
logprintf ( "result: ");
|
||||||
hexdump_in ();
|
hexdump_in ();
|
||||||
}
|
}
|
||||||
int op = prefetch_int ();
|
int op = prefetch_int ();
|
||||||
@ -124,8 +124,8 @@ void query_result (long long id UU) {
|
|||||||
|
|
||||||
int err = inflate (&strm, Z_FINISH);
|
int err = inflate (&strm, Z_FINISH);
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "inflate error = %d\n", err);
|
logprintf ( "inflate error = %d\n", err);
|
||||||
fprintf (stderr, "inflated %d bytes\n", (int)strm.total_out);
|
logprintf ( "inflated %d bytes\n", (int)strm.total_out);
|
||||||
}
|
}
|
||||||
end = in_ptr;
|
end = in_ptr;
|
||||||
eend = in_end;
|
eend = in_end;
|
||||||
@ -133,14 +133,14 @@ void query_result (long long id UU) {
|
|||||||
in_ptr = packed_buffer;
|
in_ptr = packed_buffer;
|
||||||
in_end = in_ptr + strm.total_out / 4;
|
in_end = in_ptr + strm.total_out / 4;
|
||||||
if (verbosity >= 4) {
|
if (verbosity >= 4) {
|
||||||
fprintf (stderr, "Unzipped data: ");
|
logprintf ( "Unzipped data: ");
|
||||||
hexdump_in ();
|
hexdump_in ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct query *q = query_get (id);
|
struct query *q = query_get (id);
|
||||||
if (!q) {
|
if (!q) {
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "No such query\n");
|
logprintf ( "No such query\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
remove_event_timer (&q->ev);
|
remove_event_timer (&q->ev);
|
||||||
@ -162,16 +162,18 @@ DEFINE_TREE (timer, struct event_timer *, event_timer_cmp, 0)
|
|||||||
struct tree_timer *timer_tree;
|
struct tree_timer *timer_tree;
|
||||||
|
|
||||||
void insert_event_timer (struct event_timer *ev) {
|
void insert_event_timer (struct event_timer *ev) {
|
||||||
return;
|
if (verbosity > 2) {
|
||||||
fprintf (stderr, "INSERT: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
|
logprintf ( "INSERT: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
|
||||||
|
}
|
||||||
tree_check_timer (timer_tree);
|
tree_check_timer (timer_tree);
|
||||||
timer_tree = tree_insert_timer (timer_tree, ev, lrand48 ());
|
timer_tree = tree_insert_timer (timer_tree, ev, lrand48 ());
|
||||||
tree_check_timer (timer_tree);
|
tree_check_timer (timer_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_event_timer (struct event_timer *ev) {
|
void remove_event_timer (struct event_timer *ev) {
|
||||||
return;
|
if (verbosity > 2) {
|
||||||
fprintf (stderr, "REMOVE: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
|
logprintf ( "REMOVE: %lf %p %p\n", ev->timeout, ev->self, ev->alarm);
|
||||||
|
}
|
||||||
tree_check_timer (timer_tree);
|
tree_check_timer (timer_tree);
|
||||||
timer_tree = tree_delete_timer (timer_tree, ev);
|
timer_tree = tree_delete_timer (timer_tree, ev);
|
||||||
tree_check_timer (timer_tree);
|
tree_check_timer (timer_tree);
|
||||||
@ -207,7 +209,7 @@ int help_get_config_on_answer (struct query *q UU) {
|
|||||||
assert (test_mode == CODE_bool_false);
|
assert (test_mode == CODE_bool_false);
|
||||||
int this_dc = fetch_int ();
|
int this_dc = fetch_int ();
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "this_dc = %d\n", this_dc);
|
logprintf ( "this_dc = %d\n", this_dc);
|
||||||
}
|
}
|
||||||
assert (fetch_int () == CODE_vector);
|
assert (fetch_int () == CODE_vector);
|
||||||
int n = fetch_int ();
|
int n = fetch_int ();
|
||||||
@ -222,7 +224,7 @@ int help_get_config_on_answer (struct query *q UU) {
|
|||||||
char *ip = fetch_str (l2);
|
char *ip = fetch_str (l2);
|
||||||
int port = fetch_int ();
|
int port = fetch_int ();
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "id = %d, name = %.*s ip = %.*s port = %d\n", id, l1, name, l2, ip, port);
|
logprintf ( "id = %d, name = %.*s ip = %.*s port = %d\n", id, l1, name, l2, ip, port);
|
||||||
}
|
}
|
||||||
if (!DC_list[id]) {
|
if (!DC_list[id]) {
|
||||||
alloc_dc (id, strndup (ip, l2), port);
|
alloc_dc (id, strndup (ip, l2), port);
|
||||||
@ -230,7 +232,7 @@ int help_get_config_on_answer (struct query *q UU) {
|
|||||||
}
|
}
|
||||||
max_chat_size = fetch_int ();
|
max_chat_size = fetch_int ();
|
||||||
if (verbosity >= 2) {
|
if (verbosity >= 2) {
|
||||||
fprintf (stderr, "chat_size = %d\n", max_chat_size);
|
logprintf ( "chat_size = %d\n", max_chat_size);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -259,7 +261,7 @@ int send_code_on_error (struct query *q UU, int error_code, int l, char *error)
|
|||||||
int i = error[s] - '0';
|
int i = error[s] - '0';
|
||||||
want_dc_num = i;
|
want_dc_num = i;
|
||||||
} else {
|
} else {
|
||||||
fprintf (stderr, "error_code = %d, error = %.*s\n", error_code, l, error);
|
logprintf ( "error_code = %d, error = %.*s\n", error_code, l, error);
|
||||||
assert (0);
|
assert (0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -343,13 +345,13 @@ int sign_in_on_answer (struct query *q UU) {
|
|||||||
fetch_user (&User);
|
fetch_user (&User);
|
||||||
sign_in_ok = 1;
|
sign_in_ok = 1;
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
fprintf (stderr, "authorized successfully: name = '%s %s', phone = '%s', expires = %d\n", User.first_name, User.last_name, User.phone, (int)(expires - get_double_time ()));
|
logprintf ( "authorized successfully: name = '%s %s', phone = '%s', expires = %d\n", User.first_name, User.last_name, User.phone, (int)(expires - get_double_time ()));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sign_in_on_error (struct query *q UU, int error_code, int l, char *error) {
|
int sign_in_on_error (struct query *q UU, int error_code, int l, char *error) {
|
||||||
fprintf (stderr, "error_code = %d, error = %.*s\n", error_code, l, error);
|
logprintf ( "error_code = %d, error = %.*s\n", error_code, l, error);
|
||||||
sign_in_ok = -1;
|
sign_in_ok = -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -371,11 +373,13 @@ int do_send_code_result (const char *code) {
|
|||||||
return sign_in_ok;
|
return sign_in_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern char *user_list[];
|
||||||
|
|
||||||
int get_contacts_on_answer (struct query *q UU) {
|
int get_contacts_on_answer (struct query *q UU) {
|
||||||
|
int i;
|
||||||
assert (fetch_int () == (int)CODE_contacts_contacts);
|
assert (fetch_int () == (int)CODE_contacts_contacts);
|
||||||
assert (fetch_int () == CODE_vector);
|
assert (fetch_int () == CODE_vector);
|
||||||
int n = fetch_int ();
|
int n = fetch_int ();
|
||||||
int i;
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
assert (fetch_int () == (int)CODE_contact);
|
assert (fetch_int () == (int)CODE_contact);
|
||||||
fetch_int (); // id
|
fetch_int (); // id
|
||||||
@ -384,9 +388,8 @@ int get_contacts_on_answer (struct query *q UU) {
|
|||||||
assert (fetch_int () == CODE_vector);
|
assert (fetch_int () == CODE_vector);
|
||||||
n = fetch_int ();
|
n = fetch_int ();
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
struct user User;
|
struct user *U = fetch_alloc_user ();
|
||||||
fetch_user (&User);
|
rprintf ("User #%d: " COLOR_RED "%s %s" COLOR_NORMAL " (" COLOR_GREEN "%s" COLOR_NORMAL ")\n", U->id, U->first_name, U->last_name, U->print_name);
|
||||||
rprintf ("User: id = %d, first_name = %s, last_name = %s\n", User.id, User.first_name, User.last_name);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
64
structures.c
64
structures.c
@ -1,6 +1,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "structures.h"
|
#include "structures.h"
|
||||||
#include "mtproto-common.h"
|
#include "mtproto-common.h"
|
||||||
|
#include "telegram.h"
|
||||||
|
#include "tree.h"
|
||||||
|
|
||||||
void fetch_file_location (struct file_location *loc) {
|
void fetch_file_location (struct file_location *loc) {
|
||||||
int x = fetch_int ();
|
int x = fetch_int ();
|
||||||
@ -48,6 +50,25 @@ void fetch_user (struct user *U) {
|
|||||||
}
|
}
|
||||||
U->first_name = fetch_str_dup ();
|
U->first_name = fetch_str_dup ();
|
||||||
U->last_name = fetch_str_dup ();
|
U->last_name = fetch_str_dup ();
|
||||||
|
if (!strlen (U->first_name)) {
|
||||||
|
if (!strlen (U->last_name)) {
|
||||||
|
U->print_name = strdup ("none");
|
||||||
|
} else {
|
||||||
|
U->print_name = strdup (U->last_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!strlen (U->last_name)) {
|
||||||
|
U->print_name = strdup (U->first_name);
|
||||||
|
} else {
|
||||||
|
U->print_name = malloc (strlen (U->first_name) + strlen (U->last_name) + 2);
|
||||||
|
sprintf (U->print_name, "%s_%s", U->first_name, U->last_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char *s = U->print_name;
|
||||||
|
while (*s) {
|
||||||
|
if (*s == ' ') { *s = '_'; }
|
||||||
|
s++;
|
||||||
|
}
|
||||||
if (x == CODE_user_deleted) {
|
if (x == CODE_user_deleted) {
|
||||||
U->flags = 2;
|
U->flags = 2;
|
||||||
return;
|
return;
|
||||||
@ -79,3 +100,46 @@ void fetch_user (struct user *U) {
|
|||||||
U->flags |= 16;
|
U->flags |= 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define user_cmp(a,b) ((a)->id - (b)->id)
|
||||||
|
|
||||||
|
DEFINE_TREE(user,struct user *,user_cmp,0)
|
||||||
|
struct tree_user *user_tree;
|
||||||
|
|
||||||
|
int user_num;
|
||||||
|
struct user *Users[MAX_USER_NUM];
|
||||||
|
int users_allocated;
|
||||||
|
|
||||||
|
struct user *fetch_alloc_user (void) {
|
||||||
|
struct user *U = malloc (sizeof (*U));
|
||||||
|
fetch_user (U);
|
||||||
|
users_allocated ++;
|
||||||
|
struct user *U1 = tree_lookup_user (user_tree, U);
|
||||||
|
if (U1) {
|
||||||
|
free_user (U1);
|
||||||
|
memcpy (U1, U, sizeof (*U));
|
||||||
|
free (U);
|
||||||
|
users_allocated --;
|
||||||
|
return U1;
|
||||||
|
} else {
|
||||||
|
user_tree = tree_insert_user (user_tree, U, lrand48 ());
|
||||||
|
Users[user_num ++] = U;
|
||||||
|
return U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_user (struct user *U) {
|
||||||
|
if (U->first_name) { free (U->first_name); }
|
||||||
|
if (U->last_name) { free (U->last_name); }
|
||||||
|
if (U->print_name) { free (U->print_name); }
|
||||||
|
if (U->phone) { free (U->phone); }
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_stat (char *s, int len) {
|
||||||
|
return snprintf (s, len,
|
||||||
|
"user_num\t%d\n"
|
||||||
|
"users_allocated\t%d\n",
|
||||||
|
user_num,
|
||||||
|
users_allocated);
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ struct user {
|
|||||||
char *first_name;
|
char *first_name;
|
||||||
char *last_name;
|
char *last_name;
|
||||||
char *phone;
|
char *phone;
|
||||||
|
char *print_name;
|
||||||
long long access_hash;
|
long long access_hash;
|
||||||
struct file_location photo_big;
|
struct file_location photo_big;
|
||||||
struct file_location photo_small;
|
struct file_location photo_small;
|
||||||
@ -28,4 +29,9 @@ struct user {
|
|||||||
|
|
||||||
void fetch_file_location (struct file_location *loc);
|
void fetch_file_location (struct file_location *loc);
|
||||||
void fetch_user (struct user *U);
|
void fetch_user (struct user *U);
|
||||||
|
struct user *fetch_alloc_user (void);
|
||||||
|
|
||||||
|
void free_user (struct user *U);
|
||||||
|
|
||||||
|
int print_stat (char *s, int len);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1 +1,2 @@
|
|||||||
#define MAX_DC_NUM 9
|
#define MAX_DC_NUM 9
|
||||||
|
#define MAX_USER_NUM 1000
|
||||||
|
14
tree.h
14
tree.h
@ -51,7 +51,12 @@ struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP
|
|||||||
} else {\
|
} else {\
|
||||||
int c = X_CMP (x, T->x);\
|
int c = X_CMP (x, T->x);\
|
||||||
assert (c);\
|
assert (c);\
|
||||||
return tree_insert_ ## X_NAME (c < 0 ? T->left : T->right, x, y);\
|
if (c < 0) { \
|
||||||
|
T->left = tree_insert_ ## X_NAME (T->left, x, y);\
|
||||||
|
} else { \
|
||||||
|
T->right = tree_insert_ ## X_NAME (T->right, x, y);\
|
||||||
|
} \
|
||||||
|
return T; \
|
||||||
}\
|
}\
|
||||||
}\
|
}\
|
||||||
}\
|
}\
|
||||||
@ -96,6 +101,13 @@ 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)) {\
|
||||||
|
if (!T) { return; } \
|
||||||
|
tree_act_ ## X_NAME (T->left, act); \
|
||||||
|
act (T->x); \
|
||||||
|
tree_act_ ## X_NAME (T->right, act); \
|
||||||
|
}\
|
||||||
|
\
|
||||||
int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) { \
|
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); \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user