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
bf291df3
Commit
bf291df3
authored
Oct 13, 2013
by
Vysheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Many fixes. Now (maybe) works authorization and get contact list query
parent
3243c29a
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
276 additions
and
91 deletions
+276
-91
Makefile
Makefile
+1
-0
interface.c
interface.c
+98
-14
interface.h
interface.h
+10
-0
loop.c
loop.c
+2
-0
mtproto-client.c
mtproto-client.c
+32
-31
mtproto-common.c
mtproto-common.c
+5
-4
mtproto-common.h
mtproto-common.h
+2
-3
net.c
net.c
+14
-13
queries.c
queries.c
+28
-25
structures.c
structures.c
+64
-0
structures.h
structures.h
+6
-0
telegram.h
telegram.h
+1
-0
tree.h
tree.h
+13
-1
No files found.
Makefile
View file @
bf291df3
...
...
@@ -6,6 +6,7 @@ LD=cc
SRC
=
main.c loop.c interface.c net.c mtproto-common.c mtproto-client.c queries.c structures.c
OBJ
=
$
(
SRC:.c
=
.o
)
EXE
=
telegram
HDRS
=
include.h interface.h loop.h mtproto-client.h mtproto-common.h net.h queries.h structures.h telegram.h tree.h
all
:
$(SRC) $(EXE)
...
...
interface.c
View file @
bf291df3
...
...
@@ -9,6 +9,10 @@
#include <string.h>
#include "include.h"
#include "queries.h"
#include "interface.h"
#include "telegram.h"
#include "structures.h"
char
*
default_prompt
=
">"
;
char
*
get_default_prompt
(
void
)
{
...
...
@@ -23,16 +27,18 @@ char *commands[] = {
"help"
,
"msg"
,
"contact_list"
,
"stats"
,
0
};
int
commands_flags
[]
=
{
070
,
072
,
00
,
07
,
07
,
};
char
*
a
=
0
;
char
*
*
user_list
=
&
a
;
char
*
user_list
[
MAX_USER_NUM
+
1
]
;
char
**
chat_list
=
&
a
;
int
init_token
(
char
**
q
)
{
...
...
@@ -91,12 +97,27 @@ int get_complete_mode (void) {
int
s
=
0
;
while
(
1
)
{
get_token
(
&
q
,
&
l
);
if
(
!*
q
)
{
return
flags
&
7
;
}
if
(
!*
q
)
{
return
flags
?
flags
&
7
:
7
;
}
s
++
;
if
(
s
<=
4
)
{
flags
>>=
3
;
}
}
}
extern
int
user_num
;
extern
struct
user
*
Users
[];
int
complete_user_list
(
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
index
++
;
while
(
index
<
user_num
&&
(
!
Users
[
index
]
->
print_name
||
strncmp
(
Users
[
index
]
->
print_name
,
text
,
len
)))
{
index
++
;
}
if
(
index
<
user_num
)
{
*
R
=
strdup
(
Users
[
index
]
->
print_name
);
return
index
;
}
else
{
return
-
1
;
}
}
int
complete_string_list
(
char
**
list
,
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
index
++
;
while
(
list
[
index
]
&&
strncmp
(
list
[
index
],
text
,
len
))
{
...
...
@@ -137,7 +158,7 @@ char *command_generator (const char *text, int state) {
index
=
complete_string_list
(
commands
,
index
,
text
,
len
,
&
R
);
return
R
;
case
1
:
index
=
complete_
string_list
(
user_list
,
index
,
text
,
len
,
&
R
);
index
=
complete_
user_list
(
index
,
text
,
len
,
&
R
);
return
R
;
case
2
:
index
=
complete_string_list
(
chat_list
,
index
,
text
,
len
,
&
R
);
...
...
@@ -154,27 +175,90 @@ char **complete_text (char *text, int start UU, int end UU) {
}
void
interpreter
(
char
*
line
UU
)
{
if
(
line
&&
*
line
)
{
add_history
(
line
);
}
if
(
!
memcmp
(
line
,
"contact_list"
,
12
))
{
do_update_contact_list
();
}
else
if
(
!
memcmp
(
line
,
"stats"
,
5
))
{
static
char
stat_buf
[
1
<<
15
];
print_stat
(
stat_buf
,
(
1
<<
15
)
-
1
);
printf
(
"%s
\n
"
,
stat_buf
);
}
}
int
readline_active
;
void
rprintf
(
const
char
*
format
,
...)
{
int
saved_point
=
0
;
char
*
saved_line
=
0
;
if
(
readline_active
)
{
saved_point
=
rl_point
;
saved_line
=
rl_copy_text
(
0
,
rl_end
);
rl_save_prompt
();
rl_replace_line
(
""
,
0
);
rl_redisplay
();
}
int
saved_point
=
rl_point
;
char
*
saved_line
=
rl_copy_text
(
0
,
rl_end
);
rl_save_prompt
();
rl_replace_line
(
""
,
0
);
rl_redisplay
();
va_list
ap
;
va_start
(
ap
,
format
);
vfprintf
(
stdout
,
format
,
ap
);
va_end
(
ap
);
if
(
readline_active
)
{
rl_restore_prompt
();
rl_replace_line
(
saved_line
,
0
);
rl_point
=
saved_point
;
rl_redisplay
();
free
(
saved_line
);
}
}
void
hexdump
(
int
*
in_ptr
,
int
*
in_end
)
{
int
saved_point
=
0
;
char
*
saved_line
=
0
;
if
(
readline_active
)
{
saved_point
=
rl_point
;
saved_line
=
rl_copy_text
(
0
,
rl_end
);
rl_save_prompt
();
rl_replace_line
(
""
,
0
);
rl_redisplay
();
}
int
*
ptr
=
in_ptr
;
while
(
ptr
<
in_end
)
{
fprintf
(
stdout
,
" %08x"
,
*
(
ptr
++
));
}
fprintf
(
stdout
,
"
\n
"
);
if
(
readline_active
)
{
rl_restore_prompt
();
rl_replace_line
(
saved_line
,
0
);
rl_point
=
saved_point
;
rl_redisplay
();
free
(
saved_line
);
}
}
void
logprintf
(
const
char
*
format
,
...)
{
int
saved_point
=
0
;
char
*
saved_line
=
0
;
if
(
readline_active
)
{
saved_point
=
rl_point
;
saved_line
=
rl_copy_text
(
0
,
rl_end
);
rl_save_prompt
();
rl_replace_line
(
""
,
0
);
rl_redisplay
();
}
printf
(
COLOR_GREY
" *** "
);
va_list
ap
;
va_start
(
ap
,
format
);
vfprintf
(
stdout
,
format
,
ap
);
va_end
(
ap
);
printf
(
COLOR_NORMAL
);
rl_restore_prompt
();
rl_replace_line
(
saved_line
,
0
);
rl_point
=
saved_point
;
rl_redisplay
();
free
(
saved_line
);
if
(
readline_active
)
{
rl_restore_prompt
();
rl_replace_line
(
saved_line
,
0
);
rl_point
=
saved_point
;
rl_redisplay
();
free
(
saved_line
);
}
}
interface.h
View file @
bf291df3
#ifndef __INTERFACE_H__
#define __INTERFACE_H__
#define COLOR_RED "\033[31;1m"
#define COLOR_NORMAL "\033[0m"
#define COLOR_GREEN "\033[32;1m"
#define COLOR_GREY "\033[37;1m"
char
*
get_default_prompt
(
void
);
char
*
complete_none
(
const
char
*
text
,
int
state
);
char
**
complete_text
(
char
*
text
,
int
start
,
int
end
);
void
interpreter
(
char
*
line
);
void
rprintf
(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
iprintf
(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
logprintf
(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
hexdump
(
int
*
in_ptr
,
int
*
in_end
);
#endif
loop.c
View file @
bf291df3
...
...
@@ -167,6 +167,7 @@ void read_auth_file (void) {
close
(
auth_file_fd
);
}
int
readline_active
;
int
loop
(
void
)
{
on_start
();
read_auth_file
();
...
...
@@ -216,6 +217,7 @@ int loop (void) {
fflush
(
stdout
);
fflush
(
stderr
);
readline_active
=
1
;
rl_callback_handler_install
(
get_default_prompt
(),
interpreter
);
rl_attempted_completion_function
=
(
CPPFunction
*
)
complete_text
;
rl_completion_entry_function
=
complete_none
;
...
...
mtproto-client.c
View file @
bf291df3
This diff is collapsed.
Click to expand it.
mtproto-common.c
View file @
bf291df3
...
...
@@ -16,6 +16,7 @@
#include <openssl/sha.h>
#include "mtproto-common.h"
#include "interface.h"
long
long
rsa_encrypted_chunks
,
rsa_decrypted_chunks
;
...
...
@@ -28,7 +29,7 @@ int get_random_bytes (void *buf, int n) {
r
=
read
(
h
,
buf
,
n
);
if
(
r
>
0
)
{
if
(
verbosity
>=
3
)
{
fprintf
(
stderr
,
"added %d bytes of real entropy to secure random numbers seed
\n
"
,
r
);
logprintf
(
"added %d bytes of real entropy to secure random numbers seed
\n
"
,
r
);
}
}
close
(
h
);
...
...
@@ -71,14 +72,14 @@ void prng_seed (const char *password_filename, int password_length) {
if
(
password_filename
)
{
int
fd
=
open
(
password_filename
,
O_RDONLY
);
if
(
fd
<
0
)
{
fprintf
(
stderr
,
"Warning: fail to open password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
logprintf
(
"Warning: fail to open password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
}
else
{
int
l
=
read
(
fd
,
a
+
s
,
password_length
);
if
(
l
<
0
)
{
fprintf
(
stderr
,
"Warning: fail to read password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
logprintf
(
"Warning: fail to read password file -
\"
%s
\"
, %m.
\n
"
,
password_filename
);
}
else
{
if
(
verbosity
>
0
)
{
fprintf
(
stderr
,
"read %d bytes from password file.
\n
"
,
l
);
logprintf
(
"read %d bytes from password file.
\n
"
,
l
);
}
s
+=
l
;
}
...
...
mtproto-common.h
View file @
bf291df3
...
...
@@ -7,6 +7,7 @@
#include <openssl/aes.h>
#include <stdio.h>
#include "interface.h"
/* DH key exchange protocol data structures */
#define CODE_req_pq 0x60469778
#define CODE_resPQ 0x05162463
...
...
@@ -409,8 +410,6 @@ int pad_aes_encrypt (char *from, int from_len, char *to, int size);
int
pad_aes_decrypt
(
char
*
from
,
int
from_len
,
char
*
to
,
int
size
);
static
inline
void
hexdump_in
(
void
)
{
int
*
ptr
=
in_ptr
;
while
(
ptr
<
in_end
)
{
fprintf
(
stderr
,
" %08x"
,
*
(
ptr
++
));
}
fprintf
(
stderr
,
"
\n
"
);
hexdump
(
in_ptr
,
in_end
);
}
#endif
net.c
View file @
bf291df3
...
...
@@ -17,6 +17,7 @@
#include "mtproto-client.h"
#include "mtproto-common.h"
#include "tree.h"
#include "interface.h"
DEFINE_TREE
(
int
,
int
,
int_cmp
,
0
)
...
...
@@ -156,7 +157,7 @@ struct connection *create_connection (const char *host, int port, struct session
if
(
connect
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
==
-
1
)
{
if
(
errno
!=
EINPROGRESS
)
{
fprintf
(
stderr
,
"Can not connect to %s:%d %m
\n
"
,
host
,
port
);
logprintf
(
"Can not connect to %s:%d %m
\n
"
,
host
,
port
);
close
(
fd
);
free
(
c
);
return
0
;
...
...
@@ -183,7 +184,7 @@ struct connection *create_connection (const char *host, int port, struct session
assert
(
!
Connections
[
fd
]);
Connections
[
fd
]
=
c
;
if
(
verbosity
)
{
fprintf
(
stderr
,
"connect to %s:%d successful
\n
"
,
host
,
port
);
logprintf
(
"connect to %s:%d successful
\n
"
,
host
,
port
);
}
if
(
c
->
methods
->
ready
)
{
c
->
methods
->
ready
(
c
);
...
...
@@ -211,7 +212,7 @@ void fail_connection (struct connection *c) {
void
try_write
(
struct
connection
*
c
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"try write: fd = %d
\n
"
,
c
->
fd
);
logprintf
(
"try write: fd = %d
\n
"
,
c
->
fd
);
}
int
x
=
0
;
while
(
c
->
out_head
)
{
...
...
@@ -238,12 +239,12 @@ void try_write (struct connection *c) {
}
}
if
(
verbosity
)
{
fprintf
(
stderr
,
"Sent %d bytes to %d
\n
"
,
x
,
c
->
fd
);
logprintf
(
"Sent %d bytes to %d
\n
"
,
x
,
c
->
fd
);
}
c
->
out_bytes
-=
x
;
}
void
hexdump
(
struct
connection_buffer
*
b
)
{
void
hexdump
_buf
(
struct
connection_buffer
*
b
)
{
int
pos
=
0
;
int
rem
=
8
;
while
(
b
)
{
...
...
@@ -270,7 +271,7 @@ void hexdump (struct connection_buffer *b) {
void
try_rpc_read
(
struct
connection
*
c
)
{
assert
(
c
->
in_head
);
if
(
verbosity
>=
4
)
{
hexdump
(
c
->
in_head
);
hexdump
_buf
(
c
->
in_head
);
}
while
(
1
)
{
...
...
@@ -307,7 +308,7 @@ void try_rpc_read (struct connection *c) {
void
try_read
(
struct
connection
*
c
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"try read: fd = %d
\n
"
,
c
->
fd
);
logprintf
(
"try read: fd = %d
\n
"
,
c
->
fd
);
}
if
(
!
c
->
in_tail
)
{
c
->
in_head
=
c
->
in_tail
=
new_connection_buffer
(
1
<<
20
);
...
...
@@ -334,7 +335,7 @@ void try_read (struct connection *c) {
}
}
if
(
verbosity
)
{
fprintf
(
stderr
,
"Received %d bytes from %d
\n
"
,
x
,
c
->
fd
);
logprintf
(
"Received %d bytes from %d
\n
"
,
x
,
c
->
fd
);
}
c
->
in_bytes
+=
x
;
if
(
x
)
{
...
...
@@ -356,15 +357,15 @@ int connections_make_poll_array (struct pollfd *fds, int max) {
fds
++
;
max
--
;
}
if
(
verbosity
>=
3
)
{
fprintf
(
stderr
,
"%d connections in poll
\n
"
,
_max
-
max
);
if
(
verbosity
>=
10
)
{
logprintf
(
"%d connections in poll
\n
"
,
_max
-
max
);
}
return
_max
-
max
;
}
void
connections_poll_result
(
struct
pollfd
*
fds
,
int
max
)
{
if
(
verbosity
>=
2
)
{
fprintf
(
stderr
,
"connections_poll_result: max = %d
\n
"
,
max
);
if
(
verbosity
>=
10
)
{
logprintf
(
"connections_poll_result: max = %d
\n
"
,
max
);
}
int
i
;
for
(
i
=
0
;
i
<
max
;
i
++
)
{
...
...
@@ -374,7 +375,7 @@ void connections_poll_result (struct pollfd *fds, int max) {
}
if
(
fds
[
i
].
revents
&
(
POLLHUP
|
POLLERR
|
POLLRDHUP
))
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"fail connection
\n
"
);
logprintf
(
"fail connection
\n
"
);
}
fail_connection
(
c
);
}
else
if
(
fds
[
i
].
revents
&
POLLOUT
)
{
...
...
queries.c
View file @
bf291df3
...
...
@@ -43,7 +43,7 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
dc_create_session
(
DC
);
}
if
(
verbosity
)
{
fprintf
(
stderr
,
"Sending query of size %d to DC (%s:%d)
\n
"
,
4
*
ints
,
DC
->
ip
,
DC
->
port
);
logprintf
(
"Sending query of size %d to DC (%s:%d)
\n
"
,
4
*
ints
,
DC
->
ip
,
DC
->
port
);
}
struct
query
*
q
=
malloc
(
sizeof
(
*
q
));
q
->
data_len
=
ints
;
...
...
@@ -51,11 +51,11 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth
memcpy
(
q
->
data
,
data
,
4
*
ints
);
q
->
msg_id
=
encrypt_send_message
(
DC
->
sessions
[
0
]
->
c
,
data
,
ints
,
1
);
if
(
verbosity
)
{
fprintf
(
stderr
,
"Msg_id is %lld
\n
"
,
q
->
msg_id
);
logprintf
(
"Msg_id is %lld
\n
"
,
q
->
msg_id
);
}
q
->
methods
=
methods
;
if
(
queries_tree
)
{
fprintf
(
stderr
,
"%lld %lld
\n
"
,
q
->
msg_id
,
queries_tree
->
x
->
msg_id
);
logprintf
(
"%lld %lld
\n
"
,
q
->
msg_id
,
queries_tree
->
x
->
msg_id
);
}
queries_tree
=
tree_insert_query
(
queries_tree
,
q
,
lrand48
());
...
...
@@ -77,12 +77,12 @@ void query_error (long long id) {
int
error_len
=
prefetch_strlen
();
char
*
error
=
fetch_str
(
error_len
);
if
(
verbosity
)
{
fprintf
(
stderr
,
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
logprintf
(
"error for query #%lld: #%d :%.*s
\n
"
,
id
,
error_code
,
error_len
,
error
);
}
struct
query
*
q
=
query_get
(
id
);
if
(
!
q
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"No such query
\n
"
);
logprintf
(
"No such query
\n
"
);
}
}
else
{
remove_event_timer
(
&
q
->
ev
);
...
...
@@ -100,10 +100,10 @@ static int packed_buffer[MAX_PACKED_SIZE / 4];
void
query_result
(
long
long
id
UU
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"result for query #%lld
\n
"
,
id
);
logprintf
(
"result for query #%lld
\n
"
,
id
);
}
if
(
verbosity
>=
4
)
{
fprintf
(
stderr
,
"result: "
);
logprintf
(
"result: "
);
hexdump_in
();
}
int
op
=
prefetch_int
();
...
...
@@ -124,8 +124,8 @@ void query_result (long long id UU) {
int
err
=
inflate
(
&
strm
,
Z_FINISH
);
if
(
verbosity
)
{
fprintf
(
stderr
,
"inflate error = %d
\n
"
,
err
);
fprintf
(
stderr
,
"inflated %d bytes
\n
"
,
(
int
)
strm
.
total_out
);
logprintf
(
"inflate error = %d
\n
"
,
err
);
logprintf
(
"inflated %d bytes
\n
"
,
(
int
)
strm
.
total_out
);
}
end
=
in_ptr
;
eend
=
in_end
;
...
...
@@ -133,14 +133,14 @@ void query_result (long long id UU) {
in_ptr
=
packed_buffer
;
in_end
=
in_ptr
+
strm
.
total_out
/
4
;
if
(
verbosity
>=
4
)
{
fprintf
(
stderr
,
"Unzipped data: "
);
logprintf
(
"Unzipped data: "
);
hexdump_in
();
}
}
struct
query
*
q
=
query_get
(
id
);
if
(
!
q
)
{
if
(
verbosity
)
{
fprintf
(
stderr
,
"No such query
\n
"
);
logprintf
(
"No such query
\n
"
);
}
}
else
{
remove_event_timer
(
&
q
->
ev
);
...
...
@@ -162,16 +162,18 @@ DEFINE_TREE (timer, struct event_timer *, event_timer_cmp, 0)
struct
tree_timer
*
timer_tree
;
void
insert_event_timer
(
struct
event_timer
*
ev
)
{
return
;
fprintf
(
stderr
,
"INSERT: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
if
(
verbosity
>
2
)
{
logprintf
(
"INSERT: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
}
tree_check_timer
(
timer_tree
);
timer_tree
=
tree_insert_timer
(
timer_tree
,
ev
,
lrand48
());
tree_check_timer
(
timer_tree
);
}
void
remove_event_timer
(
struct
event_timer
*
ev
)
{
return
;
fprintf
(
stderr
,
"REMOVE: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
if
(
verbosity
>
2
)
{
logprintf
(
"REMOVE: %lf %p %p
\n
"
,
ev
->
timeout
,
ev
->
self
,
ev
->
alarm
);
}
tree_check_timer
(
timer_tree
);
timer_tree
=
tree_delete_timer
(
timer_tree
,
ev
);
tree_check_timer
(
timer_tree
);
...
...
@@ -207,7 +209,7 @@ int help_get_config_on_answer (struct query *q UU) {
assert
(
test_mode
==
CODE_bool_false
);
int
this_dc
=
fetch_int
();
if
(
verbosity
)
{
fprintf
(
stderr
,
"this_dc = %d
\n
"
,
this_dc
);
logprintf
(
"this_dc = %d
\n
"
,
this_dc
);
}
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
...
...
@@ -222,7 +224,7 @@ int help_get_config_on_answer (struct query *q UU) {
char
*
ip
=
fetch_str
(
l2
);
int
port
=
fetch_int
();
if
(
verbosity
)
{
fprintf
(
stderr
,
"id = %d, name = %.*s ip = %.*s port = %d
\n
"
,
id
,
l1
,
name
,
l2
,
ip
,
port
);
logprintf
(
"id = %d, name = %.*s ip = %.*s port = %d
\n
"
,
id
,
l1
,
name
,
l2
,
ip
,
port
);
}
if
(
!
DC_list
[
id
])
{
alloc_dc
(
id
,
strndup
(
ip
,
l2
),
port
);
...
...
@@ -230,7 +232,7 @@ int help_get_config_on_answer (struct query *q UU) {
}
max_chat_size
=
fetch_int
();
if
(
verbosity
>=
2
)
{
fprintf
(
stderr
,
"chat_size = %d
\n
"
,
max_chat_size
);
logprintf
(
"chat_size = %d
\n
"
,
max_chat_size
);
}
return
0
;
}
...
...
@@ -259,7 +261,7 @@ int send_code_on_error (struct query *q UU, int error_code, int l, char *error)
int
i
=
error
[
s
]
-
'0'
;
want_dc_num
=
i
;
}
else
{
fprintf
(
stderr
,
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
logprintf
(
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
assert
(
0
);
}
return
0
;
...
...
@@ -343,13 +345,13 @@ int sign_in_on_answer (struct query *q UU) {
fetch_user
(
&
User
);
sign_in_ok
=
1
;
if
(
verbosity
)
{
fprintf
(
stderr
,
"authorized successfully: name = '%s %s', phone = '%s', expires = %d
\n
"
,
User
.
first_name
,
User
.
last_name
,
User
.
phone
,
(
int
)(
expires
-
get_double_time
()));
logprintf
(
"authorized successfully: name = '%s %s', phone = '%s', expires = %d
\n
"
,
User
.
first_name
,
User
.
last_name
,
User
.
phone
,
(
int
)(
expires
-
get_double_time
()));
}
return
0
;
}
int
sign_in_on_error
(
struct
query
*
q
UU
,
int
error_code
,
int
l
,
char
*
error
)
{
fprintf
(
stderr
,
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
logprintf
(
"error_code = %d, error = %.*s
\n
"
,
error_code
,
l
,
error
);
sign_in_ok
=
-
1
;
return
0
;
}
...
...
@@ -371,11 +373,13 @@ int do_send_code_result (const char *code) {
return
sign_in_ok
;
}
extern
char
*
user_list
[];
int
get_contacts_on_answer
(
struct
query
*
q
UU
)
{
int
i
;
assert
(
fetch_int
()
==
(
int
)
CODE_contacts_contacts
);
assert
(
fetch_int
()
==
CODE_vector
);
int
n
=
fetch_int
();
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
assert
(
fetch_int
()
==
(
int
)
CODE_contact
);
fetch_int
();
// id
...
...
@@ -384,9 +388,8 @@ int get_contacts_on_answer (struct query *q UU) {
assert
(
fetch_int
()
==
CODE_vector
);
n
=
fetch_int
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
struct
user
User
;
fetch_user
(
&
User
);
rprintf
(
"User: id = %d, first_name = %s, last_name = %s
\n
"
,
User
.
id
,
User
.
first_name
,
User
.
last_name
);
struct
user
*
U
=
fetch_alloc_user
();
rprintf
(
"User #%d: "
COLOR_RED
"%s %s"
COLOR_NORMAL
" ("
COLOR_GREEN
"%s"
COLOR_NORMAL
")
\n
"
,
U
->
id
,
U
->
first_name
,
U
->
last_name
,
U
->
print_name
);
}
return
0
;
}
...
...
structures.c
View file @
bf291df3
#include <assert.h>
#include "structures.h"
#include "mtproto-common.h"
#include "telegram.h"
#include "tree.h"
void
fetch_file_location
(
struct
file_location
*
loc
)
{
int
x
=
fetch_int
();
...
...
@@ -48,6 +50,25 @@ void fetch_user (struct user *U) {
}
U
->
first_name
=
fetch_str_dup
();
U
->
last_name
=
fetch_str_dup
();
if
(
!
strlen
(
U
->
first_name
))
{
if
(
!
strlen
(
U
->
last_name
))
{
U
->
print_name
=
strdup
(
"none"
);
}
else
{
U
->
print_name
=
strdup
(
U
->
last_name
);
}
}
else
{
if
(
!
strlen
(
U
->
last_name
))
{
U
->
print_name
=
strdup
(
U
->
first_name
);
}
else
{
U
->
print_name
=
malloc
(
strlen
(
U
->
first_name
)
+
strlen
(
U
->
last_name
)
+
2
);
sprintf
(
U
->
print_name
,
"%s_%s"
,
U
->
first_name
,
U
->
last_name
);
}
}
char
*
s
=
U
->
print_name
;
while
(
*
s
)
{
if
(
*
s
==
' '
)
{
*
s
=
'_'
;
}
s
++
;
}
if
(
x
==
CODE_user_deleted
)
{
U
->
flags
=
2
;
return
;
...
...
@@ -79,3 +100,46 @@ void fetch_user (struct user *U) {
U
->
flags
|=
16
;
}
}
#define user_cmp(a,b) ((a)->id - (b)->id)
DEFINE_TREE
(
user
,
struct
user
*
,
user_cmp
,
0
)
struct
tree_user
*
user_tree
;
int
user_num
;
struct
user
*
Users
[
MAX_USER_NUM
];
int
users_allocated
;
struct
user
*
fetch_alloc_user
(
void
)
{
struct
user
*
U
=
malloc
(
sizeof
(
*
U
));
fetch_user
(
U
);
users_allocated
++
;
struct
user
*
U1
=
tree_lookup_user
(
user_tree
,
U
);
if
(
U1
)
{
free_user
(
U1
);
memcpy
(
U1
,
U
,
sizeof
(
*
U
));
free
(
U
);
users_allocated
--
;
return
U1
;
}
else
{
user_tree
=
tree_insert_user
(
user_tree
,
U
,
lrand48
());
Users
[
user_num
++
]
=
U
;
return
U
;
}
}
void
free_user
(
struct
user
*
U
)
{
if
(
U
->
first_name
)
{
free
(
U
->
first_name
);
}
if
(
U
->
last_name
)
{
free
(
U
->
last_name
);
}
if
(
U
->
print_name
)
{
free
(
U
->
print_name
);
}
if
(
U
->
phone
)
{
free
(
U
->
phone
);
}
}
int
print_stat
(
char
*
s
,
int
len
)
{
return
snprintf
(
s
,
len
,
"user_num
\t
%d
\n
"
"users_allocated
\t
%d
\n
"
,
user_num
,
users_allocated
);
}
structures.h
View file @
bf291df3
...
...
@@ -20,6 +20,7 @@ struct user {
char
*
first_name
;
char
*
last_name
;
char
*
phone
;
char
*
print_name
;
long
long
access_hash
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
...
...
@@ -28,4 +29,9 @@ struct user {
void
fetch_file_location
(
struct
file_location
*
loc
);
void
fetch_user
(
struct
user
*
U
);
struct
user
*
fetch_alloc_user
(
void
);
void
free_user
(
struct
user
*
U
);
int
print_stat
(
char
*
s
,
int
len
);
#endif
telegram.h
View file @
bf291df3
#define MAX_DC_NUM 9
#define MAX_USER_NUM 1000
tree.h
View file @
bf291df3
...
...
@@ -51,7 +51,12 @@ struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP
} else {\
int c = X_CMP (x, T->x);\
assert (c);\
return tree_insert_ ## X_NAME (c < 0 ? T->left : T->right, x, y);\
if (c < 0) { \
T->left = tree_insert_ ## X_NAME (T->left, x, y);\
} else { \
T->right = tree_insert_ ## X_NAME (T->right, x, y);\
} \
return T; \
}\
}\
}\
...
...
@@ -96,6 +101,13 @@ X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
return T ? T->x : X_UNSET;\
}\
\
void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) {\
if (!T) { return; } \
tree_act_ ## X_NAME (T->left, act); \
act (T->x); \
tree_act_ ## X_NAME (T->right, act); \
}\
\
int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return 0; }\
return 1 + tree_count_ ## X_NAME (T->left) + tree_count_ ## X_NAME (T->right); \
...
...
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