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
baa56b70
Commit
baa56b70
authored
Oct 14, 2013
by
Vysheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit parse of many structures (message, chat, photo, etc)
parent
5f2080e9
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
490 additions
and
29 deletions
+490
-29
gen_constants_h.awk
gen_constants_h.awk
+19
-0
interface.c
interface.c
+19
-5
mtproto-common.h
mtproto-common.h
+15
-1
structures.c
structures.c
+317
-17
structures.h
structures.h
+110
-6
telegram.h
telegram.h
+1
-0
tg.pub
tg.pub
+9
-0
No files found.
gen_constants_h.awk
0 → 100644
View file @
baa56b70
BEGIN
{
print
"#ifndef CONSTANTS_H"
;
print
"#define CONSTANTS_H"
;
}
//
{
if
(
split
(
$1
,
a
,
"#"
)
==
2
)
{
gsub
(
/
[
A-Z
]
/
,
"_&"
,
a
[
1
]);
gsub
(
/
[
.
]
/
,
"_"
,
a
[
1
]);
if
(
a
[
2
]
in
h
)
{
print
"ERROR: Duplicate magic "
a
[
2
]
" for define "
a
[
1
]
" and "
h
[
a
[
2
]]
>
"/dev/stderr/"
exit
1
;
}
h
[
a
[
2
]]
=
a
[
1
];
print
"#define"
,
"CODE_"
tolower
(
a
[
1
]),
"0x"
a
[
2
];
}
}
END
{
print
"#endif"
;
}
interface.c
View file @
baa56b70
...
...
@@ -104,14 +104,28 @@ int get_complete_mode (void) {
}
extern
int
user_num
;
extern
struct
user
*
Users
[];
extern
int
chat_num
;
extern
union
user_chat
*
Peers
[];
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
)
))
{
while
(
index
<
user_num
+
chat_num
&&
(
!
Peers
[
index
]
->
print_name
||
strncmp
(
Peers
[
index
]
->
print_name
,
text
,
len
)
||
Peers
[
index
]
->
id
<
0
))
{
index
++
;
}
if
(
index
<
user_num
)
{
*
R
=
strdup
(
Users
[
index
]
->
print_name
);
if
(
index
<
user_num
+
chat_num
)
{
*
R
=
strdup
(
Peers
[
index
]
->
print_name
);
return
index
;
}
else
{
return
-
1
;
}
}
int
complete_user_chat_list
(
int
index
,
const
char
*
text
,
int
len
,
char
**
R
)
{
index
++
;
while
(
index
<
user_num
+
chat_num
&&
(
!
Peers
[
index
]
->
print_name
||
strncmp
(
Peers
[
index
]
->
print_name
,
text
,
len
)))
{
index
++
;
}
if
(
index
<
user_num
+
chat_num
)
{
*
R
=
strdup
(
Peers
[
index
]
->
print_name
);
return
index
;
}
else
{
return
-
1
;
...
...
@@ -161,7 +175,7 @@ char *command_generator (const char *text, int state) {
index
=
complete_user_list
(
index
,
text
,
len
,
&
R
);
return
R
;
case
2
:
index
=
complete_
string_list
(
chat_list
,
index
,
text
,
len
,
&
R
);
index
=
complete_
user_chat_list
(
index
,
text
,
len
,
&
R
);
return
R
;
case
3
:
return
rl_filename_completion_function
(
text
,
state
);
...
...
mtproto-common.h
View file @
baa56b70
...
...
@@ -270,7 +270,10 @@ static inline char *fetch_str (int len) {
static
inline
char
*
fetch_str_dup
(
void
)
{
int
l
=
prefetch_strlen
();
return
strndup
(
fetch_str
(
l
),
l
);
char
*
s
=
malloc
(
l
+
1
);
memcpy
(
s
,
fetch_str
(
l
),
l
);
s
[
l
]
=
0
;
return
s
;
}
static
__inline__
unsigned
long
long
rdtsc
(
void
)
{
...
...
@@ -299,6 +302,17 @@ static inline long long fetch_long (void) {
return
r
;
}
static
inline
double
fetch_double
(
void
)
{
double
r
=
*
(
double
*
)
in_ptr
;
in_ptr
+=
2
;
return
r
;
}
static
inline
void
fetch_ints
(
void
*
data
,
int
count
)
{
memcpy
(
data
,
in_ptr
,
4
*
count
);
in_ptr
+=
count
;
}
int
get_random_bytes
(
void
*
buf
,
int
n
);
int
pad_rsa_encrypt
(
char
*
from
,
int
from_len
,
char
*
to
,
int
size
,
BIGNUM
*
N
,
BIGNUM
*
E
);
...
...
structures.c
View file @
baa56b70
...
...
@@ -105,7 +105,7 @@ void fetch_chat (struct chat *C) {
memset
(
C
,
0
,
sizeof
(
*
C
));
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_chat_empty
||
x
==
CODE_chat
||
x
==
CODE_chat_forbidden
);
C
->
id
=
fetch_int
();
C
->
id
=
-
fetch_int
();
if
(
x
==
CODE_chat_empty
)
{
C
->
flags
=
1
;
return
;
...
...
@@ -130,34 +130,200 @@ void fetch_chat (struct chat *C) {
fetch_file_location
(
&
C
->
photo_small
);
fetch_file_location
(
&
C
->
photo_big
);
}
C
->
user_num
=
fetch_int
();
C
->
date
=
fetch_int
();
if
(
fetch_int
()
==
(
int
)
CODE_bool_true
)
{
C
->
flags
|=
16
;
}
C
->
version
=
fetch_int
();
}
else
{
C
->
photo_small
.
dc
=
-
2
;
C
->
photo_big
.
dc
=
-
2
;
C
->
user_num
=
-
1
;
C
->
date
=
fetch_int
();
C
->
version
=
-
1
;
}
}
void
fetch_photo_size
(
struct
photo_size
*
S
)
{
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_photo_size
||
x
==
CODE_photo_cached_size
);
S
->
type
=
fetch_str_dup
();
fetch_file_location
(
&
S
->
loc
);
S
->
w
=
fetch_int
();
S
->
h
=
fetch_int
();
if
(
x
==
CODE_photo_size
)
{
S
->
size
=
fetch_int
();
}
else
{
S
->
data
=
fetch_str_dup
();
}
}
void
fetch_geo
(
struct
geo
*
G
)
{
assert
(
fetch_int
()
==
CODE_geo_point
);
G
->
longitude
=
fetch_double
();
G
->
latitude
=
fetch_double
();
}
void
fetch_photo
(
struct
photo
*
P
)
{
memset
(
P
,
0
,
sizeof
(
*
P
));
unsigned
x
=
fetch_int
();
P
->
id
=
fetch_long
();
if
(
x
==
CODE_photo_empty
)
{
return
;
}
P
->
access_hash
=
fetch_long
();
P
->
user_id
=
fetch_int
();
P
->
date
=
fetch_int
();
P
->
caption
=
fetch_str_dup
();
fetch_geo
(
&
P
->
geo
);
assert
(
fetch_int
()
==
CODE_vector
);
P
->
sizes_num
=
fetch_int
();
P
->
sizes
=
malloc
(
sizeof
(
struct
photo_size
)
*
P
->
sizes_num
);
int
i
;
for
(
i
=
0
;
i
<
P
->
sizes_num
;
i
++
)
{
fetch_photo_size
(
&
P
->
sizes
[
i
]);
}
}
void
fetch_video
(
struct
video
*
V
)
{
memset
(
V
,
0
,
sizeof
(
*
V
));
unsigned
x
=
fetch_int
();
V
->
id
=
fetch_long
();
if
(
x
==
CODE_video_empty
)
{
return
;
}
V
->
access_hash
=
fetch_long
();
V
->
user_id
=
fetch_int
();
V
->
date
=
fetch_int
();
V
->
caption
=
fetch_str_dup
();
V
->
duration
=
fetch_int
();
V
->
size
=
fetch_int
();
fetch_photo_size
(
&
V
->
thumb
);
V
->
dc_id
=
fetch_int
();
V
->
w
=
fetch_int
();
V
->
h
=
fetch_int
();
}
void
fetch_message_action
(
struct
message_action
*
M
)
{
memset
(
M
,
0
,
sizeof
(
*
M
));
unsigned
x
=
fetch_int
();
M
->
type
=
x
;
switch
(
x
)
{
case
CODE_message_action_empty
:
break
;
case
CODE_message_action_chat_create
:
M
->
title
=
fetch_str_dup
();
assert
(
fetch_int
()
==
(
int
)
CODE_vector
);
M
->
user_num
=
fetch_int
();
M
->
users
=
malloc
(
M
->
user_num
*
4
);
fetch_ints
(
M
->
users
,
M
->
user_num
);
break
;
case
CODE_message_action_chat_edit_title
:
M
->
new_title
=
fetch_str_dup
();
break
;
case
CODE_message_action_chat_edit_photo
:
fetch_photo
(
&
M
->
photo
);
break
;
case
CODE_message_action_chat_delete_photo
:
break
;
case
CODE_message_action_chat_add_user
:
M
->
user
=
fetch_int
();
break
;
case
CODE_message_action_chat_delete_user
:
M
->
user
=
fetch_int
();
break
;
default:
assert
(
0
);
}
}
void
fetch_message_media
(
struct
message_media
*
M
)
{
memset
(
M
,
0
,
sizeof
(
*
M
));
M
->
type
=
fetch_int
();
switch
(
M
->
type
)
{
case
CODE_message_media_empty
:
break
;
case
CODE_message_media_photo
:
fetch_photo
(
&
M
->
photo
);
break
;
case
CODE_message_media_video
:
fetch_video
(
&
M
->
video
);
break
;
case
CODE_message_media_geo
:
fetch_geo
(
&
M
->
geo
);
break
;
case
CODE_message_media_contact
:
M
->
phone
=
fetch_str_dup
();
M
->
first_name
=
fetch_str_dup
();
M
->
last_name
=
fetch_str_dup
();
M
->
user_id
=
fetch_int
();
break
;
case
CODE_message_media_unsupported
:
M
->
data
=
fetch_str_dup
();
break
;
default:
assert
(
0
);
}
}
void
fetch_message
(
struct
message
*
M
)
{
memset
(
M
,
0
,
sizeof
(
*
M
));
unsigned
x
=
fetch_int
();
assert
(
x
==
CODE_message_empty
||
x
==
CODE_message
||
x
==
CODE_message_forwarded
||
x
==
CODE_message_service
);
M
->
id
=
fetch_int
();
if
(
x
==
CODE_message_empty
)
{
M
->
flags
|=
1
;
return
;
}
if
(
x
==
CODE_message_forwarded
)
{
M
->
fwd_from_id
=
fetch_int
();
M
->
fwd_date
=
fetch_int
();
}
M
->
from_id
=
fetch_int
();
M
->
to_id
=
fetch_int
();
M
->
out
=
(
fetch_int
()
==
(
int
)
CODE_bool_true
);
M
->
unread
=
(
fetch_int
()
==
(
int
)
CODE_bool_true
);
M
->
date
=
fetch_int
();
if
(
x
==
CODE_message_service
)
{
M
->
service
=
1
;
fetch_message_action
(
&
M
->
action
);
}
else
{
M
->
message
=
fetch_str_dup
();
fetch_message_media
(
&
M
->
media
);
}
}
#define user_cmp(a,b) ((a)->id - (b)->id)
DEFINE_TREE
(
user
,
struct
user
*
,
user_cmp
,
0
)
struct
tree_user
*
user_tree
;
DEFINE_TREE
(
peer
,
union
user_chat
*
,
user_cmp
,
0
)
DEFINE_TREE
(
message
,
struct
message
*
,
user_cmp
,
0
)
struct
tree_peer
*
peer_tree
;
struct
tree_message
*
message_tree
;
int
chat_num
;
int
user_num
;
struct
user
*
Users
[
MAX_USER_NUM
];
int
users_allocated
;
int
chats_allocated
;
int
messages_allocated
;
union
user_chat
*
Peers
[
MAX_USER_NUM
];
struct
message
message_list
=
{
.
next_use
=
&
message_list
,
.
prev_use
=
&
message_list
};
struct
user
*
fetch_alloc_user
(
void
)
{
struct
user
*
U
=
malloc
(
sizeof
(
*
U
));
fetch_user
(
U
);
union
user_chat
*
U
=
malloc
(
sizeof
(
*
U
));
fetch_user
(
&
U
->
user
);
users_allocated
++
;
struct
user
*
U1
=
tree_lookup_user
(
us
er_tree
,
U
);
union
user_chat
*
U1
=
tree_lookup_peer
(
pe
er_tree
,
U
);
if
(
U1
)
{
free_user
(
U1
);
free_user
(
&
U1
->
user
);
memcpy
(
U1
,
U
,
sizeof
(
*
U
));
free
(
U
);
users_allocated
--
;
return
U1
;
return
&
U1
->
user
;
}
else
{
user_tree
=
tree_insert_user
(
us
er_tree
,
U
,
lrand48
());
Users
[
user_num
++
]
=
U
;
return
U
;
peer_tree
=
tree_insert_peer
(
pe
er_tree
,
U
,
lrand48
());
Peers
[
chat_num
+
(
user_num
++
)
]
=
U
;
return
&
U
->
user
;
}
}
...
...
@@ -168,10 +334,144 @@ void free_user (struct user *U) {
if
(
U
->
phone
)
{
free
(
U
->
phone
);
}
}
void
free_photo_size
(
struct
photo_size
*
S
)
{
free
(
S
->
type
);
free
(
S
->
data
);
}
void
free_photo
(
struct
photo
*
P
)
{
free
(
P
->
caption
);
int
i
;
for
(
i
=
0
;
i
<
P
->
sizes_num
;
i
++
)
{
free_photo_size
(
&
P
->
sizes
[
i
]);
}
free
(
P
->
sizes
);
}
void
free_video
(
struct
video
*
V
)
{
free
(
V
->
caption
);
free
(
&
V
->
thumb
);
}
void
free_message_media
(
struct
message_media
*
M
)
{
switch
(
M
->
type
)
{
case
CODE_message_media_empty
:
return
;
case
CODE_message_media_photo
:
free_photo
(
&
M
->
photo
);
return
;
case
CODE_message_media_video
:
free_video
(
&
M
->
video
);
return
;
case
CODE_message_media_contact
:
free
(
M
->
phone
);
free
(
M
->
first_name
);
free
(
M
->
last_name
);
return
;
case
CODE_message_media_unsupported
:
free
(
M
->
data
);
return
;
default:
assert
(
0
);
}
}
void
free_message_action
(
struct
message_action
*
M
)
{
switch
(
M
->
type
)
{
case
CODE_message_action_empty
:
break
;
case
CODE_message_action_chat_create
:
free
(
M
->
title
);
free
(
M
->
users
);
break
;
case
CODE_message_action_chat_edit_title
:
free
(
M
->
new_title
);
break
;
case
CODE_message_action_chat_edit_photo
:
free_photo
(
&
M
->
photo
);
break
;
case
CODE_message_action_chat_delete_photo
:
break
;
case
CODE_message_action_chat_add_user
:
break
;
case
CODE_message_action_chat_delete_user
:
break
;
default:
assert
(
0
);
}
}
void
free_message
(
struct
message
*
M
)
{
if
(
!
M
->
service
)
{
if
(
M
->
message
)
{
free
(
M
->
message
);
}
free_message_media
(
&
M
->
media
);
}
else
{
free_message_action
(
&
M
->
action
);
}
}
void
message_del_use
(
struct
message
*
M
)
{
M
->
next_use
->
prev_use
=
M
->
prev_use
;
M
->
prev_use
->
next_use
=
M
->
next_use
;
}
void
message_add_use
(
struct
message
*
M
)
{
M
->
next_use
=
message_list
.
next_use
;
M
->
prev_use
=
&
message_list
;
M
->
next_use
->
prev_use
=
M
;
M
->
prev_use
->
next_use
=
M
;
}
struct
message
*
fetch_alloc_message
(
void
)
{
struct
message
*
M
=
malloc
(
sizeof
(
*
M
));
fetch_message
(
M
);
struct
message
*
M1
=
tree_lookup_message
(
message_tree
,
M
);
messages_allocated
++
;
if
(
M1
)
{
message_del_use
(
M1
);
free_message
(
M1
);
memcpy
(
M1
,
M
,
sizeof
(
*
M
));
free
(
M
);
message_add_use
(
M1
);
messages_allocated
--
;
return
M1
;
}
else
{
message_add_use
(
M
);
message_tree
=
tree_insert_message
(
message_tree
,
M
,
lrand48
());
return
M
;
}
}
struct
chat
*
fetch_alloc_chat
(
void
)
{
union
user_chat
*
U
=
malloc
(
sizeof
(
*
U
));
fetch_chat
(
&
U
->
chat
);
chats_allocated
++
;
union
user_chat
*
U1
=
tree_lookup_peer
(
peer_tree
,
U
);
if
(
U1
)
{
free_chat
(
&
U1
->
chat
);
*
U1
=
*
U
;
free
(
U
);
chats_allocated
--
;
return
&
U1
->
chat
;
}
else
{
peer_tree
=
tree_insert_peer
(
peer_tree
,
U
,
lrand48
());
Peers
[(
chat_num
++
)
+
user_num
]
=
U
;
return
&
U
->
chat
;
}
}
void
free_chat
(
struct
chat
*
U
)
{
if
(
U
->
title
)
{
free
(
U
->
title
);
}
if
(
U
->
print_title
)
{
free
(
U
->
print_title
);
}
}
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
);
"users_allocated
\t
%d
\n
"
"chats_allocated
\t
%d
\n
"
"messages_allocated
\t
%d
\n
"
,
users_allocated
,
chats_allocated
,
messages_allocated
);
}
structures.h
View file @
baa56b70
...
...
@@ -17,33 +17,137 @@ struct user_status {
struct
user
{
int
id
;
int
flags
;
char
*
print_name
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
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
;
struct
user_status
status
;
};
struct
chat
{
int
id
;
int
flags
;
char
*
title
;
char
*
print_title
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
char
*
title
;
int
user_num
;
int
date
;
int
version
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
};
union
user_chat
{
struct
{
int
id
;
int
flags
;
char
*
print_name
;
struct
file_location
photo_big
;
struct
file_location
photo_small
;
};
struct
user
user
;
struct
chat
chat
;
};
struct
photo_size
{
char
*
type
;
struct
file_location
loc
;
int
w
;
int
h
;
int
size
;
char
*
data
;
};
struct
geo
{
double
longitude
;
double
latitude
;
};
struct
photo
{
long
long
id
;
long
long
access_hash
;
int
user_id
;
int
date
;
char
*
caption
;
struct
geo
geo
;
int
sizes_num
;
struct
photo_size
*
sizes
;
};
struct
video
{
long
long
id
;
long
long
access_hash
;
int
user_id
;
int
date
;
char
*
caption
;
int
duration
;
int
size
;
struct
photo_size
thumb
;
int
dc_id
;
int
w
;
int
h
;
};
struct
message_action
{
int
type
;
union
{
struct
{
char
*
title
;
int
user_num
;
int
*
users
;
};
char
*
new_title
;
struct
photo
photo
;
int
user
;
};
};
struct
message_media
{
int
type
;
union
{
struct
photo
photo
;
struct
video
video
;
struct
geo
geo
;
struct
{
char
*
phone
;
char
*
first_name
;
char
*
last_name
;
int
user_id
;
};
void
*
data
;
};
};
struct
message
{
struct
message
*
next_use
,
*
prev_use
;
int
id
;
int
flags
;
int
fwd_from_id
;
int
fwd_date
;
int
from_id
;
int
to_id
;
int
out
;
int
unread
;
int
date
;
int
service
;
union
{
struct
message_action
action
;
struct
{
char
*
message
;
struct
message_media
media
;
};
};
};
void
fetch_file_location
(
struct
file_location
*
loc
);
void
fetch_user
(
struct
user
*
U
);
struct
user
*
fetch_alloc_user
(
void
);
struct
chat
*
fetch_alloc_chat
(
void
);
void
free_user
(
struct
user
*
U
);
void
free_chat
(
struct
chat
*
U
);
int
print_stat
(
char
*
s
,
int
len
);
#endif
telegram.h
View file @
baa56b70
#define MAX_DC_NUM 9
#define MAX_USER_NUM 1000
#define MAX_CHAT_NUM 1000
tg.pub
0 → 100644
View file @
baa56b70
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6
lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS
an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw
Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+
8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n
Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
-----END RSA PUBLIC KEY-----
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