Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
tg
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
tg
Commits
fe08f0c5
Commit
fe08f0c5
authored
Aug 14, 2014
by
vysheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more code
parent
bf86f756
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
833 additions
and
762 deletions
+833
-762
binlog.c
binlog.c
+4
-8
interface.h
interface.h
+0
-5
loop.c
loop.c
+2
-2
main.c
main.c
+21
-8
mtproto-client.c
mtproto-client.c
+63
-95
mtproto-common.c
mtproto-common.c
+4
-9
mtproto-common.h
mtproto-common.h
+8
-12
net.h
net.h
+0
-3
queries.c
queries.c
+626
-568
queries.h
queries.h
+6
-4
structures.c
structures.c
+2
-2
tgl.c
tgl.c
+16
-0
tgl.h
tgl.h
+81
-46
No files found.
binlog.c
View file @
fe08f0c5
...
...
@@ -1126,9 +1126,7 @@ static void replay_log_event (void) {
assert
(
rptr
<
wptr
);
int
op
=
*
rptr
;
if
(
verbosity
>=
2
)
{
logprintf
(
"log_pos %lld, op 0x%08x
\n
"
,
binlog_pos
,
op
);
}
vlogprintf
(
E_DEBUG
,
"replay_log_event: log_pos=%lld, op=0x%08x
\n
"
,
binlog_pos
,
op
);
in_ptr
=
rptr
;
in_end
=
wptr
;
...
...
@@ -1201,7 +1199,7 @@ static void replay_log_event (void) {
FETCH_COMBINATOR_FUNCTION
(
binlog_set_msg_id
)
FETCH_COMBINATOR_FUNCTION
(
binlog_delete_msg
)
default:
logprintf
(
"Unknown op 0x%08x
\n
"
,
op
);
vlogprintf
(
E_ERROR
,
"Unknown op 0x%08x
\n
"
,
op
);
assert
(
0
);
}
assert
(
ok
>=
0
);
...
...
@@ -1287,9 +1285,7 @@ void tgl_reopen_binlog_for_writing (void) {
}
static
void
add_log_event
(
const
int
*
data
,
int
len
)
{
if
(
verbosity
)
{
logprintf
(
"Add log event: magic = 0x%08x, len = %d
\n
"
,
data
[
0
],
len
);
}
vlogprintf
(
E_DEBUG
,
"Add log event: magic = 0x%08x, len = %d
\n
"
,
data
[
0
],
len
);
assert
(
!
(
len
&
3
));
rptr
=
(
void
*
)
data
;
wptr
=
rptr
+
(
len
/
4
);
...
...
@@ -1297,7 +1293,7 @@ static void add_log_event (const int *data, int len) {
int
*
end
=
in_end
;
replay_log_event
();
if
(
rptr
!=
wptr
)
{
logprintf
(
"Unread %lld ints. Len = %d
\n
"
,
(
long
long
)(
wptr
-
rptr
),
len
);
vlogprintf
(
E_ERROR
,
"Unread %lld ints. Len = %d
\n
"
,
(
long
long
)(
wptr
-
rptr
),
len
);
assert
(
rptr
==
wptr
);
}
if
(
tgl_state
.
binlog_enabled
)
{
...
...
interface.h
View file @
fe08f0c5
...
...
@@ -34,11 +34,6 @@
#define COLOR_INVERSE "\033[7m"
#define E_ERROR 0
#define E_WARNING 1
#define E_NOTICE 2
#define E_DEBUG 3
char
*
get_default_prompt
(
void
);
char
*
complete_none
(
const
char
*
text
,
int
state
);
char
**
complete_text
(
char
*
text
,
int
start
,
int
end
);
...
...
loop.c
View file @
fe08f0c5
...
...
@@ -155,7 +155,7 @@ char *get_state_filename (void);
char
*
get_secret_chat_filename
(
void
);
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);
...
...
@@ -436,7 +436,7 @@ void write_secret_chat_file (void) {
assert (write (fd, encr_prime, 256) == 256);
}
close (fd);
}
}
*/
extern
int
max_chat_size
;
int
mcs
(
void
)
{
...
...
main.c
View file @
fe08f0c5
...
...
@@ -49,7 +49,6 @@
#include "telegram.h"
#include "loop.h"
#include "mtproto-client.h"
#include "interface.h"
#include "tools.h"
...
...
@@ -59,8 +58,8 @@
#include "tgl.h"
#define PROGNAME "telegram-cli
ent
"
#define VERSION "0.0
1
"
#define PROGNAME "telegram-cli"
#define VERSION "0.0
7
"
#define CONFIG_DIRECTORY "." PROG_NAME
#define CONFIG_FILE "config"
...
...
@@ -319,14 +318,21 @@ void parse_config (void) {
config_directory
=
make_full_path
(
config_directory
);
parse_config_val
(
&
conf
,
&
auth_file_name
,
"auth_file"
,
AUTH_KEY_FILE
,
config_directory
);
parse_config_val
(
&
conf
,
&
state_file_name
,
"state_file"
,
STATE_FILE
,
config_directory
);
parse_config_val
(
&
conf
,
&
secret_chat_file_name
,
"secret"
,
SECRET_CHAT_FILE
,
config_directory
);
parse_config_val
(
&
conf
,
&
downloads_directory
,
"downloads"
,
DOWNLOADS_DIRECTORY
,
config_directory
);
parse_config_val
(
&
conf
,
&
binlog_file_name
,
"binlog"
,
BINLOG_FILE
,
config_directory
);
strcpy
(
buf
+
l
,
"binlog_enabled"
);
config_lookup_bool
(
&
conf
,
buf
,
&
binlog_enabled
);
if
(
binlog_enabled
)
{
tgl_set_binlog_mode
(
1
);
tgl_set_binlog_path
(
binlog_file_name
);
}
else
{
tgl_set_binlog_mode
(
0
);
tgl_set_auth_file_path
(
auth_file_name
);
}
tgl_set_download_directory
(
downloads_directory
);
if
(
!
mkdir
(
config_directory
,
CONFIG_DIRECTORY_MODE
))
{
printf
(
"[%s] created
\n
"
,
config_directory
);
}
...
...
@@ -338,10 +344,17 @@ void parse_config (void) {
void
parse_config
(
void
)
{
printf
(
"libconfig not enabled
\n
"
);
tasprintf
(
&
auth_file_name
,
"%s/%s/%s"
,
get_home_directory
(),
CONFIG_DIRECTORY
,
AUTH_KEY_FILE
);
tasprintf
(
&
state_file_name
,
"%s/%s/%s"
,
get_home_directory
(),
CONFIG_DIRECTORY
,
STATE_FILE
);
tasprintf
(
&
secret_chat_file_name
,
"%s/%s/%s"
,
get_home_directory
(),
CONFIG_DIRECTORY
,
SECRET_CHAT_FILE
);
tasprintf
(
&
downloads_directory
,
"%s/%s/%s"
,
get_home_directory
(),
CONFIG_DIRECTORY
,
DOWNLOADS_DIRECTORY
);
tasprintf
(
&
binlog_file_name
,
"%s/%s/%s"
,
get_home_directory
(),
CONFIG_DIRECTORY
,
BINLOG_FILE
);
if
(
binlog_enabled
)
{
tgl_set_binlog_mode
(
1
);
tgl_set_binlog_path
(
binlog_file_name
);
}
else
{
tgl_set_binlog_mode
(
0
);
tgl_set_auth_file_path
(
auth_file_name
;
}
tgl_set_download_directory
(
downloads_directory
);
}
#endif
...
...
@@ -488,7 +501,7 @@ int main (int argc, char **argv) {
args_parse
(
argc
,
argv
);
printf
(
"Telegram-client version "
TG_VERSION
", Copyright (C) 2013 Vitaly Valtman
\n
"
"Telegram-client version "
TG
L
_VERSION
", Copyright (C) 2013 Vitaly Valtman
\n
"
"Telegram-client comes with ABSOLUTELY NO WARRANTY; for details type `show_license'.
\n
"
"This is free software, and you are welcome to redistribute it
\n
"
"under certain conditions; type `show_license' for details.
\n
"
...
...
mtproto-client.c
View file @
fe08f0c5
...
...
@@ -50,7 +50,6 @@
#include "include.h"
#include "queries.h"
#include "loop.h"
#include "interface.h"
#include "structures.h"
#include "binlog.h"
#include "auto.h"
...
...
@@ -142,18 +141,18 @@ static int rsa_load_public_key (const char *public_key_name) {
pubKey
=
NULL
;
FILE
*
f
=
fopen
(
public_key_name
,
"r"
);
if
(
f
==
NULL
)
{
logprintf
(
"Couldn't open public key file: %s
\n
"
,
public_key_name
);
vlogprintf
(
E_WARNING
,
"Couldn't open public key file: %s
\n
"
,
public_key_name
);
return
-
1
;
}
pubKey
=
PEM_read_RSAPublicKey
(
f
,
NULL
,
NULL
,
NULL
);
fclose
(
f
);
if
(
pubKey
==
NULL
)
{
logprintf
(
"PEM_read_RSAPublicKey returns NULL.
\n
"
);
vlogprintf
(
E_WARNING
,
"PEM_read_RSAPublicKey returns NULL.
\n
"
);
return
-
1
;
}
if
(
verbosity
)
{
logprintf
(
"public key '%s' loaded successfully
\n
"
,
rsa_public_key_name
);
vlogprintf
(
E_WARNING
,
"public key '%s' loaded successfully
\n
"
,
rsa_public_key_name
);
}
return
0
;
...
...
@@ -267,9 +266,7 @@ unsigned p1, p2;
int
process_respq_answer
(
struct
connection
*
c
,
char
*
packet
,
int
len
)
{
int
i
;
if
(
verbosity
)
{
logprintf
(
"process_respq_answer(), len=%d
\n
"
,
len
);
}
vlogprintf
(
E_DEBUG
,
"process_respq_answer(), len=%d
\n
"
,
len
);
assert
(
len
>=
76
);
assert
(
!*
(
long
long
*
)
packet
);
assert
(
*
(
int
*
)
(
packet
+
16
)
==
len
-
20
);
...
...
@@ -289,10 +286,6 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
p1
=
0
,
p2
=
0
;
if
(
verbosity
>=
2
)
{
logprintf
(
"%lld received
\n
"
,
what
);
}
int
it
=
0
;
unsigned
long
long
g
=
0
;
for
(
i
=
0
;
i
<
3
||
it
<
1000
;
i
++
)
{
...
...
@@ -337,10 +330,6 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
}
if
(
verbosity
)
{
logprintf
(
"p1 = %d, p2 = %d, %d iterations
\n
"
,
p1
,
p2
,
it
);
}
/// ++p1; ///
assert
(
*
(
int
*
)
(
from
)
==
CODE_vector
);
...
...
@@ -354,7 +343,7 @@ int process_respq_answer (struct connection *c, char *packet, int len) {
}
}
if
(
i
==
fingerprints_num
)
{
logprintf
(
"fatal: don't have any matching keys (%016llx expected)
\n
"
,
pk_fingerprint
);
vlogprintf
(
E_ERROR
,
"fatal: don't have any matching keys (%016llx expected)
\n
"
,
pk_fingerprint
);
exit
(
2
);
}
// create inner part (P_Q_inner_data)
...
...
@@ -519,7 +508,7 @@ int check_g (unsigned char p[256], BIGNUM *g) {
ok
=
1
;
break
;
}
else
if
(
s
[
i
]
>
p
[
i
])
{
logprintf
(
"i = %d (%d %d)
\n
"
,
i
,
(
int
)
s
[
i
],
(
int
)
p
[
i
]);
vlogprintf
(
E_WARNING
,
"i = %d (%d %d)
\n
"
,
i
,
(
int
)
s
[
i
],
(
int
)
p
[
i
]);
return
-
1
;
}
}
...
...
@@ -536,11 +525,9 @@ int check_g_bn (BIGNUM *p, BIGNUM *g) {
}
int
process_dh_answer
(
struct
connection
*
c
,
char
*
packet
,
int
len
)
{
if
(
verbosity
)
{
logprintf
(
"process_dh_answer(), len=%d
\n
"
,
len
);
}
vlogprintf
(
E_DEBUG
,
"process_dh_answer(), len=%d
\n
"
,
len
);
if
(
len
<
116
)
{
logprintf
(
"%u * %u = %llu"
,
p1
,
p2
,
what
);
vlogprintf
(
E_ERROR
,
"%u * %u = %llu"
,
p1
,
p2
,
what
);
}
assert
(
len
>=
116
);
assert
(
!*
(
long
long
*
)
packet
);
...
...
@@ -636,9 +623,7 @@ int process_dh_answer (struct connection *c, char *packet, int len) {
int
process_auth_complete
(
struct
connection
*
c
UU
,
char
*
packet
,
int
len
)
{
if
(
verbosity
)
{
logprintf
(
"process_dh_answer(), len=%d
\n
"
,
len
);
}
vlogprintf
(
E_DEBUG
,
"process_dh_answer(), len=%d
\n
"
,
len
);
assert
(
len
==
72
);
assert
(
!*
(
long
long
*
)
packet
);
assert
(
*
(
int
*
)
(
packet
+
16
)
==
len
-
20
);
...
...
@@ -659,9 +644,6 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
assert
(
!
memcmp
(
packet
+
56
,
sha1_buffer
+
4
,
16
));
GET_DC
(
c
)
->
server_salt
=
*
(
long
long
*
)
server_nonce
^
*
(
long
long
*
)
new_nonce
;
if
(
verbosity
>=
3
)
{
logprintf
(
"auth_key_id=%016llx
\n
"
,
GET_DC
(
c
)
->
auth_key_id
);
}
//kprintf ("OK\n");
//c->status = conn_error;
...
...
@@ -669,9 +651,7 @@ int process_auth_complete (struct connection *c UU, char *packet, int len) {
c_state
=
st_authorized
;
//return 1;
if
(
verbosity
)
{
logprintf
(
"Auth success
\n
"
);
}
vlogprintf
(
E_DEBUG
,
"Auth success
\n
"
);
auth_success
++
;
GET_DC
(
c
)
->
flags
|=
1
;
write_auth_file
();
...
...
@@ -735,9 +715,7 @@ int aes_encrypt_message (struct dc *DC, struct encrypted_message *enc) {
assert
(
enc
->
msg_len
>=
0
&&
enc
->
msg_len
<=
MAX_MESSAGE_INTS
*
4
-
16
&&
!
(
enc
->
msg_len
&
3
));
sha1
((
unsigned
char
*
)
&
enc
->
server_salt
,
enc_len
,
sha1_buffer
);
//printf ("enc_len is %d\n", enc_len);
if
(
verbosity
>=
2
)
{
logprintf
(
"sending message with sha1 %08x
\n
"
,
*
(
int
*
)
sha1_buffer
);
}
vlogprintf
(
E_DEBUG
,
"sending message with sha1 %08x
\n
"
,
*
(
int
*
)
sha1_buffer
);
memcpy
(
enc
->
msg_key
,
sha1_buffer
+
4
,
16
);
init_aes_auth
(
DC
->
auth_key
,
enc
->
msg_key
,
AES_ENCRYPT
);
//hexdump ((char *)enc, (char *)enc + enc_len + 24);
...
...
@@ -831,7 +809,7 @@ void fetch_date (void) {
void
fetch_seq
(
void
)
{
int
x
=
fetch_int
();
if
(
x
>
seq
+
1
)
{
logprintf
(
"Hole in seq: seq = %d, x = %d
\n
"
,
seq
,
x
);
vlogprintf
(
E_NOTICE
,
"Hole in seq: seq = %d, x = %d
\n
"
,
seq
,
x
);
//tgl_do_get_difference ();
//seq = x;
}
else
if
(
x
==
seq
+
1
)
{
...
...
@@ -911,9 +889,11 @@ void work_update (struct connection *c UU, long long msg_id UU) {
struct
tgl_message
*
M
=
tglf_fetch_alloc_message
();
assert
(
M
);
fetch_pts
();
unread_messages
++
;
print_message
(
M
);
update_prompt
();
tgl_state
.
callback
.
new_msg
(
M
);
//unread_messages ++;
//print_message (M);
//update_prompt ();
break
;
};
case
CODE_update_message_i_d
:
...
...
@@ -930,30 +910,38 @@ void work_update (struct connection *c UU, long long msg_id UU) {
{
assert
(
fetch_int
()
==
(
int
)
CODE_vector
);
int
n
=
fetch_int
();
struct
tgl_message
**
ML
=
talloc
(
n
*
sizeof
(
void
*
));
int
p
=
0
;
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
int
id
=
fetch_int
();
struct
tgl_message
*
M
=
tgl_message_get
(
id
);
if
(
M
)
{
bl_do_set_unread
(
M
,
0
);
ML
[
p
++
]
=
M
;
}
}
fetch_pts
();
if
(
log_level
>=
1
)
{
tgl_state
.
callback
.
marked_read
(
p
,
ML
);
tfree
(
ML
,
sizeof
(
void
*
)
*
n
);
/*if (log_level >= 1) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" %d messages marked as read\n", n);
pop_color ();
print_end ();
}
}
*/
}
break
;
case
CODE_update_user_typing
:
{
tgl_peer_id_t
id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
id
);
if
(
log_level
>=
2
)
{
tgl_state
.
callback
.
type_notification
(
id
,
(
void
*
)
U
);
/*if (log_level >= 2) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
...
...
@@ -962,7 +950,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf (" is typing....\n");
pop_color ();
print_end ();
}
}
*/
}
break
;
case
CODE_update_chat_user_typing
:
...
...
@@ -971,7 +959,9 @@ void work_update (struct connection *c UU, long long msg_id UU) {
tgl_peer_id_t
id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
C
=
tgl_peer_get
(
chat_id
);
tgl_peer_t
*
U
=
tgl_peer_get
(
id
);
if
(
log_level
>=
2
)
{
tgl_state
.
callback
.
type_in_chat_notification
(
id
,
(
void
*
)
U
,
chat_id
,
(
void
*
)
C
);
/*if (log_level >= 2) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
...
...
@@ -982,7 +972,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf ("....\n");
pop_color ();
print_end ();
}
}
*/
}
break
;
case
CODE_update_user_status
:
...
...
@@ -991,7 +981,8 @@ void work_update (struct connection *c UU, long long msg_id UU) {
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
if
(
U
)
{
tglf_fetch_user_status
(
&
U
->
user
.
status
);
if
(
log_level
>=
3
)
{
tgl_state
.
callback
.
status_notification
((
void
*
)
U
);
/*if (log_level >= 3) {
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
...
...
@@ -1001,7 +992,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf ("%s\n", (U->user.status.online > 0) ? "online" : "offline");
pop_color ();
print_end ();
}
}
*/
}
else
{
struct
tgl_user_status
t
;
tglf_fetch_user_status
(
&
t
);
...
...
@@ -1019,7 +1010,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
char
*
l
=
fetch_str
(
l2
);
struct
tgl_user
*
U
=
&
UC
->
user
;
bl_do_user_set_real_name
(
U
,
f
,
l1
,
l
,
l2
);
print_start
();
/*
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
...
...
@@ -1028,7 +1019,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
print_user_name (user_id, UC);
printf ("\n");
pop_color ();
print_end
();
print_end ();
*/
}
else
{
fetch_skip_str
();
fetch_skip_str
();
...
...
@@ -1060,14 +1051,14 @@ void work_update (struct connection *c UU, long long msg_id UU) {
}
bl_do_set_user_profile_photo
(
U
,
photo_id
,
&
big
,
&
small
);
print_start
();
/*
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, UC);
printf (" updated profile photo\n");
pop_color ();
print_end
();
print_end ();
*/
}
else
{
struct
tgl_file_location
t
;
unsigned
y
=
fetch_int
();
...
...
@@ -1086,12 +1077,12 @@ void work_update (struct connection *c UU, long long msg_id UU) {
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
print_start
();
/*
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Restored %d messages\n", n);
pop_color ();
print_end
();
print_end ();
*/
fetch_skip
(
n
);
fetch_pts
();
}
...
...
@@ -1100,12 +1091,12 @@ void work_update (struct connection *c UU, long long msg_id UU) {
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
print_start
();
/*
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Deleted %d messages\n", n);
pop_color ();
print_end
();
print_end ();
*/
fetch_skip
(
n
);
fetch_pts
();
}
...
...
@@ -1142,7 +1133,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
fetch_int
();
// version
}
}
print_start
();
/*
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Chat ");
...
...
@@ -1153,7 +1144,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
printf (" changed list, but we are forbidden to know about it (Why this update even was sent to us?\n");
}
pop_color ();
print_end
();
print_end ();
*/
}
break
;
case
CODE_update_contact_registered
:
...
...
@@ -1161,28 +1152,29 @@ void work_update (struct connection *c UU, long long msg_id UU) {
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
fetch_int
();
// date
print_start
();
tgl_state
.
callback
.
user_registered
(
U
);
/*print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" User ");
print_user_name (user_id, U);
printf (" registered\n");
pop_color ();
print_end
();
print_end ();
*/
}
break
;
case
CODE_update_contact_link
:
{
tgl_peer_id_t
user_id
=
TGL_MK_USER
(
fetch_int
());
tgl_peer_t
*
U
=
tgl_peer_get
(
user_id
);
print_start
();
/*
print_start ();
push_color (COLOR_YELLOW);
print_date (time (0));
printf (" Updated link with user ");
print_user_name (user_id, U);
printf ("\n");
pop_color ();
print_end
();
print_end ();
*/
unsigned
t
=
fetch_int
();
assert
(
t
==
CODE_contacts_my_link_empty
||
t
==
CODE_contacts_my_link_requested
||
t
==
CODE_contacts_my_link_contact
);
if
(
t
==
CODE_contacts_my_link_requested
)
{
...
...
@@ -1246,9 +1238,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
case
CODE_update_encryption
:
{
struct
tgl_secret_chat
*
E
=
tglf_fetch_alloc_encrypted_chat
();
if
(
verbosity
>=
2
)
{
logprintf
(
"Secret chat state = %d
\n
"
,
E
->
state
);
}
vlogprintf
(
E_DEBUG
,
"Secret chat state = %d
\n
"
,
E
->
state
);
print_start
();
push_color
(
COLOR_YELLOW
);
print_date
(
time
(
0
));
...
...
@@ -1415,7 +1405,7 @@ void work_update (struct connection *c UU, long long msg_id UU) {
}
break
;
default:
logprintf
(
"Unknown update type %08x
\n
"
,
op
);
vlogprintf
(
E_ERROR
,
"Unknown update type %08x
\n
"
,
op
);
;
}
}
...
...
@@ -1476,9 +1466,7 @@ void work_update_short_chat_message (struct connection *c UU, long long msg_id U
}
void
work_container
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
if
(
verbosity
)
{
logprintf
(
"work_container: msg_id = %lld
\n
"
,
msg_id
);
}
vlogprintf
(
E_DEBUG
,
"work_container: msg_id = %lld
\n
"
,
msg_id
);
assert
(
fetch_int
()
==
CODE_msg_container
);
int
n
=
fetch_int
();
int
i
;
...
...
@@ -1499,9 +1487,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
)
{
if
(
verbosity
)
{
logprintf
(
"work_new_session_created: msg_id = %lld
\n
"
,
msg_id
);
}
vlogprintf
(
E_DEBUG
,
"work_new_session_created: msg_id = %lld
\n
"
,
msg_id
);
assert
(
fetch_int
()
==
(
int
)
CODE_new_session_created
);
fetch_long
();
// first message id
//DC->session_id = fetch_long ();
...
...
@@ -1511,26 +1497,20 @@ 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
)
{
if
(
verbosity
)
{
logprintf
(
"work_msgs_ack: msg_id = %lld
\n
"
,
msg_id
);
}
vlogprintf
(
E_DEBUG
,
"work_msgs_ack: msg_id = %lld
\n
"
,
msg_id
);
assert
(
fetch_int
()
==
CODE_msgs_ack
);
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
long
long
id
=
fetch_long
();
if
(
verbosity
)
{
logprintf
(
"ack for %lld
\n
"
,
id
);
}
vlogprintf
(
E_DEBUG
+
1
,
"ack for %lld
\n
"
,
id
);
query_ack
(
id
);
}
}
void
work_rpc_result
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
if
(
verbosity
)
{
logprintf
(
"work_rpc_result: msg_id = %lld
\n
"
,
msg_id
);
}
vlogprintf
(
E_DEBUG
,
"work_rpc_result: msg_id = %lld
\n
"
,
msg_id
);
assert
(
fetch_int
()
==
(
int
)
CODE_rpc_result
);
long
long
id
=
fetch_long
();
int
op
=
prefetch_int
();
...
...
@@ -1558,10 +1538,6 @@ void work_packed (struct connection *c, long long msg_id) {
//assert (total_out % 4 == 0);
in_ptr
=
buf
;
in_end
=
in_ptr
+
total_out
/
4
;
if
(
verbosity
>=
4
)
{
logprintf
(
"Unzipped data: "
);
hexdump_in
();
}
rpc_execute_answer
(
c
,
msg_id
);
in_ptr
=
end
;
in_end
=
eend
;
...
...
@@ -1601,7 +1577,7 @@ void work_new_detailed_info (struct connection *c UU, long long msg_id UU) {
void
work_updates_to_long
(
struct
connection
*
c
UU
,
long
long
msg_id
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_updates_too_long
);
logprintf
(
"updates to long... Getting difference
\n
"
);
vlogprintf
(
E_NOTICE
,
"updates to long... Getting difference
\n
"
);
tgl_do_get_difference
();
}
...
...
@@ -1610,14 +1586,10 @@ void work_bad_msg_notification (struct connection *c UU, long long msg_id UU) {
long
long
m1
=
fetch_long
();
int
s
=
fetch_int
();
int
e
=
fetch_int
();
logprintf
(
"bad_msg_notification: msg_id = %lld, seq = %d, error = %d
\n
"
,
m1
,
s
,
e
);
vlogprintf
(
E_NOTICE
,
"bad_msg_notification: msg_id = %lld, seq = %d, error = %d
\n
"
,
m1
,
s
,
e
);
}
void
rpc_execute_answer
(
struct
connection
*
c
,
long
long
msg_id
UU
)
{
if
(
verbosity
>=
5
)
{
logprintf
(
"rpc_execute_answer: fd=%d
\n
"
,
c
->
fd
);
hexdump_in
();
}
int
op
=
prefetch_int
();
switch
(
op
)
{
case
CODE_msg_container
:
...
...
@@ -1666,17 +1638,14 @@ void rpc_execute_answer (struct connection *c, long long msg_id UU) {
work_bad_msg_notification
(
c
,
msg_id
);
return
;
}
logprintf
(
"Unknown message:
\n
"
);
hexdump_in
();
vlogprintf
(
E_WARNING
,
"Unknown message: %08x
\n
"
,
op
);
in_ptr
=
in_end
;
// Will not fail due to assertion in_ptr == in_end
}
int
process_rpc_message
(
struct
connection
*
c
UU
,
struct
encrypted_message
*
enc
,
int
len
)
{
const
int
MINSZ
=
offsetof
(
struct
encrypted_message
,
message
);
const
int
UNENCSZ
=
offsetof
(
struct
encrypted_message
,
server_salt
);
if
(
verbosity
)
{
logprintf
(
"process_rpc_message(), len=%d
\n
"
,
len
);
}
vlogprintf
(
E_DEBUG
,
"process_rpc_message(), len=%d
\n
"
,
len
);
assert
(
len
>=
MINSZ
&&
(
len
&
15
)
==
(
UNENCSZ
&
15
));
struct
dc
*
DC
=
GET_DC
(
c
);
assert
(
enc
->
auth_key_id
==
DC
->
auth_key_id
);
...
...
@@ -1702,10 +1671,9 @@ int process_rpc_message (struct connection *c UU, struct encrypted_message *enc,
}
double
st
=
get_server_time
(
DC
);
if
(
this_server_time
<
st
-
300
||
this_server_time
>
st
+
30
)
{
logprintf
(
"salt = %lld, session_id = %lld, msg_id = %lld, seq_no = %d, st = %lf, now = %lf
\n
"
,
enc
->
server_salt
,
enc
->
session_id
,
enc
->
msg_id
,
enc
->
seq_no
,
st
,
get_utime
(
CLOCK_REALTIME
));
vlogprintf
(
E_WARNING
,
"salt = %lld, session_id = %lld, msg_id = %lld, seq_no = %d, st = %lf, now = %lf
\n
"
,
enc
->
server_salt
,
enc
->
session_id
,
enc
->
msg_id
,
enc
->
seq_no
,
st
,
get_utime
(
CLOCK_REALTIME
));
in_ptr
=
enc
->
message
;
in_end
=
in_ptr
+
(
enc
->
msg_len
/
4
);
hexdump_in
();
}
assert
(
this_server_time
>=
st
-
300
&&
this_server_time
<=
st
+
30
);
...
...
mtproto-common.c
View file @
fe08f0c5
...
...
@@ -39,7 +39,6 @@
#include <openssl/sha.h>
#include "mtproto-common.h"
#include "interface.h"
#include "include.h"
#ifdef __MACH__
...
...
@@ -61,9 +60,7 @@ int get_random_bytes (unsigned char *buf, int n) {
if
(
h
>=
0
)
{
r
=
read
(
h
,
buf
,
n
);
if
(
r
>
0
)
{
if
(
verbosity
>=
3
)
{
logprintf
(
"added %d bytes of real entropy to secure random numbers seed
\n
"
,
r
);
}
vlogprintf
(
E_DEBUG
,
"added %d bytes of real entropy to secure random numbers seed
\n
"
,
r
);
}
else
{
r
=
0
;
}
...
...
@@ -143,16 +140,14 @@ void prng_seed (const char *password_filename, int password_length) {
if
(
password_filename
&&
password_length
>
0
)
{
int
fd
=
open
(
password_filename
,
O_RDONLY
);
if
(
fd
<
0
)
{
logprintf
(
"Warning: fail to open password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
vlogprintf
(
E_WARNING
,
"Warning: fail to open password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
}
else
{
unsigned
char
*
a
=
talloc0
(
password_length
);
int
l
=
read
(
fd
,
a
,
password_length
);
if
(
l
<
0
)
{
logprintf
(
"Warning: fail to read password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
vlogprintf
(
E_WARNING
,
"Warning: fail to read password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
}
else
{
if
(
verbosity
>
0
)
{
logprintf
(
"read %d bytes from password file.
\n
"
,
l
);
}
vlogprintf
(
E_DEBUG
,
"read %d bytes from password file.
\n
"
,
l
);
RAND_add
(
a
,
l
,
l
);
}
close
(
fd
);
...
...
mtproto-common.h
View file @
fe08f0c5
...
...
@@ -26,9 +26,11 @@
#include <openssl/aes.h>
#include <stdio.h>
#include "interface.h"
//
#include "interface.h"
#include "tools.h"
#include "auto/constants.h"
#include "tgl.h"
/* DH key exchange protocol data structures */
#define CODE_req_pq 0x60469778
#define CODE_resPQ 0x05162463
...
...
@@ -178,9 +180,7 @@ static inline int prefetch_strlen (void) {
extern
int
verbosity
;
static
inline
char
*
fetch_str
(
int
len
)
{
assert
(
len
>=
0
);
if
(
verbosity
>
6
)
{
logprintf
(
"fetch_string: len = %d
\n
"
,
len
);
}
vlogprintf
(
E_DEBUG
+
3
,
"fetch_string: len = %d
\n
"
,
len
);
if
(
len
<
254
)
{
char
*
str
=
(
char
*
)
in_ptr
+
1
;
in_ptr
+=
1
+
(
len
>>
2
);
...
...
@@ -272,16 +272,12 @@ int fetch_bignum (BIGNUM *x);
static
inline
int
fetch_int
(
void
)
{
assert
(
in_ptr
+
1
<=
in_end
);
if
(
verbosity
>
6
)
{
logprintf
(
"fetch_int: 0x%08x (%d)
\n
"
,
*
in_ptr
,
*
in_ptr
);
}
vlogprintf
(
E_DEBUG
+
3
,
"fetch_int: 0x%08x (%d)
\n
"
,
*
in_ptr
,
*
in_ptr
);
return
*
(
in_ptr
++
);
}
static
inline
int
fetch_bool
(
void
)
{
if
(
verbosity
>
6
)
{
logprintf
(
"fetch_bool: 0x%08x (%d)
\n
"
,
*
in_ptr
,
*
in_ptr
);
}
vlogprintf
(
E_DEBUG
+
3
,
"fetch_bool: 0x%08x (%d)
\n
"
,
*
in_ptr
,
*
in_ptr
);
assert
(
in_ptr
+
1
<=
in_end
);
assert
(
*
(
in_ptr
)
==
(
int
)
CODE_bool_true
||
*
(
in_ptr
)
==
(
int
)
CODE_bool_false
);
return
*
(
in_ptr
++
)
==
(
int
)
CODE_bool_true
;
...
...
@@ -349,14 +345,14 @@ void init_aes_unauth (const char server_nonce[16], const char hidden_client_nonc
void
init_aes_auth
(
char
auth_key
[
192
],
char
msg_key
[
16
],
int
encrypt
);
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
);
/*
static inline void hexdump_in (void) {
hexdump (in_ptr, in_end);
}
static inline void hexdump_out (void) {
hexdump (packet_buffer, packet_ptr);
}
}
*/
#ifdef __MACH__
#define CLOCK_REALTIME 0
...
...
net.h
View file @
fe08f0c5
...
...
@@ -26,9 +26,6 @@ struct dc;
#define TG_SERVER_TEST "173.240.5.253"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define TG_BUILD "209"
#define TG_VERSION "0.01-beta"
#define ACK_TIMEOUT 1
#define MAX_DC_ID 10
...
...
queries.c
View file @
fe08f0c5
...
...
@@ -43,7 +43,7 @@
#include "telegram.h"
#include "loop.h"
#include "structures.h"
#include "interface.h"
//
#include "interface.h"
#include "net.h"
#include <openssl/bn.h>
#include <openssl/rand.h>
...
...
@@ -64,21 +64,21 @@
#define OPEN_BIN "xdg-open %s"
#endif
int
want_dc_num
;
char
*
get_downloads_directory
(
void
);
int
verbosity
;
extern
int
offline_mode
;
//extern int offline_mode;
long
long
cur_uploading_bytes
;
long
long
cur_uploaded_bytes
;
long
long
cur_downloading_bytes
;
long
long
cur_downloaded_bytes
;
//
long long cur_uploading_bytes;
//
long long cur_uploaded_bytes;
//
long long cur_downloading_bytes;
//
long long cur_downloaded_bytes;
extern
int
binlog_enabled
;
extern
int
sync_from_start
;
//
extern int binlog_enabled;
//
extern int sync_from_start;
int
queries_num
;
static
int
queries_num
;
void
out_peer_id
(
tgl_peer_id_t
id
);
static
void
out_peer_id
(
tgl_peer_id_t
id
);
#define QUERY_TIMEOUT 6.0
#define memcmp8(a,b) memcmp ((a), (b), 8)
...
...
@@ -97,9 +97,7 @@ struct query *query_get (long long id) {
int
alarm_query
(
struct
query
*
q
)
{
assert
(
q
);
if
(
verbosity
>=
1
)
{
logprintf
(
"Alarm query %lld
\n
"
,
q
->
msg_id
);
}
vlogprintf
(
E_DEBUG
,
"Alarm query %lld
\n
"
,
q
->
msg_id
);
q
->
ev
.
timeout
=
get_double_time
()
+
QUERY_TIMEOUT
;
insert_event_timer
(
&
q
->
ev
);
...
...
@@ -127,15 +125,13 @@ void query_restart (long long id) {
}
}
struct
query
*
send_query
(
struct
dc
*
DC
,
int
ints
,
void
*
data
,
struct
query_methods
*
methods
,
void
*
extra
)
{
struct
query
*
send_query
(
struct
dc
*
DC
,
int
ints
,
void
*
data
,
struct
query_methods
*
methods
,
void
*
extra
,
void
*
callback
,
void
*
callback_extra
)
{
assert
(
DC
);
assert
(
DC
->
auth_key_id
);
if
(
!
DC
->
sessions
[
0
])
{
dc_create_session
(
DC
);
}
if
(
verbosity
)
{
logprintf
(
"Sending query of size %d to DC (%s:%d)
\n
"
,
4
*
ints
,
DC
->
ip
,
DC
->
port
);
}
vlogprintf
(
E_DEBUG
,
"Sending query of size %d to DC (%s:%d)
\n
"
,
4
*
ints
,
DC
->
ip
,
DC
->
port
);
struct
query
*
q
=
talloc0
(
sizeof
(
*
q
));
q
->
data_len
=
ints
;
q
->
data
=
talloc
(
4
*
ints
);
...
...
@@ -143,15 +139,11 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
q
->
msg_id
=
encrypt_send_message
(
DC
->
sessions
[
0
]
->
c
,
data
,
ints
,
1
);
q
->
session
=
DC
->
sessions
[
0
];
q
->
seq_no
=
DC
->
sessions
[
0
]
->
seq_no
-
1
;
if
(
verbosity
)
{
logprintf
(
"Msg_id is %lld %p
\n
"
,
q
->
msg_id
,
q
);
}
vlogprintf
(
E_DEBUG
,
"Msg_id is %lld %p
\n
"
,
q
->
msg_id
,
q
);
q
->
methods
=
methods
;
q
->
DC
=
DC
;
if
(
queries_tree
)
{
if
(
verbosity
>=
2
)
{
logprintf
(
"%lld %lld
\n
"
,
q
->
msg_id
,
queries_tree
->
x
->
msg_id
);
}
vlogprintf
(
E_DEBUG
+
2
,
"%lld %lld
\n
"
,
q
->
msg_id
,
queries_tree
->
x
->
msg_id
);
}
queries_tree
=
tree_insert_query
(
queries_tree
,
q
,
lrand48
());
...
...
@@ -161,10 +153,18 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
insert_event_timer
(
&
q
->
ev
);
q
->
extra
=
extra
;
q
->
callback
=
callback
;
q
->
callback_extra
=
callback_extra
;
queries_num
++
;
return
q
;
}
static
int
fail_on_error
(
struct
query
*
q
UU
,
int
error_code
UU
,
int
l
UU
,
char
*
error
UU
)
{
fprintf
(
stderr
,
"error #%d: %.*s
\n
"
,
error_code
,
l
,
error
);
assert
(
0
);
return
0
;
}
void
query_ack
(
long
long
id
)
{
struct
query
*
q
=
query_get
(
id
);
if
(
q
&&
!
(
q
->
flags
&
QUERY_ACK_RECEIVED
))
{
...
...
@@ -179,14 +179,10 @@ void query_error (long long id) {
int
error_code
=
fetch_int
();
int
error_len
=
prefetch_strlen
();
char
*
error
=
fetch_str
(
error_len
);
if
(
verbosity
)
{
logprintf
(
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
}
vlogprintf
(
E_WARNING
,
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
struct
query
*
q
=
query_get
(
id
);
if
(
!
q
)
{
if
(
verbosity
)
{
logprintf
(
"No such query
\n
"
);
}
vlogprintf
(
E_WARNING
,
"No such query
\n
"
);
}
else
{
if
(
!
(
q
->
flags
&
QUERY_ACK_RECEIVED
))
{
remove_event_timer
(
&
q
->
ev
);
...
...
@@ -195,7 +191,7 @@ void query_error (long long id) {
if
(
q
->
methods
&&
q
->
methods
->
on_error
)
{
q
->
methods
->
on_error
(
q
,
error_code
,
error_len
,
error
);
}
else
{
logprintf
(
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
vlogprintf
(
E_WARNING
,
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
}
tfree
(
q
->
data
,
q
->
data_len
*
4
);
tfree
(
q
,
sizeof
(
*
q
));
...
...
@@ -207,13 +203,11 @@ void query_error (long long id) {
static
int
packed_buffer
[
MAX_PACKED_SIZE
/
4
];
void
query_result
(
long
long
id
UU
)
{
if
(
verbosity
)
{
logprintf
(
"result for query #%lld
\n
"
,
id
);
}
if
(
verbosity
>=
4
)
{
vlogprintf
(
E_DEBUG
,
"result for query #%lld
\n
"
,
id
);
/*if (verbosity >= 4) {
logprintf ( "result: ");
hexdump_in ();
}
}
*/
int
op
=
prefetch_int
();
int
*
end
=
0
;
int
*
eend
=
0
;
...
...
@@ -227,16 +221,17 @@ void query_result (long long id UU) {
//assert (total_out % 4 == 0);
in_ptr
=
packed_buffer
;
in_end
=
in_ptr
+
total_out
/
4
;
if
(
verbosity
>=
4
)
{
/*
if (verbosity >= 4) {
logprintf ( "Unzipped data: ");
hexdump_in ();
}
}
*/
}
struct
query
*
q
=
query_get
(
id
);
if
(
!
q
)
{
if
(
verbosity
)
{
logprintf
(
"No such query
\n
"
);
}
//if (verbosity) {
// logprintf ( "No such query\n");
//}
vlogprintf
(
E_WARNING
,
"No such query
\n
"
);
in_ptr
=
in_end
;
}
else
{
if
(
!
(
q
->
flags
&
QUERY_ACK_RECEIVED
))
{
...
...
@@ -247,7 +242,7 @@ void query_result (long long id UU) {
if
(
q
->
methods
->
type
)
{
int
*
save
=
in_ptr
;
if
(
skip_type_any
(
q
->
methods
->
type
)
<
0
)
{
logprintf
(
"Skipped %ld int out of %ld (type %s)
\n
"
,
in_ptr
-
save
,
in_end
-
save
,
q
->
methods
->
type
->
type
->
id
);
vlogprintf
(
E_ERROR
,
"Skipped %ld int out of %ld (type %s)
\n
"
,
in_ptr
-
save
,
in_end
-
save
,
q
->
methods
->
type
->
type
->
id
);
assert
(
0
);
}
...
...
@@ -272,16 +267,12 @@ DEFINE_TREE (timer, struct event_timer *, event_timer_cmp, 0)
struct
tree_timer
*
timer_tree
;
void
insert_event_timer
(
struct
event_timer
*
ev
)
{
if
(
verbosity
>
2
)
{
logprintf
(
"INSERT: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
}
vlogprintf
(
E_DEBUG
+
2
,
"INSERT: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
timer_tree
=
tree_insert_timer
(
timer_tree
,
ev
,
lrand48
());
}
void
remove_event_timer
(
struct
event_timer
*
ev
)
{
if
(
verbosity
>
2
)
{
logprintf
(
"REMOVE: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
}
vlogprintf
(
E_DEBUG
+
2
,
"REMOVE: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
timer_tree
=
tree_delete_timer
(
timer_tree
,
ev
);
}
...
...
@@ -298,21 +289,19 @@ void work_timers (void) {
if
(
ev
->
timeout
>
t
)
{
break
;
}
remove_event_timer
(
ev
);
assert
(
ev
->
alarm
);
if
(
verbosity
)
{
logprintf
(
"Alarm
\n
"
);
}
vlogprintf
(
E_DEBUG
,
"Alarm
\n
"
);
ev
->
alarm
(
ev
->
self
);
}
}
int
max_chat_size
;
int
max_bcast_size
;
int
want_dc_num
;
int
new_dc_num
;
//
int want_dc_num;
//
int new_dc_num;
extern
struct
dc
*
DC_list
[];
extern
struct
dc
*
DC_working
;
void
out_random
(
int
n
)
{
static
void
out_random
(
int
n
)
{
assert
(
n
<=
32
);
static
char
buf
[
32
];
secure_random
(
buf
,
n
);
...
...
@@ -331,19 +320,19 @@ void tgl_do_insert_header (void) {
static
char
buf
[
4096
];
tsnprintf
(
buf
,
sizeof
(
buf
),
"%.999s %.999s %.999s
\n
"
,
st
.
sysname
,
st
.
release
,
st
.
version
);
out_string
(
buf
);
out_string
(
TG
_VERSION
" (build "
TG
_BUILD
")"
);
out_string
(
TG
L_VERSION
" (build "
TGL
_BUILD
")"
);
out_string
(
"En"
);
}
else
{
out_string
(
"x86"
);
out_string
(
"Linux"
);
out_string
(
TG_VERSION
);
out_string
(
TG
L
_VERSION
);
out_string
(
"en"
);
}
}
/* {{{ Get config */
void
fetch_dc_option
(
void
)
{
static
void
fetch_dc_option
(
void
)
{
assert
(
fetch_int
()
==
CODE_dc_option
);
int
id
=
fetch_int
();
int
l1
=
prefetch_strlen
();
...
...
@@ -351,14 +340,12 @@ void fetch_dc_option (void) {
int
l2
=
prefetch_strlen
();
char
*
ip
=
fetch_str
(
l2
);
int
port
=
fetch_int
();
if
(
verbosity
)
{
logprintf
(
"id = %d, name = %.*s ip = %.*s port = %d
\n
"
,
id
,
l1
,
name
,
l2
,
ip
,
port
);
}
vlogprintf
(
E_DEBUG
,
"id = %d, name = %.*s ip = %.*s port = %d
\n
"
,
id
,
l1
,
name
,
l2
,
ip
,
port
);
bl_do_dc_option
(
id
,
l1
,
name
,
l2
,
ip
,
port
);
}
int
help_get_config_on_answer
(
struct
query
*
q
UU
)
{
static
int
help_get_config_on_answer
(
struct
query
*
q
UU
)
{
unsigned
op
=
fetch_int
();
assert
(
op
==
CODE_config
||
op
==
CODE_config_old
);
fetch_int
();
...
...
@@ -367,9 +354,7 @@ int help_get_config_on_answer (struct query *q UU) {
assert
(
test_mode
==
CODE_bool_true
||
test_mode
==
CODE_bool_false
);
assert
(
test_mode
==
CODE_bool_false
||
test_mode
==
CODE_bool_true
);
int
this_dc
=
fetch_int
();
if
(
verbosity
)
{
logprintf
(
"this_dc = %d
\n
"
,
this_dc
);
}
vlogprintf
(
E_DEBUG
,
"this_dc = %d
\n
"
,
this_dc
);
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
assert
(
n
<=
10
);
...
...
@@ -381,30 +366,32 @@ int help_get_config_on_answer (struct query *q UU) {
if
(
op
==
CODE_config
)
{
max_bcast_size
=
fetch_int
();
}
if
(
verbosity
>=
2
)
{
logprintf
(
"chat_size = %d
\n
"
,
max_chat_size
);
vlogprintf
(
E_DEBUG
,
"chat_size = %d
\n
"
,
max_chat_size
);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))(
q
->
callback
))(
q
->
callback_extra
,
1
);
}
return
0
;
}
struct
query_methods
help_get_config_methods
=
{
st
atic
st
ruct
query_methods
help_get_config_methods
=
{
.
on_answer
=
help_get_config_on_answer
,
.
type
=
TYPE_TO_PARAM
(
config
)
};
void
tgl_do_help_get_config
(
void
)
{
void
tgl_do_help_get_config
(
void
(
*
callback
)(
void
*
,
int
),
void
*
callback_extra
)
{
clear_packet
();
tgl_do_insert_header
();
out_int
(
CODE_help_get_config
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
help_get_config_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
help_get_config_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Send code */
char
*
phone_code_hash
;
int
send_code_on_answer
(
struct
query
*
q
UU
)
{
static
char
*
phone_code_hash
;
static
int
send_code_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_auth_sent_code
);
fetch_bool
();
int
registered
=
fetch_bool
();
int
l
=
prefetch_strlen
();
char
*
s
=
fetch_str
(
l
);
if
(
phone_code_hash
)
{
...
...
@@ -414,10 +401,13 @@ int send_code_on_answer (struct query *q UU) {
fetch_int
();
fetch_bool
();
want_dc_num
=
-
1
;
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
int
,
const
char
*
))(
q
->
callback
))
(
q
->
callback_extra
,
1
,
registered
,
phone_code_hash
);
}
return
0
;
}
int
send_code_on_error
(
struct
query
*
q
UU
,
int
error_code
,
int
l
,
char
*
error
)
{
static
int
send_code_on_error
(
struct
query
*
q
UU
,
int
error_code
,
int
l
,
char
*
error
)
{
int
s
=
strlen
(
"PHONE_MIGRATE_"
);
int
s2
=
strlen
(
"NETWORK_MIGRATE_"
);
if
(
l
>=
s
&&
!
memcmp
(
error
,
"PHONE_MIGRATE_"
,
s
))
{
...
...
@@ -427,55 +417,26 @@ int send_code_on_error (struct query *q UU, int error_code, int l, char *error)
int
i
=
error
[
s2
]
-
'0'
;
want_dc_num
=
i
;
}
else
{
logprintf
(
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
vlogprintf
(
E_ERROR
,
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
assert
(
0
);
}
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
int
,
const
char
*
))(
q
->
callback
))
(
q
->
callback_extra
,
0
,
0
,
0
);
}
return
0
;
}
struct
query_methods
send_code_methods
=
{
st
atic
st
ruct
query_methods
send_code_methods
=
{
.
on_answer
=
send_code_on_answer
,
.
on_error
=
send_code_on_error
,
.
type
=
TYPE_TO_PARAM
(
auth_sent_code
)
};
int
code_is_sent
(
void
)
{
return
want_dc_num
;
}
int
config_got
(
void
)
{
return
DC_list
[
want_dc_num
]
!=
0
;
}
char
*
suser
;
//char *suser;
extern
int
dc_working_num
;
void
tgl_do_send_code
(
const
char
*
user
)
{
logprintf
(
"sending code
\n
"
);
suser
=
tstrdup
(
user
);
want_dc_num
=
0
;
clear_packet
();
tgl_do_insert_header
();
out_int
(
CODE_auth_send_code
);
out_string
(
user
);
out_int
(
0
);
out_int
(
TG_APP_ID
);
out_string
(
TG_APP_HASH
);
out_string
(
"en"
);
logprintf
(
"send_code: dc_num = %d
\n
"
,
dc_working_num
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_code_methods
,
0
);
net_loop
(
0
,
code_is_sent
);
if
(
want_dc_num
==
-
1
)
{
return
;
}
DC_working
=
DC_list
[
want_dc_num
];
if
(
!
DC_working
->
sessions
[
0
])
{
dc_create_session
(
DC_working
);
}
dc_working_num
=
want_dc_num
;
bl_do_set_working_dc
(
dc_working_num
);
logprintf
(
"send_code: dc_num = %d
\n
"
,
dc_working_num
);
void
tgl_do_send_code
(
const
char
*
user
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
registered
,
const
char
*
hash
),
void
*
callback_extra
)
{
vlogprintf
(
E_DEBUG
,
"sending code to dc %d
\n
"
,
dc_working_num
);
//suser = tstrdup (user);
want_dc_num
=
0
;
clear_packet
();
tgl_do_insert_header
();
...
...
@@ -486,32 +447,26 @@ void tgl_do_send_code (const char *user) {
out_string
(
TG_APP_HASH
);
out_string
(
"en"
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_code_methods
,
0
);
net_loop
(
0
,
code_is_sent
);
assert
(
want_dc_num
==
-
1
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_code_methods
,
0
,
callback
,
callback_extra
);
}
int
phone_call_on_answer
(
struct
query
*
q
UU
)
{
static
int
phone_call_on_answer
(
struct
query
*
q
UU
)
{
fetch_bool
();
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))(
q
->
callback
))(
q
->
callback_extra
,
1
);
}
return
0
;
}
int
phone_call_on_error
(
struct
query
*
q
UU
,
int
error_code
,
int
l
,
char
*
error
)
{
logprintf
(
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
assert
(
0
);
return
0
;
}
struct
query_methods
phone_call_methods
=
{
static
struct
query_methods
phone_call_methods
=
{
.
on_answer
=
phone_call_on_answer
,
.
on_error
=
phone_call_on_error
,
.
type
=
TYPE_TO_PARAM
(
bool
)
};
void
tgl_do_phone_call
(
const
char
*
user
)
{
logprintf
(
"calling user
\n
"
);
suser
=
tstrdup
(
user
);
void
tgl_do_phone_call
(
const
char
*
user
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
)
{
vlogprintf
(
E_DEBUG
,
"calling user
\n
"
);
//
suser = tstrdup (user);
want_dc_num
=
0
;
clear_packet
();
tgl_do_insert_header
();
...
...
@@ -519,13 +474,12 @@ void tgl_do_phone_call (const char *user) {
out_string
(
user
);
out_string
(
phone_code_hash
);
logprintf
(
"tgl_do_phone_call: dc_num = %d
\n
"
,
dc_working_num
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
phone_call_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
phone_call_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Check phone */
int
check_phone_result
;
/*
int check_phone_result;
int cr_f (void) {
return check_phone_result >= 0;
}
...
...
@@ -586,11 +540,11 @@ int tgl_do_auth_check_phone (const char *user) {
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &check_phone_methods, 0);
net_loop (0, cr_f);
return check_phone_result;
}
}
*/
/* }}} */
/* {{{ Nearest DC */
int
nearest_dc_num
;
/*
int nearest_dc_num;
int nr_f (void) {
return nearest_dc_num >= 0;
}
...
...
@@ -607,12 +561,6 @@ int nearest_dc_on_answer (struct query *q UU) {
return 0;
}
int
fail_on_error
(
struct
query
*
q
UU
,
int
error_code
UU
,
int
l
UU
,
char
*
error
UU
)
{
fprintf
(
stderr
,
"error #%d: %.*s
\n
"
,
error_code
,
l
,
error
);
assert
(
0
);
return
0
;
}
struct query_methods nearest_dc_methods = {
.on_answer = nearest_dc_on_answer,
.on_error = fail_on_error,
...
...
@@ -626,79 +574,58 @@ int tgl_do_get_nearest_dc (void) {
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &nearest_dc_methods, 0);
net_loop (0, nr_f);
return nearest_dc_num;
}
}
*/
/* }}} */
/* {{{ Sign in / Sign up */
int
sign_in_ok
;
int
sign_in_is_ok
(
void
)
{
return
sign_in_ok
;
}
struct
tgl_user
User
;
int
sign_in_on_answer
(
struct
query
*
q
UU
)
{
static
int
sign_in_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_auth_authorization
);
int
expires
=
fetch_int
();
tglf_fetch_user
(
&
User
);
if
(
!
tgl_state
.
our_id
)
{
bl_do_set_our_id
(
tgl_get_peer_id
(
User
.
id
));
}
sign_in_ok
=
1
;
if
(
verbosity
)
{
logprintf
(
"authorized successfully: name = '%s %s', phone = '%s', expires = %d
\n
"
,
User
.
first_name
,
User
.
last_name
,
User
.
phone
,
(
int
)(
expires
-
get_double_time
()));
}
vlogprintf
(
E_DEBUG
,
"Expires in %d
\n
"
,
expires
);
struct
tgl_user
*
U
=
tglf_fetch_alloc_user
();
DC_working
->
has_auth
=
1
;
bl_do_dc_signed
(
DC_working
->
id
);
return
0
;
}
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_user
*
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
U
);
}
int
sign_in_on_error
(
struct
query
*
q
UU
,
int
error_code
,
int
l
,
char
*
error
)
{
logprintf
(
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
sign_in_ok
=
-
1
;
assert
(
0
);
return
0
;
}
struct
query_methods
sign_in_methods
=
{
st
atic
st
ruct
query_methods
sign_in_methods
=
{
.
on_answer
=
sign_in_on_answer
,
.
on_error
=
sign_in_on_error
,
.
type
=
TYPE_TO_PARAM
(
auth_authorization
)
};
int
tgl_do_send_code_result
(
const
char
*
code
)
{
int
tgl_do_send_code_result
(
const
char
*
user
,
const
char
*
code
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_user
*
Self
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_auth_sign_in
);
out_string
(
s
user
);
out_string
(
user
);
out_string
(
phone_code_hash
);
out_string
(
code
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
sign_in_methods
,
0
);
sign_in_ok
=
0
;
net_loop
(
0
,
sign_in_is_ok
);
return
sign_in_ok
;
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
sign_in_methods
,
0
,
callback
,
callback_extra
);
return
0
;
}
int
tgl_do_send_code_result_auth
(
const
char
*
code
,
const
char
*
first_name
,
const
char
*
last_name
)
{
int
tgl_do_send_code_result_auth
(
const
char
*
user
,
const
char
*
code
,
const
char
*
first_name
,
const
char
*
last_name
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_user
*
Self
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_auth_sign_up
);
out_string
(
s
user
);
out_string
(
user
);
out_string
(
phone_code_hash
);
out_string
(
code
);
out_string
(
first_name
);
out_string
(
last_name
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
sign_in_methods
,
0
);
sign_in_ok
=
0
;
net_loop
(
0
,
sign_in_is_ok
);
return
sign_in_ok
;
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
sign_in_methods
,
0
,
callback
,
callback_extra
);
return
0
;
}
/* }}} */
/* {{{ Get contacts */
extern
char
*
user_list
[];
int
get_contacts_on_answer
(
struct
query
*
q
UU
)
{
static
int
get_contacts_on_answer
(
struct
query
*
q
UU
)
{
int
i
;
assert
(
fetch_int
()
==
(
int
)
CODE_contacts_contacts
);
...
...
@@ -711,7 +638,15 @@ int get_contacts_on_answer (struct query *q UU) {
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
struct
tgl_user
**
list
=
talloc
(
sizeof
(
void
*
)
*
n
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
list
[
i
]
=
tglf_fetch_alloc_user
();
}
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
int
,
struct
tgl_user
**
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
n
,
list
);
}
tfree
(
list
,
sizeof
(
void
*
)
*
n
);
/* for (i = 0; i < n; i++) {
struct tgl_user *U = tglf_fetch_alloc_user ();
print_start ();
push_color (COLOR_YELLOW);
...
...
@@ -739,30 +674,30 @@ int get_contacts_on_answer (struct query *q UU) {
}
pop_color ();
print_end ();
}
}
*/
return
0
;
}
struct
query_methods
get_contacts_methods
=
{
st
atic
st
ruct
query_methods
get_contacts_methods
=
{
.
on_answer
=
get_contacts_on_answer
,
.
type
=
TYPE_TO_PARAM
(
contacts_contacts
)
};
void
tgl_do_update_contact_list
(
void
)
{
void
tgl_do_update_contact_list
(
void
(
*
callback
)
(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_user
*
contacts
[]),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_contacts_get_contacts
);
out_string
(
""
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_contacts_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_contacts_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Encrypt decrypted */
int
*
encr_extra
;
int
*
encr_ptr
;
int
*
encr_end
;
static
int
*
encr_extra
;
static
int
*
encr_ptr
;
static
int
*
encr_end
;
char
*
encrypt_decrypted_message
(
struct
tgl_secret_chat
*
E
)
{
static
char
*
encrypt_decrypted_message
(
struct
tgl_secret_chat
*
E
)
{
static
int
msg_key
[
4
];
static
unsigned
char
sha1a_buffer
[
20
];
static
unsigned
char
sha1b_buffer
[
20
];
...
...
@@ -848,22 +783,25 @@ void tgl_do_send_encr_chat_layer (struct tgl_secret_chat *E) {
struct
tgl_message
*
M
=
tgl_message_get
(
t
);
assert
(
M
);
tgl_do_send_msg
(
M
);
print_message
(
M
);
tgl_do_send_msg
(
M
,
0
,
0
);
//
print_message (M);
}
/* {{{ Seng msg (plain text) */
int
msg_send_encr_on_answer
(
struct
query
*
q
UU
)
{
static
int
msg_send_encr_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
CODE_messages_sent_encrypted_message
);
rprintf
(
"Sent
\n
"
);
struct
tgl_message
*
M
=
q
->
extra
;
//M->date = fetch_int ();
fetch_int
();
bl_do_set_message_sent
(
M
);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
M
);
}
return
0
;
}
int
msg_send_on_answer
(
struct
query
*
q
UU
)
{
static
int
msg_send_on_answer
(
struct
query
*
q
UU
)
{
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_messages_sent_message
||
x
==
CODE_messages_sent_message_link
);
int
id
=
fetch_int
();
// id
...
...
@@ -873,6 +811,9 @@ int msg_send_on_answer (struct query *q UU) {
fetch_pts
();
fetch_seq
();
if
(
x
==
CODE_messages_sent_message_link
)
{
assert
(
skip_type_any
(
TYPE_TO_PARAM_1
(
vector
,
TYPE_TO_PARAM
(
contacts_link
)))
>=
0
);
}
/*if (x == CODE_messages_sent_message_link) {
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
int i;
...
...
@@ -910,35 +851,46 @@ int msg_send_on_answer (struct query *q UU) {
pop_color ();
print_end ();
}
}
rprintf
(
"Sent: id = %d
\n
"
,
id
);
}*/
bl_do_set_message_sent
(
M
);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
M
);
}
return
0
;
}
int
msg_send_on_error
(
struct
query
*
q
,
int
error_code
,
int
error_len
,
char
*
error
)
{
logprintf
(
"error for query #%lld: #%d :%.*s
\n
"
,
q
->
msg_id
,
error_code
,
error_len
,
error
);
static
int
msg_send_on_error
(
struct
query
*
q
,
int
error_code
,
int
error_len
,
char
*
error
)
{
vlogprintf
(
E_WARNING
,
"error for query #%lld: #%d :%.*s
\n
"
,
q
->
msg_id
,
error_code
,
error_len
,
error
);
struct
tgl_message
*
M
=
q
->
extra
;
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)
(
q
->
callback_extra
,
0
,
M
);
}
bl_do_delete_msg
(
M
);
return
0
;
}
struct
query_methods
msg_send_methods
=
{
st
atic
st
ruct
query_methods
msg_send_methods
=
{
.
on_answer
=
msg_send_on_answer
,
.
on_error
=
msg_send_on_error
,
.
type
=
TYPE_TO_PARAM
(
messages_sent_message
)
};
struct
query_methods
msg_send_encr_methods
=
{
st
atic
st
ruct
query_methods
msg_send_encr_methods
=
{
.
on_answer
=
msg_send_encr_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_sent_encrypted_message
)
};
int
out_message_num
;
//
int out_message_num;
void
tgl_do_send_encr_msg_action
(
struct
tgl_message
*
M
)
{
void
tgl_do_send_encr_msg_action
(
struct
tgl_message
*
M
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
tgl_peer_t
*
P
=
tgl_peer_get
(
M
->
to_id
);
if
(
!
P
||
P
->
encr_chat
.
state
!=
sc_ok
)
{
return
;
}
if
(
!
P
||
P
->
encr_chat
.
state
!=
sc_ok
)
{
vlogprintf
(
E_WARNING
,
"Unknown encrypted chat
\n
"
);
if
(
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
callback
)
(
callback_extra
,
0
,
M
);
}
return
;
}
clear_packet
();
out_int
(
CODE_messages_send_encrypted_service
);
...
...
@@ -963,16 +915,22 @@ void tgl_do_send_encr_msg_action (struct tgl_message *M) {
}
encr_finish
(
&
P
->
encr_chat
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_encr_methods
,
M
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_encr_methods
,
M
,
callback
,
callback_extra
);
}
void
tgl_do_send_encr_msg
(
struct
tgl_message
*
M
)
{
void
tgl_do_send_encr_msg
(
struct
tgl_message
*
M
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
if
(
M
->
service
)
{
tgl_do_send_encr_msg_action
(
M
);
tgl_do_send_encr_msg_action
(
M
,
callback
,
callback_extra
);
return
;
}
tgl_peer_t
*
P
=
tgl_peer_get
(
M
->
to_id
);
if
(
!
P
||
P
->
encr_chat
.
state
!=
sc_ok
)
{
return
;
}
if
(
!
P
||
P
->
encr_chat
.
state
!=
sc_ok
)
{
vlogprintf
(
E_WARNING
,
"Unknown encrypted chat
\n
"
);
if
(
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
callback
)
(
callback_extra
,
0
,
M
);
}
return
;
}
clear_packet
();
out_int
(
CODE_messages_send_encrypted
);
...
...
@@ -990,12 +948,12 @@ void tgl_do_send_encr_msg (struct tgl_message *M) {
out_int
(
CODE_decrypted_message_media_empty
);
encr_finish
(
&
P
->
encr_chat
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_encr_methods
,
M
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_encr_methods
,
M
,
callback
,
callback_extra
);
}
void
tgl_do_send_msg
(
struct
tgl_message
*
M
)
{
void
tgl_do_send_msg
(
struct
tgl_message
*
M
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
if
(
tgl_get_peer_type
(
M
->
to_id
)
==
TGL_PEER_ENCR_CHAT
)
{
tgl_do_send_encr_msg
(
M
);
tgl_do_send_encr_msg
(
M
,
callback
,
callback_extra
);
return
;
}
clear_packet
();
...
...
@@ -1003,50 +961,60 @@ void tgl_do_send_msg (struct tgl_message *M) {
out_peer_id
(
M
->
to_id
);
out_cstring
(
M
->
message
,
M
->
message_len
);
out_long
(
M
->
id
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_methods
,
M
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_send_methods
,
M
,
callback
,
callback_extra
);
}
void
tgl_do_send_message
(
tgl_peer_id_t
id
,
const
char
*
msg
,
int
len
)
{
void
tgl_do_send_message
(
tgl_peer_id_t
id
,
const
char
*
msg
,
int
len
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
if
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_ENCR_CHAT
)
{
tgl_peer_t
*
P
=
tgl_peer_get
(
id
);
if
(
!
P
)
{
logprintf
(
"Can not send to unknown encrypted chat
\n
"
);
vlogprintf
(
E_WARNING
,
"Unknown encrypted chat
\n
"
);
if
(
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
callback
)
(
callback_extra
,
0
,
0
);
}
return
;
}
if
(
P
->
encr_chat
.
state
!=
sc_ok
)
{
logprintf
(
"Chat is not yet initialized
\n
"
);
vlogprintf
(
E_WARNING
,
"Chat is not yet initialized
\n
"
);
if
(
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
callback
)
(
callback_extra
,
0
,
0
);
}
return
;
}
}
long
long
t
;
secure_random
(
&
t
,
8
);
logprintf
(
"t = %lld, len = %d
\n
"
,
t
,
len
);
vlogprintf
(
E_DEBUG
,
"t = %lld, len = %d
\n
"
,
t
,
len
);
bl_do_send_message_text
(
t
,
tgl_state
.
our_id
,
tgl_get_peer_type
(
id
),
tgl_get_peer_id
(
id
),
time
(
0
),
len
,
msg
);
struct
tgl_message
*
M
=
tgl_message_get
(
t
);
assert
(
M
);
tgl_do_send_msg
(
M
);
print_message
(
M
);
tgl_do_send_msg
(
M
,
callback
,
callback_extra
);
//
print_message (M);
}
/* }}} */
/* {{{ Send text file */
void
tgl_do_send_text
(
tgl_peer_id_t
id
,
char
*
file_name
)
{
void
tgl_do_send_text
(
tgl_peer_id_t
id
,
char
*
file_name
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
int
fd
=
open
(
file_name
,
O_RDONLY
);
if
(
fd
<
0
)
{
rprintf
(
"No such file '%s'
\n
"
,
file_name
);
tfree_str
(
file_name
);
vlogprintf
(
E_WARNING
,
"No such file '%s'
\n
"
,
file_name
);
if
(
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
callback
)
(
callback_extra
,
0
,
0
);
}
return
;
}
static
char
buf
[(
1
<<
20
)
+
1
];
int
x
=
read
(
fd
,
buf
,
(
1
<<
20
)
+
1
);
assert
(
x
>=
0
);
if
(
x
==
(
1
<<
20
)
+
1
)
{
rprintf
(
"Too big file '%s'
\n
"
,
file_name
);
tfree_str
(
file_name
);
vlogprintf
(
E_WARNING
,
"Too big file '%s'
\n
"
,
file_name
);
close
(
fd
);
if
(
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
callback
)
(
callback_extra
,
0
,
0
);
}
}
else
{
buf
[
x
]
=
0
;
tgl_do_send_message
(
id
,
buf
,
x
);
tgl_do_send_message
(
id
,
buf
,
x
,
callback
,
callback_extra
);
tfree_str
(
file_name
);
close
(
fd
);
}
...
...
@@ -1054,96 +1022,93 @@ void tgl_do_send_text (tgl_peer_id_t id, char *file_name) {
/* }}} */
/* {{{ Mark read */
int
mark_read_on_receive
(
struct
query
*
q
UU
)
{
static
int
mark_read_on_receive
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_messages_affected_history
);
fetch_pts
();
fetch_seq
();
fetch_int
();
// offset
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)(
q
->
callback_extra
,
1
);
}
return
0
;
}
int
mark_read_encr_on_receive
(
struct
query
*
q
UU
)
{
static
int
mark_read_encr_on_receive
(
struct
query
*
q
UU
)
{
fetch_bool
();
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)(
q
->
callback_extra
,
1
);
}
return
0
;
}
struct
query_methods
mark_read_methods
=
{
st
atic
st
ruct
query_methods
mark_read_methods
=
{
.
on_answer
=
mark_read_on_receive
,
.
type
=
TYPE_TO_PARAM
(
messages_affected_history
)
};
struct
query_methods
mark_read_encr_methods
=
{
st
atic
st
ruct
query_methods
mark_read_encr_methods
=
{
.
on_answer
=
mark_read_encr_on_receive
,
.
type
=
TYPE_TO_PARAM
(
bool
)
};
void
tgl_do_messages_mark_read
(
tgl_peer_id_t
id
,
int
max_id
)
{
void
tgl_do_messages_mark_read
(
tgl_peer_id_t
id
,
int
max_id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_messages_read_history
);
out_peer_id
(
id
);
out_int
(
max_id
);
out_int
(
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_methods
,
0
,
callback
,
callback_extra
);
}
void
tgl_do_messages_mark_read_encr
(
tgl_peer_id_t
id
,
long
long
access_hash
,
int
last_time
)
{
void
tgl_do_messages_mark_read_encr
(
tgl_peer_id_t
id
,
long
long
access_hash
,
int
last_time
,
void
(
*
callback
)(
void
*
callback_extra
,
int
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_messages_read_encrypted_history
);
out_int
(
CODE_input_encrypted_chat
);
out_int
(
tgl_get_peer_id
(
id
));
out_long
(
access_hash
);
out_int
(
last_time
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_encr_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
mark_read_encr_methods
,
0
,
callback
,
callback_extra
);
}
void
tgl_do_mark_read
(
tgl_peer_id_t
id
)
{
void
tgl_do_mark_read
(
tgl_peer_id_t
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
)
{
tgl_peer_t
*
P
=
tgl_peer_get
(
id
);
if
(
!
P
)
{
rprintf
(
"Unknown peer
\n
"
);
vlogprintf
(
E_WARNING
,
"Unknown peer
\n
"
);
callback
(
callback_extra
,
0
);
return
;
}
if
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_USER
||
tgl_get_peer_type
(
id
)
==
TGL_PEER_CHAT
)
{
if
(
!
P
->
last
)
{
rprintf
(
"Unknown last peer message
\n
"
);
vlogprintf
(
E_WARNING
,
"Unknown last peer message
\n
"
);
callback
(
callback_extra
,
0
);
return
;
}
tgl_do_messages_mark_read
(
id
,
P
->
last
->
id
);
tgl_do_messages_mark_read
(
id
,
P
->
last
->
id
,
callback
,
callback_extra
);
return
;
}
assert
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_ENCR_CHAT
);
if
(
P
->
last
)
{
tgl_do_messages_mark_read_encr
(
id
,
P
->
encr_chat
.
access_hash
,
P
->
last
->
date
);
tgl_do_messages_mark_read_encr
(
id
,
P
->
encr_chat
.
access_hash
,
P
->
last
->
date
,
callback
,
callback_extra
);
}
else
{
tgl_do_messages_mark_read_encr
(
id
,
P
->
encr_chat
.
access_hash
,
time
(
0
)
-
10
);
tgl_do_messages_mark_read_encr
(
id
,
P
->
encr_chat
.
access_hash
,
time
(
0
)
-
10
,
callback
,
callback_extra
);
}
}
/* }}} */
/* {{{ Get history */
int
get_history_on_answer
(
struct
query
*
q
UU
)
{
static
struct
tgl_message
*
ML
[
10000
];
static
int
get_history_on_answer
(
struct
query
*
q
UU
)
{
int
i
;
int
x
=
fetch_int
();
if
(
x
==
(
int
)
CODE_messages_messages_slice
)
{
fetch_int
();
rprintf
(
"...
\n
"
);
}
else
{
assert
(
x
==
(
int
)
CODE_messages_messages
);
}
assert
(
x
==
(
int
)
CODE_messages_messages_slice
||
x
==
(
int
)
CODE_messages_messages
);
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
struct
tgl_message
**
ML
=
talloc
(
sizeof
(
void
*
)
*
n
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
struct
tgl_message
*
M
=
tglf_fetch_alloc_message
();
if
(
i
<=
9999
)
{
ML
[
i
]
=
M
;
ML
[
i
]
=
tglf_fetch_alloc_message
();
}
}
if
(
n
>
10000
)
{
n
=
10000
;
}
int
sn
=
n
;
for
(
i
=
n
-
1
;
i
>=
0
;
i
--
)
{
print_message
(
ML
[
i
]);
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
...
...
@@ -1154,20 +1119,32 @@ int get_history_on_answer (struct query *q UU) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglf_fetch_alloc_user
();
}
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
int
,
struct
tgl_message
**
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
sn
,
ML
);
}
tfree
(
ML
,
sizeof
(
void
*
)
*
n
);
/*for (i = n - 1; i >= 0; i--) {
print_message (ML[i]);
}*/
if
(
sn
>
0
&&
q
->
extra
)
{
tgl_do_messages_mark_read
(
*
(
tgl_peer_id_t
*
)
&
(
q
->
extra
),
ML
[
0
]
->
id
);
tgl_do_messages_mark_read
(
*
(
tgl_peer_id_t
*
)
&
(
q
->
extra
),
ML
[
0
]
->
id
,
0
,
0
);
}
return
0
;
}
struct
query_methods
get_history_methods
=
{
st
atic
st
ruct
query_methods
get_history_methods
=
{
.
on_answer
=
get_history_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_messages
)
};
void
tgl_do_get_local_history
(
tgl_peer_id_t
id
,
int
limit
)
{
void
tgl_do_get_local_history
(
tgl_peer_id_t
id
,
int
limit
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_message
*
list
[]),
void
*
callback_extra
)
{
tgl_peer_t
*
P
=
tgl_peer_get
(
id
);
if
(
!
P
||
!
P
->
last
)
{
return
;
}
if
(
!
P
||
!
P
->
last
)
{
callback
(
callback_extra
,
0
,
0
,
0
);
return
;
}
struct
tgl_message
*
M
=
P
->
last
;
int
count
=
1
;
assert
(
!
M
->
prev
);
...
...
@@ -1175,16 +1152,23 @@ void tgl_do_get_local_history (tgl_peer_id_t id, int limit) {
M
=
M
->
next
;
count
++
;
}
while
(
M
)
{
print_message
(
M
);
M
=
M
->
prev
;
struct
tgl_message
**
ML
=
talloc
(
sizeof
(
void
*
)
*
count
);
M
=
P
->
last
;
ML
[
0
]
=
M
;
count
=
1
;
while
(
count
<
limit
&&
M
->
next
)
{
M
=
M
->
next
;
ML
[
count
++
]
=
M
->
next
;
}
callback
(
callback_extra
,
1
,
count
,
ML
);
tfree
(
ML
,
sizeof
(
void
*
)
*
count
);
}
void
tgl_do_get_history
(
tgl_peer_id_t
id
,
int
limit
)
{
void
tgl_do_get_history
(
tgl_peer_id_t
id
,
int
limit
,
int
offline_mode
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_message
*
list
[]),
void
*
callback_extra
)
{
if
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_ENCR_CHAT
||
offline_mode
)
{
tgl_do_get_local_history
(
id
,
limit
);
tgl_do_mark_read
(
id
);
tgl_do_get_local_history
(
id
,
limit
,
callback
,
callback_extra
);
tgl_do_mark_read
(
id
,
0
,
0
);
return
;
}
clear_packet
();
...
...
@@ -1193,13 +1177,12 @@ void tgl_do_get_history (tgl_peer_id_t id, int limit) {
out_int
(
0
);
out_int
(
0
);
out_int
(
limit
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_history_methods
,
(
void
*
)
*
(
long
*
)
&
id
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_history_methods
,
(
void
*
)
*
(
long
*
)
&
id
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Get dialogs */
int
dialog_list_got
;
int
get_dialogs_on_answer
(
struct
query
*
q
UU
)
{
static
int
get_dialogs_on_answer
(
struct
query
*
q
UU
)
{
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_messages_dialogs
||
x
==
CODE_messages_dialogs_slice
);
if
(
x
==
CODE_messages_dialogs_slice
)
{
...
...
@@ -1208,20 +1191,16 @@ int get_dialogs_on_answer (struct query *q UU) {
assert
(
fetch_int
()
==
CODE_vector
);
int
n
,
i
;
n
=
fetch_int
();
static
int
dlist
[
2
*
100
];
static
tgl_peer_id_t
plist
[
100
];
int
dl_size
=
n
;
tgl_peer_id_t
*
PL
=
talloc0
(
sizeof
(
tgl_peer_id_t
)
*
n
);
int
*
UC
=
talloc0
(
4
*
n
);
int
*
LM
=
talloc0
(
4
*
n
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_dialog
);
if
(
i
<
100
)
{
plist
[
i
]
=
tglf_fetch_peer_id
();
dlist
[
2
*
i
+
0
]
=
fetch_int
();
dlist
[
2
*
i
+
1
]
=
fetch_int
();
}
else
{
tglf_fetch_peer_id
();
fetch_int
();
fetch_int
();
}
PL
[
i
]
=
tglf_fetch_peer_id
();
LM
[
i
]
=
fetch_int
();
UC
[
i
]
=
fetch_int
();
assert
(
skip_type_any
(
TYPE_TO_PARAM
(
peer_notify_settings
))
>=
0
);
}
assert
(
fetch_int
()
==
CODE_vector
);
...
...
@@ -1239,7 +1218,7 @@ int get_dialogs_on_answer (struct query *q UU) {
for
(
i
=
0
;
i
<
n
;
i
++
)
{
tglf_fetch_alloc_user
();
}
print_start
();
/*
print_start ();
push_color (COLOR_YELLOW);
for (i = dl_size - 1; i >= 0; i--) {
tgl_peer_t *UC;
...
...
@@ -1261,23 +1240,31 @@ int get_dialogs_on_answer (struct query *q UU) {
pop_color ();
print_end ();
dialog_list_got
=
1
;
dialog_list_got = 1;*/
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
int
,
tgl_peer_id_t
*
,
int
*
,
int
*
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
dl_size
,
PL
,
LM
,
UC
);
}
tfree
(
PL
,
sizeof
(
tgl_peer_id_t
)
*
dl_size
);
tfree
(
UC
,
4
*
dl_size
);
tfree
(
LM
,
4
*
dl_size
);
return
0
;
}
struct
query_methods
get_dialogs_methods
=
{
st
atic
st
ruct
query_methods
get_dialogs_methods
=
{
.
on_answer
=
get_dialogs_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_dialogs
)
};
void
tgl_do_get_dialog_list
(
void
)
{
void
tgl_do_get_dialog_list
(
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
size
,
tgl_peer_id_t
peers
[],
int
last_msg_id
[],
int
unread_count
[]),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_messages_get_dialogs
);
out_int
(
0
);
out_int
(
0
);
out_int
(
1000
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dialogs_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dialogs_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
...
...
@@ -1301,7 +1288,7 @@ struct send_file {
unsigned
char
*
key
;
};
void
out_peer_id
(
tgl_peer_id_t
id
)
{
static
void
out_peer_id
(
tgl_peer_id_t
id
)
{
tgl_peer_t
*
U
;
switch
(
tgl_get_peer_type
(
id
))
{
case
TGL_PEER_CHAT
:
...
...
@@ -1324,14 +1311,14 @@ void out_peer_id (tgl_peer_id_t id) {
}
}
void
send_part
(
struct
send_file
*
f
);
int
send_file_part_on_answer
(
struct
query
*
q
)
{
static
void
send_part
(
struct
send_file
*
f
,
void
*
callback
,
void
*
callback_extra
);
static
int
send_file_part_on_answer
(
struct
query
*
q
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_bool_true
);
send_part
(
q
->
extra
);
send_part
(
q
->
extra
,
q
->
callback
,
q
->
callback_extra
);
return
0
;
}
int
send_file_on_answer
(
struct
query
*
q
UU
)
{
static
int
send_file_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_messages_stated_message
);
struct
tgl_message
*
M
=
tglf_fetch_alloc_message
();
assert
(
fetch_int
()
==
CODE_vector
);
...
...
@@ -1347,14 +1334,15 @@ int send_file_on_answer (struct query *q UU) {
}
fetch_pts
();
fetch_seq
();
print_message
(
M
);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)(
q
->
callback_extra
,
1
,
M
);
}
//print_message (M);
return
0
;
}
int
send_encr_file_on_answer
(
struct
query
*
q
UU
)
{
if
(
prefetch_int
()
!=
(
int
)
CODE_messages_sent_encrypted_file
)
{
hexdump_in
();
}
static
int
send_encr_file_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_messages_sent_encrypted_file
);
struct
tgl_message
*
M
=
q
->
extra
;
M
->
date
=
fetch_int
();
...
...
@@ -1365,30 +1353,34 @@ int send_encr_file_on_answer (struct query *q UU) {
fetch_int
();
M
->
media
.
encr_photo
.
dc_id
=
fetch_int
();
assert
(
fetch_int
()
==
M
->
media
.
encr_photo
.
key_fingerprint
);
print_message
(
M
);
//
print_message (M);
tglm_message_insert
(
M
);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)(
q
->
callback_extra
,
1
,
M
);
}
return
0
;
}
struct
query_methods
send_file_part_methods
=
{
st
atic
st
ruct
query_methods
send_file_part_methods
=
{
.
on_answer
=
send_file_part_on_answer
,
.
type
=
TYPE_TO_PARAM
(
bool
)
};
struct
query_methods
send_file_methods
=
{
st
atic
st
ruct
query_methods
send_file_methods
=
{
.
on_answer
=
send_file_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_stated_message
)
};
struct
query_methods
send_encr_file_methods
=
{
st
atic
st
ruct
query_methods
send_encr_file_methods
=
{
.
on_answer
=
send_encr_file_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_sent_encrypted_message
)
};
void
send_part
(
struct
send_file
*
f
)
{
static
void
send_part
(
struct
send_file
*
f
,
void
*
callback
,
void
*
callback_extra
)
{
if
(
f
->
fd
>=
0
)
{
if
(
!
f
->
part_num
)
{
cur_uploading_bytes
+=
f
->
size
;
tgl_state
.
cur_uploading_bytes
+=
f
->
size
;
}
clear_packet
();
if
(
f
->
size
<
(
16
<<
20
))
{
...
...
@@ -1405,7 +1397,7 @@ void send_part (struct send_file *f) {
int
x
=
read
(
f
->
fd
,
buf
,
f
->
part_size
);
assert
(
x
>
0
);
f
->
offset
+=
x
;
cur_uploaded_bytes
+=
x
;
tgl_state
.
cur_uploaded_bytes
+=
x
;
if
(
f
->
encr
)
{
if
(
x
&
15
)
{
...
...
@@ -1420,21 +1412,19 @@ void send_part (struct send_file *f) {
memset
(
&
aes_key
,
0
,
sizeof
(
aes_key
));
}
out_cstring
(
buf
,
x
);
if
(
verbosity
>=
2
)
{
logprintf
(
"offset=%lld size=%lld
\n
"
,
f
->
offset
,
f
->
size
);
}
vlogprintf
(
E_DEBUG
,
"offset=%lld size=%lld
\n
"
,
f
->
offset
,
f
->
size
);
if
(
f
->
offset
==
f
->
size
)
{
close
(
f
->
fd
);
f
->
fd
=
-
1
;
}
else
{
assert
(
f
->
part_size
==
x
);
}
update_prompt
();
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_file_part_methods
,
f
);
//
update_prompt ();
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_file_part_methods
,
f
,
callback
,
callback_extra
);
}
else
{
cur_uploaded_bytes
-=
f
->
size
;
cur_uploading_bytes
-=
f
->
size
;
update_prompt
();
tgl_state
.
cur_uploaded_bytes
-=
f
->
size
;
tgl_state
.
cur_uploading_bytes
-=
f
->
size
;
//
update_prompt ();
clear_packet
();
assert
(
f
->
media_type
==
CODE_input_media_uploaded_photo
||
f
->
media_type
==
CODE_input_media_uploaded_video
||
f
->
media_type
==
CODE_input_media_uploaded_thumb_video
||
f
->
media_type
==
CODE_input_media_uploaded_audio
||
f
->
media_type
==
CODE_input_media_uploaded_document
||
f
->
media_type
==
CODE_input_media_uploaded_thumb_document
);
if
(
!
f
->
encr
)
{
...
...
@@ -1477,7 +1467,7 @@ void send_part (struct send_file *f) {
}
out_long
(
-
lrand48
()
*
(
1ll
<<
32
)
-
lrand48
());
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_file_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_file_methods
,
0
,
callback
,
callback_extra
);
}
else
{
struct
tgl_message
*
M
=
talloc0
(
sizeof
(
*
M
));
...
...
@@ -1568,38 +1558,37 @@ void send_part (struct send_file *f) {
M
->
id
=
r
;
M
->
date
=
time
(
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_file_methods
,
M
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_file_methods
,
M
,
callback
,
callback_extra
);
}
tfree_str
(
f
->
file_name
);
tfree
(
f
,
sizeof
(
*
f
));
}
}
void
send_file_thumb
(
struct
send_file
*
f
)
{
/*void send_file_thumb (struct send_file *f, void *callback, void *callback_extra
) {
clear_packet ();
f->thumb_id = lrand48 () * (1ll << 32) + lrand48 ();
out_int (CODE_upload_save_file_part);
out_long (f->thumb_id);
out_int (0);
out_cstring ((void *)thumb_file, thumb_file_size);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_file_part_methods
,
f
);
}
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f
, callback, callback_extra
);
}
*/
void
tgl_do_send_photo
(
int
type
,
tgl_peer_id_t
to_id
,
char
*
file_name
)
{
void
tgl_do_send_photo
(
int
type
,
tgl_peer_id_t
to_id
,
char
*
file_name
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
int
fd
=
open
(
file_name
,
O_RDONLY
);
if
(
fd
<
0
)
{
rprintf
(
"No such file '%s'
\n
"
,
file_name
);
tfree_str
(
file_name
);
vlogprintf
(
E_WARNING
,
"No such file '%s'
\n
"
,
file_name
);
callback
(
callback_extra
,
0
,
0
);
return
;
}
struct
stat
buf
;
fstat
(
fd
,
&
buf
);
long
long
size
=
buf
.
st_size
;
if
(
size
<=
0
)
{
rprintf
(
"File has zero length
\n
"
);
tfree_str
(
file_name
);
vlogprintf
(
E_WARNING
,
"File has zero length
\n
"
);
close
(
fd
);
callback
(
callback_extra
,
0
,
0
);
return
;
}
struct
send_file
*
f
=
talloc0
(
sizeof
(
*
f
));
...
...
@@ -1615,16 +1604,16 @@ void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name) {
if
(
f
->
part_size
>
(
512
<<
10
))
{
close
(
fd
);
rprintf
(
"Too big file. Maximal supported size is %d.
\n
"
,
(
512
<<
10
)
*
1000
);
vlogprintf
(
E_WARNING
,
"Too big file. Maximal supported size is %d.
\n
"
,
(
512
<<
10
)
*
1000
);
tfree
(
f
,
sizeof
(
*
f
));
tfree_str
(
file_name
);
callback
(
callback_extra
,
0
,
0
);
return
;
}
f
->
id
=
lrand48
()
*
(
1ll
<<
32
)
+
lrand48
();
f
->
to_id
=
to_id
;
f
->
media_type
=
type
;
f
->
file_name
=
file_name
;
f
->
file_name
=
tstrdup
(
file_name
)
;
if
(
tgl_get_peer_type
(
f
->
to_id
)
==
TGL_PEER_ENCR_CHAT
)
{
f
->
encr
=
1
;
f
->
iv
=
talloc
(
32
);
...
...
@@ -1643,12 +1632,12 @@ void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name) {
} else {
send_part (f);
}*/
send_part
(
f
);
send_part
(
f
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Forward */
int
fwd_msg_on_answer
(
struct
query
*
q
UU
)
{
static
int
fwd_msg_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_messages_stated_message
);
struct
tgl_message
*
M
=
tglf_fetch_alloc_message
();
assert
(
fetch_int
()
==
CODE_vector
);
...
...
@@ -1664,18 +1653,22 @@ int fwd_msg_on_answer (struct query *q UU) {
}
fetch_pts
();
fetch_seq
();
print_message
(
M
);
//print_message (M);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
M
);
}
return
0
;
}
struct
query_methods
fwd_msg_methods
=
{
st
atic
st
ruct
query_methods
fwd_msg_methods
=
{
.
on_answer
=
fwd_msg_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_stated_message
)
};
void
tgl_do_forward_message
(
tgl_peer_id_t
id
,
int
n
)
{
void
tgl_do_forward_message
(
tgl_peer_id_t
id
,
int
n
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
if
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_ENCR_CHAT
)
{
rprintf
(
"Can not forward messages from secret chat
\n
"
);
vlogprintf
(
E_WARNING
,
"Can not forward messages from secret chat
\n
"
);
callback
(
callback_extra
,
0
,
0
);
return
;
}
clear_packet
();
...
...
@@ -1683,12 +1676,12 @@ void tgl_do_forward_message (tgl_peer_id_t id, int n) {
out_peer_id
(
id
);
out_int
(
n
);
out_long
(
lrand48
()
*
(
1ll
<<
32
)
+
lrand48
());
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
fwd_msg_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
fwd_msg_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Rename chat */
int
rename_chat_on_answer
(
struct
query
*
q
UU
)
{
static
int
rename_chat_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_messages_stated_message
);
struct
tgl_message
*
M
=
tglf_fetch_alloc_message
();
assert
(
fetch_int
()
==
CODE_vector
);
...
...
@@ -1704,27 +1697,30 @@ int rename_chat_on_answer (struct query *q UU) {
}
fetch_pts
();
fetch_seq
();
print_message
(
M
);
//print_message (M);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_message
*
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
M
);
}
return
0
;
}
struct
query_methods
rename_chat_methods
=
{
st
atic
st
ruct
query_methods
rename_chat_methods
=
{
.
on_answer
=
rename_chat_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_stated_message
)
};
void
tgl_do_rename_chat
(
tgl_peer_id_t
id
,
char
*
name
UU
)
{
void
tgl_do_rename_chat
(
tgl_peer_id_t
id
,
char
*
name
UU
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_messages_edit_chat_title
);
assert
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_CHAT
);
out_int
(
tgl_get_peer_id
(
id
));
out_string
(
name
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
rename_chat_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
rename_chat_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Chat info */
void
print_chat_info
(
struct
tgl_chat
*
C
)
{
/*
void print_chat_info (struct tgl_chat *C) {
tgl_peer_t *U = (void *)C;
print_start ();
push_color (COLOR_YELLOW);
...
...
@@ -1746,26 +1742,31 @@ void print_chat_info (struct tgl_chat *C) {
}
pop_color ();
print_end ();
}
}
*/
int
chat_info_on_answer
(
struct
query
*
q
UU
)
{
static
int
chat_info_on_answer
(
struct
query
*
q
UU
)
{
struct
tgl_chat
*
C
=
tglf_fetch_alloc_chat_full
();
print_chat_info
(
C
);
//print_chat_info (C);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_chat
*
))
q
->
callback
)
(
q
->
callback_extra
,
0
,
C
);
}
return
0
;
}
struct
query_methods
chat_info_methods
=
{
st
atic
st
ruct
query_methods
chat_info_methods
=
{
.
on_answer
=
chat_info_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_chat_full
)
};
void
tgl_do_get_chat_info
(
tgl_peer_id_t
id
)
{
void
tgl_do_get_chat_info
(
tgl_peer_id_t
id
,
int
offline_mode
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_chat
*
C
),
void
*
callback_extra
)
{
if
(
offline_mode
)
{
tgl_peer_t
*
C
=
tgl_peer_get
(
id
);
if
(
!
C
)
{
rprintf
(
"No such chat
\n
"
);
vlogprintf
(
E_WARNING
,
"No such chat
\n
"
);
callback
(
callback_extra
,
0
,
0
);
}
else
{
print_chat_info
(
&
C
->
chat
);
//print_chat_info (&C->chat);
callback
(
callback_extra
,
1
,
&
C
->
chat
);
}
return
;
}
...
...
@@ -1773,13 +1774,13 @@ void tgl_do_get_chat_info (tgl_peer_id_t id) {
out_int
(
CODE_messages_get_full_chat
);
assert
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_CHAT
);
out_int
(
tgl_get_peer_id
(
id
));
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
chat_info_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
chat_info_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ User info */
void
print_user_info
(
struct
tgl_user
*
U
)
{
/*
void print_user_info (struct tgl_user *U) {
tgl_peer_t *C = (void *)U;
print_start ();
push_color (COLOR_YELLOW);
...
...
@@ -1797,26 +1798,29 @@ void print_user_info (struct tgl_user *U) {
}
pop_color ();
print_end ();
}
}
*/
int
user_info_on_answer
(
struct
query
*
q
UU
)
{
static
int
user_info_on_answer
(
struct
query
*
q
UU
)
{
struct
tgl_user
*
U
=
tglf_fetch_alloc_user_full
();
print_user_info
(
U
);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_user
*
))
q
->
callback
)
(
q
->
callback_extra
,
0
,
U
);
}
return
0
;
}
struct
query_methods
user_info_methods
=
{
st
atic
st
ruct
query_methods
user_info_methods
=
{
.
on_answer
=
user_info_on_answer
,
.
type
=
TYPE_TO_PARAM
(
user_full
)
};
void
tgl_do_get_user_info
(
tgl_peer_id_t
id
)
{
void
tgl_do_get_user_info
(
tgl_peer_id_t
id
,
int
offline_mode
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_user
*
U
),
void
*
callback_extra
)
{
if
(
offline_mode
)
{
tgl_peer_t
*
C
=
tgl_peer_get
(
id
);
if
(
!
C
)
{
rprintf
(
"No such user
\n
"
);
vlogprintf
(
E_WARNING
,
"No such user
\n
"
);
callback
(
callback_extra
,
0
,
0
);
}
else
{
print_user_info
(
&
C
->
user
);
callback
(
callback_extra
,
1
,
&
C
->
user
);
}
return
;
}
...
...
@@ -1832,12 +1836,12 @@ void tgl_do_get_user_info (tgl_peer_id_t id) {
out_int
(
CODE_input_user_contact
);
out_int
(
tgl_get_peer_id
(
id
));
}
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
user_info_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
user_info_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Get user info silently */
int
user_list_info_silent_on_answer
(
struct
query
*
q
UU
)
{
/*
int user_list_info_silent_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
int i;
...
...
@@ -1864,7 +1868,7 @@ void tgl_do_get_user_list_info_silent (int num, int *list) {
//out_long (0);
}
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &user_list_info_silent_methods, 0);
}
}
*/
/* }}} */
/* {{{ Load photo/video */
...
...
@@ -1886,12 +1890,12 @@ struct download {
};
void
end_load
(
struct
download
*
D
)
{
cur_downloading_bytes
-=
D
->
size
;
cur_downloaded_bytes
-=
D
->
size
;
update_prompt
();
static
void
end_load
(
struct
download
*
D
,
void
*
callback
,
void
*
callback_extra
)
{
tgl_state
.
cur_downloading_bytes
-=
D
->
size
;
tgl_state
.
cur_downloaded_bytes
-=
D
->
size
;
//
update_prompt ();
close
(
D
->
fd
);
if
(
D
->
next
==
1
)
{
/*
if (D->next == 1) {
logprintf ("Done: %s\n", D->name);
} else if (D->next == 2) {
static char buf[PATH_MAX];
...
...
@@ -1904,7 +1908,12 @@ void end_load (struct download *D) {
logprintf ("Image is at %s\n", D->name);
}
}
}*/
if
(
callback
)
{
((
void
(
*
)(
void
*
,
int
,
char
*
))
callback
)
(
callback_extra
,
1
,
D
->
name
);
}
if
(
D
->
iv
)
{
tfree_secure
(
D
->
iv
,
32
);
}
...
...
@@ -1912,8 +1921,8 @@ void end_load (struct download *D) {
tfree
(
D
,
sizeof
(
*
D
));
}
void
load_next_part
(
struct
download
*
D
);
int
download_on_answer
(
struct
query
*
q
)
{
static
void
load_next_part
(
struct
download
*
D
,
void
*
callback
,
void
*
callback_extra
);
static
int
download_on_answer
(
struct
query
*
q
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_upload_file
);
unsigned
x
=
fetch_int
();
assert
(
x
);
...
...
@@ -1924,8 +1933,8 @@ int download_on_answer (struct query *q) {
fetch_int
();
// mtime
int
len
=
prefetch_strlen
();
assert
(
len
>=
0
);
cur_downloaded_bytes
+=
len
;
update_prompt
();
tgl_state
.
cur_downloaded_bytes
+=
len
;
//
update_prompt ();
if
(
D
->
iv
)
{
unsigned
char
*
ptr
=
(
void
*
)
fetch_str
(
len
);
assert
(
!
(
len
&
15
));
...
...
@@ -1942,20 +1951,20 @@ int download_on_answer (struct query *q) {
}
D
->
offset
+=
len
;
if
(
D
->
offset
<
D
->
size
)
{
load_next_part
(
D
);
load_next_part
(
D
,
q
->
callback
,
q
->
callback_extra
);
return
0
;
}
else
{
end_load
(
D
);
end_load
(
D
,
q
->
callback
,
q
->
callback_extra
);
return
0
;
}
}
struct
query_methods
download_methods
=
{
st
atic
st
ruct
query_methods
download_methods
=
{
.
on_answer
=
download_on_answer
,
.
type
=
TYPE_TO_PARAM
(
upload_file
)
};
void
load_next_part
(
struct
download
*
D
)
{
static
void
load_next_part
(
struct
download
*
D
,
void
*
callback
,
void
*
callback_extra
)
{
if
(
!
D
->
offset
)
{
static
char
buf
[
PATH_MAX
];
int
l
;
...
...
@@ -1965,7 +1974,7 @@ void load_next_part (struct download *D) {
l
=
tsnprintf
(
buf
,
sizeof
(
buf
),
"%s/download_%lld"
,
get_downloads_directory
(),
D
->
id
);
}
if
(
l
>=
(
int
)
sizeof
(
buf
))
{
logprintf
(
"Download filename is too long"
);
vlogprintf
(
E_ERROR
,
"Download filename is too long"
);
exit
(
1
);
}
D
->
name
=
tstrdup
(
buf
);
...
...
@@ -1973,17 +1982,17 @@ void load_next_part (struct download *D) {
if
(
stat
(
buf
,
&
st
)
>=
0
)
{
D
->
offset
=
st
.
st_size
;
if
(
D
->
offset
>=
D
->
size
)
{
cur_downloading_bytes
+=
D
->
size
;
cur_downloaded_bytes
+=
D
->
offset
;
rprintf
(
"Already downloaded
\n
"
);
end_load
(
D
);
tgl_state
.
cur_downloading_bytes
+=
D
->
size
;
tgl_state
.
cur_downloaded_bytes
+=
D
->
offset
;
vlogprintf
(
E_NOTICE
,
"Already downloaded
\n
"
);
end_load
(
D
,
callback
,
callback_extra
);
return
;
}
}
cur_downloading_bytes
+=
D
->
size
;
cur_downloaded_bytes
+=
D
->
offset
;
update_prompt
();
tgl_state
.
cur_downloading_bytes
+=
D
->
size
;
tgl_state
.
cur_downloaded_bytes
+=
D
->
offset
;
//
update_prompt ();
}
clear_packet
();
out_int
(
CODE_upload_get_file
);
...
...
@@ -2003,18 +2012,18 @@ void load_next_part (struct download *D) {
}
out_int
(
D
->
offset
);
out_int
(
1
<<
14
);
send_query
(
DC_list
[
D
->
dc
],
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
download_methods
,
D
);
send_query
(
DC_list
[
D
->
dc
],
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
download_methods
,
D
,
callback
,
callback_extra
);
//send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &download_methods, D);
}
void
tgl_do_load_photo_size
(
struct
tgl_photo_size
*
P
,
int
next
)
{
void
tgl_do_load_photo_size
(
struct
tgl_photo_size
*
P
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
)
{
if
(
!
P
->
loc
.
dc
)
{
rprintf
(
"Bad video thumb
\n
"
);
vlogprintf
(
E_WARNING
,
"Bad video thumb
\n
"
);
callback
(
callback_extra
,
0
,
0
);
return
;
}
assert
(
P
);
assert
(
next
);
struct
download
*
D
=
talloc0
(
sizeof
(
*
D
));
D
->
id
=
0
;
D
->
offset
=
0
;
...
...
@@ -2023,14 +2032,17 @@ void tgl_do_load_photo_size (struct tgl_photo_size *P, int next) {
D
->
dc
=
P
->
loc
.
dc
;
D
->
local_id
=
P
->
loc
.
local_id
;
D
->
secret
=
P
->
loc
.
secret
;
D
->
next
=
next
;
D
->
name
=
0
;
D
->
fd
=
-
1
;
load_next_part
(
D
);
load_next_part
(
D
,
callback
,
callback_extra
);
}
void
tgl_do_load_photo
(
struct
tgl_photo
*
photo
,
int
next
)
{
if
(
!
photo
->
sizes_num
)
{
return
;
}
void
tgl_do_load_photo
(
struct
tgl_photo
*
photo
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
)
{
if
(
!
photo
->
sizes_num
)
{
vlogprintf
(
E_WARNING
,
"No sizes
\n
"
);
callback
(
callback_extra
,
0
,
0
);
return
;
}
int
max
=
-
1
;
int
maxi
=
0
;
int
i
;
...
...
@@ -2040,81 +2052,73 @@ void tgl_do_load_photo (struct tgl_photo *photo, int next) {
maxi
=
i
;
}
}
tgl_do_load_photo_size
(
&
photo
->
sizes
[
maxi
],
next
);
tgl_do_load_photo_size
(
&
photo
->
sizes
[
maxi
],
callback
,
callback_extra
);
}
void
tgl_do_load_video_thumb
(
struct
tgl_video
*
video
,
int
next
)
{
tgl_do_load_photo_size
(
&
video
->
thumb
,
next
);
void
tgl_do_load_video_thumb
(
struct
tgl_video
*
video
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
)
{
tgl_do_load_photo_size
(
&
video
->
thumb
,
callback
,
callback_extra
);
}
void
tgl_do_load_document_thumb
(
struct
tgl_document
*
video
,
int
next
)
{
tgl_do_load_photo_size
(
&
video
->
thumb
,
next
);
void
tgl_do_load_document_thumb
(
struct
tgl_document
*
video
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
)
{
tgl_do_load_photo_size
(
&
video
->
thumb
,
callback
,
callback_extra
);
}
void
tgl_do_load_video
(
struct
tgl_video
*
V
,
int
next
)
{
void
tgl_do_load_video
(
struct
tgl_video
*
V
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
)
{
assert
(
V
);
assert
(
next
);
struct
download
*
D
=
talloc0
(
sizeof
(
*
D
));
D
->
offset
=
0
;
D
->
size
=
V
->
size
;
D
->
id
=
V
->
id
;
D
->
access_hash
=
V
->
access_hash
;
D
->
dc
=
V
->
dc_id
;
D
->
next
=
next
;
D
->
name
=
0
;
D
->
fd
=
-
1
;
D
->
type
=
CODE_input_video_file_location
;
load_next_part
(
D
);
load_next_part
(
D
,
callback
,
callback_extra
);
}
void
tgl_do_load_audio
(
struct
tgl_video
*
V
,
int
next
)
{
void
tgl_do_load_audio
(
struct
tgl_video
*
V
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
)
{
assert
(
V
);
assert
(
next
);
struct
download
*
D
=
talloc0
(
sizeof
(
*
D
));
D
->
offset
=
0
;
D
->
size
=
V
->
size
;
D
->
id
=
V
->
id
;
D
->
access_hash
=
V
->
access_hash
;
D
->
dc
=
V
->
dc_id
;
D
->
next
=
next
;
D
->
name
=
0
;
D
->
fd
=
-
1
;
D
->
type
=
CODE_input_audio_file_location
;
load_next_part
(
D
);
load_next_part
(
D
,
callback
,
callback_extra
);
}
void
tgl_do_load_document
(
struct
tgl_document
*
V
,
int
next
)
{
void
tgl_do_load_document
(
struct
tgl_document
*
V
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
)
{
assert
(
V
);
assert
(
next
);
struct
download
*
D
=
talloc0
(
sizeof
(
*
D
));
D
->
offset
=
0
;
D
->
size
=
V
->
size
;
D
->
id
=
V
->
id
;
D
->
access_hash
=
V
->
access_hash
;
D
->
dc
=
V
->
dc_id
;
D
->
next
=
next
;
D
->
name
=
0
;
D
->
fd
=
-
1
;
D
->
type
=
CODE_input_document_file_location
;
load_next_part
(
D
);
load_next_part
(
D
,
callback
,
callback_extra
);
}
void
tgl_do_load_encr_video
(
struct
tgl_encr_video
*
V
,
int
next
)
{
void
tgl_do_load_encr_video
(
struct
tgl_encr_video
*
V
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
)
{
assert
(
V
);
assert
(
next
);
struct
download
*
D
=
talloc0
(
sizeof
(
*
D
));
D
->
offset
=
0
;
D
->
size
=
V
->
size
;
D
->
id
=
V
->
id
;
D
->
access_hash
=
V
->
access_hash
;
D
->
dc
=
V
->
dc_id
;
D
->
next
=
next
;
D
->
name
=
0
;
D
->
fd
=
-
1
;
D
->
key
=
V
->
key
;
D
->
iv
=
talloc
(
32
);
memcpy
(
D
->
iv
,
V
->
iv
,
32
);
load_next_part
(
D
);
load_next_part
(
D
,
callback
,
callback_extra
);
unsigned
char
md5
[
16
];
unsigned
char
str
[
64
];
...
...
@@ -2126,78 +2130,64 @@ void tgl_do_load_encr_video (struct tgl_encr_video *V, int next) {
/* }}} */
/* {{{ Export auth */
char
*
export_auth_str
;
int
export_auth_str_len
;
int
is_export_auth_str
(
void
)
{
return
export_auth_str
!=
0
;
}
int
isn_export_auth_str
(
void
)
{
return
export_auth_str
==
0
;
static
int
import_auth_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_auth_authorization
);
fetch_int
();
// expires
tglf_fetch_alloc_user
();
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)
(
q
->
callback_extra
,
1
);
}
return
0
;
}
int
export_auth_on_answer
(
struct
query
*
q
UU
)
{
static
struct
query_methods
import_auth_methods
=
{
.
on_answer
=
import_auth_on_answer
,
.
on_error
=
fail_on_error
,
.
type
=
TYPE_TO_PARAM
(
auth_authorization
)
};
static
int
export_auth_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_auth_exported_authorization
);
bl_do_set_our_id
(
fetch_int
());
int
l
=
prefetch_strlen
();
char
*
s
=
talloc
(
l
);
memcpy
(
s
,
fetch_str
(
l
),
l
);
export_auth_str_len
=
l
;
export_auth_str
=
s
;
clear_packet
();
tgl_do_insert_header
();
out_int
(
CODE_auth_import_authorization
);
out_int
(
tgl_state
.
our_id
);
out_cstring
(
s
,
l
);
send_query
(
q
->
extra
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
import_auth_methods
,
0
,
q
->
callback
,
q
->
callback_extra
);
tfree
(
s
,
l
);
return
0
;
}
struct
query_methods
export_auth_methods
=
{
st
atic
st
ruct
query_methods
export_auth_methods
=
{
.
on_answer
=
export_auth_on_answer
,
.
on_error
=
fail_on_error
,
.
type
=
TYPE_TO_PARAM
(
auth_exported_authorization
)
};
void
tgl_do_export_auth
(
int
num
)
{
export_auth_str
=
0
;
void
tgl_do_export_auth
(
int
num
,
void
(
*
callback
)
(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_auth_export_authorization
);
out_int
(
num
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
export_auth_methods
,
0
);
net_loop
(
0
,
is_export_auth_str
);
}
/* }}} */
/* {{{ Import auth */
int
import_auth_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_auth_authorization
);
fetch_int
();
// expires
tglf_fetch_alloc_user
();
tfree
(
export_auth_str
,
export_auth_str_len
);
export_auth_str
=
0
;
return
0
;
}
struct
query_methods
import_auth_methods
=
{
.
on_answer
=
import_auth_on_answer
,
.
on_error
=
fail_on_error
,
.
type
=
TYPE_TO_PARAM
(
auth_authorization
)
};
void
tgl_do_import_auth
(
int
num
)
{
clear_packet
();
tgl_do_insert_header
();
out_int
(
CODE_auth_import_authorization
);
out_int
(
tgl_state
.
our_id
);
out_cstring
(
export_auth_str
,
export_auth_str_len
);
send_query
(
DC_list
[
num
],
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
import_auth_methods
,
0
);
net_loop
(
0
,
isn_export_auth_str
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
export_auth_methods
,
DC_list
[
num
],
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Add contact */
int
add_contact_on_answer
(
struct
query
*
q
UU
)
{
static
int
add_contact_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_contacts_imported_contacts
);
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
if
(
n
>
0
)
{
logprintf
(
"Added successfully"
);
vlogprintf
(
E_DEBUG
,
"Added successfully"
);
}
else
{
logprintf
(
"Not added"
);
vlogprintf
(
E_DEBUG
,
"Not added"
);
}
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
...
...
@@ -2209,11 +2199,16 @@ int add_contact_on_answer (struct query *q UU) {
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
long
long
id
=
fetch_long
();
logprintf
(
"contact #%lld not added. Please retry
\n
"
,
id
);
vlogprintf
(
E_NOTICE
,
"contact #%lld not added. Please retry
\n
"
,
id
);
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
struct
tgl_user
**
UL
=
talloc
(
n
*
sizeof
(
void
*
));
for
(
i
=
0
;
i
<
n
;
i
++
)
{
UL
[
i
]
=
tglf_fetch_alloc_user
();
}
/*for (i = 0; i < n ; i++) {
struct tgl_user *U = tglf_fetch_alloc_user ();
print_start ();
push_color (COLOR_YELLOW);
...
...
@@ -2242,16 +2237,21 @@ int add_contact_on_answer (struct query *q UU) {
pop_color ();
print_end ();
}*/
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
int
,
struct
tgl_user
**
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
n
,
UL
);
}
tfree
(
UL
,
n
*
sizeof
(
void
*
));
return
0
;
}
struct
query_methods
add_contact_methods
=
{
st
atic
st
ruct
query_methods
add_contact_methods
=
{
.
on_answer
=
add_contact_on_answer
,
.
type
=
TYPE_TO_PARAM
(
contacts_imported_contacts
)
};
void
tgl_do_add_contact
(
const
char
*
phone
,
int
phone_len
,
const
char
*
first_name
,
int
first_name_len
,
const
char
*
last_name
,
int
last_name_len
,
int
force
)
{
void
tgl_do_add_contact
(
const
char
*
phone
,
int
phone_len
,
const
char
*
first_name
,
int
first_name_len
,
const
char
*
last_name
,
int
last_name_len
,
int
force
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_user
*
users
[]),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_contacts_import_contacts
);
out_int
(
CODE_vector
);
...
...
@@ -2262,23 +2262,26 @@ void tgl_do_add_contact (const char *phone, int phone_len, const char *first_nam
out_cstring
(
first_name
,
first_name_len
);
out_cstring
(
last_name
,
last_name_len
);
out_int
(
force
?
CODE_bool_true
:
CODE_bool_false
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_contact_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_contact_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Msg search */
int
msg_search_on_answer
(
struct
query
*
q
UU
)
{
static
int
msg_search_on_answer
(
struct
query
*
q
UU
)
{
return
get_history_on_answer
(
q
);
}
struct
query_methods
msg_search_methods
=
{
st
atic
st
ruct
query_methods
msg_search_methods
=
{
.
on_answer
=
msg_search_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_messages
)
};
void
tgl_do_msg_search
(
tgl_peer_id_t
id
,
int
from
,
int
to
,
int
limit
,
const
char
*
s
)
{
void
tgl_do_msg_search
(
tgl_peer_id_t
id
,
int
from
,
int
to
,
int
limit
,
const
char
*
s
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_message
*
list
[]),
void
*
callback_extra
)
{
if
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_ENCR_CHAT
)
{
rprintf
(
"Can not search in secure chat
\n
"
);
vlogprintf
(
E_WARNING
,
"Can not search in secure chat
\n
"
);
if
(
callback
)
{
callback
(
callback_extra
,
0
,
0
,
0
);
}
return
;
}
clear_packet
();
...
...
@@ -2295,12 +2298,12 @@ void tgl_do_msg_search (tgl_peer_id_t id, int from, int to, int limit, const cha
out_int
(
0
);
// offset
out_int
(
0
);
// max_id
out_int
(
limit
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_search_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
msg_search_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Contacts search */
int
contacts_search_on_answer
(
struct
query
*
q
UU
)
{
static
int
contacts_search_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
CODE_contacts_found
);
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
...
...
@@ -2311,7 +2314,12 @@ int contacts_search_on_answer (struct query *q UU) {
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
print_start
();
struct
tgl_user
**
UL
=
talloc
(
sizeof
(
void
*
)
*
n
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
UL
[
i
]
=
tglf_fetch_alloc_user
();
}
/*print_start ();
push_color (COLOR_YELLOW);
for (i = 0; i < n; i++) {
struct tgl_user *U = tglf_fetch_alloc_user ();
...
...
@@ -2322,29 +2330,33 @@ int contacts_search_on_answer (struct query *q UU) {
printf (". Phone %s\n", U->phone);
}
pop_color ();
print_end
();
print_end ();*/
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
int
,
struct
tgl_user
**
))
q
->
callback
)
(
q
->
callback_extra
,
1
,
n
,
UL
);
}
tfree
(
UL
,
sizeof
(
void
*
)
*
n
);
return
0
;
}
struct
query_methods
contacts_search_methods
=
{
st
atic
st
ruct
query_methods
contacts_search_methods
=
{
.
on_answer
=
contacts_search_on_answer
,
.
type
=
TYPE_TO_PARAM
(
contacts_found
)
};
void
tgl_do_contacts_search
(
int
limit
,
const
char
*
s
)
{
void
tgl_do_contacts_search
(
int
limit
,
const
char
*
s
,
void
(
*
callback
)
(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_user
*
users
[]),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_contacts_search
);
out_string
(
s
);
out_int
(
limit
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
contacts_search_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
contacts_search_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Encr accept */
int
send_encr_accept_on_answer
(
struct
query
*
q
UU
)
{
static
int
send_encr_accept_on_answer
(
struct
query
*
q
UU
)
{
struct
tgl_secret_chat
*
E
=
tglf_fetch_alloc_encrypted_chat
();
if
(
E
->
state
==
sc_ok
)
{
/*
if (E->state == sc_ok) {
print_start ();
push_color (COLOR_YELLOW);
printf ("Encrypted connection with ");
...
...
@@ -2360,13 +2372,17 @@ int send_encr_accept_on_answer (struct query *q UU) {
printf (" failed\n");
pop_color ();
print_end ();
}*/
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_secret_chat
*
))
q
->
callback
)
(
q
->
callback_extra
,
E
->
state
==
sc_ok
,
E
);
}
return
0
;
}
int
send_encr_request_on_answer
(
struct
query
*
q
UU
)
{
static
int
send_encr_request_on_answer
(
struct
query
*
q
UU
)
{
struct
tgl_secret_chat
*
E
=
tglf_fetch_alloc_encrypted_chat
();
if
(
E
->
state
==
sc_deleted
)
{
/*
if (E->state == sc_deleted) {
print_start ();
push_color (COLOR_YELLOW);
printf ("Encrypted connection with ");
...
...
@@ -2384,26 +2400,30 @@ int send_encr_request_on_answer (struct query *q UU) {
print_end ();
assert (E->state == sc_waiting);
}*/
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
,
struct
tgl_secret_chat
*
))
q
->
callback
)
(
q
->
callback_extra
,
E
->
state
!=
sc_deleted
,
E
);
}
return
0
;
}
struct
query_methods
send_encr_accept_methods
=
{
st
atic
st
ruct
query_methods
send_encr_accept_methods
=
{
.
on_answer
=
send_encr_accept_on_answer
,
.
type
=
TYPE_TO_PARAM
(
encrypted_chat
)
};
struct
query_methods
send_encr_request_methods
=
{
st
atic
st
ruct
query_methods
send_encr_request_methods
=
{
.
on_answer
=
send_encr_request_on_answer
,
.
type
=
TYPE_TO_PARAM
(
encrypted_chat
)
};
int
encr_root
;
unsigned
char
*
encr_prime
;
int
encr_param_version
;
BN_CTX
*
ctx
;
//
int encr_root;
//
unsigned char *encr_prime;
//
int encr_param_version;
static
BN_CTX
*
ctx
;
void
tgl_do_send_accept_encr_chat
(
struct
tgl_secret_chat
*
E
,
unsigned
char
*
random
)
{
void
tgl_do_send_accept_encr_chat
(
struct
tgl_secret_chat
*
E
,
unsigned
char
*
random
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_secret_chat
*
E
),
void
*
callback_extra
)
{
int
i
;
int
ok
=
0
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
...
...
@@ -2412,7 +2432,10 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
break
;
}
}
if
(
ok
)
{
return
;
}
// Already generated key for this chat
if
(
ok
)
{
callback
(
callback_extra
,
1
,
E
);
return
;
}
// Already generated key for this chat
unsigned
char
random_here
[
256
];
secure_random
(
random_here
,
256
);
for
(
i
=
0
;
i
<
256
;
i
++
)
{
...
...
@@ -2422,12 +2445,12 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
ensure_ptr
(
b
);
BIGNUM
*
g_a
=
BN_bin2bn
(
E
->
g_key
,
256
,
0
);
ensure_ptr
(
g_a
);
assert
(
check_g
(
encr_prime
,
g_a
)
>=
0
);
assert
(
check_g
(
tgl_state
.
encr_prime
,
g_a
)
>=
0
);
if
(
!
ctx
)
{
ctx
=
BN_CTX_new
();
ensure_ptr
(
ctx
);
}
BIGNUM
*
p
=
BN_bin2bn
(
encr_prime
,
256
,
0
);
BIGNUM
*
p
=
BN_bin2bn
(
tgl_state
.
encr_prime
,
256
,
0
);
ensure_ptr
(
p
);
BIGNUM
*
r
=
BN_new
();
ensure_ptr
(
r
);
...
...
@@ -2449,7 +2472,7 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
out_int
(
tgl_get_peer_id
(
E
->
id
));
out_long
(
E
->
access_hash
);
ensure
(
BN_set_word
(
g_a
,
encr_root
));
ensure
(
BN_set_word
(
g_a
,
tgl_state
.
encr_root
));
ensure
(
BN_mod_exp
(
r
,
g_a
,
b
,
p
,
ctx
));
static
unsigned
char
buf
[
256
];
memset
(
buf
,
0
,
sizeof
(
buf
));
...
...
@@ -2462,19 +2485,19 @@ void tgl_do_send_accept_encr_chat (struct tgl_secret_chat *E, unsigned char *ran
BN_clear_free
(
p
);
BN_clear_free
(
r
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_accept_methods
,
E
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_accept_methods
,
E
,
callback
,
callback_extra
);
}
void
tgl_do_create_keys_end
(
struct
tgl_secret_chat
*
U
)
{
assert
(
encr_prime
);
assert
(
tgl_state
.
encr_prime
);
BIGNUM
*
g_b
=
BN_bin2bn
(
U
->
g_key
,
256
,
0
);
ensure_ptr
(
g_b
);
assert
(
check_g
(
encr_prime
,
g_b
)
>=
0
);
assert
(
check_g
(
tgl_state
.
encr_prime
,
g_b
)
>=
0
);
if
(
!
ctx
)
{
ctx
=
BN_CTX_new
();
ensure_ptr
(
ctx
);
}
BIGNUM
*
p
=
BN_bin2bn
(
encr_prime
,
256
,
0
);
BIGNUM
*
p
=
BN_bin2bn
(
tgl_state
.
encr_prime
,
256
,
0
);
ensure_ptr
(
p
);
BIGNUM
*
r
=
BN_new
();
ensure_ptr
(
r
);
...
...
@@ -2496,13 +2519,7 @@ void tgl_do_create_keys_end (struct tgl_secret_chat *U) {
sha1
((
void
*
)
U
->
key
,
256
,
sha_buffer
);
long
long
k
=
*
(
long
long
*
)(
sha_buffer
+
12
);
if
(
k
!=
U
->
key_fingerprint
)
{
logprintf
(
"version = %d
\n
"
,
encr_param_version
);
hexdump
((
void
*
)
U
->
nonce
,
(
void
*
)(
U
->
nonce
+
256
));
hexdump
((
void
*
)
U
->
g_key
,
(
void
*
)(
U
->
g_key
+
256
));
hexdump
((
void
*
)
U
->
key
,
(
void
*
)(
U
->
key
+
64
));
hexdump
((
void
*
)
t
,
(
void
*
)(
t
+
256
));
hexdump
((
void
*
)
sha_buffer
,
(
void
*
)(
sha_buffer
+
20
));
logprintf
(
"!!Key fingerprint mismatch (my 0x%llx 0x%llx)
\n
"
,
(
unsigned
long
long
)
k
,
(
unsigned
long
long
)
U
->
key_fingerprint
);
vlogprintf
(
E_WARNING
,
"Key fingerprint mismatch (my 0x%llx 0x%llx)
\n
"
,
(
unsigned
long
long
)
k
,
(
unsigned
long
long
)
U
->
key_fingerprint
);
U
->
state
=
sc_deleted
;
}
...
...
@@ -2514,7 +2531,7 @@ void tgl_do_create_keys_end (struct tgl_secret_chat *U) {
BN_clear_free
(
a
);
}
void
tgl_do_send_create_encr_chat
(
void
*
x
,
unsigned
char
*
random
)
{
void
tgl_do_send_create_encr_chat
(
void
*
x
,
unsigned
char
*
random
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_secret_chat
*
E
),
void
*
callback_extra
)
{
int
user_id
=
(
long
)
x
;
int
i
;
unsigned
char
random_here
[
256
];
...
...
@@ -2528,13 +2545,13 @@ void tgl_do_send_create_encr_chat (void *x, unsigned char *random) {
}
BIGNUM
*
a
=
BN_bin2bn
(
random
,
256
,
0
);
ensure_ptr
(
a
);
BIGNUM
*
p
=
BN_bin2bn
(
encr_prime
,
256
,
0
);
BIGNUM
*
p
=
BN_bin2bn
(
tgl_state
.
encr_prime
,
256
,
0
);
ensure_ptr
(
p
);
BIGNUM
*
g
=
BN_new
();
ensure_ptr
(
g
);
ensure
(
BN_set_word
(
g
,
encr_root
));
ensure
(
BN_set_word
(
g
,
tgl_state
.
encr_root
));
BIGNUM
*
r
=
BN_new
();
ensure_ptr
(
r
);
...
...
@@ -2578,10 +2595,10 @@ void tgl_do_send_create_encr_chat (void *x, unsigned char *random) {
BN_clear_free
(
p
);
BN_clear_free
(
r
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_request_methods
,
E
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
send_encr_request_methods
,
E
,
callback
,
callback_extra
);
}
int
get_dh_config_on_answer
(
struct
query
*
q
UU
)
{
static
int
get_dh_config_on_answer
(
struct
query
*
q
UU
)
{
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_messages_dh_config
||
x
==
CODE_messages_dh_config_not_modified
);
if
(
x
==
CODE_messages_dh_config
)
{
...
...
@@ -2603,7 +2620,7 @@ int get_dh_config_on_answer (struct query *q UU) {
memcpy
(
random
,
fetch_str
(
256
),
256
);
if
(
q
->
extra
)
{
void
**
x
=
q
->
extra
;
((
void
(
*
)(
void
*
,
void
*
))(
*
x
))(
x
[
1
],
random
);
((
void
(
*
)(
void
*
,
void
*
,
void
*
,
void
*
))(
*
x
))(
x
[
1
],
random
,
q
->
callback
,
q
->
callback_extra
);
tfree
(
x
,
2
*
sizeof
(
void
*
));
tfree_secure
(
random
,
256
);
}
else
{
...
...
@@ -2612,81 +2629,84 @@ int get_dh_config_on_answer (struct query *q UU) {
return
0
;
}
struct
query_methods
get_dh_config_methods
=
{
st
atic
st
ruct
query_methods
get_dh_config_methods
=
{
.
on_answer
=
get_dh_config_on_answer
,
.
type
=
TYPE_TO_PARAM
(
messages_dh_config
)
};
void
tgl_do_accept_encr_chat_request
(
struct
tgl_secret_chat
*
E
)
{
void
tgl_do_accept_encr_chat_request
(
struct
tgl_secret_chat
*
E
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_secret_chat
*
E
),
void
*
callback_extra
)
{
assert
(
E
->
state
==
sc_request
);
clear_packet
();
out_int
(
CODE_messages_get_dh_config
);
out_int
(
encr_param_version
);
out_int
(
tgl_state
.
encr_param_version
);
out_int
(
256
);
void
**
x
=
talloc
(
2
*
sizeof
(
void
*
));
x
[
0
]
=
tgl_do_send_accept_encr_chat
;
x
[
1
]
=
E
;
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dh_config_methods
,
x
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dh_config_methods
,
x
,
callback
,
callback_extra
);
}
void
tgl_do_create_encr_chat_request
(
int
user_id
)
{
void
tgl_do_create_encr_chat_request
(
int
user_id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_secret_chat
*
E
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_messages_get_dh_config
);
out_int
(
encr_param_version
);
out_int
(
tgl_state
.
encr_param_version
);
out_int
(
256
);
void
**
x
=
talloc
(
2
*
sizeof
(
void
*
));
x
[
0
]
=
tgl_do_send_create_encr_chat
;
x
[
1
]
=
(
void
*
)(
long
)(
user_id
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dh_config_methods
,
x
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_dh_config_methods
,
x
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Get difference */
int
unread_messages
;
int
difference_got
;
int
seq
,
pts
,
qts
,
last_date
;
int
get_state_on_answer
(
struct
query
*
q
UU
)
{
//
int unread_messages;
//
int difference_got;
//
int seq, pts, qts, last_date;
static
int
get_state_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_updates_state
);
bl_do_set_pts
(
fetch_int
());
bl_do_set_qts
(
fetch_int
());
bl_do_set_date
(
fetch_int
());
bl_do_set_seq
(
fetch_int
());
unread_messages
=
fetch_int
();
write_state_file
();
difference_got
=
1
;
//unread_messages = fetch_int ();
fetch_int
();
//write_state_file ();
//difference_got = 1;
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)
(
q
->
callback_extra
,
1
);
}
return
0
;
}
int
get_difference_active
;
int
get_difference_on_answer
(
struct
query
*
q
UU
)
{
get_difference_active
=
0
;
//
int get_difference_active;
static
int
get_difference_on_answer
(
struct
query
*
q
UU
)
{
//
get_difference_active = 0;
unsigned
x
=
fetch_int
();
if
(
x
==
CODE_updates_difference_empty
)
{
bl_do_set_date
(
fetch_int
());
bl_do_set_seq
(
fetch_int
());
difference_got
=
1
;
//difference_got = 1;
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)
(
q
->
callback_extra
,
1
);
}
}
else
if
(
x
==
CODE_updates_difference
||
x
==
CODE_updates_difference_slice
)
{
int
n
,
i
;
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
st
atic
struct
tgl_message
*
ML
[
10000
]
;
st
ruct
tgl_message
**
ML
=
talloc
(
n
*
sizeof
(
void
*
))
;
int
ml_pos
=
0
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
if
(
ml_pos
<
10000
)
{
ML
[
ml_pos
++
]
=
tglf_fetch_alloc_message
();
}
else
{
tglf_fetch_alloc_message
();
}
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
struct
tgl_message
**
EL
=
talloc
(
n
*
sizeof
(
void
*
));
int
el_pos
=
0
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
if
(
ml_pos
<
10000
)
{
ML
[
ml_pos
++
]
=
tglf_fetch_alloc_encrypted_message
();
}
else
{
tglf_fetch_alloc_encrypted_message
();
}
EL
[
el_pos
++
]
=
tglf_fetch_alloc_encrypted_message
();
}
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
...
...
@@ -2708,15 +2728,28 @@ int get_difference_on_answer (struct query *q UU) {
bl_do_set_qts
(
fetch_int
());
bl_do_set_date
(
fetch_int
());
bl_do_set_seq
(
fetch_int
());
unread_messages
=
fetch_int
();
write_state_file
();
for
(
i
=
0
;
i
<
ml_pos
;
i
++
)
{
//unread_messages = fetch_int ();
fetch_int
();
//write_state_file ();
/*for (i = 0; i < ml_pos; i++) {
print_message (ML[i]);
}*/
for
(
i
=
0
;
i
<
ml_pos
;
i
++
)
{
tgl_state
.
callback
.
new_msg
(
ML
[
i
]);
}
for
(
i
=
0
;
i
<
el_pos
;
i
++
)
{
tgl_state
.
callback
.
new_msg
(
EL
[
i
]);
}
tfree
(
ML
,
ml_pos
*
sizeof
(
void
*
));
tfree
(
EL
,
el_pos
*
sizeof
(
void
*
));
if
(
x
==
CODE_updates_difference_slice
)
{
tgl_do_get_difference
();
tgl_do_get_difference
(
0
,
q
->
callback
,
q
->
callback_extra
);
}
else
{
difference_got
=
1
;
//difference_got = 1;
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)
(
q
->
callback_extra
,
1
);
}
}
}
else
{
assert
(
0
);
...
...
@@ -2724,39 +2757,39 @@ int get_difference_on_answer (struct query *q UU) {
return
0
;
}
struct
query_methods
get_state_methods
=
{
st
atic
st
ruct
query_methods
get_state_methods
=
{
.
on_answer
=
get_state_on_answer
,
.
type
=
TYPE_TO_PARAM
(
updates_state
)
};
struct
query_methods
get_difference_methods
=
{
st
atic
st
ruct
query_methods
get_difference_methods
=
{
.
on_answer
=
get_difference_on_answer
,
.
type
=
TYPE_TO_PARAM
(
updates_difference
)
};
void
tgl_do_get_difference
(
void
)
{
get_difference_active
=
1
;
difference_got
=
0
;
void
tgl_do_get_difference
(
int
sync_from_start
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
)
{
//
get_difference_active = 1;
//
difference_got = 0;
clear_packet
();
tgl_do_insert_header
();
if
(
seq
>
0
||
sync_from_start
)
{
if
(
pts
==
0
)
{
pts
=
1
;
}
if
(
qts
==
0
)
{
qts
=
1
;
}
if
(
last_date
==
0
)
{
last_
date
=
1
;
}
if
(
tgl_state
.
seq
>
0
||
sync_from_start
)
{
if
(
tgl_state
.
pts
==
0
)
{
tgl_state
.
pts
=
1
;
}
if
(
tgl_state
.
qts
==
0
)
{
tgl_state
.
qts
=
1
;
}
if
(
tgl_state
.
date
==
0
)
{
tgl_state
.
date
=
1
;
}
out_int
(
CODE_updates_get_difference
);
out_int
(
pts
);
out_int
(
last_
date
);
out_int
(
qts
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_difference_methods
,
0
);
out_int
(
tgl_state
.
pts
);
out_int
(
tgl_state
.
date
);
out_int
(
tgl_state
.
qts
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_difference_methods
,
0
,
callback
,
callback_extra
);
}
else
{
out_int
(
CODE_updates_get_state
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_state_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
get_state_methods
,
0
,
callback
,
callback_extra
);
}
}
/* }}} */
/* {{{ Visualize key */
char
*
colors
[
4
]
=
{
COLOR_GREY
,
COLOR_CYAN
,
COLOR_BLUE
,
COLOR_GREEN
};
/*
char *colors[4] = {COLOR_GREY, COLOR_CYAN, COLOR_BLUE, COLOR_GREEN};
void tgl_do_visualize_key (tgl_peer_id_t id) {
assert (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT);
...
...
@@ -2784,11 +2817,24 @@ void tgl_do_visualize_key (tgl_peer_id_t id) {
if (i & 1) { printf ("\n"); }
}
print_end ();
}*/
void
tgl_do_visualize_key
(
tgl_peer_id_t
id
,
unsigned
char
buf
[
16
])
{
assert
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_ENCR_CHAT
);
tgl_peer_t
*
P
=
tgl_peer_get
(
id
);
assert
(
P
);
if
(
P
->
encr_chat
.
state
!=
sc_ok
)
{
vlogprintf
(
E_WARNING
,
"Chat is not initialized yet
\n
"
);
return
;
}
unsigned
char
res
[
20
];
SHA1
((
void
*
)
P
->
encr_chat
.
key
,
256
,
res
);
memcpy
(
buf
,
res
,
16
);
}
/* }}} */
/* {{{ Get suggested */
int
get_suggested_on_answer
(
struct
query
*
q
UU
)
{
/*
int get_suggested_on_answer (struct query *q UU) {
assert (fetch_int () == CODE_contacts_suggested);
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
...
...
@@ -2827,17 +2873,17 @@ void tgl_do_get_suggested (void) {
out_int (CODE_contacts_get_suggested);
out_int (100);
send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &get_suggested_methods, 0);
}
}
*/
/* }}} */
/* {{{ Add user to chat */
struct
query_methods
add_user_to_chat_methods
=
{
st
atic
st
ruct
query_methods
add_user_to_chat_methods
=
{
.
on_answer
=
fwd_msg_on_answer
,
.
type
=
TYPE_TO_PARAM
(
message_action
)
};
void
tgl_do_add_user_to_chat
(
tgl_peer_id_t
chat_id
,
tgl_peer_id_t
id
,
int
limit
)
{
void
tgl_do_add_user_to_chat
(
tgl_peer_id_t
chat_id
,
tgl_peer_id_t
id
,
int
limit
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_messages_add_chat_user
);
out_int
(
tgl_get_peer_id
(
chat_id
));
...
...
@@ -2853,10 +2899,10 @@ void tgl_do_add_user_to_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id, int limit
out_int
(
tgl_get_peer_id
(
id
));
}
out_int
(
limit
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_user_to_chat_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_user_to_chat_methods
,
0
,
callback
,
callback_extra
);
}
void
tgl_do_del_user_from_chat
(
tgl_peer_id_t
chat_id
,
tgl_peer_id_t
id
)
{
void
tgl_do_del_user_from_chat
(
tgl_peer_id_t
chat_id
,
tgl_peer_id_t
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_messages_delete_chat_user
);
out_int
(
tgl_get_peer_id
(
chat_id
));
...
...
@@ -2871,36 +2917,36 @@ void tgl_do_del_user_from_chat (tgl_peer_id_t chat_id, tgl_peer_id_t id) {
out_int
(
CODE_input_user_contact
);
out_int
(
tgl_get_peer_id
(
id
));
}
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_user_to_chat_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
add_user_to_chat_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Create secret chat */
char
*
create_print_name
(
tgl_peer_id_t
id
,
const
char
*
a1
,
const
char
*
a2
,
const
char
*
a3
,
const
char
*
a4
);
//
char *create_print_name (tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
void
tgl_do_create_secret_chat
(
tgl_peer_id_t
id
)
{
void
tgl_do_create_secret_chat
(
tgl_peer_id_t
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_secret_chat
*
E
),
void
*
callback_extra
)
{
assert
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_USER
);
tgl_peer_t
*
U
=
tgl_peer_get
(
id
);
if
(
!
U
)
{
rprintf
(
"Can not create chat with unknown user
\n
"
);
vlogprintf
(
E_WARNING
,
"Can not create chat with unknown user
\n
"
);
return
;
}
tgl_do_create_encr_chat_request
(
tgl_get_peer_id
(
id
));
tgl_do_create_encr_chat_request
(
tgl_get_peer_id
(
id
)
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Create group chat */
struct
query_methods
create_group_chat_methods
=
{
st
atic
st
ruct
query_methods
create_group_chat_methods
=
{
.
on_answer
=
fwd_msg_on_answer
,
.
type
=
TYPE_TO_PARAM
(
message_action
)
};
void
tgl_do_create_group_chat
(
tgl_peer_id_t
id
,
char
*
chat_topic
)
{
void
tgl_do_create_group_chat
(
tgl_peer_id_t
id
,
char
*
chat_topic
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
)
{
assert
(
tgl_get_peer_type
(
id
)
==
TGL_PEER_USER
);
tgl_peer_t
*
U
=
tgl_peer_get
(
id
);
if
(
!
U
)
{
rprintf
(
"Can not create chat with unknown user
\n
"
);
vlogprintf
(
E_WARNING
,
"Can not create chat with unknown user
\n
"
);
return
;
}
clear_packet
();
...
...
@@ -2916,62 +2962,74 @@ void tgl_do_create_group_chat (tgl_peer_id_t id, char *chat_topic) {
out_int
(
tgl_get_peer_id
(
id
));
}
out_string
(
chat_topic
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
create_group_chat_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
create_group_chat_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Delete msg */
int
delete_msg_on_answer
(
struct
query
*
q
UU
)
{
static
int
delete_msg_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
fetch_skip
(
n
);
logprintf
(
"Deleted %d messages
\n
"
,
n
);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)
(
q
->
callback_extra
,
1
);
}
return
0
;
}
struct
query_methods
delete_msg_methods
=
{
st
atic
st
ruct
query_methods
delete_msg_methods
=
{
.
on_answer
=
delete_msg_on_answer
,
.
type
=
TYPE_TO_PARAM_1
(
vector
,
TYPE_TO_PARAM
(
bare_int
))
};
void
tgl_do_delete_msg
(
long
long
id
)
{
void
tgl_do_delete_msg
(
long
long
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_messages_delete_messages
);
out_int
(
CODE_vector
);
out_int
(
1
);
out_int
(
id
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
delete_msg_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
delete_msg_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
/* {{{ Restore msg */
int
restore_msg_on_answer
(
struct
query
*
q
UU
)
{
static
int
restore_msg_on_answer
(
struct
query
*
q
UU
)
{
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
fetch_skip
(
n
);
logprintf
(
"Restored %d messages
\n
"
,
n
);
//logprintf ("Restored %d messages\n", n);
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)
(
q
->
callback_extra
,
1
);
}
return
0
;
}
struct
query_methods
restore_msg_methods
=
{
st
atic
st
ruct
query_methods
restore_msg_methods
=
{
.
on_answer
=
restore_msg_on_answer
,
.
type
=
TYPE_TO_PARAM_1
(
vector
,
TYPE_TO_PARAM
(
bare_int
))
};
void
tgl_do_restore_msg
(
long
long
id
)
{
void
tgl_do_restore_msg
(
long
long
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_messages_restore_messages
);
out_int
(
CODE_vector
);
out_int
(
1
);
out_int
(
id
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
restore_msg_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
restore_msg_methods
,
0
,
callback
,
callback_extra
);
}
/* }}} */
int
update_status_on_answer
(
struct
query
*
q
UU
)
{
fetch_bool
();
if
(
q
->
callback
)
{
((
void
(
*
)(
void
*
,
int
))
q
->
callback
)
(
q
->
callback_extra
,
1
);
}
return
0
;
}
...
...
@@ -2980,9 +3038,9 @@ struct query_methods update_status_methods = {
.
type
=
TYPE_TO_PARAM
(
bool
)
};
void
tgl_do_update_status
(
int
online
UU
)
{
void
tgl_do_update_status
(
int
online
UU
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
)
{
clear_packet
();
out_int
(
CODE_account_update_status
);
out_int
(
online
?
CODE_bool_false
:
CODE_bool_true
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
update_status_methods
,
0
);
send_query
(
DC_working
,
packet_ptr
-
packet_buffer
,
packet_buffer
,
&
update_status_methods
,
0
,
callback
,
callback_extra
);
}
queries.h
View file @
fe08f0c5
...
...
@@ -50,10 +50,12 @@ struct query {
struct
dc
*
DC
;
struct
session
*
session
;
void
*
extra
;
void
*
callback
;
void
*
callback_extra
;
};
struct
query
*
send_query
(
struct
dc
*
DC
,
int
len
,
void
*
data
,
struct
query_methods
*
methods
,
void
*
extra
);
struct
query
*
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
query_error
(
long
long
id
);
void
query_result
(
long
long
id
);
...
...
@@ -64,13 +66,13 @@ void remove_event_timer (struct event_timer *ev);
double
next_timer_in
(
void
);
void
work_timers
(
void
);
extern
struct
query_methods
help_get_config_methods
;
//
extern struct query_methods help_get_config_methods;
double
get_double_time
(
void
);
// For binlog
int
get_dh_config_on_answer
(
struct
query
*
q
);
void
fetch_dc_option
(
void
);
//
int get_dh_config_on_answer (struct query *q);
//
void fetch_dc_option (void);
#endif
structures.c
View file @
fe08f0c5
...
...
@@ -1628,9 +1628,9 @@ void tglm_message_remove_unsent (struct tgl_message *M) {
static
void
__send_msg
(
struct
tgl_message
*
M
)
{
vlogprintf
(
E_NOTICE
,
"Resending message...
\n
"
);
print_message
(
M
);
//
print_message (M);
tgl_do_send_msg
(
M
);
tgl_do_send_msg
(
M
,
0
,
0
);
}
void
tglm_send_all_unsent
(
void
)
{
...
...
tgl.c
View file @
fe08f0c5
...
...
@@ -5,3 +5,19 @@
#include "tgl.h"
struct
tgl_state
tgl_state
;
void
tgl_set_binlog_mode
(
int
mode
)
{
tgl_state
.
binlog_enabled
=
mode
;
}
void
tgl_set_binlog_path
(
const
char
*
path
)
{
tgl_state
.
binlog_name
=
tstrdup
(
path
);
}
void
tgl_set_auth_file_path
(
const
char
*
path
)
{
tgl_state
.
auth_file
=
tstrdup
(
path
);
}
void
tgl_set_download_directory
(
const
char
*
path
)
{
tgl_state
.
downloads_directory
=
tstrdup
(
path
);
}
tgl.h
View file @
fe08f0c5
...
...
@@ -6,7 +6,33 @@
#define TGL_MAX_DC_NUM 100
#define TGL_BUILD "1828"
#define TGL_VERSION "0.9-beta"
// Do not modify this structure, unless you know what you do
struct
tgl_update_callback
{
void
(
*
new_msg
)(
struct
tgl_message
*
M
);
void
(
*
marked_read
)(
int
num
,
struct
tgl_message
*
list
[]);
void
(
*
logprintf
)(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
(
*
type_notification
)(
tgl_peer_id_t
id
,
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
(
*
status_notification
)(
struct
tgl_user
*
U
);
void
(
*
user_registered
)(
struct
tgl_user
*
U
);
};
#define vlogprintf(verbosity_level,...) \
do { \
if (tgl_state.verbosity >= verbosity_level) { \
tgl_state.callback.logprintf (__VA_ARGS__); \
} \
} while (0)
#define E_ERROR 0
#define E_WARNING 1
#define E_NOTICE 2
#define E_DEBUG 3
struct
tgl_state
{
int
our_id
;
// ID of logged in user
int
encr_root
;
...
...
@@ -29,6 +55,12 @@ struct tgl_state {
long
long
cur_uploaded_bytes
;
long
long
cur_downloading_bytes
;
long
long
cur_downloaded_bytes
;
char
*
binlog_name
;
char
*
auth_file
;
char
*
downloads_directory
;
struct
tgl_update_callback
callback
;
};
extern
struct
tgl_state
tgl_state
;
...
...
@@ -58,6 +90,12 @@ int tgl_complete_peer_list (int index, const char *text, int len, char **R);
#define TGL_MK_GEO_CHAT(id) tgl_set_peer_id (TGL_PEER_GEO_CHAT,id)
#define TGL_MK_ENCR_CHAT(id) tgl_set_peer_id (TGL_PEER_ENCR_CHAT,id)
void
tgl_set_binlog_mode
(
int
mode
);
void
tgl_set_binlog_path
(
const
char
*
path
);
void
tgl_set_auth_file_path
(
const
char
*
path
);
void
tgl_set_download_directory
(
const
char
*
path
);
static
inline
int
tgl_get_peer_type
(
tgl_peer_id_t
id
)
{
return
id
.
type
;
}
...
...
@@ -89,52 +127,49 @@ static inline void tgl_set_test_mode (void) {
tgl_state
.
test_mode
++
;
}
void
tgl_do_send_code
(
const
char
*
user
);
void
tgl_do_phone_call
(
const
char
*
user
);
int
tgl_do_send_code_result
(
const
char
*
code
);
void
tgl_do_update_contact_list
(
void
);
void
tgl_do_send_message
(
tgl_peer_id_t
id
,
const
char
*
msg
,
int
len
);
void
tgl_do_send_text
(
tgl_peer_id_t
id
,
char
*
file
);
void
tgl_do_get_history
(
tgl_peer_id_t
id
,
int
limit
);
void
tgl_do_get_dialog_list
(
void
);
void
tgl_do_get_dialog_list_ex
(
void
);
void
tgl_do_send_photo
(
int
type
,
tgl_peer_id_t
to_id
,
char
*
file_name
);
void
tgl_do_get_chat_info
(
tgl_peer_id_t
id
);
void
tgl_do_get_user_list_info_silent
(
int
num
,
int
*
list
);
void
tgl_do_get_user_info
(
tgl_peer_id_t
id
);
void
tgl_do_forward_message
(
tgl_peer_id_t
id
,
int
n
);
void
tgl_do_rename_chat
(
tgl_peer_id_t
id
,
char
*
name
);
void
tgl_do_load_encr_video
(
struct
tgl_encr_video
*
V
,
int
next
);
void
tgl_do_create_encr_chat_request
(
int
user_id
);
void
tgl_do_create_secret_chat
(
tgl_peer_id_t
id
);
void
tgl_do_create_group_chat
(
tgl_peer_id_t
id
,
char
*
chat_topic
);
void
tgl_do_get_suggested
(
void
);
void
tgl_do_load_photo
(
struct
tgl_photo
*
photo
,
int
next
);
void
tgl_do_load_video_thumb
(
struct
tgl_video
*
video
,
int
next
);
void
tgl_do_load_audio
(
struct
tgl_video
*
V
,
int
next
);
void
tgl_do_load_video
(
struct
tgl_video
*
V
,
int
next
);
void
tgl_do_load_document
(
struct
tgl_document
*
V
,
int
next
);
void
tgl_do_load_document_thumb
(
struct
tgl_document
*
video
,
int
next
);
void
tgl_do_help_get_config
(
void
);
int
tgl_do_auth_check_phone
(
const
char
*
user
);
int
tgl_do_get_nearest_dc
(
void
);
int
tgl_do_send_code_result_auth
(
const
char
*
code
,
const
char
*
first_name
,
const
char
*
last_name
);
void
tgl_do_import_auth
(
int
num
);
void
tgl_do_export_auth
(
int
num
);
void
tgl_do_add_contact
(
const
char
*
phone
,
int
phone_len
,
const
char
*
first_name
,
int
first_name_len
,
const
char
*
last_name
,
int
last_name_len
,
int
force
);
void
tgl_do_msg_search
(
tgl_peer_id_t
id
,
int
from
,
int
to
,
int
limit
,
const
char
*
s
);
void
tgl_do_accept_encr_chat_request
(
struct
tgl_secret_chat
*
E
);
void
tgl_do_get_difference
(
void
);
void
tgl_do_mark_read
(
tgl_peer_id_t
id
);
void
tgl_do_visualize_key
(
tgl_peer_id_t
id
);
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_phone_call
(
const
char
*
user
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
);
int
tgl_do_send_code_result
(
const
char
*
user
,
const
char
*
code
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_user
*
Self
),
void
*
callback_extra
)
;
int
tgl_do_send_code_result_auth
(
const
char
*
user
,
const
char
*
code
,
const
char
*
first_name
,
const
char
*
last_name
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_user
*
Self
),
void
*
callback_extra
);
void
tgl_do_update_contact_list
(
void
(
*
callback
)
(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_user
*
contacts
[]),
void
*
callback_extra
);
void
tgl_do_send_message
(
tgl_peer_id_t
id
,
const
char
*
msg
,
int
len
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
);
void
tgl_do_send_msg
(
struct
tgl_message
*
M
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
);
void
tgl_do_send_text
(
tgl_peer_id_t
id
,
char
*
file
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
);
void
tgl_do_mark_read
(
tgl_peer_id_t
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
);
void
tgl_do_get_history
(
tgl_peer_id_t
id
,
int
limit
,
int
offline_mode
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_message
*
list
[]),
void
*
callback_extra
);
void
tgl_do_get_dialog_list
(
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
size
,
tgl_peer_id_t
peers
[],
int
last_msg_id
[],
int
unread_count
[]),
void
*
callback_extra
);
void
tgl_do_send_photo
(
int
type
,
tgl_peer_id_t
to_id
,
char
*
file_name
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
);
void
tgl_do_forward_message
(
tgl_peer_id_t
id
,
int
n
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
);
void
tgl_do_rename_chat
(
tgl_peer_id_t
id
,
char
*
name
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
);
void
tgl_do_get_chat_info
(
tgl_peer_id_t
id
,
int
offline_mode
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_chat
*
C
),
void
*
callback_extra
);
void
tgl_do_get_user_info
(
tgl_peer_id_t
id
,
int
offline_mode
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_user
*
U
),
void
*
callback_extra
);
void
tgl_do_load_photo
(
struct
tgl_photo
*
photo
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
);
void
tgl_do_load_video_thumb
(
struct
tgl_video
*
video
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
);
void
tgl_do_load_audio
(
struct
tgl_video
*
V
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
);
void
tgl_do_load_video
(
struct
tgl_video
*
V
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
);
void
tgl_do_load_document
(
struct
tgl_document
*
V
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
);
void
tgl_do_load_document_thumb
(
struct
tgl_document
*
video
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
);
void
tgl_do_load_encr_video
(
struct
tgl_encr_video
*
V
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
char
*
filename
),
void
*
callback_extra
);
void
tgl_do_export_auth
(
int
num
,
void
(
*
callback
)
(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
);
void
tgl_do_add_contact
(
const
char
*
phone
,
int
phone_len
,
const
char
*
first_name
,
int
first_name_len
,
const
char
*
last_name
,
int
last_name_len
,
int
force
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_user
*
users
[]),
void
*
callback_extra
);
void
tgl_do_msg_search
(
tgl_peer_id_t
id
,
int
from
,
int
to
,
int
limit
,
const
char
*
s
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_message
*
list
[]),
void
*
callback_extra
);
void
tgl_do_contacts_search
(
int
limit
,
const
char
*
s
,
void
(
*
callback
)
(
void
*
callback_extra
,
int
success
,
int
size
,
struct
tgl_user
*
users
[]),
void
*
callback_extra
);
void
tgl_do_create_encr_chat_request
(
int
user_id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_secret_chat
*
E
),
void
*
callback_extra
);
void
tgl_do_create_secret_chat
(
tgl_peer_id_t
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_secret_chat
*
E
),
void
*
callback_extra
);
void
tgl_do_accept_encr_chat_request
(
struct
tgl_secret_chat
*
E
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_secret_chat
*
E
),
void
*
callback_extra
);
void
tgl_do_get_difference
(
int
sync_from_start
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
);
void
tgl_do_add_user_to_chat
(
tgl_peer_id_t
chat_id
,
tgl_peer_id_t
id
,
int
limit
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
);
void
tgl_do_del_user_from_chat
(
tgl_peer_id_t
chat_id
,
tgl_peer_id_t
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
);
void
tgl_do_create_group_chat
(
tgl_peer_id_t
id
,
char
*
chat_topic
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
,
struct
tgl_message
*
M
),
void
*
callback_extra
);
void
tgl_do_delete_msg
(
long
long
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
);
void
tgl_do_restore_msg
(
long
long
id
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
);
void
tgl_do_update_status
(
int
online
,
void
(
*
callback
)(
void
*
callback_extra
,
int
success
),
void
*
callback_extra
);
void
tgl_do_visualize_key
(
tgl_peer_id_t
id
,
unsigned
char
buf
[
16
]);
//void tgl_do_get_suggested (void);
void
tgl_do_create_keys_end
(
struct
tgl_secret_chat
*
U
);
void
tgl_do_add_user_to_chat
(
tgl_peer_id_t
chat_id
,
tgl_peer_id_t
id
,
int
limit
);
void
tgl_do_del_user_from_chat
(
tgl_peer_id_t
chat_id
,
tgl_peer_id_t
id
);
void
tgl_do_update_status
(
int
online
);
void
tgl_do_contacts_search
(
int
limit
,
const
char
*
s
);
void
tgl_do_send_msg
(
struct
tgl_message
*
M
);
void
tgl_do_delete_msg
(
long
long
id
);
void
tgl_do_restore_msg
(
long
long
id
);
void
tgl_do_send_encr_chat_layer
(
struct
tgl_secret_chat
*
E
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment