Compare commits

...

205 commits

Author SHA1 Message Date
Vysheng
5ec9a88872 Fixed loop.c 2014-09-24 14:35:27 +04:00
Vysheng
4f7778c8e9 fixes in bignum padding 2014-09-23 19:06:20 +04:00
Vysheng
6f60ed5818 mtproto-client: fixed bad bignum pad 2014-09-23 18:59:28 +04:00
Vysheng
ef37551f04 Fixed readline_disable mode 2014-09-23 18:39:28 +04:00
Vysheng
39819d2eb9 Some more clear 2014-09-23 17:18:42 +04:00
Vysheng
a0a3361d7d Fixed small memory leaks. Added functions to clear most part of data 2014-09-23 16:58:49 +04:00
vysheng
998b89d124 Update CHANGELOG 2014-09-23 12:37:57 +04:00
vvaltman
8eeac24783 Merge github.com:vysheng/tg 2014-09-23 02:23:54 +04:00
vvaltman
95a9edbd8a Support for unix sockets 2014-09-23 02:23:40 +04:00
vysheng
508d23cebc Update test.lua 2014-09-22 22:52:35 +04:00
Vysheng
dc27be5eae Updated test.lua. Libnotify use example 2014-09-22 17:41:51 +04:00
vvaltman
4440f5b80e Small bugfixes 2014-09-22 01:00:46 +04:00
vvaltman
7c32c52116 Make get_state once per hour 2014-09-21 14:13:40 +04:00
vvaltman
05e1606d03 Fixes for listening socket 2014-09-21 13:41:10 +04:00
vvaltman
d577731f98 fixes for libevent 1.4 2014-09-21 13:25:46 +04:00
vvaltman
7a0fdd7f35 Fixed CE with old libevent 2014-09-21 13:18:12 +04:00
vvaltman
990221ea4d Fixed CE on some systems 2014-09-21 13:10:22 +04:00
vvaltman
11e6e19272 Fixed missing include on some systems 2014-09-21 13:07:06 +04:00
vvaltman
76e7c8fd38 updated CHANGELOG 2014-09-21 12:59:47 +04:00
vvaltman
02b37e503e Fixes in refcnt 2014-09-21 12:58:57 +04:00
vvaltman
db85bf4836 Added listening socket support 2014-09-21 02:22:35 +04:00
vvaltman
48e96f3a7a test-lua: updated with sample cron function 2014-09-18 21:16:27 +04:00
Vysheng
9d40537345 updated changelog 2014-09-18 19:16:26 +04:00
Vysheng
53e9491914 increased version 2014-09-18 19:15:47 +04:00
Vysheng
997116ff43 Fixed search 2014-09-18 19:14:24 +04:00
Vysheng
3fcfe6fc3b Fix get difference after reset_authorization 2014-09-18 18:36:43 +04:00
Vysheng
82dad2b1f4 Fixed geo in lua 2014-09-18 18:11:22 +04:00
Vysheng
65843d7695 Added reset authorization key 2014-09-18 17:57:23 +04:00
Vysheng
3a7da2d67b Fixed help 2014-09-18 17:10:42 +04:00
Vysheng
d56cd2e2cb Fixed escape string 2014-09-18 14:42:02 +04:00
Vysheng
35f90fd0b9 Merge github.com:vysheng/tg 2014-09-18 14:11:36 +04:00
Vysheng
5c2f7d688e Fixed small memory leaks 2014-09-18 14:11:23 +04:00
vvaltman
a6af86a266 rewitten input parse 2014-09-18 01:03:20 +04:00
Vysheng
0326dbf69e Merge github.com:vysheng/tg 2014-09-15 18:48:04 +04:00
vvaltman
c9a0346971 Run get_differece on new_session_created 2014-09-15 12:45:17 +04:00
Vysheng
9488f56f4b Deleted bad def 2014-09-12 19:58:47 +04:00
vvaltman
8bdaf6e55b Fixed send_photo to encr chats 2014-09-12 00:57:59 +04:00
vvaltman
efebedc08a Fixed escape of string 2014-09-11 19:47:44 +04:00
vvaltman
1896b2b905 Merge github.com:vysheng/tg 2014-09-11 19:30:10 +04:00
vvaltman
3e868b4249 Fixed problems with send_msg on start 2014-09-11 19:29:16 +04:00
vysheng
342a7f323c Update README.md 2014-09-11 16:05:25 +04:00
vysheng
4e55083b41 Update README.es 2014-09-11 15:54:40 +04:00
Vysheng
324221f5de support for set_ttl query 2014-09-11 15:04:04 +04:00
Vysheng
ecc1ef02f5 Deleted unneeded code 2014-09-11 14:33:12 +04:00
Vysheng
a240e3536b Changed default DC. Fixed memory leak 2014-09-11 14:28:56 +04:00
Vysheng
56b30ac358 Fixed memory leak 2014-09-11 13:35:27 +04:00
Vysheng
a7e0f25a6a Check return values of malloc, realloc, strdup and strndup 2014-09-11 13:24:06 +04:00
Vysheng
51b3f5295b Fixed fail when trying to send emssage before get_difference end 2014-09-10 21:54:41 +04:00
Vysheng
01746fe177 Merge github.com:vysheng/tg 2014-09-10 21:36:25 +04:00
Vysheng
f9528ff627 Fixed check_utf8 2014-09-10 21:36:05 +04:00
Vysheng
c7a15630c6 Fixed extended_functions mode. Small memory leak there. Should be fixed shorly. 2014-09-10 21:29:57 +04:00
vysheng
595346391e Update README.md 2014-09-10 18:38:46 +04:00
Vysheng
2cd6465440 ext_f added to lua. fixed del_contact from lua 2014-09-10 18:25:31 +04:00
Vysheng
ba10513786 del_contact query 2014-09-10 18:13:52 +04:00
Vysheng
dd4e757ea5 Fixed strange warn about unused result of strtod and strtoll 2014-09-10 16:25:49 +04:00
Vysheng
da451e6436 Added support for direct queries enter 2014-09-10 15:52:42 +04:00
vvaltman
9f90a325b7 Increased version 2014-09-10 01:02:50 +04:00
vvaltman
41287c13d7 added SIGUSR1 handler to rotate logs 2014-09-10 01:01:22 +04:00
vvaltman
6b9ce8a2b6 Added scripts to help run telegram as daemon 2014-09-10 00:47:34 +04:00
Vysheng
47ef058f84 Merge github.com:vysheng/tg
Conflicts:
	main.c
2014-09-09 22:07:30 +04:00
Vysheng
dfc0578302 Added -U and -G keys to make setuid and setgid at start if started as root 2014-09-09 22:05:56 +04:00
vvaltman
1c46ba8e3a Added [-D] (disable output) key 2014-09-09 21:05:36 +04:00
vvaltman
8f84df8789 Fixed rsa pad 2014-09-09 20:50:07 +04:00
Vysheng
55ce5bac99 Fixed config search 2014-09-09 19:10:01 +04:00
Vysheng
db4d36c8b6 Daemonize options 2014-09-09 19:01:27 +04:00
Vysheng
d3f2ac2eba Merge github.com:vysheng/tg 2014-09-09 17:28:05 +04:00
Vysheng
4e35360aff status function to lua 2014-09-09 17:27:43 +04:00
vysheng
1d58448e19 Update README.md 2014-09-09 17:11:37 +04:00
Vysheng
30656e49be deleted debug 2014-09-09 16:03:35 +04:00
Vysheng
5539d232d5 Fixed __builtin config 2014-09-09 15:58:47 +04:00
Vysheng
74de6b24d1 Merge github.com:vysheng/tg 2014-09-09 15:53:19 +04:00
vysheng
22e9f7778d Merge pull request #253 from corsaroquad/patch-1
Included MacPorts commands
2014-09-09 15:55:13 +04:00
Vysheng
bb1fd17d08 Debug 2014-09-09 15:52:58 +04:00
Giovanni Grieco
bfe3d140b3 Included MacPorts commands
Included solution to build correctly telegram-cli if using MacPorts on OS X.
Details: https://github.com/vysheng/tg/issues/237#issuecomment-54955961
2014-09-09 13:39:01 +02:00
Vysheng
e6efa4097c Support for compilers without __builtin_bswap32 2014-09-09 15:34:59 +04:00
Vysheng
9eef9444d5 Fixed get history 2014-09-09 15:05:30 +04:00
Vysheng
6d2fa85b70 Merge github.com:vysheng/tg 2014-09-09 15:02:57 +04:00
vvaltman
6074086de6 Support for big history 2014-09-09 00:09:05 +04:00
vvaltman
ff805e1140 Fixed set of real_name of uninitialezed user 2014-09-08 23:18:51 +04:00
vvaltman
b15ea055d0 Merge github.com:vysheng/tg 2014-09-08 23:18:02 +04:00
vvaltman
da201171ab Updated test.lua 2014-09-08 23:17:47 +04:00
Vysheng
8b558db00b Fixed crush on real_name update for unknown user 2014-09-08 20:55:22 +04:00
Vysheng
d28209e3d1 Fixed rare crush in case of multiple query answers 2014-09-08 20:48:59 +04:00
Vysheng
c9ed692d24 increased version 2014-09-08 17:35:00 +04:00
Vysheng
5369423e3c Fixed event-1.4 2014-09-08 17:33:33 +04:00
Vysheng
6d8deb9135 Added _GNU_SOURCE for strndup 2014-09-08 17:05:41 +04:00
Vysheng
3dd341a08f Added attribute unused 2014-09-08 17:02:59 +04:00
Vysheng
34b81ab400 Try to build with libevent-1.4 2014-09-08 16:49:51 +04:00
Vysheng
fac3ddf2d8 Fixes for old libevent 2014-09-08 16:40:35 +04:00
Vysheng
613867fb09 Try to fix net 2014-09-08 15:56:12 +04:00
vvaltman
7ac53571d2 Fixed CE 2014-09-08 01:50:19 +04:00
vvaltman
743cc4b3f3 Fixed double send of one message 2014-09-08 00:23:45 +04:00
vvaltman
176d19fc4b Merge github.com:vysheng/tg 2014-09-07 23:13:13 +04:00
vvaltman
8f50bab9f0 Try to add support of libevent 1.4.* 2014-09-07 23:12:39 +04:00
vvaltman
3871561c09 Fixed updates 2014-09-07 22:44:19 +04:00
vvaltman
44a8a813c8 Fixed lua media types 2014-09-07 19:30:46 +04:00
vvaltman
2e7d468397 Fixed configure. Added fwd_media command 2014-09-07 19:17:35 +04:00
vvaltman
56f31ae3be Merge github.com:vysheng/tg 2014-09-04 20:50:13 +04:00
vvaltman
62cefe5a8e Fixed parse of create_group_chat 2014-09-04 20:48:04 +04:00
vysheng
91871043b1 Merge pull request #242 from nopjmp/fix_rand_bytes
fixed RAND_bytes return code checking
2014-09-04 15:13:49 +04:00
nopjmp
66d35aea76 fixed RAND_bytes return code checking 2014-09-03 19:39:42 -05:00
Vysheng
a245f86dd5 Fixed chat_info 2014-09-03 20:32:56 +04:00
vysheng
8d923387ba Update README.md 2014-09-03 20:02:50 +04:00
Vysheng
05f6824de7 changed user#... to user#id... 2014-09-03 19:54:50 +04:00
Vysheng
e113d3469b Merge github.com:vysheng/tg 2014-09-03 19:15:57 +04:00
Vysheng
a60ae1ae93 Fixed CE on MACH 2014-09-03 19:15:39 +04:00
vysheng
6a5b001de7 Merge pull request #241 from wiseoldman95/patch-1
Added Debian to installation instructions
2014-09-03 19:03:07 +04:00
wiseoldman95
6d8f975567 Added Debian.
The Ubuntu instructions work for Debian. See https://github.com/vysheng/tg/issues/128
2014-09-03 17:28:37 +03:00
Vysheng
017851107c Fixed mark_read 2014-09-03 17:25:35 +04:00
Vysheng
ad6a38454e Merge github.com:vysheng/tg 2014-09-03 17:06:18 +04:00
Vysheng
f4f4be579e Mark read messages from not peers 2014-09-03 17:05:48 +04:00
vysheng
523fa3f6d5 Update README.md 2014-09-03 14:33:45 +04:00
vysheng
ce462d4a70 Update README.md 2014-09-03 13:54:51 +04:00
Vysheng
6937fa0bee Fixed CE 2014-09-03 13:49:38 +04:00
Vysheng
d2ac430c9c Fixed bad assertion. Maybe fixed MACH CE 2014-09-03 13:39:28 +04:00
Vysheng
6c9d18cacf Fixed bad assertion 2014-09-03 13:31:39 +04:00
Vysheng
6fb56f1496 Supported user#id... and chat#id... from lua 2014-09-02 16:22:32 +04:00
Vysheng
c711019ea8 Added send_contact function 2014-09-02 15:20:18 +04:00
Vysheng
784db14d6a Added dependence to Makefile 2014-09-02 14:32:25 +04:00
Vysheng
306c571794 Fixed chat_add_user/chat_del_user queries 2014-09-02 14:27:23 +04:00
Vysheng
e0782b77a3 Added dependences to Makefile 2014-09-02 14:23:22 +04:00
Vysheng
0e13277938 Fixed params types in create_group_chat 2014-09-02 14:22:26 +04:00
vysheng
1814b2f581 Update README.md 2014-08-31 20:51:57 +01:00
vysheng
5731386848 Update README.md 2014-08-31 20:51:41 +01:00
vvaltman
c840b636c3 Fixed secert_chat_file read 2014-08-31 21:24:39 +04:00
vvaltman
f51f3b4da3 Fixed CE on 32-bit platforms 2014-08-31 21:19:56 +04:00
vvaltman
c1fa31c3d7 Fixed fail on startup 2014-08-31 21:15:49 +04:00
vvaltman
8ce965f045 Updated to layer 16 2014-08-31 18:57:03 +04:00
vvaltman
d5109e2545 support for secret chats file in no-binlog mode 2014-08-31 18:18:19 +04:00
vvaltman
c7bd5587ff Added changlog. increased version 2014-08-31 14:04:16 +04:00
vvaltman
d44dfa859d Fail on error 2014-08-31 14:02:00 +04:00
vvaltman
4b3c936cd4 Added export_card/import_card queries 2014-08-29 19:46:04 +04:00
vvaltman
92c9d0d7f0 generate random_id with secure_random 2014-08-29 18:04:04 +04:00
vvaltman
63605c7971 clear ack flag when session is renewed 2014-08-29 17:50:05 +04:00
vvaltman
4fb3d3503b Fixes small bug in query resend while changing session 2014-08-29 17:48:47 +04:00
vvaltman
548f4fe997 Added PFS support. Parallel auth_key generation. Small bug fixes 2014-08-29 17:33:15 +04:00
vvaltman
13313af979 Fixed encrypted chat updates. 2014-08-27 20:59:42 +04:00
vvaltman
d954f87514 added accept_secret_chat 2014-08-27 19:40:21 +04:00
vvaltman
654df2c05c fixed bug in crc32 2014-08-27 19:40:04 +04:00
vvaltman
a7b8b1286c Fixed work with updates 2014-08-27 19:12:45 +04:00
vvaltman
5e653e85c8 Fixed assert after hibernate 2014-08-27 03:17:28 +04:00
vvaltman
d39193f2f7 fixed get difference 2014-08-27 02:10:52 +04:00
vvaltman
cdb6b9cec5 debug output 2014-08-27 02:02:19 +04:00
vvaltman
c66d07ce35 Fixed updates work 2014-08-27 01:55:46 +04:00
vvaltman
050560ece9 Merge branch 'test' of github.com:vysheng/tg into test 2014-08-27 01:16:19 +04:00
vysheng
abdae6a6f7 Update README.md 2014-08-27 20:15:58 +04:00
vvaltman
8fd05fdba4 Fixed name 2014-08-27 01:06:59 +04:00
vvaltman
3bf992f0cb Fixed visualize key in nocolor output mode. 2014-08-27 01:03:50 +04:00
vvaltman
ecc239e291 Added disable_readline. Do not try read stdin, after end of stdin reached 2014-08-26 22:26:00 +04:00
vvaltman
d67fc774bf Fixed seq 2014-08-26 20:57:30 +04:00
vvaltman
29d06e6d1e Updated test lua script 2014-08-26 20:30:30 +04:00
vvaltman
e5534b6545 Added lua readme 2014-08-26 20:26:01 +04:00
vvaltman
152ebc3898 Updates in lua callbacks 2014-08-26 20:06:30 +04:00
vvaltman
1bd7d2cfad Fixed updates 2014-08-26 00:48:22 +04:00
vvaltman
eb4e9055b7 Some fixes in updates 2014-08-25 22:26:19 +04:00
vvaltman
82e9e0b09d More logic in autocompletion. Added set_chat_photo and set_profile_photo methods 2014-08-25 20:17:17 +04:00
vvaltman
8b2aec9703 Fixed bug with short updates 2014-08-25 18:12:17 +04:00
vvaltman
fef8398860 Fixed problems with read mark. Deleted unused code 2014-08-25 18:04:27 +04:00
vvaltman
ca34ddd404 Fixed chat_add_user query 2014-08-25 05:11:03 +04:00
vvaltman
6f711aa1fb Fixed args parse 2014-08-25 04:54:12 +04:00
vvaltman
cf7e7b45bb interface updates 2014-08-25 04:11:41 +04:00
vvaltman
93cb32a43f Updated ebuild 2014-08-25 02:40:54 +04:00
vvaltman
b083e80dc7 Fixed bug in set_friend() 2014-08-24 20:49:06 +04:00
vvaltman
ab5b9c306f Fixed licenses. libtgl is now distributed under LGPL 2.1+ 2014-08-22 02:02:43 +04:00
vvaltman
29d2e32912 Updated unread notification 2014-08-22 00:35:27 +04:00
V Valtman
e2e18c9f34 Fixes with awk and upper case 2014-08-22 13:49:11 +00:00
Vysheng
e7b04da661 Fixed small error 2014-08-22 16:30:28 +04:00
Vysheng
c97cba7e9e added attribute unused 2014-08-22 16:27:16 +04:00
Vysheng
021db46dc4 Fixed awk 2014-08-22 16:18:15 +04:00
Vysheng
cfca590a30 added more debug 2014-08-22 16:13:21 +04:00
Vysheng
1cd379abd0 debug to travis.yml 2014-08-22 16:09:52 +04:00
Vysheng
6d56f4ac6b Fixed dependence list 2014-08-22 16:00:33 +04:00
Vysheng
3c1d61bf26 Fixes travis.tml 2014-08-22 15:52:48 +04:00
Vysheng
e7d554dc81 Fixed gentoo ebuild 2014-08-22 15:50:21 +04:00
Vysheng
3ae872010e fix queries_num 2014-08-22 15:45:16 +04:00
vvaltman
07b1646423 Merge branch 'test' of github.com:vysheng/tg 2014-08-21 07:25:09 +04:00
vvaltman
0299a6375d changes 2014-08-21 07:24:52 +04:00
vvaltman
ec15b4b1b6 Merge branch 'test' of github.com:vysheng/tg 2014-08-21 06:06:46 +04:00
vysheng
e58ff46e96 Update README.md 2014-08-21 22:43:14 +01:00
vvaltman
8c58fb7f00 fixes 2014-08-21 05:56:53 +04:00
vvaltman
bd4e59b6ab updates 2014-08-21 02:33:19 +04:00
Vysheng
45778cffdf fixes 2014-08-21 20:28:01 +04:00
Vysheng
3b58fed8e4 updates 2014-08-21 19:38:51 +04:00
vvaltman
64981ad777 Merge branch 'master' of adm239:tg
Conflicts:
	interface.c
	tgl.h
2014-08-20 20:41:56 +04:00
vvaltman
311489b168 Fixes 2014-08-20 20:36:45 +04:00
Vysheng
52b5a2d3ce fixes 2014-08-19 16:57:55 +04:00
vvaltman
d08a64a481 updates 2014-08-18 20:39:04 +04:00
vvaltman
b1cbaa5105 many fixes 2014-08-15 02:16:01 +04:00
Vysheng
e0ded4a86c fixes 2014-08-15 18:57:43 +04:00
Vysheng
4a48059e8a many updates 2014-08-14 22:03:33 +04:00
vysheng
3dde03db86 more code 2014-08-14 01:31:24 +00:00
Vysheng
3b5458de54 fixes 2014-08-13 19:55:16 +04:00
Vysheng
cb95039f51 Some refactoring 2014-08-13 16:56:55 +04:00
Vysheng
bc1648a7c7 renamed user_chat_get to peer_get 2014-08-13 14:09:52 +04:00
vysheng
ddbe7ba88c Mant fixes. Sometimes work now 2014-08-13 01:22:15 +00:00
vysheng
c05bb2683e Some renaming 2014-08-12 21:51:16 +00:00
vysheng
143d672884 A bit working version 2014-08-12 21:32:11 +00:00
Vysheng
c34e6a3abe Fixes 2014-08-12 22:05:18 +04:00
vvaltman
fc8a20b74c fixes 2014-08-12 01:15:22 +04:00
Vysheng
7741fe8da9 many changes 2014-08-12 19:15:04 +04:00
Vysheng
30f949ee75 Fixed build options. Updated gitignore 2014-08-12 16:29:42 +04:00
Vysheng
474a76a010 many fixes. Autogenerated code probably works 2014-08-12 16:20:00 +04:00
vysheng
a8fae1278f Updates 2014-08-12 09:59:59 +00:00
Vysheng
9b622ba083 temp 2014-08-11 22:04:59 +04:00
Vysheng
74b05dbf8e files for new version 2014-08-11 19:27:34 +04:00
71 changed files with 21706 additions and 7838 deletions

5
.gitignore vendored
View file

@ -7,3 +7,8 @@ config.log
config.status
.idea/
nbproject/
bin/
objs/
dep/
auto/
libs/

View file

@ -9,6 +9,7 @@ install:
- sudo apt-get install libreadline6-dev
- sudo apt-get install libssl-dev
- sudo apt-get install liblua5.2-dev lua5.2
- sudo apt-get install libevent-dev
script:
- ./configure

13
CHANGELOG Normal file
View file

@ -0,0 +1,13 @@
1.0.5
* listening socket (tcp and unix) for commands
1.0.4
* changed create_group_chat format
* changed search query
* rewritten interface code. Support for escaped characters in quotes
1.0.3
* options to help to run telegram-cli as daemon
1.0.2
* Bug fixes
1.0.1
* Added pfs support. To use it you should add 'pfs_enabled=true' line to config.
* Added export_card/import_card methods

View file

@ -1,35 +1,90 @@
srcdir=@srcdir@
CFLAGS=@CFLAGS@
LDFLAGS=@LDFLAGS@
CPPFLAGS=@CPPFLAGS@
LDFLAGS=@LDFLAGS@ @OPENSSL_LDFLAGS@
CPPFLAGS=@CPPFLAGS@ @OPENSSL_INCLUDES@
DEFS=@DEFS@
COMPILE_FLAGS=${CFLAGS} ${CPPFLAGS} ${DEFS} -Wall -Wextra -Werror -Wno-deprecated-declarations -fno-strict-aliasing -fno-omit-frame-pointer -ggdb
COMPILE_FLAGS=${CFLAGS} ${CPFLAGS} ${CPPFLAGS} ${DEFS} -Wall -Wextra -Werror -Wno-deprecated-declarations -fno-strict-aliasing -fno-omit-frame-pointer -ggdb -Wno-unused-parameter -fPIC
EXTRA_LIBS=@LIBS@ @EXTRA_LIBS@
LOCAL_LDFLAGS=-rdynamic -ggdb ${EXTRA_LIBS}
EXTRA_LIBS=@LIBS@ @EXTRA_LIBS@ @OPENSSL_LIBS@
LOCAL_LDFLAGS=-rdynamic -ggdb -levent ${EXTRA_LIBS}
LINK_FLAGS=${LDFLAGS} ${LOCAL_LDFLAGS}
HEADERS= ${srcdir}/constants.h ${srcdir}/include.h ${srcdir}/interface.h ${srcdir}/LICENSE.h ${srcdir}/loop.h ${srcdir}/mtproto-client.h ${srcdir}/mtproto-common.h ${srcdir}/net.h ${srcdir}/no-preview.h ${srcdir}/queries.h ${srcdir}/structures.h ${srcdir}/telegram.h ${srcdir}/tree.h ${srcdir}/config.h ${srcdir}/binlog.h ${srcdir}/tools.h ${srcdir}/lua-tg.h
DEP=${srcdir}/dep
AUTO=${srcdir}/auto
EXE=${srcdir}/bin
OBJ=${srcdir}/objs
LIB=${srcdir}/libs
DIR_LIST=${DEP} ${AUTO} ${EXE} ${OBJ} ${LIB} ${DEP}/auto ${OBJ}/auto
EXE_LIST=${EXE}/generate ${EXE}/tlc ${EXE}/telegram-cli
LIB_LIST=${LIB}/libtgl.a
TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/lua-tg.o
TGL_OBJECTS=${OBJ}/net.o ${OBJ}/mtproto-common.o ${OBJ}/mtproto-client.o ${OBJ}/queries.o ${OBJ}/structures.o ${OBJ}/binlog.o ${OBJ}/auto/auto.o ${OBJ}/tgl.o ${OBJ}/updates.o
TLC_OBJECTS=${OBJ}/tlc.o ${OBJ}/tl-parser.o ${OBJ}/crc32.o
GENERATE_OBJECTS=${OBJ}/generate.o
COMMON_OBJECTS=${OBJ}/tools.o
OBJ_LIST=${TG_OBJECTS} ${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS}
OBJ_C=${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS}
DEPENDENCE=$(subst ${OBJ}/,${DEP}/,$(patsubst %.o,%.d,${OBJ_LIST}))
DEPENDENCE_LIST=${DEPENDENCE}
INCLUDE=-I. -I${srcdir}
CC=@CC@
OBJECTS=main.o loop.o interface.o net.o mtproto-common.o mtproto-client.o queries.o structures.o binlog.o tools.o lua-tg.o
.SUFFIXES:
.SUFFIXES: .c .h .o
all: telegram
all: ${EXE_LIST} ${DIR_LIST} ${LIB_LIST}
create_dirs_and_headers: ${DIR_LIST} ${AUTO}/auto.c ${AUTO}/auto-header.h ${AUTO}/constants.h
create_dirs: ${DIR_LIST}
${OBJECTS}: ${HEADERS}
${DIR_LIST}:
@test -d $@ || mkdir -p $@
telegram: ${OBJECTS}
${CC} ${OBJECTS} ${LINK_FLAGS} -o $@
-include ${DEPENDENCE_LIST}
.c.o :
${CC} ${COMPILE_FLAGS} ${INCLUDE} -c $< -o $@
${TG_OBJECTS} ${TGL_OBJECTS}: ${AUTO}/constants.h ${AUTO}/auto-header.h
${TG_OBJECTS}: ${OBJ}/%.o: %.c | create_dirs_and_headers
${CC} ${INCLUDE} ${COMPILE_FLAGS} -c -MP -MD -MF ${DEP}/$*.d -MQ ${OBJ}/$*.o -o $@ $<
${OBJ_C}: ${OBJ}/%.o: %.c | create_dirs
${CC} ${INCLUDE} ${COMPILE_FLAGS} -c -MP -MD -MF ${DEP}/$*.d -MQ ${OBJ}/$*.o -o $@ $<
${EXE}/tlc: ${TLC_OBJECTS} ${COMMON_OBJECTS}
${CC} ${TLC_OBJECTS} ${COMMON_OBJECTS} ${LINK_FLAGS} -o $@
${EXE}/telegram-cli: ${TG_OBJECTS} ${COMMON_OBJECTS} ${LIB}/libtgl.a
${CC} ${TG_OBJECTS} ${COMMON_OBJECTS} ${LINK_FLAGS} -L${LIB} -l tgl -o $@
${LIB}/libtgl.a: ${TGL_OBJECTS} ${COMMON_OBJECTS}
ar ruv $@ ${TGL_OBJECTS} ${COMMON_OBJECTS}
${EXE}/generate: ${GENERATE_OBJECTS} ${COMMON_OBJECTS}
${CC} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${LINK_FLAGS} -o $@
${AUTO}/scheme.tlo: ${AUTO}/scheme.tl ${EXE}/tlc
${EXE}/tlc -e $@ ${AUTO}/scheme.tl
${AUTO}/scheme.tl: ${srcdir}/scheme.tl ${srcdir}/encrypted_scheme.tl ${srcdir}/binlog.tl ${srcdir}/append.tl | ${AUTO}
cat $^ > $@
${AUTO}/scheme2.tl: ${AUTO}/scheme.tl ${EXE}/tlc
${EXE}/tlc -E ${AUTO}/scheme.tl 2> $@ || ( cat $@ && rm $@ && false )
${AUTO}/auto.c: ${AUTO}/scheme.tlo ${EXE}/generate
${EXE}/generate ${AUTO}/scheme.tlo > $@
${AUTO}/auto-header.h: ${AUTO}/scheme.tlo ${EXE}/generate
${EXE}/generate -H ${AUTO}/scheme.tlo > $@
${AUTO}/constants.h: ${AUTO}/scheme2.tl ${srcdir}/gen_constants_h.awk
awk -f ${srcdir}/gen_constants_h.awk < $< > $@
clean:
rm -rf *.o telegram config.log config.status > /dev/null || echo "all clean"
rm -rf ${DIR_LIST} config.log config.status > /dev/null || echo "all clean"

78
README-LUA Normal file
View file

@ -0,0 +1,78 @@
To use lua with client you should write lua script. You can specify it from config ("lua_script" option) or from command_line [-s].
It should have several functions:
on_binlog_replay_end() - it is called when replay of old events end. Any updates prior this call were already received by this client
some time ago.
on_get_difference_end() - it is called after first get_difference call. So we received all updates after last client execute.
on_our_id(our_id) - Informs about id of currently logged in user.
on_msg_receive(msg) - it is called when we receive new msg (!! may be called before on_binlog_replay_end, than it is old msg).
on_user_update(user,what_changed) - updated info about user. what_changed is array of strings.
on_chat_update(user,what_changed) - updated info about user. what_changed is array of strings.
on_secret_chat_update(user,what_changed) - updated info about user. what_changed is array of strings.
Also, you can call several functions. Each this function last two arguments, are cb_function and cb_extra.
These functions may return false immidiately if something is bad with args, or return true and call cb_function in future.
cb_function would have two or three arguments: first cb_extra, second success (1 or 0), third result (if applicable).
If you want to pass msg to function, you should pass it's id.
If you want to pass peer to function, you should pass it's print_name.
Or, you can pass string user#id<id> chat#id<id> and secret_chat#id<id> as peer. It is in some cases better. For example if you want to postpone and you are afraid, that print_name would be changed in the meantime.
Function_list (arguments are listed aside from cb_function and cb_extra, :
get_contact_list ()
get_dialog_list ()
rename_chat (chat, new_name)
chat_set_photo (chat, file)
send_msg (peer, text)
fwd_msg (peer, msg)
send_photo (peer, file)
send_video (peer, file)
send_audio (peer, file)
send_document (peer, file)
send_text (peer, file)
load_photo(msg)
load_video(msg)
load_video_thumb(msg)
load_audio(msg)
load_document(msg)
load_document_thumb(msg)
chat_info (chat)
user_info (user)
get_history (peer, limit)
chat_add_user (chat, user)
chat_del_user (chat, user)
add_contactt (phone, first_name, last_name)
rename_contactt (phone, first_name, last_name)
msg_search (peer, text)
msg_global_search (text)
mark_read (peer)
set_profile_photo (file)
create_secret_chat (user)
create_group_chat (user, name)
delete_msg (msg)
restore_msg (number)
status_online ()
status_offline ()
Also, you have function
postpone (cb_function, cb_extra, timeout). It will call your cb_function in specified number of seconds (number of seconds may be double).

View file

@ -1,5 +1,8 @@
## Telegram messenger CLI [![Build Status](https://travis-ci.org/vysheng/tg.png)](https://travis-ci.org/vysheng/tg)
!!!! May be outdated. Please refer to english README as more actual.
Interfaz de línea de comandos para: [Telegram](http://telegram.org). Usa interfaz readline.
### Documentación del API y el protocolo

View file

@ -8,6 +8,16 @@ Documentation for Telegram API is available here: http://core.telegram.org/api
Documentation for MTproto protocol is available here: http://core.telegram.org/mtproto
### Upgrading to version 1.0
First of all, the binary is now in ./bin folder and is named telegram-cli. So be careful, not to use old binary.
Second, config folder is now ${HOME}/.telegram-cli
Third, database is not compatible with older versions, so you'll have to login again.
Fourth, in peer_name '#' are substitued to '@'. (Not applied to appending of '#%d' in case of two peers having same name).
### Installation
Clone GitHub Repository
@ -24,13 +34,13 @@ or download and extract zip
Install libs: readline or libedit, openssl and (if you want to use config) libconfig and liblua.
If you do not want to use them pass options --disable-libconfig and --disable-liblua respectively.
On ubuntu use:
On Ubuntu/Debian use:
sudo apt-get install libreadline-dev libconfig-dev libssl-dev lua5.2 liblua5.2-dev
sudo apt-get install libreadline-dev libconfig-dev libssl-dev lua5.2 liblua5.2-dev libevent-dev
On gentoo:
sudo emerge -av sys-libs/readline dev-libs/libconfig dev-libs/openssl dev-lang/lua
sudo emerge -av sys-libs/readline dev-libs/libconfig dev-libs/openssl dev-lang/lua dev-libs/libevent
On Fedora:
@ -49,9 +59,17 @@ Then,
./configure
make
#### Other methods to install on linux
On Gentoo: use ebuild provided.
On Arch: https://aur.archlinux.org/packages/telegram-git/
#### Mac OS X
The client depends on [readline library](http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html) and [libconfig](http://www.hyperrealm.com/libconfig/), which are not included in OS X by default. You have to install these libraries manually, e.g. using [Homebrew](http://brew.sh/).
The client depends on [readline library](http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html) and [libconfig](http://www.hyperrealm.com/libconfig/), which are not included in OS X by default. You have to install these libraries manually.
If using [Homebrew](http://brew.sh/):
brew install libconfig
brew install readline
@ -62,6 +80,14 @@ The client depends on [readline library](http://cnswww.cns.cwru.edu/php/chet/rea
Thanks to [@jfontan](https://github.com/vysheng/tg/issues/3#issuecomment-28293731) for this solution.
If using [MacPorts](https://www.macports.org):
sudo port install libconfig-hr
sudo port install readline
sudo port install lua51
export CFLAGS="-I/usr/local/include -I/opt/local/include"
export LDFLAGS="-L/usr/local/lib -L/opt/local/lib/"
./configure && make
Install these ports:
@ -78,13 +104,17 @@ Then build:
If you manage to launch it on other UNIX, please let me know.
### Contacts
If you would like to ask a question, you can write to my telegram or to the github (or both). To contact me via telegram, you should use import_card method with argument 000653bf:0738ca5d:5521fbac:29246815:a27d0cda
### Usage
./telegram -k <public-server-key>
bin/telegram-cli -k <public-server-key>
By default public key is stored in the same folder named tg-server.pub or in /etc/telegram/server.pub, if it's not, specify where to find it:
By default public key is stored in the same folder named tg-server.pub or in /etc/telegram-cli/server.pub, if it's not, specify where to find it:
./telegram -k tg-server.pub
bin/telegram-cli -k tg-server.pub
Client support TAB completion and command history.
@ -105,14 +135,19 @@ If two or more peers have same name, <sharp>number is appended to the name. (for
* **add_contact** \<phone-number\> \<first-name\> \<last-name\> - tries to add contact to contact-list by phone
* **rename_contact** \<user\> \<first-name\> \<last-name\> - tries to rename contact. If you have another device it will be a fight
* **mark_read** \<peer\> - mark read all received messages with peer
* **delete_msg** \<msg-seqno\> - deletes message (not completly, though)
* **restore_msg** \<msg-seqno\> - restores delete message. Impossible for secret chats. Only possible short time (one hour, I think) after deletion
#### Multimedia
* **send_photo** \<peer\> \<photo-file-name\> - sends photo to peer
* **send_video** \<peer\> \<video-file-name\> - sends video to peer
* **send_text** \<peer\> \<text-file-name> - sends text file as plain messages
* **load_photo**/load_video/load_video_thumb \<msg-seqno\> - loads photo/video to download dir
* **view_photo**/view_video/view_video_thumb \<msg-seqno\> - loads photo/video to download dir and starts system default viewer
* **load_photo**/load_video/load_video_thumb/load_audio/load_document/load_document_thumb \<msg-seqno\> - loads photo/video/audio/document to download dir
* **view_photo**/view_video/view_video_thumb/view_audio/view_document/view_document_thumb \<msg-seqno\> - loads photo/video to download dir and starts system default viewer
* **fwd_media** \<msg-seqno\> send media in your message. Use this to prevent sharing info about author of media (though, it is possible to determine user_id from media itself, it is not possible get access_hash of this user)
* **set_profile_photo** \<photo-file-name\> - sets userpic. Photo should be square, or server will cut biggest central square part
#### Group chat options
@ -121,6 +156,7 @@ If two or more peers have same name, <sharp>number is appended to the name. (for
* **chat_del_user** \<chat\> \<user\> - remove user from chat
* **rename_chat** \<chat\> \<new-name\>
* **create_group_chat** \<user\> \<chat topic\> - creates a groupchat with user, use chat_add_user to add more users
* **chat_set_photo** \<chat\> \<photo-file-name\> - sets group chat photo. Same limits as for profile photos.
#### Search
@ -131,6 +167,8 @@ If two or more peers have same name, <sharp>number is appended to the name. (for
* **create_secret_chat** \<user\> - creates secret chat with this user
* **visualize_key** \<secret_chat\> - prints visualization of encryption key. You should compare it to your partner's one
* **set_ttl** \<secret_chat\> \<ttl\> - sets ttl to secret chat. Though client does ignore it, client on other end can make use of it
* **accept_secret_chat** \<secret_chat\> - manually accept secret chat (only useful when starting with -E key)
#### Stats and various info
@ -142,3 +180,11 @@ If two or more peers have same name, <sharp>number is appended to the name. (for
* **stats** - just for debugging
* **show_license** - prints contents of GPLv2
* **help** - prints this help
#### Card
* **export_card** - print your 'card' that anyone can later use to import your contact
* **import_card** \<card\> - gets user by card. You can write messages to him after that.
#### Other
* **quit** - quit
* **safe_quit** - wait for all queries to end then quit

2
append.tl Normal file
View file

@ -0,0 +1,2 @@
decryptedMessageMediaVideoL12#4cee6ef3 thumb:bytes thumb_w:int thumb_h:int duration:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaAudioL12#6080758f duration:int size:int key:bytes iv:bytes = DecryptedMessageMedia;

437
auto-static.c Normal file
View file

@ -0,0 +1,437 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2014
*/
#include "mtproto-common.h"
#include <string.h>
static int cur_token_len;
static char *cur_token;
static int cur_token_real_len;
static int cur_token_quoted;
static int multiline_output = 1;
static int multiline_offset;
static int multiline_offset_size = 2;
static int disable_field_names;
#define expect_token(token,len) \
if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return -1; } \
local_next_token ();
#define expect_token_ptr(token,len) \
if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return 0; } \
local_next_token ();
#define expect_token_autocomplete(token,len) \
if (cur_token_len == -3 && len >= cur_token_real_len && !memcmp (cur_token, token, cur_token_real_len)) { set_autocomplete_string (token); return -1; }\
if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return -1; } \
local_next_token ();
#define expect_token_ptr_autocomplete(token,len) \
if (cur_token_len == -3 && len >= cur_token_real_len && !memcmp (cur_token, token, cur_token_real_len)) { set_autocomplete_string (token); return 0; }\
if (len != cur_token_len || memcmp (cur_token, token, cur_token_len)) { return 0; } \
local_next_token ();
static int autocomplete_mode;
static char *autocomplete_string;
static int (*autocomplete_fun)(const char *, int, int, char **);
static void set_autocomplete_string (const char *s) {
if (autocomplete_string) { free (autocomplete_string); }
autocomplete_string = strdup (s);
assert (autocomplete_string);
autocomplete_mode = 1;
}
static void set_autocomplete_type (int (*f)(const char *, int, int, char **)) {
autocomplete_fun = f;
autocomplete_mode = 2;
}
static int is_int (void) {
if (cur_token_len <= 0) { return 0; }
char c = cur_token[cur_token_len];
cur_token[cur_token_len] = 0;
char *p = 0;
if (strtoll (cur_token, &p, 10)) {}
cur_token[cur_token_len] = c;
return p == cur_token + cur_token_len;
}
static long long get_int (void) {
if (cur_token_len <= 0) { return 0; }
char c = cur_token[cur_token_len];
cur_token[cur_token_len] = 0;
char *p = 0;
long long val = strtoll (cur_token, &p, 0);
cur_token[cur_token_len] = c;
return val;
}
static int is_double (void) {
if (cur_token_len <= 0) { return 0; }
char c = cur_token[cur_token_len];
cur_token[cur_token_len] = 0;
char *p = 0;
if (strtod (cur_token, &p)) {}
cur_token[cur_token_len] = c;
return p == cur_token + cur_token_len;
}
static double get_double (void) {
if (cur_token_len <= 0) { return 0; }
char c = cur_token[cur_token_len];
cur_token[cur_token_len] = 0;
char *p = 0;
double val = strtod (cur_token, &p);
cur_token[cur_token_len] = c;
return val;
}
static struct paramed_type *paramed_type_dup (struct paramed_type *P) {
if (ODDP (P)) { return P; }
struct paramed_type *R = malloc (sizeof (*R));
assert (R);
R->type = malloc (sizeof (*R->type));
assert (R->type);
memcpy (R->type, P->type, sizeof (*P->type));
R->type->id = strdup (P->type->id);
assert (R->type->id);
if (P->type->params_num) {
R->params = malloc (sizeof (void *) * P->type->params_num);
assert (R->params);
int i;
for (i = 0; i < P->type->params_num; i++) {
R->params[i] = paramed_type_dup (P->params[i]);
}
}
return R;
}
void tgl_paramed_type_free (struct paramed_type *P) {
if (ODDP (P)) { return; }
if (P->type->params_num) {
int i;
for (i = 0; i < P->type->params_num; i++) {
tgl_paramed_type_free (P->params[i]);
}
free (P->params);
}
free (P->type->id);
free (P->type);
free (P);
}
static char *buffer_pos, *buffer_end;
static int is_wspc (char c) {
return c <= 32 && c > 0;
}
static void skip_wspc (void) {
while (buffer_pos < buffer_end && is_wspc (*buffer_pos)) {
buffer_pos ++;
}
}
static int is_letter (char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-';
}
static char exp_buffer[1 << 25];;
static int exp_buffer_pos;
static inline int is_hex (char c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
}
static inline int hex2dec (char c) {
if (c >= '0' && c <= '9') { return c - '0'; }
else { return c - 'a' + 10; }
}
static void expand_backslashed (char *s, int len) {
int backslashed = 0;
exp_buffer_pos = 0;
int i = 0;
while (i < len) {
assert (i + 3 <= (1 << 25));
if (backslashed) {
backslashed = 0;
switch (s[i ++]) {
case 'n':
exp_buffer[exp_buffer_pos ++] = '\n';
break;
case 'r':
exp_buffer[exp_buffer_pos ++] = '\r';
break;
case 't':
exp_buffer[exp_buffer_pos ++] = '\t';
break;
case 'b':
exp_buffer[exp_buffer_pos ++] = '\b';
break;
case 'a':
exp_buffer[exp_buffer_pos ++] = '\a';
break;
case '\\':
exp_buffer[exp_buffer_pos ++] = '\\';
break;
case 'x':
if (i + 2 > len || !is_hex (s[i]) || !is_hex (s[i + 1])) {
exp_buffer_pos = -1;
return;
}
exp_buffer[exp_buffer_pos ++] = hex2dec (s[i]) * 16 + hex2dec (s[i + 1]);
i += 2;
break;
default:
break;
}
} else {
if (s[i] == '\\') {
backslashed = 1;
i ++;
} else {
exp_buffer[exp_buffer_pos ++] = s[i ++];
}
}
}
}
static void local_next_token (void) {
skip_wspc ();
cur_token_quoted = 0;
if (buffer_pos >= buffer_end) {
cur_token_len = -3;
cur_token_real_len = 0;
return;
}
char c = *buffer_pos;
if (is_letter (c)) {
cur_token = buffer_pos;
while (buffer_pos < buffer_end && is_letter (*buffer_pos)) {
buffer_pos ++;
}
if (buffer_pos < buffer_end) {
cur_token_len = buffer_pos - cur_token;
} else {
cur_token_real_len = buffer_pos - cur_token;
cur_token_len = -3;
}
return;
} else if (c == '"') {
cur_token_quoted = 1;
cur_token = buffer_pos ++;
int backslashed = 0;
while (buffer_pos < buffer_end && (*buffer_pos != '"' || backslashed)) {
if (*buffer_pos == '\\') {
backslashed ^= 1;
} else {
backslashed = 0;
}
buffer_pos ++;
}
if (*buffer_pos == '"') {
buffer_pos ++;
expand_backslashed (cur_token + 1, buffer_pos - cur_token - 2);
if (exp_buffer_pos < 0) {
cur_token_len = -2;
} else {
cur_token_len = exp_buffer_pos;
cur_token = exp_buffer;
}
} else {
cur_token_len = -2;
}
return;
} else {
if (c) {
cur_token = buffer_pos ++;
cur_token_len = 1;
} else {
cur_token_len = -3;
cur_token_real_len = 0;
}
}
}
#define MAX_FVARS 100
static struct paramed_type *fvars[MAX_FVARS];
static int fvars_pos;
static void add_var_to_be_freed (struct paramed_type *P) {
assert (fvars_pos < MAX_FVARS);
fvars[fvars_pos ++] = P;
}
static void free_vars_to_be_freed (void) {
int i;
for (i = 0; i < fvars_pos; i++) {
tgl_paramed_type_free (fvars[i]);
}
fvars_pos = 0;
}
int tglf_extf_autocomplete (const char *text, int text_len, int index, char **R, char *data, int data_len) {
if (index == -1) {
buffer_pos = data;
buffer_end = data + data_len;
autocomplete_mode = 0;
local_next_token ();
struct paramed_type *P = autocomplete_function_any ();
free_vars_to_be_freed ();
if (P) { tgl_paramed_type_free (P); }
}
if (autocomplete_mode == 0) { return -1; }
int len = strlen (text);
if (autocomplete_mode == 1) {
if (index >= 0) { return -1; }
index = 0;
if (!strncmp (text, autocomplete_string, len)) {
*R = strdup (autocomplete_string);
assert (*R);
return index;
} else {
return -1;
}
} else {
return autocomplete_fun (text, len, index, R);
}
}
struct paramed_type *tglf_extf_store (const char *data, int data_len) {
buffer_pos = (char *)data;
buffer_end = (char *)(data + data_len);
local_next_token ();
return store_function_any ();
}
#define OUT_BUF_SIZE (1 << 25)
static char out_buf[OUT_BUF_SIZE];
static int out_buf_pos;
#define eprintf(...) \
do { \
out_buf_pos += snprintf (out_buf + out_buf_pos, OUT_BUF_SIZE - out_buf_pos, __VA_ARGS__);\
assert (out_buf_pos < OUT_BUF_SIZE);\
} while (0)\
static int valid_utf8_char (const char *str) {
unsigned char c = (unsigned char) *str;
int n = 0;
if ((c & 0x80) == 0x00) {
n = 0;
} else if ((c & 0xe0) == 0xc0) {
n = 1;
} else if ((c & 0xf0) == 0xe0) {
n = 2;
} else if ((c & 0xf8) == 0xf0) {
n = 3;
} else if ((c & 0xfc) == 0xf8) {
n = 4;
} else if ((c & 0xfe) == 0xfc) {
n = 5;
} else {
return -1;
}
int i;
for (i = 0; i < n; i ++) {
if ((((unsigned char)(str[i + 1])) & 0xc0) != 0x80) {
return -1;
}
}
return n + 1;
}
static void print_escaped_string (const char *str, int len) {
eprintf ("\"");
const char *end = str + len;
while (str < end) {
int n = valid_utf8_char (str);
if (n < 0) {
eprintf ("\\x%02x", (int)(unsigned char)*str);
str ++;
} else if (n >= 2) {
int i;
for (i = 0; i < n; i++) {
eprintf ("%c", *(str ++));
}
} else if (((unsigned char)*str) >= ' ' && *str != '"' && *str != '\\') {
eprintf ("%c", *str);
str ++;
} else {
switch (*str) {
case '\n':
eprintf("\\n");
break;
case '\r':
eprintf("\\r");
break;
case '\t':
eprintf("\\t");
break;
case '\b':
eprintf("\\b");
break;
case '\a':
eprintf("\\a");
break;
case '\\':
eprintf ("\\\\");
break;
case '"':
eprintf ("\\\"");
break;
default:
eprintf ("\\x%02x", (int)(unsigned char)*str);
break;
}
str ++;
}
}
eprintf ("\"");
}
static void print_offset (void) {
int i;
for (i = 0; i < multiline_offset; i++) {
eprintf (" ");
}
}
char *tglf_extf_fetch (struct paramed_type *T) {
out_buf_pos = 0;
fetch_type_any (T);
return out_buf;
}

48
auto.h Normal file
View file

@ -0,0 +1,48 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2014
*/
#ifndef __AUTO_H__
#define __AUTO_H__
struct tl_type_descr {
unsigned name;
char *id;
int params_num;
long long params_types;
};
struct paramed_type {
struct tl_type_descr *type;
struct paramed_type **params;
};
#define NAME_ARRAY 0x89932ad9
#define TYPE_TO_PARAM(NAME) (&(struct paramed_type) {.type = &tl_type_## NAME, .params=0})
#define TYPE_TO_PARAM_1(NAME,PARAM1) (&(struct paramed_type) {.type = &tl_type_## NAME, .params=(struct paramed_type *[1]){PARAM1}})
#define ODDP(x) (((long)(x)) & 1)
#define EVENP(x) (!ODDP(x))
#define INT2PTR(x) (void *)(long)(((long)x) * 2 + 1)
#define PTR2INT(x) ((((long)x) - 1) / 2)
void tgl_paramed_type_free (struct paramed_type *P);
#include "auto/auto-header.h"
#endif

2736
binlog.c

File diff suppressed because it is too large Load diff

185
binlog.h
View file

@ -1,115 +1,54 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#ifndef __BINLOG_H__
#define __BINLOG_H__
#include "structures.h"
//#include "structures.h"
#include "tgl.h"
#define LOG_START 0x8948329a
#define LOG_AUTH_KEY 0x984932aa
#define LOG_DEFAULT_DC 0x95382908
#define LOG_OUR_ID 0x8943211a
#define LOG_DC_SIGNED 0x234f9893
#define LOG_DC_SALT 0x92192ffa
#define LOG_DH_CONFIG 0x8983402b
#define LOG_ENCR_CHAT_KEY 0x894320aa
#define LOG_ENCR_CHAT_SEND_ACCEPT 0x12ab01c4
#define LOG_ENCR_CHAT_SEND_CREATE 0xab091e24
#define LOG_ENCR_CHAT_DELETED 0x99481230
#define LOG_ENCR_CHAT_WAITING 0x7102100a
#define LOG_ENCR_CHAT_REQUESTED 0x9011011a
#define LOG_ENCR_CHAT_OK 0x7612ce13
#define CODE_binlog_new_user 0xe04f30de
#define CODE_binlog_user_delete 0xf7a27c79
#define CODE_binlog_set_user_access_token 0x1349f615
#define CODE_binlog_set_user_phone 0x5d3afde2
#define CODE_binlog_set_user_friend 0x75a7ec5a
#define CODE_binlog_dc_option 0x08c0ef19
#define CODE_binlog_user_full_photo 0xfaa35824
#define CODE_binlog_user_blocked 0xb2dea7cd
#define CODE_binlog_set_user_full_name 0x4ceb4cf0
#define CODE_binlog_encr_chat_delete 0xb9d33f87
#define CODE_binlog_encr_chat_requested 0xf57d1ea2
#define CODE_binlog_set_encr_chat_access_hash 0xe5612bb3
#define CODE_binlog_set_encr_chat_date 0x54f16911
#define CODE_binlog_set_encr_chat_state 0x76a6e45b
#define CODE_binlog_encr_chat_accepted 0x4627e926
#define CODE_binlog_set_encr_chat_key 0x179df2d4
#define CODE_binlog_set_dh_params 0x20ba46bc
#define CODE_binlog_encr_chat_init 0x939cd1c7
#define CODE_binlog_set_pts 0x844e4c1c
#define CODE_binlog_set_qts 0x3cf22b79
#define CODE_binlog_set_date 0x33dfe392
#define CODE_binlog_set_seq 0xb9294837
#define CODE_binlog_chat_create 0xbaa75791
#define CODE_binlog_chat_change_flags 0x1e494031
#define CODE_binlog_set_chat_title 0x7dd9bea8
#define CODE_binlog_set_chat_photo 0xb4ea1fd2
#define CODE_binlog_set_chat_date 0x78d1114e
#define CODE_binlog_set_chat_version 0xa5d3504f
#define CODE_binlog_set_chat_admin 0x1e7cea04
#define CODE_binlog_set_chat_participants 0x3a29d335
#define CODE_binlog_chat_full_photo 0x6cca6629
#define CODE_binlog_add_chat_participant 0x63345108
#define CODE_binlog_del_chat_participant 0x82d1f0ee
#define CODE_binlog_create_message_text 0x269acd5b
#define CODE_binlog_create_message_text_fwd 0xa3d864cd
#define CODE_binlog_create_message_service 0xbbe5e94b
#define CODE_binlog_create_message_service_fwd 0xea9c57ae
#define CODE_binlog_create_message_media 0x62a92d19
#define CODE_binlog_create_message_media_fwd 0xbefdc462
#define CODE_binlog_send_message_text 0x31cfd652
#define CODE_binlog_set_unread 0x21d4c909
#define CODE_binlog_set_message_sent 0xc335282b
#define CODE_binlog_set_msg_id 0xf3285b6a
#define CODE_binlog_create_message_media_encr 0x19cd7c9d
#define CODE_binlog_create_message_service_encr 0x8b4b9395
#define CODE_binlog_delete_msg 0xa1d6ab6d
void *alloc_log_event (int l);
void replay_log (void);
void add_log_event (const int *data, int l);
void write_binlog (void);
void bl_do_set_auth_key_id (int num, unsigned char *buf);
void bl_do_dc_option (int id, int l1, const char *name, int l2, const char *ip, int port);
void bl_do_set_our_id (int id);
void bl_do_new_user (int id, const char *f, int fl, const char *l, int ll, long long access_token, const char *p, int pl, int contact);
void bl_do_user_delete (struct user *U);
void bl_do_set_user_profile_photo (struct user *U, long long photo_id, struct file_location *big, struct file_location *small);
void bl_do_set_user_name (struct user *U, const char *f, int fl, const char *l, int ll);
void bl_do_set_user_access_token (struct user *U, long long access_token);
void bl_do_set_user_phone (struct user *U, const char *p, int pl);
void bl_do_set_user_friend (struct user *U, int friend);
void bl_do_set_user_full_photo (struct user *U, const int *start, int len);
void bl_do_set_user_blocked (struct user *U, int blocked);
void bl_do_set_user_real_name (struct user *U, const char *f, int fl, const char *l, int ll);
void bl_do_user_add (int id, const char *f, int fl, const char *l, int ll, long long access_token, const char *p, int pl, int contact);
void bl_do_user_delete (struct tgl_user *U);
void bl_do_set_user_profile_photo (struct tgl_user *U, long long photo_id, struct tgl_file_location *big, struct tgl_file_location *small);
void bl_do_user_set_name (struct tgl_user *U, const char *f, int fl, const char *l, int ll);
void bl_do_user_set_access_hash (struct tgl_user *U, long long access_token);
void bl_do_user_set_phone (struct tgl_user *U, const char *p, int pl);
void bl_do_user_set_friend (struct tgl_user *U, int friend);
void bl_do_user_set_full_photo (struct tgl_user *U, const int *start, int len);
void bl_do_user_set_blocked (struct tgl_user *U, int blocked);
void bl_do_user_set_real_name (struct tgl_user *U, const char *f, int fl, const char *l, int ll);
void bl_do_encr_chat_delete (struct secret_chat *U);
void bl_do_encr_chat_requested (struct secret_chat *U, long long access_hash, int date, int admin_id, int user_id, unsigned char g_key[], unsigned char nonce[]);
void bl_do_set_encr_chat_access_hash (struct secret_chat *U, long long access_hash);
void bl_do_set_encr_chat_date (struct secret_chat *U, int date);
void bl_do_set_encr_chat_state (struct secret_chat *U, enum secret_chat_state state);
void bl_do_encr_chat_accepted (struct secret_chat *U, const unsigned char g_key[], const unsigned char nonce[], long long key_fingerprint);
void bl_do_set_encr_chat_key (struct secret_chat *E, unsigned char key[], long long key_fingerprint);
void bl_do_encr_chat_delete (struct tgl_secret_chat *U);
void bl_do_encr_chat_requested (struct tgl_secret_chat *U, long long access_hash, int date, int admin_id, int user_id, unsigned char g_key[], unsigned char nonce[]);
void bl_do_encr_chat_create (int id, int user_id, int admin_id, char *name, int name_len);
void bl_do_encr_chat_set_access_hash (struct tgl_secret_chat *U, long long access_hash);
void bl_do_encr_chat_set_date (struct tgl_secret_chat *U, int date);
void bl_do_encr_chat_set_state (struct tgl_secret_chat *U, enum tgl_secret_chat_state state);
void bl_do_encr_chat_set_ttl (struct tgl_secret_chat *U, int ttl);
void bl_do_encr_chat_set_layer (struct tgl_secret_chat *U, int layer);
void bl_do_encr_chat_accepted (struct tgl_secret_chat *U, const unsigned char g_key[], const unsigned char nonce[], long long key_fingerprint);
void bl_do_encr_chat_set_key (struct tgl_secret_chat *E, unsigned char key[], long long key_fingerprint);
void bl_do_encr_chat_init (int id, int user_id, unsigned char random[], unsigned char g_a[]);
void bl_do_dc_signed (int id);
@ -121,30 +60,40 @@ void bl_do_set_qts (int qts);
void bl_do_set_seq (int seq);
void bl_do_set_date (int date);
void bl_do_create_chat (struct chat *C, int y, const char *s, int l, int users_num, int date, int version, struct file_location *big, struct file_location *small);
void bl_do_chat_forbid (struct chat *C, int on);
void bl_do_set_chat_title (struct chat *C, const char *s, int l);
void bl_do_set_chat_photo (struct chat *C, struct file_location *big, struct file_location *small);
void bl_do_set_chat_date (struct chat *C, int date);
void bl_do_set_chat_set_in_chat (struct chat *C, int on);
void bl_do_set_chat_version (struct chat *C, int version, int user_num);
void bl_do_set_chat_admin (struct chat *C, int admin);
void bl_do_set_chat_participants (struct chat *C, int version, int user_num, struct chat_user *users);
void bl_do_set_chat_full_photo (struct chat *U, const int *start, int len);
void bl_do_chat_add_user (struct chat *C, int version, int user, int inviter, int date);
void bl_do_chat_del_user (struct chat *C, int version, int user);
void bl_do_create_chat (struct tgl_chat *C, int y, const char *s, int l, int users_num, int date, int version, struct tgl_file_location *big, struct tgl_file_location *small);
void bl_do_chat_forbid (struct tgl_chat *C, int on);
void bl_do_chat_set_title (struct tgl_chat *C, const char *s, int l);
void bl_do_chat_set_photo (struct tgl_chat *C, struct tgl_file_location *big, struct tgl_file_location *small);
void bl_do_chat_set_date (struct tgl_chat *C, int date);
void bl_do_chat_set_set_in_chat (struct tgl_chat *C, int on);
void bl_do_chat_set_version (struct tgl_chat *C, int version, int user_num);
void bl_do_chat_set_admin (struct tgl_chat *C, int admin);
void bl_do_chat_set_participants (struct tgl_chat *C, int version, int user_num, struct tgl_chat_user *users);
void bl_do_chat_set_full_photo (struct tgl_chat *U, const int *start, int len);
void bl_do_chat_add_user (struct tgl_chat *C, int version, int user, int inviter, int date);
void bl_do_chat_del_user (struct tgl_chat *C, int version, int user);
void bl_do_create_message_text (int msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s);
void bl_do_create_message_text_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int l, const char *s);
void bl_do_create_message_service (int msg_id, int from_id, int to_type, int to_id, int date, const int *data, int len);
void bl_do_create_message_service_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, const int *data, int len);
void bl_do_create_message_media (int msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len);
void bl_do_create_message_media_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int l, const char *s, const int *data, int len);
void bl_do_create_message_text (int msg_id, int from_id, int to_type, int to_id, int date, int unread, int l, const char *s);
void bl_do_create_message_text_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int unread, int l, const char *s);
void bl_do_create_message_service (int msg_id, int from_id, int to_type, int to_id, int date, int unread, const int *data, int len);
void bl_do_create_message_service_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int unread, const int *data, int len);
void bl_do_create_message_media (int msg_id, int from_id, int to_type, int to_id, int date, int unread, int l, const char *s, const int *data, int len);
void bl_do_create_message_media_encr_pending (long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len);
void bl_do_create_message_media_encr_sent (long long msg_id, const int *data, int len);
void bl_do_create_message_media_fwd (int msg_id, int from_id, int to_type, int to_id, int date, int fwd, int fwd_date, int unread, int l, const char *s, const int *data, int len);
void bl_do_create_message_media_encr (long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s, const int *data, int len, const int *data2, int len2);
void bl_do_create_message_service_encr (long long msg_id, int from_id, int to_type, int to_id, int date, const int *data, int len);
void bl_do_send_message_text (long long msg_id, int from_id, int to_type, int to_id, int date, int l, const char *s);
void bl_do_set_unread (struct message *M, int unread);
void bl_do_set_message_sent (struct message *M);
void bl_do_set_msg_id (struct message *M, int id);
void bl_do_delete_msg (struct message *M);
void bl_do_send_message_action_encr (long long msg_id, int from_id, int to_type, int to_id, int date, int l, const int *s);
void bl_do_set_unread (struct tgl_message *M, int unread);
void bl_do_set_message_sent (struct tgl_message *M);
void bl_do_set_msg_id (struct tgl_message *M, int id);
void bl_do_delete_msg (struct tgl_message *M);
void bl_do_msg_seq_update (long long id);
void bl_do_msg_update (long long id);
void bl_do_reset_authorization (void);
//void bl_do_add_dc (int id, const char *ip, int l, int port, long long auth_key_id, const char *auth_key);
#endif

View file

@ -1,10 +1,79 @@
log.peer peer_type:int peer_id:int = log.Peer;
---types---
binlog.fileLocation dc:int volume:long local_id:int secret:long = binlog.FileLocation;
binlog.chatParticipant user:int inviter:int date:int = binlog.ChatParticipant;
log.dc num:int hostname:string ip:string port:int = log.Event;
log.dcRenum old_num:int new_num:int = log.Event;
log.authKey dc:int key:bytes key_id:long = log.Event;
log.signIn dc:int id:int = log.Event;
binlog.start = binlog.Update;
binlog.dcOption id:int name:string ip:string port:int = binlog.Update;
binlog.authKey dc:int key_id:long key:64*[int] = binlog.Update;
binlog.defaultDc dc:int = binlog.Update;
binlog.ourId id:int = binlog.Update;
binlog.dcSigned id:int = binlog.Update;
binlog.dcSalt id:int salt:long = binlog.Update;
log.user id:int flags:int access_hash:long first_name:string last_name:string real_first_name:string real_last_name:string phone:string photo:log.Photo photo_id:long photo_big:log.FileLocation photo_small:long.FileLocation = log.Event;
binlog.setDhParams root:int prime:64*[int] version:int = binlog.Update;
binlog.setPts pts:int = binlog.Update;
binlog.setQts qts:int = binlog.Update;
binlog.setDate date:int = binlog.Update;
binlog.setSeq seq:int = binlog.Update;
binlog.userAdd id:int first_name:string last_name:string hash:long phone:string is_contact:int = binlog.Update;
binlog.userDelete id:int = binlog.Update;
binlog.userSetAccessHash id:int hash:long = binlog.Update;
binlog.userSetPhone id:int phone:string = binlog.Update;
binlog.userSetFriend id:int friend:int = binlog.Update;
binlog.userSetFullPhoto id:int photo:Photo = binlog.Update;
binlog.userSetBlocked id:int blocked:int = binlog.Update;
binlog.userSetRealName id:int real_first_name:string real_last_name:string = binlog.Update;
binlog.userSetName id:int first_name:string last_name:string = binlog.Update;
binlog.userSetPhoto id:int photo:UserProfilePhoto = binlog.Update;
binlog.encrChatDelete id:int = binlog.Update;
binlog.encrChatRequested id:int hash:long date:int admin:int user:int key:64*[int] nonce:64*[int] = binlog.Update;
binlog.encrChatAccepted id:int key:64*[int] nonce:64*[int] fingerprint:long = binlog.Update;
binlog.encrChatInit id:int user:int key:64*[int] g_key:64*[int] = binlog.Update;
binlog.encrChatCreate id:int user_id:int admin_id:int name:string = binlog.Update;
binlog.encrChatSetAccessHash id:int hash:long = binlog.Update;
binlog.encrChatSetDate id:int date:int = binlog.Update;
binlog.encrChatSetTtl id:int ttl:int = binlog.Update;
binlog.encrChatSetLayer id:int layer:int = binlog.Update;
binlog.encrChatSetState id:int state:int = binlog.Update;
binlog.encrChatSetKey id:int key:64*[int] fingerprint:long = binlog.Update;
binlog.chatCreate id:int flags:int title:string user_num:int date:int version:int photo_big:%binlog.FileLocation photo_small:%binlog.FileLocation = binlog.Update;
binlog.chatChangeFlags id:int set_flags:int clear_flags:int = binlog.Update;
binlog.chatSetTitle id:int title:string = binlog.Update;
binlog.chatSetPhoto id:int photo_big:%binlog.FileLocation photo_small:%binlog.FileLocation = binlog.Update;
binlog.chatSetDate id:int date:int = binlog.Update;
binlog.chatSetVersion id:int version:int users_num:int = binlog.Update;
binlog.chatSetAdmin id:int admin:int = binlog.Update;
binlog.chatSetParticipants id:int version:int participants:%(Vector %binlog.ChatParticipant) = binlog.Update;
binlog.chatSetFullPhoto id:int photo:Photo = binlog.Update;
binlog.chatAddParticipant id:int version:int user:%binlog.ChatParticipant = binlog.Update;
binlog.chatDelParticipant id:int version:int user:int = binlog.Update;
binlog.createMessageText id:int from_id:int to_type:int to_id:int date:int unread:int text:string = binlog.Update;
binlog.sendMessageText id:long from_id:int to_type:int to_id:int date:int text:string = binlog.Update;
binlog.sendMessageActionEncr id:long from_id:int to_type:int to_id:int date:int action:DecryptedMessageAction = binlog.Update;
binlog.createMessageTextFwd id:int from_id:int to_type:int to_id:int date:int fwd_from_id:int fwd_date:int unread:int text:string = binlog.Update;
binlog.createMessageMedia id:int from_id:int to_type:int to_id:int date:int unread:int text:string media:MessageMedia = binlog.Update;
binlog.createMessageMediaEncr id:long from_id:int to_type:int to_id:int date:int text:string media:DecryptedMessageMedia file:EncryptedFile = binlog.Update;
binlog.createMessageMediaEncrPending id:long from_id:int to_type:int to_id:int date:int text:string media:DecryptedMessageMedia = binlog.Update;
binlog.createMessageMediaEncrSent id:long file:EncryptedFile = binlog.Update;
binlog.createMessageMediaFwd id:int from_id:int to_type:int to_id:int date:int fwd_from_id:int fwd_date:int unread:int text:string media:MessageMedia = binlog.Update;
binlog.createMessageService id:int from_id:int to_type:int to_id:int date:int unread:int action:MessageAction = binlog.Update;
binlog.createMessageServiceEncr id:long from_id:int to_type:int to_id:int date:int action:DecryptedMessageAction = binlog.Update;
binlog.createMessageServiceFwd id:int from_id:int to_type:int to_id:int date:int fwd_from_id:int fwd_date:int unread:int action:MessageAction = binlog.Update;
binlog.messageSetUnread id:int = binlog.Update;
binlog.messageSetUnreadLong id:long = binlog.Update;
binlog.setMessageSent id:long = binlog.Update;
binlog.setMsgId old_id:long new_id:int = binlog.Update;
binlog.deleteMsg id:long = binlog.Update;
binlog.msgSeqUpdate id:long = binlog.Update;
binlog.msgUpdate id:long = binlog.Update;
binlog.resetAuthorization = binlog.Update;
//binlog.addDc id:int ip:string port:int auth_key_id:long auth_key:64*[int] = binlog.Update;

View file

@ -1,5 +1,11 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Use libevent v1 */
#undef EVENT_V1
/* Use libevent v2 */
#undef EVENT_V2
/* Define to 1 if you have the `alarm' function. */
#undef HAVE_ALARM
@ -24,16 +30,13 @@
/* Define to 1 if you have the `config' library (-lconfig). */
#undef HAVE_LIBCONFIG
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define to 1 if you have the `edit' library (-ledit). */
#undef HAVE_LIBEDIT
/* Define to 1 if you have the `event' library (-levent). */
#undef HAVE_LIBEVENT
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* Define to 1 if you have the `z' library (-lz). */
/* Define to 1 if you have `z' library (-lz) */
#undef HAVE_LIBZ
/* Define to 1 if you have the <luaconf.h> header file. */
@ -122,6 +125,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if the system has the `__builtin_bswap32' built-in function */
#undef HAVE___BUILTIN_BSWAP32
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
@ -143,12 +149,6 @@
/* Use custom prog name */
#undef PROG_NAME
/* Use libedit */
#undef READLINE_EDIT
/* Use gnu libreadline */
#undef READLINE_GNU
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

1146
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,12 @@
AC_PREREQ([2.68])
AC_INIT([telegram], [0.1])
AC_INIT([telegram-cli], [1.0])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
m4_include([ax_lua.m4])
m4_include([m4_ax_check_openssl.m4])
m4_include([m4_ax_check_zlib.m4])
m4_include([m4-ax_gcc_builtin.m4])
# Checks for programs.
AC_PROG_CC
@ -16,22 +19,24 @@ LDFLAGS="$LDFLAGS -L/usr/local/lib"
AC_CHECK_LIB([m], [sqrt])
AC_SEARCH_LIBS([clock_gettime], [rt])
AC_SEARCH_LIBS([backtrace], [execinfo])
AC_CHECK_LIB([z], [inflate])
AC_CHECK_LIB([crypto], [AES_set_encrypt_key])
AC_CHECK_LIB([event], [event_base_new], [], [AC_MSG_ERROR([no libevent found])])
EVENT_VER=""
AC_CHECK_HEADER(event2/event.h, [AC_DEFINE([EVENT_V2], [1], [Use libevent v2])], [
AC_CHECK_HEADER(event.h, [AC_DEFINE([EVENT_V1], [1], [Use libevent v1])], [AC_MSG_ERROR([no libevent found])])
])
EXTRA_LIBS=""
AC_CHECK_LIB([readline], [rl_save_prompt],
[
AC_DEFINE([READLINE_GNU], [1], [Use gnu libreadline])
[ EXTRA_LIBS="${EXTRA_LIBS} -lreadline" ; ]
],
[
AC_SEARCH_LIBS([tgetnum], [ncursesw ncurses curses])
AC_CHECK_LIB([edit], [rl_set_prompt])
AC_DEFINE([READLINE_EDIT], [1], [Use libedit])
[ EXTRA_LIBS="${EXTRA_LIBS} -ledit" ; ]
]
)
# OPENSSL_INCLUDES to the include directives required
# OPENSSL_LIBS to the -l directives required
# OPENSSL_LDFLAGS to the -L or -R flags required
AX_CHECK_OPENSSL(,[AC_MSG_ERROR([No openssl found])])
AX_CHECK_ZLIB(, [AC_MSG_ERROR([No zlib found])])
AC_CHECK_LIB([readline], [rl_save_prompt], [ EXTRA_LIBS="${EXTRA_LIBS} -lreadline" ; ], [AC_MSG_ERROR([no libreadline found])])
AC_MSG_CHECKING([for libconfig])
AC_ARG_ENABLE(libconfig,[--enable-libconfig/--disable-libconfig],
@ -109,6 +114,8 @@ AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([alarm endpwent memset memmove mkdir select socket strdup strndup uname])
AX_GCC_BUILTIN(__builtin_bswap32)
AC_SUBST(EXTRA_LIBS)
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View file

@ -1,383 +0,0 @@
/*
This file is part of telegram-client.
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
Copyright Vitaly Valtman 2013
*/
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define CODE_bool_false 0xbc799737
#define CODE_bool_true 0x997275b5
#define CODE_vector 0x1cb5c415
#define CODE_error 0xc4b9f9bb
#define CODE_null 0x56730bcc
#define CODE_input_peer_empty 0x7f3b18ea
#define CODE_input_peer_self 0x7da07ec9
#define CODE_input_peer_contact 0x1023dbe8
#define CODE_input_peer_foreign 0x9b447325
#define CODE_input_peer_chat 0x179be863
#define CODE_input_user_empty 0xb98886cf
#define CODE_input_user_self 0xf7c1b13f
#define CODE_input_user_contact 0x86e94f65
#define CODE_input_user_foreign 0x655e74ff
#define CODE_input_phone_contact 0xf392b7f4
#define CODE_input_file 0xf52ff27f
#define CODE_input_media_empty 0x9664f57f
#define CODE_input_media_uploaded_photo 0x2dc53a7d
#define CODE_input_media_photo 0x8f2ab2ec
#define CODE_input_media_geo_point 0xf9c44144
#define CODE_input_media_contact 0xa6e45987
#define CODE_input_media_uploaded_video 0x4847d92a
#define CODE_input_media_uploaded_thumb_video 0xe628a145
#define CODE_input_media_video 0x7f023ae6
#define CODE_input_chat_photo_empty 0x1ca48f57
#define CODE_input_chat_uploaded_photo 0x94254732
#define CODE_input_chat_photo 0xb2e1bf08
#define CODE_input_geo_point_empty 0xe4c123d6
#define CODE_input_geo_point 0xf3b7acc9
#define CODE_input_photo_empty 0x1cd7bf0d
#define CODE_input_photo 0xfb95c6c4
#define CODE_input_video_empty 0x5508ec75
#define CODE_input_video 0xee579652
#define CODE_input_file_location 0x14637196
#define CODE_input_video_file_location 0x3d0364ec
#define CODE_input_photo_crop_auto 0xade6b004
#define CODE_input_photo_crop 0xd9915325
#define CODE_input_app_event 0x770656a8
#define CODE_peer_user 0x9db1bc6d
#define CODE_peer_chat 0xbad0e5bb
#define CODE_storage_file_unknown 0xaa963b05
#define CODE_storage_file_jpeg 0x7efe0e
#define CODE_storage_file_gif 0xcae1aadf
#define CODE_storage_file_png 0xa4f63c0
#define CODE_storage_file_mp3 0x528a0677
#define CODE_storage_file_mov 0x4b09ebbc
#define CODE_storage_file_partial 0x40bc6f52
#define CODE_storage_file_mp4 0xb3cea0e4
#define CODE_storage_file_webp 0x1081464c
#define CODE_file_location_unavailable 0x7c596b46
#define CODE_file_location 0x53d69076
#define CODE_user_empty 0x200250ba
#define CODE_user_self 0x720535ec
#define CODE_user_contact 0xf2fb8319
#define CODE_user_request 0x22e8ceb0
#define CODE_user_foreign 0x5214c89d
#define CODE_user_deleted 0xb29ad7cc
#define CODE_user_profile_photo_empty 0x4f11bae1
#define CODE_user_profile_photo 0xd559d8c8
#define CODE_user_status_empty 0x9d05049
#define CODE_user_status_online 0xedb93949
#define CODE_user_status_offline 0x8c703f
#define CODE_chat_empty 0x9ba2d800
#define CODE_chat 0x6e9c9bc7
#define CODE_chat_forbidden 0xfb0ccc41
#define CODE_chat_full 0x630e61be
#define CODE_chat_participant 0xc8d7493e
#define CODE_chat_participants_forbidden 0xfd2bb8a
#define CODE_chat_participants 0x7841b415
#define CODE_chat_photo_empty 0x37c1011c
#define CODE_chat_photo 0x6153276a
#define CODE_message_empty 0x83e5de54
#define CODE_message 0x22eb6aba
#define CODE_message_forwarded 0x5f46804
#define CODE_message_service 0x9f8d60bb
#define CODE_message_media_empty 0x3ded6320
#define CODE_message_media_photo 0xc8c45a2a
#define CODE_message_media_video 0xa2d24290
#define CODE_message_media_geo 0x56e0d474
#define CODE_message_media_contact 0x5e7d2f39
#define CODE_message_media_unsupported 0x29632a36
#define CODE_message_action_empty 0xb6aef7b0
#define CODE_message_action_chat_create 0xa6638b9a
#define CODE_message_action_chat_edit_title 0xb5a1ce5a
#define CODE_message_action_chat_edit_photo 0x7fcb13a8
#define CODE_message_action_chat_delete_photo 0x95e3fbef
#define CODE_message_action_chat_add_user 0x5e3cfc4b
#define CODE_message_action_chat_delete_user 0xb2ae9b0c
#define CODE_dialog 0x214a8cdf
#define CODE_photo_empty 0x2331b22d
#define CODE_photo 0x22b56751
#define CODE_photo_size_empty 0xe17e23c
#define CODE_photo_size 0x77bfb61b
#define CODE_photo_cached_size 0xe9a734fa
#define CODE_video_empty 0xc10658a8
#define CODE_video 0x5a04a49f
#define CODE_geo_point_empty 0x1117dd5f
#define CODE_geo_point 0x2049d70c
#define CODE_auth_checked_phone 0xe300cc3b
#define CODE_auth_sent_code 0xefed51d9
#define CODE_auth_authorization 0xf6b673a4
#define CODE_auth_exported_authorization 0xdf969c2d
#define CODE_input_notify_peer 0xb8bc5b0c
#define CODE_input_notify_users 0x193b4417
#define CODE_input_notify_chats 0x4a95e84e
#define CODE_input_notify_all 0xa429b886
#define CODE_input_peer_notify_events_empty 0xf03064d8
#define CODE_input_peer_notify_events_all 0xe86a2c74
#define CODE_input_peer_notify_settings 0x46a2ce98
#define CODE_peer_notify_events_empty 0xadd53cb3
#define CODE_peer_notify_events_all 0x6d1ded88
#define CODE_peer_notify_settings_empty 0x70a68512
#define CODE_peer_notify_settings 0x8d5e11ee
#define CODE_wall_paper 0xccb03657
#define CODE_user_full 0x771095da
#define CODE_contact 0xf911c994
#define CODE_imported_contact 0xd0028438
#define CODE_contact_blocked 0x561bc879
#define CODE_contact_found 0xea879f95
#define CODE_contact_suggested 0x3de191a1
#define CODE_contact_status 0xaa77b873
#define CODE_chat_located 0x3631cf4c
#define CODE_contacts_foreign_link_unknown 0x133421f8
#define CODE_contacts_foreign_link_requested 0xa7801f47
#define CODE_contacts_foreign_link_mutual 0x1bea8ce1
#define CODE_contacts_my_link_empty 0xd22a1c60
#define CODE_contacts_my_link_requested 0x6c69efee
#define CODE_contacts_my_link_contact 0xc240ebd9
#define CODE_contacts_link 0xeccea3f5
#define CODE_contacts_contacts 0x6f8b8cb2
#define CODE_contacts_contacts_not_modified 0xb74ba9d2
#define CODE_contacts_imported_contacts 0xd1cd0a4c
#define CODE_contacts_blocked 0x1c138d15
#define CODE_contacts_blocked_slice 0x900802a1
#define CODE_contacts_found 0x566000e
#define CODE_contacts_suggested 0x5649dcc5
#define CODE_messages_dialogs 0x15ba6c40
#define CODE_messages_dialogs_slice 0x71e094f3
#define CODE_messages_messages 0x8c718e87
#define CODE_messages_messages_slice 0xb446ae3
#define CODE_messages_message_empty 0x3f4e0648
#define CODE_messages_message 0xff90c417
#define CODE_messages_stated_messages 0x969478bb
#define CODE_messages_stated_message 0xd07ae726
#define CODE_messages_sent_message 0xd1f4d35c
#define CODE_messages_chat 0x40e9002a
#define CODE_messages_chats 0x8150cbd8
#define CODE_messages_chat_full 0xe5d7d19c
#define CODE_messages_affected_history 0xb7de36f2
#define CODE_input_messages_filter_empty 0x57e2f66c
#define CODE_input_messages_filter_photos 0x9609a51c
#define CODE_input_messages_filter_video 0x9fc00e65
#define CODE_input_messages_filter_photo_video 0x56e9f0e4
#define CODE_update_new_message 0x13abdb3
#define CODE_update_message_i_d 0x4e90bfd6
#define CODE_update_read_messages 0xc6649e31
#define CODE_update_delete_messages 0xa92bfe26
#define CODE_update_restore_messages 0xd15de04d
#define CODE_update_user_typing 0x6baa8508
#define CODE_update_chat_user_typing 0x3c46cfe6
#define CODE_update_chat_participants 0x7761198
#define CODE_update_user_status 0x1bfbd823
#define CODE_update_user_name 0xda22d9ad
#define CODE_update_user_photo 0x95313b0c
#define CODE_update_contact_registered 0x2575bbb9
#define CODE_update_contact_link 0x51a48a9a
#define CODE_update_activation 0x6f690963
#define CODE_update_new_authorization 0x8f06529a
#define CODE_updates_state 0xa56c2a3e
#define CODE_updates_difference_empty 0x5d75a138
#define CODE_updates_difference 0xf49ca0
#define CODE_updates_difference_slice 0xa8fb1981
#define CODE_updates_too_long 0xe317af7e
#define CODE_update_short_message 0xd3f45784
#define CODE_update_short_chat_message 0x2b2fbd4e
#define CODE_update_short 0x78d4dec1
#define CODE_updates_combined 0x725b04c3
#define CODE_updates 0x74ae4240
#define CODE_photos_photos 0x8dca6aa5
#define CODE_photos_photos_slice 0x15051f54
#define CODE_photos_photo 0x20212ca8
#define CODE_upload_file 0x96a18d5
#define CODE_dc_option 0x2ec2a43c
#define CODE_config 0x2e54dd74
#define CODE_nearest_dc 0x8e1a1775
#define CODE_help_app_update 0x8987f311
#define CODE_help_no_app_update 0xc45a6536
#define CODE_help_invite_text 0x18cb9f78
#define CODE_messages_stated_messages_links 0x3e74f5c6
#define CODE_messages_stated_message_link 0xa9af2881
#define CODE_messages_sent_message_link 0xe9db4a3f
#define CODE_input_geo_chat 0x74d456fa
#define CODE_input_notify_geo_chat_peer 0x4d8ddec8
#define CODE_geo_chat 0x75eaea5a
#define CODE_geo_chat_message_empty 0x60311a9b
#define CODE_geo_chat_message 0x4505f8e1
#define CODE_geo_chat_message_service 0xd34fa24e
#define CODE_geochats_stated_message 0x17b1578b
#define CODE_geochats_located 0x48feb267
#define CODE_geochats_messages 0xd1526db1
#define CODE_geochats_messages_slice 0xbc5863e8
#define CODE_message_action_geo_chat_create 0x6f038ebc
#define CODE_message_action_geo_chat_checkin 0xc7d53de
#define CODE_update_new_geo_chat_message 0x5a68e3f7
#define CODE_wall_paper_solid 0x63117f24
#define CODE_update_new_encrypted_message 0x12bcbd9a
#define CODE_update_encrypted_chat_typing 0x1710f156
#define CODE_update_encryption 0xb4a2e88d
#define CODE_update_encrypted_messages_read 0x38fe25b7
#define CODE_encrypted_chat_empty 0xab7ec0a0
#define CODE_encrypted_chat_waiting 0x3bf703dc
#define CODE_encrypted_chat_requested 0xc878527e
#define CODE_encrypted_chat 0xfa56ce36
#define CODE_encrypted_chat_discarded 0x13d6dd27
#define CODE_input_encrypted_chat 0xf141b5e1
#define CODE_encrypted_file_empty 0xc21f497e
#define CODE_encrypted_file 0x4a70994c
#define CODE_input_encrypted_file_empty 0x1837c364
#define CODE_input_encrypted_file_uploaded 0x64bd0306
#define CODE_input_encrypted_file 0x5a17b5e5
#define CODE_input_encrypted_file_location 0xf5235d55
#define CODE_encrypted_message 0xed18c118
#define CODE_encrypted_message_service 0x23734b06
#define CODE_decrypted_message_layer 0x99a438cf
#define CODE_decrypted_message 0x1f814f1f
#define CODE_decrypted_message_service 0xaa48327d
#define CODE_decrypted_message_media_empty 0x89f5c4a
#define CODE_decrypted_message_media_photo 0x32798a8c
#define CODE_decrypted_message_media_video 0x4cee6ef3
#define CODE_decrypted_message_media_geo_point 0x35480a59
#define CODE_decrypted_message_media_contact 0x588a0a97
#define CODE_decrypted_message_action_set_message_t_t_l 0xa1733aec
#define CODE_messages_dh_config_not_modified 0xc0e24635
#define CODE_messages_dh_config 0x2c221edd
#define CODE_messages_sent_encrypted_message 0x560f8935
#define CODE_messages_sent_encrypted_file 0x9493ff32
#define CODE_input_file_big 0xfa4f0bb5
#define CODE_input_encrypted_file_big_uploaded 0x2dc173c8
#define CODE_update_chat_participant_add 0x3a0eeb22
#define CODE_update_chat_participant_delete 0x6e5f8c22
#define CODE_update_dc_options 0x8e5e9873
#define CODE_input_media_uploaded_audio 0x61a6d436
#define CODE_input_media_audio 0x89938781
#define CODE_input_media_uploaded_document 0x34e794bd
#define CODE_input_media_uploaded_thumb_document 0x3e46de5d
#define CODE_input_media_document 0xd184e841
#define CODE_message_media_document 0x2fda2204
#define CODE_message_media_audio 0xc6b68300
#define CODE_input_audio_empty 0xd95adc84
#define CODE_input_audio 0x77d440ff
#define CODE_input_document_empty 0x72f0eaae
#define CODE_input_document 0x18798952
#define CODE_input_audio_file_location 0x74dc404d
#define CODE_input_document_file_location 0x4e45abe9
#define CODE_decrypted_message_media_document 0xb095434b
#define CODE_decrypted_message_media_audio 0x6080758f
#define CODE_audio_empty 0x586988d8
#define CODE_audio 0x427425e7
#define CODE_document_empty 0x36f8c871
#define CODE_document 0x9efc6326
#define CODE_invoke_after_msg 0xcb9f372d
#define CODE_invoke_after_msgs 0x3dc4b4f0
#define CODE_invoke_with_layer1 0x53835315
#define CODE_auth_check_phone 0x6fe51dfb
#define CODE_auth_send_code 0x768d5f4d
#define CODE_auth_send_call 0x3c51564
#define CODE_auth_sign_up 0x1b067634
#define CODE_auth_sign_in 0xbcd51581
#define CODE_auth_log_out 0x5717da40
#define CODE_auth_reset_authorizations 0x9fab0d1a
#define CODE_auth_send_invites 0x771c1d97
#define CODE_auth_export_authorization 0xe5bfffcd
#define CODE_auth_import_authorization 0xe3ef9613
#define CODE_account_register_device 0x446c712c
#define CODE_account_unregister_device 0x65c55b40
#define CODE_account_update_notify_settings 0x84be5b93
#define CODE_account_get_notify_settings 0x12b3ad31
#define CODE_account_reset_notify_settings 0xdb7e1747
#define CODE_account_update_profile 0xf0888d68
#define CODE_account_update_status 0x6628562c
#define CODE_account_get_wall_papers 0xc04cfac2
#define CODE_users_get_users 0xd91a548
#define CODE_users_get_full_user 0xca30a5b1
#define CODE_contacts_get_statuses 0xc4a353ee
#define CODE_contacts_get_contacts 0x22c6aa08
#define CODE_contacts_import_contacts 0xda30b32d
#define CODE_contacts_search 0x11f812d8
#define CODE_contacts_get_suggested 0xcd773428
#define CODE_contacts_delete_contact 0x8e953744
#define CODE_contacts_delete_contacts 0x59ab389e
#define CODE_contacts_block 0x332b49fc
#define CODE_contacts_unblock 0xe54100bd
#define CODE_contacts_get_blocked 0xf57c350f
#define CODE_messages_get_messages 0x4222fa74
#define CODE_messages_get_dialogs 0xeccf1df6
#define CODE_messages_get_history 0x92a1df2f
#define CODE_messages_search 0x7e9f2ab
#define CODE_messages_read_history 0xb04f2510
#define CODE_messages_delete_history 0xf4f8fb61
#define CODE_messages_delete_messages 0x14f2dd0a
#define CODE_messages_restore_messages 0x395f9d7e
#define CODE_messages_received_messages 0x28abcb68
#define CODE_messages_set_typing 0x719839e9
#define CODE_messages_send_message 0x4cde0aab
#define CODE_messages_send_media 0xa3c85d76
#define CODE_messages_forward_messages 0x514cd10f
#define CODE_messages_get_chats 0x3c6aa187
#define CODE_messages_get_full_chat 0x3b831c66
#define CODE_messages_edit_chat_title 0xb4bc68b5
#define CODE_messages_edit_chat_photo 0xd881821d
#define CODE_messages_add_chat_user 0x2ee9ee9e
#define CODE_messages_delete_chat_user 0xc3c5cd23
#define CODE_messages_create_chat 0x419d9aee
#define CODE_updates_get_state 0xedd4882a
#define CODE_updates_get_difference 0xa041495
#define CODE_photos_update_profile_photo 0xeef579a0
#define CODE_photos_upload_profile_photo 0xd50f9c88
#define CODE_upload_save_file_part 0xb304a621
#define CODE_upload_get_file 0xe3a6cfb5
#define CODE_help_get_config 0xc4f9186b
#define CODE_help_get_nearest_dc 0x1fb33026
#define CODE_help_get_app_update 0xc812ac7e
#define CODE_help_save_app_log 0x6f02f748
#define CODE_help_get_invite_text 0xa4a95186
#define CODE_photos_get_user_photos 0xb7ee553c
#define CODE_invoke_with_layer2 0x289dd1f6
#define CODE_messages_forward_message 0x3f3f4f2
#define CODE_messages_send_broadcast 0x41bb0972
#define CODE_invoke_with_layer3 0xb7475268
#define CODE_geochats_get_located 0x7f192d8f
#define CODE_geochats_get_recents 0xe1427e6f
#define CODE_geochats_checkin 0x55b3e8fb
#define CODE_geochats_get_full_chat 0x6722dd6f
#define CODE_geochats_edit_chat_title 0x4c8e2273
#define CODE_geochats_edit_chat_photo 0x35d81a95
#define CODE_geochats_search 0xcfcdc44d
#define CODE_geochats_get_history 0xb53f7a68
#define CODE_geochats_set_typing 0x8b8a729
#define CODE_geochats_send_message 0x61b0044
#define CODE_geochats_send_media 0xb8f0deff
#define CODE_geochats_create_geo_chat 0xe092e16
#define CODE_invoke_with_layer4 0xdea0d430
#define CODE_invoke_with_layer5 0x417a57ae
#define CODE_invoke_with_layer6 0x3a64d54d
#define CODE_invoke_with_layer7 0xa5be56d3
#define CODE_messages_get_dh_config 0x26cf8950
#define CODE_messages_request_encryption 0xf64daf43
#define CODE_messages_accept_encryption 0x3dbc0415
#define CODE_messages_discard_encryption 0xedd923c5
#define CODE_messages_set_encrypted_typing 0x791451ed
#define CODE_messages_read_encrypted_history 0x7f4b690a
#define CODE_messages_send_encrypted 0xa9776773
#define CODE_messages_send_encrypted_file 0x9a901b66
#define CODE_messages_send_encrypted_service 0x32d439a4
#define CODE_messages_received_queue 0x55a5bb66
#define CODE_invoke_with_layer8 0xe9abd9fd
#define CODE_upload_save_big_file_part 0xde7b673d
#define CODE_init_connection 0x69796de9
#define CODE_invoke_with_layer9 0x76715a63
#define CODE_invoke_with_layer10 0x39620c41
#define CODE_invoke_with_layer11 0xa6b88fdf
#define CODE_invoke_with_layer12 0xdda60d3c
#endif

668
crc32.c Normal file
View file

@ -0,0 +1,668 @@
/*
This file is part of VK/KittenPHP-DB-Engine Library.
VK/KittenPHP-DB-Engine Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
VK/KittenPHP-DB-Engine Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with VK/KittenPHP-DB-Engine Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2009-2012 Vkontakte Ltd
2009-2012 Nikolai Durov
2009-2012 Andrei Lopatin
2012 Anton Maydell
*/
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "config.h"
#ifdef HAVE_CONFIG_H
#include "crc32.h"
#endif
#ifndef HAVE___BUILTIN_BSWAP32
static inline unsigned __builtin_bswap32(unsigned x) {
return ((x << 24) & 0xff000000 ) |
((x << 8) & 0x00ff0000 ) |
((x >> 8) & 0x0000ff00 ) |
((x >> 24) & 0x000000ff );
}
#endif
unsigned int crc32_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
unsigned int crc32_table2[256] =
{
0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3,
0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7,
0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb,
0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,
0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192,
0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496,
0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a,
0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,
0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761,
0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69,
0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,
0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530,
0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034,
0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38,
0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,
0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6,
0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2,
0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce,
0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97,
0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93,
0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f,
0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,
0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864,
0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60,
0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c,
0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,
0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35,
0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d,
0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,
0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88,
0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c,
0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180,
0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,
0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9,
0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd,
0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1,
0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a,
0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e,
0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522,
0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,
0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b,
0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f,
0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773,
0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,
0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d,
0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85,
0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,
0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc,
0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8,
0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4,
0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,
0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f,
0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b,
0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27,
0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e,
0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a,
0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876,
0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72,
};
unsigned int crc32_table1[256] =
{
0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59,
0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685,
0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1,
0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,
0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29,
0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5,
0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91,
0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,
0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9,
0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901,
0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,
0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9,
0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315,
0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71,
0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,
0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399,
0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45,
0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221,
0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9,
0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835,
0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151,
0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,
0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579,
0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5,
0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1,
0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,
0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609,
0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1,
0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,
0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9,
0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05,
0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461,
0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,
0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9,
0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75,
0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711,
0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339,
0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5,
0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281,
0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,
0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049,
0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895,
0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1,
0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,
0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819,
0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1,
0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,
0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69,
0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5,
0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1,
0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,
0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9,
0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625,
0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41,
0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89,
0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555,
0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31,
0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed,
};
unsigned int crc32_table0[256] = {
0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee,
0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9,
0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701,
0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,
0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871,
0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26,
0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e,
0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,
0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0,
0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f,
0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,
0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f,
0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018,
0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0,
0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,
0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3,
0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084,
0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c,
0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c,
0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b,
0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3,
0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,
0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed,
0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba,
0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002,
0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,
0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72,
0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d,
0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,
0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5,
0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82,
0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a,
0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,
0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a,
0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d,
0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5,
0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb,
0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc,
0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04,
0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,
0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174,
0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623,
0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b,
0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,
0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8,
0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907,
0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,
0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677,
0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120,
0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98,
0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,
0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6,
0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981,
0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639,
0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949,
0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e,
0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6,
0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1,
};
unsigned crc32_partial_old (const void *data, int len, unsigned crc) {
const char *p = data;
for (; len > 0; len--) {
crc = crc32_table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
}
return crc;
}
/*
unsigned crc32_partial_fast (const void *data, int len, unsigned crc) {
const int *p = (const int *) data;
int x;
for (x = (len >> 2); x > 0; x--) {
crc ^= *p++;
crc = crc32_table0[crc & 0xff] ^ crc32_table1[(crc & 0xff00) >> 8] ^ crc32_table2[(crc & 0xff0000) >> 16] ^ crc32_table[crc >> 24];
}
const char *q = (const char *) p;
switch (len & 3) {
case 3:
crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8);
case 2:
crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8);
case 1:
crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8);
}
return crc;
}
*/
unsigned crc32_partial (const void *data, int len, unsigned crc) {
const int *p = (const int *) data;
int x;
#define DO_ONE(v) crc ^= v; crc = crc32_table0[crc & 0xff] ^ crc32_table1[(crc & 0xff00) >> 8] ^ crc32_table2[(crc & 0xff0000) >> 16] ^ crc32_table[crc >> 24];
#define DO_FOUR(p) DO_ONE((p)[0]); DO_ONE((p)[1]); DO_ONE((p)[2]); DO_ONE((p)[3]);
for (x = (len >> 5); x > 0; x--) {
DO_FOUR (p);
DO_FOUR (p + 4);
p += 8;
}
if (len & 16) {
DO_FOUR (p);
p += 4;
}
if (len & 8) {
DO_ONE (p[0]);
DO_ONE (p[1]);
p += 2;
}
if (len & 4) {
DO_ONE (*p++);
}
/*
for (x = (len >> 2) & 7; x > 0; x--) {
DO_ONE (*p++);
}
*/
#undef DO_ONE
#undef DO_FOUR
const char *q = (const char *) p;
if (len & 2) {
crc = crc32_table[(crc ^ q[0]) & 0xff] ^ (crc >> 8);
crc = crc32_table[(crc ^ q[1]) & 0xff] ^ (crc >> 8);
q += 2;
}
if (len & 1) {
crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8);
}
return crc;
}
unsigned compute_crc32 (const void *data, int len) {
return crc32_partial (data, len, -1) ^ -1;
}
unsigned long long crc64_table[256] = {
0x0000000000000000LL, 0xb32e4cbe03a75f6fLL, 0xf4843657a840a05bLL, 0x47aa7ae9abe7ff34LL,
0x7bd0c384ff8f5e33LL, 0xc8fe8f3afc28015cLL, 0x8f54f5d357cffe68LL, 0x3c7ab96d5468a107LL,
0xf7a18709ff1ebc66LL, 0x448fcbb7fcb9e309LL, 0x0325b15e575e1c3dLL, 0xb00bfde054f94352LL,
0x8c71448d0091e255LL, 0x3f5f08330336bd3aLL, 0x78f572daa8d1420eLL, 0xcbdb3e64ab761d61LL,
0x7d9ba13851336649LL, 0xceb5ed8652943926LL, 0x891f976ff973c612LL, 0x3a31dbd1fad4997dLL,
0x064b62bcaebc387aLL, 0xb5652e02ad1b6715LL, 0xf2cf54eb06fc9821LL, 0x41e11855055bc74eLL,
0x8a3a2631ae2dda2fLL, 0x39146a8fad8a8540LL, 0x7ebe1066066d7a74LL, 0xcd905cd805ca251bLL,
0xf1eae5b551a2841cLL, 0x42c4a90b5205db73LL, 0x056ed3e2f9e22447LL, 0xb6409f5cfa457b28LL,
0xfb374270a266cc92LL, 0x48190ecea1c193fdLL, 0x0fb374270a266cc9LL, 0xbc9d3899098133a6LL,
0x80e781f45de992a1LL, 0x33c9cd4a5e4ecdceLL, 0x7463b7a3f5a932faLL, 0xc74dfb1df60e6d95LL,
0x0c96c5795d7870f4LL, 0xbfb889c75edf2f9bLL, 0xf812f32ef538d0afLL, 0x4b3cbf90f69f8fc0LL,
0x774606fda2f72ec7LL, 0xc4684a43a15071a8LL, 0x83c230aa0ab78e9cLL, 0x30ec7c140910d1f3LL,
0x86ace348f355aadbLL, 0x3582aff6f0f2f5b4LL, 0x7228d51f5b150a80LL, 0xc10699a158b255efLL,
0xfd7c20cc0cdaf4e8LL, 0x4e526c720f7dab87LL, 0x09f8169ba49a54b3LL, 0xbad65a25a73d0bdcLL,
0x710d64410c4b16bdLL, 0xc22328ff0fec49d2LL, 0x85895216a40bb6e6LL, 0x36a71ea8a7ace989LL,
0x0adda7c5f3c4488eLL, 0xb9f3eb7bf06317e1LL, 0xfe5991925b84e8d5LL, 0x4d77dd2c5823b7baLL,
0x64b62bcaebc387a1LL, 0xd7986774e864d8ceLL, 0x90321d9d438327faLL, 0x231c512340247895LL,
0x1f66e84e144cd992LL, 0xac48a4f017eb86fdLL, 0xebe2de19bc0c79c9LL, 0x58cc92a7bfab26a6LL,
0x9317acc314dd3bc7LL, 0x2039e07d177a64a8LL, 0x67939a94bc9d9b9cLL, 0xd4bdd62abf3ac4f3LL,
0xe8c76f47eb5265f4LL, 0x5be923f9e8f53a9bLL, 0x1c4359104312c5afLL, 0xaf6d15ae40b59ac0LL,
0x192d8af2baf0e1e8LL, 0xaa03c64cb957be87LL, 0xeda9bca512b041b3LL, 0x5e87f01b11171edcLL,
0x62fd4976457fbfdbLL, 0xd1d305c846d8e0b4LL, 0x96797f21ed3f1f80LL, 0x2557339fee9840efLL,
0xee8c0dfb45ee5d8eLL, 0x5da24145464902e1LL, 0x1a083bacedaefdd5LL, 0xa9267712ee09a2baLL,
0x955cce7fba6103bdLL, 0x267282c1b9c65cd2LL, 0x61d8f8281221a3e6LL, 0xd2f6b4961186fc89LL,
0x9f8169ba49a54b33LL, 0x2caf25044a02145cLL, 0x6b055fede1e5eb68LL, 0xd82b1353e242b407LL,
0xe451aa3eb62a1500LL, 0x577fe680b58d4a6fLL, 0x10d59c691e6ab55bLL, 0xa3fbd0d71dcdea34LL,
0x6820eeb3b6bbf755LL, 0xdb0ea20db51ca83aLL, 0x9ca4d8e41efb570eLL, 0x2f8a945a1d5c0861LL,
0x13f02d374934a966LL, 0xa0de61894a93f609LL, 0xe7741b60e174093dLL, 0x545a57dee2d35652LL,
0xe21ac88218962d7aLL, 0x5134843c1b317215LL, 0x169efed5b0d68d21LL, 0xa5b0b26bb371d24eLL,
0x99ca0b06e7197349LL, 0x2ae447b8e4be2c26LL, 0x6d4e3d514f59d312LL, 0xde6071ef4cfe8c7dLL,
0x15bb4f8be788911cLL, 0xa6950335e42fce73LL, 0xe13f79dc4fc83147LL, 0x521135624c6f6e28LL,
0x6e6b8c0f1807cf2fLL, 0xdd45c0b11ba09040LL, 0x9aefba58b0476f74LL, 0x29c1f6e6b3e0301bLL,
0xc96c5795d7870f42LL, 0x7a421b2bd420502dLL, 0x3de861c27fc7af19LL, 0x8ec62d7c7c60f076LL,
0xb2bc941128085171LL, 0x0192d8af2baf0e1eLL, 0x4638a2468048f12aLL, 0xf516eef883efae45LL,
0x3ecdd09c2899b324LL, 0x8de39c222b3eec4bLL, 0xca49e6cb80d9137fLL, 0x7967aa75837e4c10LL,
0x451d1318d716ed17LL, 0xf6335fa6d4b1b278LL, 0xb199254f7f564d4cLL, 0x02b769f17cf11223LL,
0xb4f7f6ad86b4690bLL, 0x07d9ba1385133664LL, 0x4073c0fa2ef4c950LL, 0xf35d8c442d53963fLL,
0xcf273529793b3738LL, 0x7c0979977a9c6857LL, 0x3ba3037ed17b9763LL, 0x888d4fc0d2dcc80cLL,
0x435671a479aad56dLL, 0xf0783d1a7a0d8a02LL, 0xb7d247f3d1ea7536LL, 0x04fc0b4dd24d2a59LL,
0x3886b22086258b5eLL, 0x8ba8fe9e8582d431LL, 0xcc0284772e652b05LL, 0x7f2cc8c92dc2746aLL,
0x325b15e575e1c3d0LL, 0x8175595b76469cbfLL, 0xc6df23b2dda1638bLL, 0x75f16f0cde063ce4LL,
0x498bd6618a6e9de3LL, 0xfaa59adf89c9c28cLL, 0xbd0fe036222e3db8LL, 0x0e21ac88218962d7LL,
0xc5fa92ec8aff7fb6LL, 0x76d4de52895820d9LL, 0x317ea4bb22bfdfedLL, 0x8250e80521188082LL,
0xbe2a516875702185LL, 0x0d041dd676d77eeaLL, 0x4aae673fdd3081deLL, 0xf9802b81de97deb1LL,
0x4fc0b4dd24d2a599LL, 0xfceef8632775faf6LL, 0xbb44828a8c9205c2LL, 0x086ace348f355aadLL,
0x34107759db5dfbaaLL, 0x873e3be7d8faa4c5LL, 0xc094410e731d5bf1LL, 0x73ba0db070ba049eLL,
0xb86133d4dbcc19ffLL, 0x0b4f7f6ad86b4690LL, 0x4ce50583738cb9a4LL, 0xffcb493d702be6cbLL,
0xc3b1f050244347ccLL, 0x709fbcee27e418a3LL, 0x3735c6078c03e797LL, 0x841b8ab98fa4b8f8LL,
0xadda7c5f3c4488e3LL, 0x1ef430e13fe3d78cLL, 0x595e4a08940428b8LL, 0xea7006b697a377d7LL,
0xd60abfdbc3cbd6d0LL, 0x6524f365c06c89bfLL, 0x228e898c6b8b768bLL, 0x91a0c532682c29e4LL,
0x5a7bfb56c35a3485LL, 0xe955b7e8c0fd6beaLL, 0xaeffcd016b1a94deLL, 0x1dd181bf68bdcbb1LL,
0x21ab38d23cd56ab6LL, 0x9285746c3f7235d9LL, 0xd52f0e859495caedLL, 0x6601423b97329582LL,
0xd041dd676d77eeaaLL, 0x636f91d96ed0b1c5LL, 0x24c5eb30c5374ef1LL, 0x97eba78ec690119eLL,
0xab911ee392f8b099LL, 0x18bf525d915feff6LL, 0x5f1528b43ab810c2LL, 0xec3b640a391f4fadLL,
0x27e05a6e926952ccLL, 0x94ce16d091ce0da3LL, 0xd3646c393a29f297LL, 0x604a2087398eadf8LL,
0x5c3099ea6de60cffLL, 0xef1ed5546e415390LL, 0xa8b4afbdc5a6aca4LL, 0x1b9ae303c601f3cbLL,
0x56ed3e2f9e224471LL, 0xe5c372919d851b1eLL, 0xa26908783662e42aLL, 0x114744c635c5bb45LL,
0x2d3dfdab61ad1a42LL, 0x9e13b115620a452dLL, 0xd9b9cbfcc9edba19LL, 0x6a978742ca4ae576LL,
0xa14cb926613cf817LL, 0x1262f598629ba778LL, 0x55c88f71c97c584cLL, 0xe6e6c3cfcadb0723LL,
0xda9c7aa29eb3a624LL, 0x69b2361c9d14f94bLL, 0x2e184cf536f3067fLL, 0x9d36004b35545910LL,
0x2b769f17cf112238LL, 0x9858d3a9ccb67d57LL, 0xdff2a94067518263LL, 0x6cdce5fe64f6dd0cLL,
0x50a65c93309e7c0bLL, 0xe388102d33392364LL, 0xa4226ac498dedc50LL, 0x170c267a9b79833fLL,
0xdcd7181e300f9e5eLL, 0x6ff954a033a8c131LL, 0x28532e49984f3e05LL, 0x9b7d62f79be8616aLL,
0xa707db9acf80c06dLL, 0x14299724cc279f02LL, 0x5383edcd67c06036LL, 0xe0ada17364673f59LL
};
unsigned long long crc64_partial (const void *data, int len, unsigned long long crc) {
const char *p = data;
for (; len > 0; len--) {
crc = crc64_table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
}
return crc;
}
unsigned long long crc64 (const void *data, int len) {
return crc64_partial (data, len, -1LL) ^ -1LL;
}
static unsigned gf32_matrix_times (unsigned *matrix, unsigned vector) {
unsigned sum = 0;
while (vector) {
if (vector & 1) {
sum ^= *matrix;
}
vector >>= 1;
matrix++;
}
return sum;
}
static void gf32_matrix_square (unsigned *square, unsigned *matrix) {
int n = 0;
do {
square[n] = gf32_matrix_times (matrix, matrix[n]);
} while (++n < 32);
}
unsigned compute_crc32_combine (unsigned crc1, unsigned crc2, int len2) {
assert (len2 < (1 << 29));
static int power_buf_initialized = 0;
static unsigned power_buf[1024];
int n;
/* degenerate case (also disallow negative lengths) */
if (len2 <= 0) {
return crc1;
}
if (!power_buf_initialized) {
power_buf[0] = 0xedb88320UL;
for (n = 0; n < 31; n++) {
power_buf[n+1] = 1U << n;
}
for (n = 1; n < 32; n++) {
gf32_matrix_square (power_buf + (n << 5), power_buf + ((n - 1) << 5));
}
power_buf_initialized = 1;
}
unsigned int *p = power_buf + 64;
do {
p += 32;
if (len2 & 1) {
crc1 = gf32_matrix_times (p, crc1);
}
len2 >>= 1;
} while (len2);
return crc1 ^ crc2;
}
/********************************* crc32 repair ************************/
struct fcb_table_entry {
unsigned p; //zeta ^ k
int i;
};
static inline unsigned gf32_mod (unsigned long long r, int high_bit) {
int j = high_bit;
for (j = high_bit; j >= 32; j--) {
if ((1ULL << j) & r) {
r ^= 0x04C11DB7ULL << (j - 32);
}
}
return (unsigned) r;
}
static unsigned gf32_mult (unsigned a, unsigned b) {
int i;
const unsigned long long m = b;
unsigned long long r = 0;
for (i = 0; i < 32; i++) {
if (a & (1U << i)) {
r ^= m << i;
}
}
return gf32_mod (r, 62);
}
static unsigned gf32_shl (unsigned int a, int shift) {
unsigned long long r = a;
r <<= shift;
return gf32_mod (r, 31 + shift);
}
static unsigned gf32_pow (unsigned a, int k) {
if (!k) { return 1; }
unsigned x = gf32_pow (gf32_mult (a, a), k >> 1);
if (k & 1) {
x = gf32_mult (x, a);
}
return x;
}
static int cmp_fcb_table_entry (const void *a, const void *b) {
const struct fcb_table_entry *x = a;
const struct fcb_table_entry *y = b;
if (x->p < y->p) { return -1; }
if (x->p > y->p) { return 1; }
if (x->i < y->i) { return -1; }
if (x->i > y->i) { return 1; }
return 0;
}
#define GROUP_SWAP(x,m,s) ((x & m) << s) | ((x & (~m)) >> s)
static unsigned revbin (unsigned x) {
x = GROUP_SWAP(x,0x55555555U,1);
x = GROUP_SWAP(x,0x33333333U,2);
x = GROUP_SWAP(x,0x0f0f0f0fU,4);
x = __builtin_bswap32 (x);
return x;
}
#undef GROUP_SWAP
static inline unsigned xmult (unsigned a) {
unsigned r = a << 1;
if (a & (1U<<31)) {
r ^= 0x04C11DB7U;
}
return r;
}
static int find_corrupted_bit (int size, unsigned d) {
int i, j;
size += 4;
d = revbin (d);
int n = size << 3;
int r = (int) (sqrt (n) + 0.5);
struct fcb_table_entry *T = calloc (r, sizeof (struct fcb_table_entry));
assert (T != NULL);
T[0].i = 0;
T[0].p = 1;
for (i = 1; i < r; i++) {
T[i].i = i;
T[i].p = xmult (T[i-1].p);
}
assert (xmult (0x82608EDB) == 1);
qsort (T, r, sizeof (T[0]), cmp_fcb_table_entry);
unsigned q = gf32_pow (0x82608EDB, r);
unsigned A[32];
for (i = 0; i < 32; i++) {
A[i] = gf32_shl (q, i);
}
unsigned x = d;
int max_j = n / r, res = -1;
for (j = 0; j <= max_j; j++) {
int a = -1, b = r;
while (b - a > 1) {
int c = ((a + b) >> 1);
if (T[c].p <= x) { a = c; } else { b = c; }
}
if (a >= 0 && T[a].p == x) {
res = T[a].i + r * j;
break;
}
x = gf32_matrix_times (A, x);
}
free (T);
return res;
}
static int repair_bit (unsigned char *input, int l, int k) {
if (k < 0) {
return -1;
}
int idx = k >> 5, bit = k & 31, i = (l - 1) - (idx - 1) * 4;
while (bit >= 8) {
i--;
bit -= 8;
}
if (i < 0) {
return -2;
}
if (i >= l) {
return -3;
}
int j = 7 - bit;
input[i] ^= 1 << j;
return 0;
}
int crc32_check_and_repair (void *input, int l, unsigned *input_crc32, int force_exit) {
unsigned computed_crc32 = compute_crc32 (input, l);
const unsigned crc32_diff = computed_crc32 ^ (*input_crc32);
if (!crc32_diff) {
return 0;
}
int k = find_corrupted_bit (l, crc32_diff);
int r = repair_bit (input, l, k);
if (!r) {
assert (compute_crc32 (input, l) == *input_crc32);
return 1;
}
if (!(crc32_diff & (crc32_diff - 1))) { /* crc32_diff is power of 2 */
*input_crc32 = computed_crc32;
return 2;
}
assert (!force_exit);
*input_crc32 = computed_crc32;
return -1;
}

59
crc32.h Normal file
View file

@ -0,0 +1,59 @@
/*
This file is part of VK/KittenPHP-DB-Engine Library.
VK/KittenPHP-DB-Engine Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
VK/KittenPHP-DB-Engine Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with VK/KittenPHP-DB-Engine Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2009-2012 Vkontakte Ltd
2009-2012 Nikolai Durov
2009-2012 Andrei Lopatin
2012 Anton Maydell
*/
#ifndef __CRC32_H__
#define __CRC32_H__
#ifdef __cplusplus
extern "C" {
#endif
extern unsigned int crc32_table[256];
unsigned crc32_partial (const void *data, int len, unsigned crc);
//unsigned crc32_partial_fast (const void *data, int len, unsigned crc);
//unsigned crc32_partial_fastest (const void *data, int len, unsigned crc);
unsigned compute_crc32 (const void *data, int len);
unsigned compute_crc32_combine (unsigned crc1, unsigned crc2, int len2);
extern unsigned long long crc64_table[256];
unsigned long long crc64_partial (const void *data, int len, unsigned long long crc);
unsigned long long crc64 (const void *data, int len);
//unsigned gf32_matrix_times (unsigned *matrix, unsigned vector);
/* crc32_check_and_repair returns
0 : Cyclic redundancy check is ok
1 : Cyclic redundancy check fails, but we fix one bit in input
2 : Cyclic redundancy check fails, but we fix one bit in input_crc32
-1 : Cyclic redundancy check fails, no repair possible.
In this case *input_crc32 will be equal crc32 (input, l)
Case force_exit == 1 (case 1, 2: kprintf call, case -1: assert fail).
*/
int crc32_check_and_repair (void *input, int l, unsigned *input_crc32, int force_exit);
#ifdef __cplusplus
}
#endif
#endif

1
encrypted_scheme.tl Symbolic link
View file

@ -0,0 +1 @@
encrypted_scheme16.tl

22
encrypted_scheme16.tl Normal file
View file

@ -0,0 +1,22 @@
---types---
decryptedMessageLayer#99a438cf layer:int message:DecryptedMessage = DecryptedMessageLayer;
decryptedMessage#1f814f1f random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage;
decryptedMessageService#aa48327d random_id:long random_bytes:bytes action:DecryptedMessageAction = DecryptedMessage;
decryptedMessageMediaEmpty#89f5c4a = DecryptedMessageMedia;
decryptedMessageMediaPhoto#32798a8c thumb:bytes thumb_w:int thumb_h:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
//decryptedMessageMediaVideo#4cee6ef3 thumb:bytes thumb_w:int thumb_h:int duration:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaGeoPoint#35480a59 lat:double long:double = DecryptedMessageMedia;
decryptedMessageMediaContact#588a0a97 phone_number:string first_name:string last_name:string user_id:int = DecryptedMessageMedia;
decryptedMessageActionSetMessageTTL#a1733aec ttl_seconds:int = DecryptedMessageAction;
decryptedMessageMediaDocument#b095434b thumb:bytes thumb_w:int thumb_h:int file_name:string mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
//decryptedMessageMediaAudio#6080758f duration:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaVideo#524a415d thumb:bytes thumb_w:int thumb_h:int duration:int mime_type:string w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaAudio#57e0a9cb duration:int mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageActionReadMessages#c4f40be random_ids:Vector<long> = DecryptedMessageAction;
decryptedMessageActionDeleteMessages#65614304 random_ids:Vector<long> = DecryptedMessageAction;
decryptedMessageActionScreenshotMessages#8ac1f475 random_ids:Vector<long> = DecryptedMessageAction;
decryptedMessageActionFlushHistory#6719e45c = DecryptedMessageAction;
decryptedMessageActionNotifyLayer#f3048883 layer:int = DecryptedMessageAction;
---functions---

43
event-old.h Normal file
View file

@ -0,0 +1,43 @@
#ifndef __EVENT_OLD_H__
#define __EVENT_OLD_H__
#include <assert.h>
#define BEV_EVENT_READ EVBUFFER_READ
#define BEV_EVENT_WRITE EVBUFFER_WRITE
#define BEV_EVENT_EOF EVBUFFER_EOF
#define BEV_EVENT_ERROR EVBUFFER_ERROR
#define BEV_EVENT_TIMEOUT EVBUFFER_TIMEOUT
typedef int evutil_socket_t;
static inline struct event *event_new (struct event_base *base, int fd, int what, void(*callback)(int, short, void *), void *arg) __attribute__ ((unused));
static inline struct event *event_new (struct event_base *base, int fd, int what, void(*callback)(int, short, void *), void *arg) {
struct event *ev = malloc (sizeof (*ev));
event_set (ev, fd, what, callback, arg);
event_base_set (base, ev);
return ev;
}
static inline struct event *evtimer_new (struct event_base *base, void(*callback)(int, short, void *), void *arg) __attribute__ ((unused));
static inline struct event *evtimer_new (struct event_base *base, void(*callback)(int, short, void *), void *arg) {
struct event *ev = malloc (sizeof (*ev));
event_set (ev, -1, 0, callback, arg);
event_base_set (base, ev);
return ev;
}
static void event_free (struct event *ev) __attribute__ ((unused));
static void event_free (struct event *ev) {
event_del (ev);
free (ev);
}
static struct bufferevent *bufferevent_socket_new (struct event_base *base, int fd, int flags) __attribute__ ((unused));
static struct bufferevent *bufferevent_socket_new (struct event_base *base, int fd, int flags) {
assert (!flags);
struct bufferevent *bev = bufferevent_new(fd, 0, 0, 0, 0);
bufferevent_base_set (base, bev);
return bev;
}
#endif

View file

@ -22,7 +22,7 @@ BEGIN {
}
// {
if (split ($1, a, "#") == 2) {
gsub (/[A-Z]/, "_&", a[1]);
gsub (/[ABCDEFGHIJKLMNOPQRSTUVWXYZ]/, "_&", 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/"

1812
generate.c Normal file

File diff suppressed because it is too large Load diff

171
generate.h Normal file
View file

@ -0,0 +1,171 @@
/*
This file is part of tgl-libary/generate
Tgl-library/generate is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Tgl-library/generate is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this tgl-library/generate. If not, see <http://www.gnu.org/licenses/>.
Copyright Vitaly Valtman 2014
It is derivative work of VK/KittenPHP-DB-Engine (https://github.com/vk-com/kphp-kdb/)
Copyright 2012-2013 Vkontakte Ltd
2012-2013 Vitaliy Valtman
*/
#ifndef __GENERATE_H__
#define __GENERATE_H__
struct tl_combinator;
struct tl_type {
// struct tl_type_methods *methods;
char *id;
char *print_id;
unsigned name;
int arity;
int flags;
int constructors_num;
struct tl_combinator **constructors;
long long params_types;
int extra;
};
#define NODE_TYPE_TYPE 1
#define NODE_TYPE_NAT_CONST 2
#define NODE_TYPE_VAR_TYPE 3
#define NODE_TYPE_VAR_NUM 4
#define NODE_TYPE_ARRAY 5
#define MAX_COMBINATOR_VARS 64
#define NAME_VAR_NUM 0x70659eff
#define NAME_VAR_TYPE 0x2cecf817
#define NAME_INT 0xa8509bda
#define NAME_LONG 0x22076cba
#define NAME_DOUBLE 0x2210c154
#define NAME_STRING 0xb5286e24
#define NAME_VECTOR 0x1cb5c415
#define NAME_MAYBE_TRUE 0x3f9c8ef8
#define NAME_MAYBE_FALSE 0x27930a7b
#define NAME_BOOL_FALSE 0xbc799737
#define NAME_BOOL_TRUE 0x997275b5
#define FLAG_OPT_VAR (1 << 17)
#define FLAG_EXCL (1 << 18)
#define FLAG_OPT_FIELD (1 << 20)
#define FLAG_NOVAR (1 << 21)
#define FLAG_BARE 1
#define FLAGS_MASK ((1 << 16) - 1)
#define FLAG_DEFAULT_CONSTRUCTOR (1 << 25)
#define FLAG_NOCONS (1 << 1)
extern struct tl_tree_methods tl_nat_const_methods;
extern struct tl_tree_methods tl_nat_const_full_methods;
extern struct tl_tree_methods tl_pnat_const_full_methods;
extern struct tl_tree_methods tl_array_methods;
extern struct tl_tree_methods tl_type_methods;
extern struct tl_tree_methods tl_parray_methods;
extern struct tl_tree_methods tl_ptype_methods;
extern struct tl_tree_methods tl_var_num_methods;
extern struct tl_tree_methods tl_var_type_methods;
extern struct tl_tree_methods tl_pvar_num_methods;
extern struct tl_tree_methods tl_pvar_type_methods;
#define TL_IS_NAT_VAR(x) (((long)x) & 1)
#define TL_TREE_METHODS(x) (TL_IS_NAT_VAR (x) ? &tl_nat_const_methods : ((struct tl_tree *)(x))->methods)
#define DEC_REF(x) (TL_TREE_METHODS(x)->dec_ref ((void *)x))
#define INC_REF(x) (TL_TREE_METHODS(x)->inc_ref ((void *)x))
#define TYPE(x) (TL_TREE_METHODS(x)->type ((void *)x))
typedef unsigned long long tl_tree_hash_t;
struct tl_tree;
struct tl_tree_methods {
int (*type)(struct tl_tree *T);
int (*eq)(struct tl_tree *T, struct tl_tree *U);
void (*inc_ref)(struct tl_tree *T);
void (*dec_ref)(struct tl_tree *T);
};
struct tl_tree {
int ref_cnt;
int flags;
//tl_tree_hash_t hash;
struct tl_tree_methods *methods;
};
/*
struct tl_tree_nat_const {
struct tl_tree self;
int value;
};*/
struct tl_tree_type {
struct tl_tree self;
struct tl_type *type;
int children_num;
struct tl_tree **children;
};
struct tl_tree_array {
struct tl_tree self;
struct tl_tree *multiplicity;
int args_num;
struct arg **args;
};
struct tl_tree_var_type {
struct tl_tree self;
int var_num;
};
struct tl_tree_var_num {
struct tl_tree self;
int var_num;
int dif;
};
struct tl_tree_nat_const {
struct tl_tree self;
long long value;
};
struct arg {
char *id;
int var_num;
int flags;
int exist_var_num;
int exist_var_bit;
struct tl_tree *type;
};
struct tl_combinator {
//struct tl_combinator_methods *methods;
char *id;
char *print_id;
unsigned name;
int is_fun;
int var_num;
int args_num;
struct arg **args;
struct tl_tree *result;
void **IP;
void **fIP;
int IP_len;
int fIP_len;
};
#endif

View file

@ -0,0 +1 @@
EBUILD telegram-cli-9999.ebuild 665 SHA256 446cf5cd54f60485dda2f47e5c027b78f182053ef88cd09d7327603e2d5f3d86 SHA512 8a3673de91ec60e89391956523a4b61872161a23a7e0babdbd90cbdd8602104ba1855d09bd0af1d2092890eb202f498750610bf71e3bd0562e37ec984deb333e WHIRLPOOL e943b8870f461c62e3dc7f061dcad264c25758d1d50a0c34f5232d3be6ae26e9dd2ca1289e65b6153ff5b8800194969f1c53e3adc81aa4e47bf25c2f7e6aab7c

View file

@ -5,6 +5,7 @@
EAPI=5
EGIT_REPO_URI="https://github.com/vysheng/tg.git"
EGIT_BRANCH="test"
inherit git-2
IUSE="lua"
DESCRIPTION="Command line interface client for Telegram"
@ -17,14 +18,15 @@ DEPEND="sys-libs/zlib
sys-libs/readline
dev-libs/libconfig
dev-libs/openssl
dev-libs/libevent
lua? ( dev-lang/lua )"
src_configure() {
econf $(use_enable lua liblua ) --with-progname=telegram-cli
econf $(use_enable lua liblua )
}
src_install() {
newbin telegram telegram-cli
newbin bin/telegram-cli telegram-cli
insinto /etc/telegram-cli/
newins tg-server.pub server.pub

View file

@ -1 +0,0 @@
EBUILD telegram-cli-9999.ebuild 641 SHA256 4597e2f84c36b1ee02ecc415c399408bb8536b456e94370e996d57477db621be SHA512 287da263c9a4ba2058bf2f5844599432619053abc9249fd5725ed7b5e920c5c02e2493ad7b07f89177933b2c15394d939e7dc7dbf05d5873c32e55c9ec614d4c WHIRLPOOL 73dee37f91f1d4b747afc35c0a0cb2efb141d37702c71a7a9d188d2e1d727375c0ee3e7a1192e6c4c34f17ba1303f3a0be47b24272b5378ff255bce1a4a281be

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,25 @@
/*
This file is part of telegram-client.
This file is part of telegram-cli.
Telegram-client is free software: you can redistribute it and/or modify
Telegram-cli is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
Telegram-cli is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
along with this telegram-cli. If not, see <http://www.gnu.org/licenses/>.
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#ifndef __INTERFACE_H__
#define __INTERFACE_H__
#include "structures.h"
#include "tgl-layout.h"
#define COLOR_RED "\033[0;31m"
#define COLOR_REDB "\033[1;31m"
@ -37,25 +38,47 @@ 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 interpreter_ex (char *line, void *ex);
void rprintf (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);
struct message;
union peer;
void print_message (struct message *M);
void print_chat_name (peer_id_t id, union peer *C);
void print_user_name (peer_id_t id, union peer *U);
void print_encr_chat_name_full (peer_id_t id, peer_t *C);
void print_encr_chat_name (peer_id_t id, peer_t *C);
//void print_media (struct message_media *M);
#define vlogprintf(v,...) \
do { \
if (tgl_state.verbosity >= (v)) {\
logprintf (__VA_ARGS__);\
}\
} while (0);\
//void hexdump (int *in_ptr, int *in_end);
struct bufferevent;
struct in_ev {
struct bufferevent *bev;
char in_buf[4096];
int in_buf_pos;
int refcnt;
int error;
int fd;
};
struct tgl_message;
struct in_ev;
void print_message (struct in_ev *ev, struct tgl_message *M);
void print_chat_name (struct in_ev *ev, tgl_peer_id_t id, tgl_peer_t *C);
void print_user_name (struct in_ev *ev, tgl_peer_id_t id, tgl_peer_t *U);
void print_encr_chat_name_full (struct in_ev *ev, tgl_peer_id_t id, tgl_peer_t *C);
void print_encr_chat_name (struct in_ev *ev, tgl_peer_id_t id, tgl_peer_t *C);
//void print_media (struct tgl_message_media *M);
//
void pop_color (void);
void push_color (const char *color);
void print_start (void);
void print_end (void);
void print_date_full (long t);
void print_date (long t);
void print_date_full (struct in_ev *ev, long t);
void print_date (struct in_ev *ev, long t);
void play_sound (void);
void update_prompt (void);

948
loop.c

File diff suppressed because it is too large Load diff

11
loop.h
View file

@ -1,24 +1,25 @@
/*
This file is part of telegram-client.
This file is part of telegram-cli.
Telegram-client is free software: you can redistribute it and/or modify
Telegram-cli is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
Telegram-cli is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
along with this telegram-cli. If not, see <http://www.gnu.org/licenses/>.
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#ifndef __LOOP_H__
#define __LOOP_H__
int loop (void);
void do_halt (int error);
void net_loop (int flags, int (*end)(void));
void write_auth_file (void);
void write_state_file (void);

1265
lua-tg.c

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,34 @@
/*
This file is part of telegram-cli.
Telegram-cli is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Telegram-cli is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-cli. If not, see <http://www.gnu.org/licenses/>.
Copyright Vitaly Valtman 2013-2014
*/
#ifndef __LUA_TG_H__
#define __LUA_TG_H__
#include <string.h>
#include "structures.h"
#include "lua-tg.h"
#include "tgl.h"
void lua_init (const char *file);
void lua_new_msg (struct message *M);
void lua_new_msg (struct tgl_message *M);
void lua_our_id (int id);
void lua_secret_chat_created (struct secret_chat *U);
void lua_user_update (struct user *U);
void lua_chat_update (struct chat *C);
void lua_secret_chat_update (struct tgl_secret_chat *U, unsigned flags);
void lua_user_update (struct tgl_user *U, unsigned flags);
void lua_chat_update (struct tgl_chat *C, unsigned flags);
void lua_binlog_end (void);
void lua_diff_end (void);
void lua_do_all (void);

168
m4-ax_gcc_builtin.m4 Normal file
View file

@ -0,0 +1,168 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_gcc_builtin.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_BUILTIN(BUILTIN)
#
# DESCRIPTION
#
# This macro checks if the compiler supports one of GCC's built-in
# functions; many other compilers also provide those same built-ins.
#
# The BUILTIN parameter is the name of the built-in function.
#
# If BUILTIN is supported define HAVE_<BUILTIN>. Keep in mind that since
# builtins usually start with two underscores they will be copied over
# into the HAVE_<BUILTIN> definition (e.g. HAVE___BUILTIN_EXPECT for
# __builtin_expect()).
#
# The macro caches its result in the ax_cv_have_<BUILTIN> variable (e.g.
# ax_cv_have___builtin_expect).
#
# The macro currently supports the following built-in functions:
#
# __builtin_assume_aligned
# __builtin_bswap32
# __builtin_bswap64
# __builtin_choose_expr
# __builtin___clear_cache
# __builtin_clrsb
# __builtin_clrsbl
# __builtin_clrsbll
# __builtin_clz
# __builtin_clzl
# __builtin_clzll
# __builtin_complex
# __builtin_constant_p
# __builtin_ctz
# __builtin_ctzl
# __builtin_ctzll
# __builtin_expect
# __builtin_ffs
# __builtin_ffsl
# __builtin_ffsll
# __builtin_fpclassify
# __builtin_huge_val
# __builtin_huge_valf
# __builtin_huge_vall
# __builtin_inf
# __builtin_infd128
# __builtin_infd32
# __builtin_infd64
# __builtin_inff
# __builtin_infl
# __builtin_isinf_sign
# __builtin_nan
# __builtin_nand128
# __builtin_nand32
# __builtin_nand64
# __builtin_nanf
# __builtin_nanl
# __builtin_nans
# __builtin_nansf
# __builtin_nansl
# __builtin_object_size
# __builtin_parity
# __builtin_parityl
# __builtin_parityll
# __builtin_popcount
# __builtin_popcountl
# __builtin_popcountll
# __builtin_powi
# __builtin_powif
# __builtin_powil
# __builtin_prefetch
# __builtin_trap
# __builtin_types_compatible_p
# __builtin_unreachable
#
# Unsuppored built-ins will be tested with an empty parameter set and the
# result of the check might be wrong or meaningless so use with care.
#
# LICENSE
#
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 2
AC_DEFUN([AX_GCC_BUILTIN], [
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_$1])
AC_CACHE_CHECK([for $1], [ac_var], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [
m4_case([$1],
[__builtin_assume_aligned], [$1("", 0)],
[__builtin_bswap32], [$1(0)],
[__builtin_bswap64], [$1(0)],
[__builtin_choose_expr], [$1(0, 0, 0)],
[__builtin___clear_cache], [$1("", "")],
[__builtin_clrsb], [$1(0)],
[__builtin_clrsbl], [$1(0)],
[__builtin_clrsbll], [$1(0)],
[__builtin_clz], [$1(0)],
[__builtin_clzl], [$1(0)],
[__builtin_clzll], [$1(0)],
[__builtin_complex], [$1(0.0, 0.0)],
[__builtin_constant_p], [$1(0)],
[__builtin_ctz], [$1(0)],
[__builtin_ctzl], [$1(0)],
[__builtin_ctzll], [$1(0)],
[__builtin_expect], [$1(0, 0)],
[__builtin_ffs], [$1(0)],
[__builtin_ffsl], [$1(0)],
[__builtin_ffsll], [$1(0)],
[__builtin_fpclassify], [$1(0, 1, 2, 3, 4, 0.0)],
[__builtin_huge_val], [$1()],
[__builtin_huge_valf], [$1()],
[__builtin_huge_vall], [$1()],
[__builtin_inf], [$1()],
[__builtin_infd128], [$1()],
[__builtin_infd32], [$1()],
[__builtin_infd64], [$1()],
[__builtin_inff], [$1()],
[__builtin_infl], [$1()],
[__builtin_isinf_sign], [$1(0.0)],
[__builtin_nan], [$1("")],
[__builtin_nand128], [$1("")],
[__builtin_nand32], [$1("")],
[__builtin_nand64], [$1("")],
[__builtin_nanf], [$1("")],
[__builtin_nanl], [$1("")],
[__builtin_nans], [$1("")],
[__builtin_nansf], [$1("")],
[__builtin_nansl], [$1("")],
[__builtin_object_size], [$1("", 0)],
[__builtin_parity], [$1(0)],
[__builtin_parityl], [$1(0)],
[__builtin_parityll], [$1(0)],
[__builtin_popcount], [$1(0)],
[__builtin_popcountl], [$1(0)],
[__builtin_popcountll], [$1(0)],
[__builtin_powi], [$1(0, 0)],
[__builtin_powif], [$1(0, 0)],
[__builtin_powil], [$1(0, 0)],
[__builtin_prefetch], [$1("")],
[__builtin_trap], [$1()],
[__builtin_types_compatible_p], [$1(int, int)],
[__builtin_unreachable], [$1()],
[m4_warn([syntax], [Unsupported built-in $1, the test may fail])
$1()]
)
])],
[AS_VAR_SET([ac_var], [yes])],
[AS_VAR_SET([ac_var], [no])])
])
AS_IF([test yes = AS_VAR_GET([ac_var])],
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1), 1,
[Define to 1 if the system has the `$1' built-in function])], [])
AS_VAR_POPDEF([ac_var])
])

124
m4_ax_check_openssl.m4 Normal file
View file

@ -0,0 +1,124 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_check_openssl.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_OPENSSL([action-if-found[, action-if-not-found]])
#
# DESCRIPTION
#
# Look for OpenSSL in a number of default spots, or in a user-selected
# spot (via --with-openssl). Sets
#
# OPENSSL_INCLUDES to the include directives required
# OPENSSL_LIBS to the -l directives required
# OPENSSL_LDFLAGS to the -L or -R flags required
#
# and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately
#
# This macro sets OPENSSL_INCLUDES such that source files should use the
# openssl/ directory in include directives:
#
# #include <openssl/hmac.h>
#
# LICENSE
#
# Copyright (c) 2009,2010 Zmanda Inc. <http://www.zmanda.com/>
# Copyright (c) 2009,2010 Dustin J. Mitchell <dustin@zmanda.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 8
AU_ALIAS([CHECK_SSL], [AX_CHECK_OPENSSL])
AC_DEFUN([AX_CHECK_OPENSSL], [
found=false
AC_ARG_WITH([openssl],
[AS_HELP_STRING([--with-openssl=DIR],
[root of the OpenSSL directory])],
[
case "$withval" in
"" | y | ye | yes | n | no)
AC_MSG_ERROR([Invalid --with-openssl value])
;;
*) ssldirs="$withval"
;;
esac
], [
# if pkg-config is installed and openssl has installed a .pc file,
# then use that information and don't search ssldirs
AC_PATH_PROG([PKG_CONFIG], [pkg-config])
if test x"$PKG_CONFIG" != x""; then
OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null`
if test $? = 0; then
OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null`
OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null`
found=true
fi
fi
# no such luck; use some default ssldirs
if ! $found; then
ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr"
fi
]
)
# note that we #include <openssl/foo.h>, so the OpenSSL headers have to be in
# an 'openssl' subdirectory
if ! $found; then
OPENSSL_INCLUDES=
for ssldir in $ssldirs; do
AC_MSG_CHECKING([for openssl/ssl.h in $ssldir])
if test -f "$ssldir/include/openssl/ssl.h"; then
OPENSSL_INCLUDES="-I$ssldir/include"
OPENSSL_LDFLAGS="-L$ssldir/lib"
OPENSSL_LIBS="-lssl -lcrypto"
found=true
AC_MSG_RESULT([yes])
break
else
AC_MSG_RESULT([no])
fi
done
# if the file wasn't found, well, go ahead and try the link anyway -- maybe
# it will just work!
fi
# try the preprocessor and linker with our new flags,
# being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS
AC_MSG_CHECKING([whether compiling and linking against OpenSSL works])
echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \
"OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&AS_MESSAGE_LOG_FD
save_LIBS="$LIBS"
save_LDFLAGS="$LDFLAGS"
save_CPPFLAGS="$CPPFLAGS"
LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS"
LIBS="$OPENSSL_LIBS $LIBS"
CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([#include <openssl/ssl.h>], [SSL_new(NULL)])],
[
AC_MSG_RESULT([yes])
$1
], [
AC_MSG_RESULT([no])
$2
])
CPPFLAGS="$save_CPPFLAGS"
LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
AC_SUBST([OPENSSL_INCLUDES])
AC_SUBST([OPENSSL_LIBS])
AC_SUBST([OPENSSL_LDFLAGS])
])

142
m4_ax_check_zlib.m4 Normal file
View file

@ -0,0 +1,142 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_check_zlib.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_ZLIB([action-if-found], [action-if-not-found])
#
# DESCRIPTION
#
# This macro searches for an installed zlib library. If nothing was
# specified when calling configure, it searches first in /usr/local and
# then in /usr, /opt/local and /sw. If the --with-zlib=DIR is specified,
# it will try to find it in DIR/include/zlib.h and DIR/lib/libz.a. If
# --without-zlib is specified, the library is not searched at all.
#
# If either the header file (zlib.h) or the library (libz) is not found,
# shell commands 'action-if-not-found' is run. If 'action-if-not-found' is
# not specified, the configuration exits on error, asking for a valid zlib
# installation directory or --without-zlib.
#
# If both header file and library are found, shell commands
# 'action-if-found' is run. If 'action-if-found' is not specified, the
# default action appends '-I${ZLIB_HOME}/include' to CPFLAGS, appends
# '-L$ZLIB_HOME}/lib' to LDFLAGS, prepends '-lz' to LIBS, and calls
# AC_DEFINE(HAVE_LIBZ). You should use autoheader to include a definition
# for this symbol in a config.h file. Sample usage in a C/C++ source is as
# follows:
#
# #ifdef HAVE_LIBZ
# #include <zlib.h>
# #endif /* HAVE_LIBZ */
#
# LICENSE
#
# Copyright (c) 2008 Loic Dachary <loic@senga.org>
# Copyright (c) 2010 Bastien Chevreux <bach@chevreux.org>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 14
AU_ALIAS([CHECK_ZLIB], [AX_CHECK_ZLIB])
AC_DEFUN([AX_CHECK_ZLIB],
#
# Handle user hints
#
[AC_MSG_CHECKING(if zlib is wanted)
zlib_places="/usr/local /usr /opt/local /sw"
AC_ARG_WITH([zlib],
[ --with-zlib=DIR root directory path of zlib installation @<:@defaults to
/usr/local or /usr if not found in /usr/local@:>@
--without-zlib to disable zlib usage completely],
[if test "$withval" != no ; then
AC_MSG_RESULT(yes)
if test -d "$withval"
then
zlib_places="$withval $zlib_places"
else
AC_MSG_WARN([Sorry, $withval does not exist, checking usual places])
fi
else
zlib_places=
AC_MSG_RESULT(no)
fi],
[AC_MSG_RESULT(yes)])
#
# Locate zlib, if wanted
#
if test -n "${zlib_places}"
then
# check the user supplied or any other more or less 'standard' place:
# Most UNIX systems : /usr/local and /usr
# MacPorts / Fink on OSX : /opt/local respectively /sw
for ZLIB_HOME in ${zlib_places} ; do
if test -f "${ZLIB_HOME}/include/zlib.h"; then break; fi
ZLIB_HOME=""
done
ZLIB_OLD_LDFLAGS=$LDFLAGS
ZLIB_OLD_CPPFLAGS=$CPPFLAGS
if test -n "${ZLIB_HOME}"; then
LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
fi
AC_LANG_SAVE
AC_LANG_C
AC_CHECK_LIB([z], [inflateEnd], [zlib_cv_libz=yes], [zlib_cv_libz=no])
AC_CHECK_HEADER([zlib.h], [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no])
AC_LANG_RESTORE
if test "$zlib_cv_libz" = "yes" && test "$zlib_cv_zlib_h" = "yes"
then
#
# If both library and header were found, action-if-found
#
m4_ifblank([$1],[
CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
LIBS="-lz $LIBS"
AC_DEFINE([HAVE_LIBZ], [1],
[Define to 1 if you have `z' library (-lz)])
],[
# Restore variables
LDFLAGS="$ZLIB_OLD_LDFLAGS"
CPPFLAGS="$ZLIB_OLD_CPPFLAGS"
$1
])
else
#
# If either header or library was not found, action-if-not-found
#
m4_default([$2],[
AC_MSG_ERROR([either specify a valid zlib installation with --with-zlib=DIR or disable zlib usage with --without-zlib])
])
fi
fi
])

482
main.c
View file

@ -1,20 +1,20 @@
/*
This file is part of telegram-client.
This file is part of telegram-cli.
Telegram-client is free software: you can redistribute it and/or modify
Telegram-cli is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
Telegram-cli is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
along with this telegram-cli. If not, see <http://www.gnu.org/licenses/>.
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#ifdef HAVE_CONFIG_H
@ -34,8 +34,18 @@
#else
#include <editline/readline.h>
#endif
#ifdef EVENT_V2
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#else
#include <event.h>
#include "event-old.h"
#endif
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <fcntl.h>
@ -47,9 +57,11 @@
#include <libconfig.h>
#endif
#include <grp.h>
#include <arpa/inet.h>
#include "telegram.h"
#include "loop.h"
#include "mtproto-client.h"
#include "interface.h"
#include "tools.h"
@ -57,8 +69,10 @@
# include "lua-tg.h"
#endif
#define PROGNAME "telegram-client"
#define VERSION "0.01"
#include "tgl.h"
#define PROGNAME "telegram-cli"
#define VERSION "0.07"
#define CONFIG_DIRECTORY "." PROG_NAME
#define CONFIG_FILE "config"
@ -68,28 +82,34 @@
#define DOWNLOADS_DIRECTORY "downloads"
#define BINLOG_FILE "binlog"
#define CONFIG_DIRECTORY_MODE 0700
#define DEFAULT_CONFIG_CONTENTS \
"# This is an empty config file\n" \
"# Feel free to put something here\n"
char *default_username;
char *auth_token;
int verbosity;
int msg_num_mode;
char *default_username;
char *config_filename;
char *prefix;
int test_dc;
char *auth_file_name;
char *state_file_name;
char *secret_chat_file_name;
char *downloads_directory;
char *config_directory;
char *binlog_file_name;
char *lua_file;
int binlog_enabled;
extern int log_level;
int sync_from_start;
int allow_weak_random;
int disable_colors;
int readline_disabled;
int disable_output;
int reset_authorization;
int port;
void set_default_username (const char *s) {
if (default_username) {
@ -214,7 +234,9 @@ void running_for_first_time (void) {
//char *downloads_directory = get_downloads_directory ();
if (!mkdir (config_directory, CONFIG_DIRECTORY_MODE)) {
printf ("[%s] created\n", config_directory);
if (!disable_output) {
printf ("[%s] created\n", config_directory);
}
}
tfree_str (config_directory);
@ -267,16 +289,16 @@ void parse_config_val (config_t *conf, char **s, char *param_name, const char *d
*s = tstrdup (r);
}
} else {
if (path) {
if (path && default_name) {
tasprintf (s, "%s/%s", path, default_name);
} else {
*s = tstrdup (default_name);
*s = default_name ? tstrdup (default_name) : 0;
}
}
}
void parse_config (void) {
config_filename = make_full_path (config_filename);
//config_filename = make_full_path (config_filename);
config_t conf;
config_init (&conf);
@ -296,9 +318,13 @@ void parse_config (void) {
memcpy (buf, prefix, l);
buf[l ++] = '.';
}
test_dc = 0;
int test_mode = 0;
strcpy (buf + l, "test");
config_lookup_bool (&conf, buf, &test_dc);
config_lookup_bool (&conf, buf, &test_mode);
if (test_mode) {
tgl_set_test_mode ();
}
strcpy (buf + l, "log_level");
long long t = log_level;
@ -314,29 +340,65 @@ 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);
if (!lua_file) {
parse_config_val (&conf, &lua_file, "lua_script", 0, config_directory);
}
strcpy (buf + l, "binlog_enabled");
config_lookup_bool (&conf, buf, &binlog_enabled);
int pfs_enabled = 0;
strcpy (buf + l, "pfs_enabled");
config_lookup_bool (&conf, buf, &pfs_enabled);
if (pfs_enabled) {
tgl_enable_pfs ();
}
if (binlog_enabled) {
parse_config_val (&conf, &binlog_file_name, "binlog", BINLOG_FILE, config_directory);
tgl_set_binlog_mode (1);
tgl_set_binlog_path (binlog_file_name);
} else {
tgl_set_binlog_mode (0);
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);
//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);
if (!disable_output) {
printf ("[%s] created\n", config_directory);
}
}
if (!mkdir (downloads_directory, CONFIG_DIRECTORY_MODE)) {
printf ("[%s] created\n", downloads_directory);
if (!disable_output) {
printf ("[%s] created\n", downloads_directory);
}
}
config_destroy (&conf);
}
#else
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);
if (!disable_output) {
printf ("libconfig not enabled\n");
}
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) {
tasprintf (&binlog_file_name, "%s/%s/%s", get_home_directory (), CONFIG_DIRECTORY, BINLOG_FILE);
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;
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);
}
tgl_set_download_directory (downloads_directory);
}
#endif
@ -346,31 +408,42 @@ void inner_main (void) {
void usage (void) {
printf ("%s Usage\n", PROGNAME);
printf (" -h this help list\n");
printf (" -u username specify username\n");
printf (" -k public-key specify server public key\n");
printf (" -v verbose\n");
printf (" -l [1-3] log level\n");
printf (" -L log-file log net file\n");
printf (" -N message num mode\n");
printf (" -c config-file specify config file\n");
printf (" -p prefix specify prefix\n");
printf (" -R register mode\n");
printf (" -f sync from start\n");
printf (" -B enable binlog\n");
printf (" -E disable auto accept\n");
printf (" -w allow weak random\n");
printf (" -s specify lua script\n");
printf (" -W wait dialog list\n");
printf ("\n");
printf (" -u specify username (would not be asked during authorization)\n");
printf (" -k specify location of public key (possible multiple entries)\n");
printf (" -v increase verbosity (0-ERROR 1-WARNIN 2-NOTICE 3+-DEBUG-levels)\n");
printf (" -N message num mode\n");
#ifdef HAVE_LIBCONFIG
printf (" -c config file name\n");
printf (" -p use specified profile\n");
#else
printf (" -B enable binlog\n");
#endif
printf (" -l log level\n");
printf (" -f during authorization fetch all messages since registration\n");
printf (" -E diable auto accept of encrypted chats\n");
#ifdef USE_LUA
printf (" -s lua script file\n");
#endif
printf (" -W send dialog_list query and wait for answer before reading input\n");
printf (" -C disable color output\n");
printf (" -R disable readline\n");
printf (" -d daemon mode\n");
printf (" -L <log-name> log file name\n");
printf (" -U <user-name> change uid after start\n");
printf (" -G <group-name> change gid after start\n");
printf (" -D disable output\n");
printf (" -P <port> port to listen for input commands\n");
printf (" -S <socket-name> unix socket to create\n");
exit (1);
}
extern char *rsa_public_key_name;
extern int verbosity;
extern int default_dc_num;
//extern char *rsa_public_key_name;
//extern int default_dc_num;
char *log_net_file;
FILE *log_net_f;
@ -379,24 +452,118 @@ int register_mode;
int disable_auto_accept;
int wait_dialog_list;
char *lua_file;
char *logname;
int daemonize;
void reopen_logs (void) {
int fd;
fflush (stdout);
fflush (stderr);
if ((fd = open ("/dev/null", O_RDWR, 0)) != -1) {
dup2 (fd, 0);
dup2 (fd, 1);
dup2 (fd, 2);
if (fd > 2) {
close (fd);
}
}
if (logname && (fd = open (logname, O_WRONLY|O_APPEND|O_CREAT, 0640)) != -1) {
dup2 (fd, 1);
dup2 (fd, 2);
if (fd > 2) {
close (fd);
}
}
}
static void sigusr1_handler (const int sig) {
fprintf(stderr, "got SIGUSR1, rotate logs.\n");
reopen_logs ();
signal (SIGUSR1, sigusr1_handler);
}
static void sighup_handler (const int sig) {
fprintf(stderr, "got SIGHUP.\n");
signal (SIGHUP, sighup_handler);
}
char *set_user_name;
char *set_group_name;
int change_user_group () {
char *username = set_user_name;
char *groupname = set_group_name;
struct passwd *pw;
/* lose root privileges if we have them */
if (getuid() == 0 || geteuid() == 0) {
if (username == 0 || *username == '\0') {
username = "telegramd";
}
if ((pw = getpwnam (username)) == 0) {
fprintf (stderr, "change_user_group: can't find the user %s to switch to\n", username);
return -1;
}
gid_t gid = pw->pw_gid;
if (setgroups (1, &gid) < 0) {
fprintf (stderr, "change_user_group: failed to clear supplementary groups list: %m\n");
return -1;
}
if (groupname) {
struct group *g = getgrnam (groupname);
if (g == NULL) {
fprintf (stderr, "change_user_group: can't find the group %s to switch to\n", groupname);
return -1;
}
gid = g->gr_gid;
}
if (setgid (gid) < 0) {
fprintf (stderr, "change_user_group: setgid (%d) failed. %m\n", (int) gid);
return -1;
}
if (setuid (pw->pw_uid) < 0) {
fprintf (stderr, "change_user_group: failed to assume identity of user %s\n", username);
return -1;
}
}
return 0;
}
char *unix_socket;
void args_parse (int argc, char **argv) {
int opt = 0;
while ((opt = getopt (argc, argv, "u:hk:vn:Nc:p:l:RfBL:Es:wW")) != -1) {
while ((opt = getopt (argc, argv, "u:hk:vNl:fEwWCRdL:DU:G:qP:S:"
#ifdef HAVE_LIBCONFIG
"c:p:"
#else
"B"
#endif
#ifdef USE_LUA
"s:"
#endif
)) != -1) {
switch (opt) {
case 'u':
set_default_username (optarg);
break;
case 'k':
rsa_public_key_name = tstrdup (optarg);
//rsa_public_key_name = tstrdup (optarg);
tgl_set_rsa_key (optarg);
break;
case 'v':
tgl_incr_verbosity ();
verbosity ++;
break;
case 'N':
msg_num_mode ++;
break;
#ifdef HAVE_LIBCONFIG
case 'c':
config_filename = tstrdup (optarg);
break;
@ -404,25 +571,16 @@ void args_parse (int argc, char **argv) {
prefix = tstrdup (optarg);
assert (strlen (prefix) <= 100);
break;
case 'l':
log_level = atoi (optarg);
break;
case 'R':
register_mode = 1;
break;
case 'f':
sync_from_start = 1;
break;
#else
case 'B':
binlog_enabled = 1;
break;
case 'L':
if (log_net_file) {
usage ();
}
log_net_file = tstrdup (optarg);
log_net_f = fopen (log_net_file, "a");
assert (log_net_f);
#endif
case 'l':
log_level = atoi (optarg);
break;
case 'f':
sync_from_start = 1;
break;
case 'E':
disable_auto_accept = 1;
@ -430,12 +588,44 @@ void args_parse (int argc, char **argv) {
case 'w':
allow_weak_random = 1;
break;
#ifdef USE_LUA
case 's':
lua_file = tstrdup (optarg);
lua_file = strdup (optarg);
break;
#endif
case 'W':
wait_dialog_list = 1;
break;
case 'C':
disable_colors ++;
break;
case 'R':
readline_disabled ++;
break;
case 'd':
daemonize ++;
break;
case 'L':
logname = optarg;
break;
case 'U':
set_user_name = optarg;
break;
case 'G':
set_group_name = optarg;
break;
case 'D':
disable_output ++;
break;
case 'q':
reset_authorization ++;
break;
case 'P':
port = atoi (optarg);
break;
case 'S':
unix_socket = optarg;
break;
case 'h':
default:
usage ();
@ -458,40 +648,164 @@ void print_backtrace (void) {
}
#endif
void sig_segv_handler (int signum __attribute__ ((unused))) {
set_terminal_attributes ();
if (write (1, "SIGSEGV received\n", 18) < 0) {
int sfd;
int usfd;
void termination_signal_handler (int signum) {
if (!readline_disabled) {
rl_free_line_state ();
rl_cleanup_after_signal ();
}
if (write (1, "SIGNAL received\n", 18) < 0) {
// Sad thing
}
if (unix_socket) {
unlink (unix_socket);
}
if (usfd > 0) {
close (usfd);
}
if (sfd > 0) {
close (sfd);
}
print_backtrace ();
exit (EXIT_FAILURE);
}
void sig_abrt_handler (int signum __attribute__ ((unused))) {
set_terminal_attributes ();
if (write (1, "SIGABRT received\n", 18) < 0) {
volatile int sigterm_cnt;
void sig_term_handler (int signum __attribute__ ((unused))) {
signal (signum, termination_signal_handler);
//set_terminal_attributes ();
if (write (1, "SIGTERM/SIGINT received\n", 25) < 0) {
// Sad thing
}
print_backtrace ();
exit (EXIT_FAILURE);
if (tgl_state.ev_base) {
event_base_loopbreak(tgl_state.ev_base);
}
sigterm_cnt ++;
}
void do_halt (int error) {
if (!readline_disabled) {
rl_free_line_state ();
rl_cleanup_after_signal ();
}
if (write (1, "halt\n", 5) < 0) {
// Sad thing
}
if (unix_socket) {
unlink (unix_socket);
}
if (usfd > 0) {
close (usfd);
}
if (sfd > 0) {
close (sfd);
}
exit (error ? EXIT_FAILURE : EXIT_SUCCESS);
}
int main (int argc, char **argv) {
signal (SIGSEGV, sig_segv_handler);
signal (SIGABRT, sig_abrt_handler);
signal (SIGSEGV, termination_signal_handler);
signal (SIGABRT, termination_signal_handler);
signal (SIGBUS, termination_signal_handler);
signal (SIGQUIT, termination_signal_handler);
signal (SIGFPE, termination_signal_handler);
signal (SIGPIPE, SIG_IGN);
signal (SIGTERM, sig_term_handler);
signal (SIGINT, sig_term_handler);
rl_catch_signals = 0;
log_level = 10;
args_parse (argc, argv);
printf (
"Telegram-client version " TG_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"
);
change_user_group ();
if (port > 0) {
struct sockaddr_in serv_addr;
sfd = socket (AF_INET, SOCK_STREAM, 0);
if (sfd < 0) {
perror ("socket");
exit(1);
}
memset (&serv_addr, 0, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl (0x7f000001);
serv_addr.sin_port = htons (port);
if (bind (sfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
perror ("bind");
exit(1);
}
listen (sfd, 5);
} else {
sfd = -1;
}
if (unix_socket) {
assert (strlen (unix_socket) < 100);
struct sockaddr_un serv_addr;
usfd = socket (AF_UNIX, SOCK_STREAM, 0);
if (usfd < 0) {
perror ("socket");
exit(1);
}
memset (&serv_addr, 0, sizeof (serv_addr));
serv_addr.sun_family = AF_UNIX;
snprintf (serv_addr.sun_path, 108, "%s", unix_socket);
if (bind (usfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
perror ("bind");
exit(1);
}
listen (usfd, 5);
} else {
usfd = -1;
}
if (daemonize) {
signal (SIGHUP, sighup_handler);
reopen_logs ();
}
signal (SIGUSR1, sigusr1_handler);
if (!disable_output) {
printf (
"Telegram-cli version " TGL_VERSION ", Copyright (C) 2013-2014 Vitaly Valtman\n"
"Telegram-cli 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"
);
}
running_for_first_time ();
parse_config ();
tgl_set_rsa_key ("/etc/" PROG_NAME "/server.pub");
tgl_set_rsa_key ("tg-server.pub");
get_terminal_attributes ();

File diff suppressed because it is too large Load diff

View file

@ -1,33 +1,60 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Nikolay Durov, Andrey Lopatin 2012-2013
Copyright Vitaly Valtman 2013
Vitaly Valtman 2013-2014
*/
#ifndef __MTPROTO_CLIENT_H__
#define __MTPROTO_CLIENT_H__
#include "net.h"
//#include "net.h"
#include <openssl/bn.h>
void on_start (void);
long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful);
void dc_authorize (struct dc *DC);
void work_update (struct connection *c, long long msg_id);
void work_update_binlog (void);
int check_g (unsigned char p[256], BIGNUM *g);
int check_g_bn (BIGNUM *p, BIGNUM *g);
int check_DH_params (BIGNUM *p, int g);
void secure_random (void *s, int l);
//void on_start (void);
//..long long encrypt_send_message (struct connection *c, int *msg, int msg_ints, int useful);
//void dc_authorize (struct tgl_dc *DC);
//void work_update (struct connection *c, long long msg_id);
//void work_update_binlog (void);
//int check_g (unsigned char p[256], BIGNUM *g);
//int check_g_bn (BIGNUM *p, BIGNUM *g);
//int check_DH_params (BIGNUM *p, int g);
//void secure_random (void *s, int l);
#include "tgl.h"
struct connection;
struct tgl_dc;
//#include "queries.h"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define ACK_TIMEOUT 1
#define MAX_DC_ID 10
struct connection;
long long tglmp_encrypt_send_message (struct connection *c, int *msg, int msg_ints, int flags);
void tglmp_dc_create_session (struct tgl_dc *DC);
int tglmp_check_g (unsigned char p[256], BIGNUM *g);
int tglmp_check_DH_params (BIGNUM *p, int g);
struct tgl_dc *tglmp_alloc_dc (int id, char *ip, int port);
void tglmp_regenerate_temp_auth_key (struct tgl_dc *D);
void tgln_insert_msg_id (struct tgl_session *S, long long id);
void tglmp_on_start (void);
void tgl_dc_authorize (struct tgl_dc *DC);
void tgls_free_dc (struct tgl_dc *DC);
void tgls_free_pubkey (void);
#endif

View file

@ -1,21 +1,22 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Nikolay Durov, Andrey Lopatin 2012-2013
Copyright Vitaly Valtman 2013
Vitaly Valtman 2013-2014
*/
#ifdef HAVE_CONFIG_H
@ -39,8 +40,8 @@
#include <openssl/sha.h>
#include "mtproto-common.h"
#include "interface.h"
#include "include.h"
#include "tools.h"
#ifdef __MACH__
#include <mach/clock.h>
@ -48,22 +49,20 @@
#endif
int __packet_buffer[PACKET_BUFFER_SIZE], *packet_ptr;
int *packet_buffer = __packet_buffer + 16;
static int __packet_buffer[PACKET_BUFFER_SIZE + 16];
int *tgl_packet_ptr;
int *tgl_packet_buffer = __packet_buffer + 16;
long long rsa_encrypted_chunks, rsa_decrypted_chunks;
static long long rsa_encrypted_chunks, rsa_decrypted_chunks;
BN_CTX *BN_ctx;
int verbosity;
//int verbosity;
int get_random_bytes (unsigned char *buf, int n) {
static int get_random_bytes (unsigned char *buf, int n) {
int r = 0, h = open ("/dev/random", O_RDONLY | O_NONBLOCK);
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;
}
@ -90,20 +89,6 @@ int get_random_bytes (unsigned char *buf, int n) {
return r;
}
void my_clock_gettime (int clock_id UU, struct timespec *T) {
#ifdef __MACH__
// We are ignoring MONOTONIC and hope time doesn't go back to often
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
T->tv_sec = mts.tv_sec;
T->tv_nsec = mts.tv_nsec;
#else
assert (clock_gettime(clock_id, T) >= 0);
#endif
}
/* RDTSC */
#if defined(__i386__)
@ -122,9 +107,9 @@ static __inline__ unsigned long long rdtsc (void) {
}
#endif
void prng_seed (const char *password_filename, int password_length) {
void tgl_prng_seed (const char *password_filename, int password_length) {
struct timespec T;
my_clock_gettime (CLOCK_REALTIME, &T);
tgl_my_clock_gettime (CLOCK_REALTIME, &T);
RAND_add (&T, sizeof (T), 4.0);
#ifdef HAVE_RDTSC
unsigned long long r = rdtsc ();
@ -143,27 +128,25 @@ 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);
tfree_secure (a, password_length);
}
}
BN_ctx = BN_CTX_new ();
ensure_ptr (BN_ctx);
tgl_state.BN_ctx = BN_CTX_new ();
ensure_ptr (tgl_state.BN_ctx);
}
int serialize_bignum (BIGNUM *b, char *buffer, int maxlen) {
int tgl_serialize_bignum (BIGNUM *b, char *buffer, int maxlen) {
int itslen = BN_num_bytes (b);
int reqlen;
if (itslen < 254) {
@ -193,19 +176,19 @@ int serialize_bignum (BIGNUM *b, char *buffer, int maxlen) {
}
long long compute_rsa_key_fingerprint (RSA *key) {
long long tgl_do_compute_rsa_key_fingerprint (RSA *key) {
static char tempbuff[4096];
static unsigned char sha[20];
assert (key->n && key->e);
int l1 = serialize_bignum (key->n, tempbuff, 4096);
int l1 = tgl_serialize_bignum (key->n, tempbuff, 4096);
assert (l1 > 0);
int l2 = serialize_bignum (key->e, tempbuff + l1, 4096 - l1);
int l2 = tgl_serialize_bignum (key->e, tempbuff + l1, 4096 - l1);
assert (l2 > 0 && l1 + l2 <= 4096);
SHA1 ((unsigned char *)tempbuff, l1 + l2, sha);
return *(long long *)(sha + 12);
}
void out_cstring (const char *str, long len) {
void tgl_out_cstring (const char *str, long len) {
assert (len >= 0 && len < (1 << 24));
assert ((char *) packet_ptr + len + 8 < (char *) (packet_buffer + PACKET_BUFFER_SIZE));
char *dest = (char *) packet_ptr;
@ -223,7 +206,7 @@ void out_cstring (const char *str, long len) {
packet_ptr = (int *) dest;
}
void out_cstring_careful (const char *str, long len) {
void tgl_out_cstring_careful (const char *str, long len) {
assert (len >= 0 && len < (1 << 24));
assert ((char *) packet_ptr + len + 8 < (char *) (packet_buffer + PACKET_BUFFER_SIZE));
char *dest = (char *) packet_ptr;
@ -248,16 +231,16 @@ void out_cstring_careful (const char *str, long len) {
}
void out_data (const void *data, long len) {
void tgl_out_data (const void *data, long len) {
assert (len >= 0 && len < (1 << 24) && !(len & 3));
assert ((char *) packet_ptr + len + 8 < (char *) (packet_buffer + PACKET_BUFFER_SIZE));
memcpy (packet_ptr, data, len);
packet_ptr += len >> 2;
}
int *in_ptr, *in_end;
int *tgl_in_ptr, *tgl_in_end;
int fetch_bignum (BIGNUM *x) {
int tgl_fetch_bignum (BIGNUM *x) {
int l = prefetch_strlen ();
if (l < 0) {
return l;
@ -267,7 +250,7 @@ int fetch_bignum (BIGNUM *x) {
return l;
}
int pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *E) {
int tgl_pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *E) {
int pad = (255000 - from_len - 32) % 255 + 32;
int chunks = (from_len + pad) / 255;
int bits = BN_num_bits (N);
@ -282,7 +265,7 @@ int pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BI
rsa_encrypted_chunks += chunks;
for (i = 0; i < chunks; i++) {
BN_bin2bn ((unsigned char *) from, 255, &x);
assert (BN_mod_exp (&y, &x, E, N, BN_ctx) == 1);
assert (BN_mod_exp (&y, &x, E, N, tgl_state.BN_ctx) == 1);
unsigned l = 256 - BN_num_bytes (&y);
assert (l <= 256);
memset (to, 0, l);
@ -294,7 +277,7 @@ int pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BI
return chunks * 256;
}
int pad_rsa_decrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *D) {
int tgl_pad_rsa_decrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *D) {
if (from_len < 0 || from_len > 0x1000 || (from_len & 0xff)) {
return -1;
}
@ -309,7 +292,7 @@ int pad_rsa_decrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BI
for (i = 0; i < chunks; i++) {
++rsa_decrypted_chunks;
BN_bin2bn ((unsigned char *) from, 256, &x);
assert (BN_mod_exp (&y, &x, D, N, BN_ctx) == 1);
assert (BN_mod_exp (&y, &x, D, N, tgl_state.BN_ctx) == 1);
int l = BN_num_bytes (&y);
if (l > 255) {
BN_free (&x);
@ -326,10 +309,10 @@ int pad_rsa_decrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BI
return chunks * 255;
}
unsigned char aes_key_raw[32], aes_iv[32];
AES_KEY aes_key;
static unsigned char aes_key_raw[32], aes_iv[32];
static AES_KEY aes_key;
void init_aes_unauth (const char server_nonce[16], const char hidden_client_nonce[32], int encrypt) {
void tgl_init_aes_unauth (const char server_nonce[16], const char hidden_client_nonce[32], int encrypt) {
static unsigned char buffer[64], hash[20];
memcpy (buffer, hidden_client_nonce, 32);
memcpy (buffer + 32, server_nonce, 16);
@ -350,7 +333,7 @@ void init_aes_unauth (const char server_nonce[16], const char hidden_client_nonc
memset (aes_key_raw, 0, sizeof (aes_key_raw));
}
void init_aes_auth (char auth_key[192], char msg_key[16], int encrypt) {
void tgl_init_aes_auth (char auth_key[192], char msg_key[16], int encrypt) {
static unsigned char buffer[48], hash[20];
// sha1_a = SHA1 (msg_key + substr (auth_key, 0, 32));
// sha1_b = SHA1 (substr (auth_key, 32, 16) + msg_key + substr (auth_key, 48, 16));
@ -390,7 +373,7 @@ void init_aes_auth (char auth_key[192], char msg_key[16], int encrypt) {
memset (aes_key_raw, 0, sizeof (aes_key_raw));
}
int pad_aes_encrypt (char *from, int from_len, char *to, int size) {
int tgl_pad_aes_encrypt (char *from, int from_len, char *to, int size) {
int padded_size = (from_len + 15) & -16;
assert (from_len > 0 && padded_size <= size);
if (from_len < padded_size) {
@ -400,7 +383,7 @@ int pad_aes_encrypt (char *from, int from_len, char *to, int size) {
return padded_size;
}
int pad_aes_decrypt (char *from, int from_len, char *to, int size) {
int tgl_pad_aes_decrypt (char *from, int from_len, char *to, int size) {
if (from_len <= 0 || from_len > size || (from_len & 15)) {
return -1;
}

View file

@ -1,21 +1,22 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Nikolay Durov, Andrey Lopatin 2012-2013
Copyright Vitaly Valtman 2013
Vitaly Valtman 2013-2014
*/
#ifndef __MTPROTO_COMMON_H__
#define __MTPROTO_COMMON_H__
@ -25,15 +26,20 @@
#include <openssl/bn.h>
#include <openssl/aes.h>
#include <stdio.h>
#include <assert.h>
#include "interface.h"
//#include "interface.h"
#include "tools.h"
#include "constants.h"
#include "auto/constants.h"
#include "tgl.h"
#include "tgl-inner.h"
/* DH key exchange protocol data structures */
#define CODE_req_pq 0x60469778
#define CODE_resPQ 0x05162463
#define CODE_req_DH_params 0xd712e4be
#define CODE_p_q_inner_data 0x83c95aec
#define CODE_p_q_inner_data_temp 0x3c6a84d4
#define CODE_server_DH_inner_data 0xb5890dba
#define CODE_server_DH_params_fail 0x79cb045d
#define CODE_server_DH_params_ok 0xd0e8075c
@ -43,6 +49,8 @@
#define CODE_dh_gen_retry 0x46dc1fb9
#define CODE_dh_gen_fail 0xa69dae02
#define CODE_bind_auth_key_inner 0x75a3f765
/* service messages */
#define CODE_rpc_result 0xf35c6d01
#define CODE_rpc_error 0x2144ca19
@ -107,14 +115,17 @@ struct encrypted_message {
#pragma pack(pop)
BN_CTX *BN_ctx;
//BN_CTX *BN_ctx;
void prng_seed (const char *password_filename, int password_length);
int serialize_bignum (BIGNUM *b, char *buffer, int maxlen);
long long compute_rsa_key_fingerprint (RSA *key);
void tgl_prng_seed (const char *password_filename, int password_length);
int tgl_serialize_bignum (BIGNUM *b, char *buffer, int maxlen);
long long tgl_do_compute_rsa_key_fingerprint (RSA *key);
extern int *packet_buffer;
extern int *packet_ptr;
#define packet_buffer tgl_packet_buffer
#define packet_ptr tgl_packet_ptr
extern int *tgl_packet_buffer;
extern int *tgl_packet_ptr;
static inline void out_ints (const int *what, int len) {
assert (packet_ptr + len <= packet_buffer + PACKET_BUFFER_SIZE);
@ -135,30 +146,43 @@ static inline void out_long (long long x) {
packet_ptr += 2;
}
static inline void out_double (double x) {
assert (packet_ptr + 2 <= packet_buffer + PACKET_BUFFER_SIZE);
*(double *)packet_ptr = x;
packet_ptr += 2;
}
static inline void clear_packet (void) {
packet_ptr = packet_buffer;
}
void out_cstring (const char *str, long len);
void out_cstring_careful (const char *str, long len);
void out_data (const void *data, long len);
void tgl_out_cstring (const char *str, long len);
void tgl_out_cstring_careful (const char *str, long len);
void tgl_out_data (const void *data, long len);
#define out_cstring tgl_out_cstring
#define out_cstring_careful tgl_out_cstring_careful
#define out_data tgl_out_data
static inline void out_string (const char *str) {
out_cstring (str, strlen (str));
}
static inline void out_bignum (BIGNUM *n) {
int l = serialize_bignum (n, (char *)packet_ptr, (PACKET_BUFFER_SIZE - (packet_ptr - packet_buffer)) * 4);
int l = tgl_serialize_bignum (n, (char *)packet_ptr, (PACKET_BUFFER_SIZE - (packet_ptr - packet_buffer)) * 4);
assert (l > 0);
packet_ptr += l >> 2;
}
extern int *in_ptr, *in_end;
#define in_ptr tgl_in_ptr
#define in_end tgl_in_end
extern int *tgl_in_ptr, *tgl_in_end;
void fetch_pts (void);
void fetch_qts (void);
void fetch_date (void);
void fetch_seq (void);
//void fetch_pts (void);
//void fetch_qts (void);
//void fetch_date (void);
//void fetch_seq (void);
static inline int prefetch_strlen (void) {
if (in_ptr >= in_end) {
return -1;
@ -175,12 +199,9 @@ 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);
@ -268,20 +289,17 @@ static inline long have_prefetch_ints (void) {
return in_end - in_ptr;
}
int fetch_bignum (BIGNUM *x);
int tgl_fetch_bignum (BIGNUM *x);
#define fetch_bignum tgl_fetch_bignum
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;
@ -323,33 +341,47 @@ static inline void fetch_ints (void *data, int count) {
memcpy (data, in_ptr, 4 * count);
in_ptr += count;
}
static inline void fetch256 (void *buf) {
int l = prefetch_strlen ();
assert (l >= 0);
char *s = fetch_str (l);
if (l < 256) {
memcpy (buf + 256 - l, s, l);
} else {
memcpy (buf, s + (l - 256), 256);
}
}
int get_random_bytes (unsigned char *buf, int n);
static inline int in_remaining (void) {
return 4 * (in_end - in_ptr);
}
int pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *E);
int pad_rsa_decrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *D);
//int get_random_bytes (unsigned char *buf, int n);
extern long long rsa_encrypted_chunks, rsa_decrypted_chunks;
int tgl_pad_rsa_encrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *E);
int tgl_pad_rsa_decrypt (char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *D);
extern unsigned char aes_key_raw[32], aes_iv[32];
extern AES_KEY aes_key;
//extern long long rsa_encrypted_chunks, rsa_decrypted_chunks;
void init_aes_unauth (const char server_nonce[16], const char hidden_client_nonce[32], int encrypt);
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);
//extern unsigned char aes_key_raw[32], aes_iv[32];
//extern AES_KEY aes_key;
void tgl_init_aes_unauth (const char server_nonce[16], const char hidden_client_nonce[32], int encrypt);
void tgl_init_aes_auth (char auth_key[192], char msg_key[16], int encrypt);
int tgl_pad_aes_encrypt (char *from, int from_len, char *to, int size);
int tgl_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
#define CLOCK_MONOTONIC 1
#endif
void my_clock_gettime (int clock_id, struct timespec *T);
#endif

422
net.c
View file

@ -1,20 +1,21 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#ifdef HAVE_CONFIG_H
@ -37,81 +38,79 @@
#include <poll.h>
#include <openssl/rand.h>
#include <arpa/inet.h>
#ifdef EVENT_V2
#include <event2/event.h>
#else
#include <event.h>
#include "event-old.h"
#endif
#include <sys/time.h>
#include <time.h>
#include "net.h"
#include "include.h"
#include "mtproto-client.h"
#include "mtproto-common.h"
#include "tgl.h"
#include "tgl-inner.h"
//#include "mtproto-client.h"
//#include "mtproto-common.h"
#include "tree.h"
#include "interface.h"
#include "tools.h"
#ifndef POLLRDHUP
#define POLLRDHUP 0
#endif
#define long_cmp(a,b) ((a) > (b) ? 1 : (a) == (b) ? 0 : -1)
DEFINE_TREE(long,long long,long_cmp,0)
double get_utime (int clock_id);
//double get_utime (int clock_id);
int verbosity;
extern struct connection_methods auth_methods;
extern FILE *log_net_f;
//extern struct mtproto_methods auth_methods;
void fail_connection (struct connection *c);
static void fail_connection (struct connection *c);
#define PING_TIMEOUT 10
void start_ping_timer (struct connection *c);
int ping_alarm (struct connection *c) {
if (verbosity > 2) {
logprintf ("ping alarm\n");
}
static void start_ping_timer (struct connection *c);
static void ping_alarm (evutil_socket_t fd, short what, void *arg) {
struct connection *c = arg;
vlogprintf (E_DEBUG + 2,"ping alarm\n");
assert (c->state == conn_ready || c->state == conn_connecting);
if (get_double_time () - c->last_receive_time > 20 * PING_TIMEOUT) {
if (verbosity) {
logprintf ( "fail connection: reason: ping timeout\n");
}
if (tglt_get_double_time () - c->last_receive_time > 6 * PING_TIMEOUT) {
vlogprintf (E_WARNING, "fail connection: reason: ping timeout\n");
c->state = conn_failed;
fail_connection (c);
} else if (get_double_time () - c->last_receive_time > 5 * PING_TIMEOUT && c->state == conn_ready) {
int x[3];
x[0] = CODE_ping;
*(long long *)(x + 1) = lrand48 () * (1ll << 32) + lrand48 ();
encrypt_send_message (c, x, 3, 0);
} else if (tglt_get_double_time () - c->last_receive_time > 3 * PING_TIMEOUT && c->state == conn_ready) {
tgl_do_send_ping (c);
start_ping_timer (c);
} else {
start_ping_timer (c);
}
return 0;
}
void stop_ping_timer (struct connection *c) {
remove_event_timer (&c->ev);
static void stop_ping_timer (struct connection *c) {
event_del (c->ping_ev);
}
void start_ping_timer (struct connection *c) {
c->ev.timeout = get_double_time () + PING_TIMEOUT;
c->ev.alarm = (void *)ping_alarm;
c->ev.self = c;
insert_event_timer (&c->ev);
static void start_ping_timer (struct connection *c) {
static struct timeval ptimeout = { PING_TIMEOUT, 0};
event_add (c->ping_ev, &ptimeout);
}
void restart_connection (struct connection *c);
int fail_alarm (void *ev) {
((struct connection *)ev)->in_fail_timer = 0;
restart_connection (ev);
return 0;
static void restart_connection (struct connection *c);
static void fail_alarm (evutil_socket_t fd, short what, void *arg) {
struct connection *c = arg;
c->in_fail_timer = 0;
restart_connection (c);
}
void start_fail_timer (struct connection *c) {
static void start_fail_timer (struct connection *c) {
if (c->in_fail_timer) { return; }
c->in_fail_timer = 1;
c->ev.timeout = get_double_time () + 10;
c->ev.alarm = (void *)fail_alarm;
c->ev.self = c;
insert_event_timer (&c->ev);
static struct timeval ptimeout = { 10, 0};
event_add (c->fail_ev, &ptimeout);
}
struct connection_buffer *new_connection_buffer (int size) {
static struct connection_buffer *new_connection_buffer (int size) {
struct connection_buffer *b = talloc0 (sizeof (*b));
b->start = talloc (size);
b->end = b->start + size;
@ -119,16 +118,20 @@ struct connection_buffer *new_connection_buffer (int size) {
return b;
}
void delete_connection_buffer (struct connection_buffer *b) {
static void delete_connection_buffer (struct connection_buffer *b) {
tfree (b->start, b->end - b->start);
tfree (b, sizeof (*b));
}
int write_out (struct connection *c, const void *_data, int len) {
int tgln_write_out (struct connection *c, const void *_data, int len) {
vlogprintf (E_DEBUG, "write_out: %d bytes\n", len);
const unsigned char *data = _data;
if (!len) { return 0; }
assert (len > 0);
int x = 0;
if (!c->out_bytes) {
event_add (c->write_ev, 0);
}
if (!c->out_head) {
struct connection_buffer *b = new_connection_buffer (1 << 20);
c->out_head = c->out_tail = b;
@ -156,7 +159,7 @@ int write_out (struct connection *c, const void *_data, int len) {
return x;
}
int read_in (struct connection *c, void *_data, int len) {
int tgln_read_in (struct connection *c, void *_data, int len) {
unsigned char *data = _data;
if (!len) { return 0; }
assert (len > 0);
@ -188,7 +191,7 @@ int read_in (struct connection *c, void *_data, int len) {
return x;
}
int read_in_lookup (struct connection *c, void *_data, int len) {
int tgln_read_in_lookup (struct connection *c, void *_data, int len) {
unsigned char *data = _data;
if (!len || !c->in_bytes) { return 0; }
assert (len > 0);
@ -213,14 +216,14 @@ int read_in_lookup (struct connection *c, void *_data, int len) {
return x;
}
void flush_out (struct connection *c UU) {
void tgln_flush_out (struct connection *c UU) {
}
#define MAX_CONNECTIONS 100
struct connection *Connections[MAX_CONNECTIONS];
int max_connection_fd;
static struct connection *Connections[MAX_CONNECTIONS];
static int max_connection_fd;
void rotate_port (struct connection *c) {
static void rotate_port (struct connection *c) {
switch (c->port) {
case 443:
c->port = 80;
@ -234,11 +237,31 @@ void rotate_port (struct connection *c) {
}
}
struct connection *create_connection (const char *host, int port, struct session *session, struct connection_methods *methods) {
static void try_read (struct connection *c);
static void try_write (struct connection *c);
static void conn_try_read (evutil_socket_t fd, short what, void *arg) {
struct connection *c = arg;
vlogprintf (E_DEBUG + 1, "Try read. Fd = %d\n", c->fd);
try_read (c);
}
static void conn_try_write (evutil_socket_t fd, short what, void *arg) {
struct connection *c = arg;
if (c->state == conn_connecting) {
c->state = conn_ready;
c->methods->ready (c);
}
try_write (c);
if (c->out_bytes) {
event_add (c->write_ev, 0);
}
}
struct connection *tgln_create_connection (const char *host, int port, struct tgl_session *session, struct tgl_dc *dc, struct mtproto_methods *methods) {
struct connection *c = talloc0 (sizeof (*c));
int fd = socket (AF_INET, SOCK_STREAM, 0);
if (fd == -1) {
logprintf ("Can not create socket: %m\n");
vlogprintf (E_ERROR, "Can not create socket: %m\n");
exit (1);
}
assert (fd >= 0 && fd < MAX_CONNECTIONS);
@ -259,52 +282,46 @@ struct connection *create_connection (const char *host, int port, struct session
fcntl (fd, F_SETFL, O_NONBLOCK);
if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
//vlogprintf (E_ERROR, "Can not connect to %s:%d %m\n", host, port);
if (errno != EINPROGRESS) {
logprintf ( "Can not connect to %s:%d %m\n", host, port);
vlogprintf (E_ERROR, "Can not connect to %s:%d %m\n", host, port);
close (fd);
tfree (c, sizeof (*c));
return 0;
}
}
struct pollfd s;
s.fd = fd;
s.events = POLLOUT | POLLERR | POLLRDHUP | POLLHUP;
errno = 0;
while (poll (&s, 1, 10000) <= 0 || !(s.revents & POLLOUT)) {
if (errno == EINTR) { continue; }
if (errno) {
logprintf ("Problems in poll: %m\n");
exit (1);
}
logprintf ("Connect with %s:%d timeout\n", host, port);
close (fd);
tfree (c, sizeof (*c));
return 0;
}
c->session = session;
c->fd = fd;
c->fd = fd;
c->state = conn_connecting;
c->last_receive_time = tglt_get_double_time ();
c->ip = tstrdup (host);
c->flags = 0;
c->state = conn_ready;
c->methods = methods;
c->port = port;
assert (!Connections[fd]);
Connections[fd] = c;
if (verbosity) {
logprintf ( "connect to %s:%d successful\n", host, port);
}
if (c->methods->ready) {
c->methods->ready (c);
}
c->last_receive_time = get_double_time ();
c->ping_ev = evtimer_new (tgl_state.ev_base, ping_alarm, c);
c->fail_ev = evtimer_new (tgl_state.ev_base, fail_alarm, c);
c->write_ev = event_new (tgl_state.ev_base, c->fd, EV_WRITE, conn_try_write, c);
struct timeval tv = {5, 0};
c->read_ev = event_new (tgl_state.ev_base, c->fd, EV_READ | EV_PERSIST, conn_try_read, c);
event_add (c->read_ev, &tv);
start_ping_timer (c);
c->dc = dc;
c->session = session;
c->methods = methods;
char byte = 0xef;
assert (tgln_write_out (c, &byte, 1) == 1);
tgln_flush_out (c);
return c;
}
void restart_connection (struct connection *c) {
static void restart_connection (struct connection *c) {
if (c->last_connect_time == time (0)) {
start_fail_timer (c);
return;
@ -313,7 +330,7 @@ void restart_connection (struct connection *c) {
c->last_connect_time = time (0);
int fd = socket (AF_INET, SOCK_STREAM, 0);
if (fd == -1) {
logprintf ("Can not create socket: %m\n");
vlogprintf (E_ERROR, "Can not create socket: %m\n");
exit (1);
}
assert (fd >= 0 && fd < MAX_CONNECTIONS);
@ -335,7 +352,7 @@ void restart_connection (struct connection *c) {
if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
if (errno != EINPROGRESS) {
logprintf ( "Can not connect to %s:%d %m\n", c->ip, c->port);
vlogprintf (E_WARNING, "Can not connect to %s:%d %m\n", c->ip, c->port);
start_fail_timer (c);
close (fd);
return;
@ -344,19 +361,28 @@ void restart_connection (struct connection *c) {
c->fd = fd;
c->state = conn_connecting;
c->last_receive_time = get_double_time ();
c->last_receive_time = tglt_get_double_time ();
start_ping_timer (c);
Connections[fd] = c;
c->write_ev = event_new (tgl_state.ev_base, c->fd, EV_WRITE, conn_try_write, c);
struct timeval tv = {5, 0};
c->read_ev = event_new (tgl_state.ev_base, c->fd, EV_READ | EV_PERSIST, conn_try_read, c);
event_add (c->read_ev, &tv);
char byte = 0xef;
assert (write_out (c, &byte, 1) == 1);
flush_out (c);
assert (tgln_write_out (c, &byte, 1) == 1);
tgln_flush_out (c);
}
void fail_connection (struct connection *c) {
static void fail_connection (struct connection *c) {
if (c->state == conn_ready || c->state == conn_connecting) {
stop_ping_timer (c);
}
event_free (c->write_ev);
event_free (c->read_ev);
rotate_port (c);
struct connection_buffer *b = c->out_head;
while (b) {
@ -375,27 +401,16 @@ void fail_connection (struct connection *c) {
c->out_bytes = c->in_bytes = 0;
close (c->fd);
Connections[c->fd] = 0;
logprintf ("Lost connection to server... %s:%d\n", c->ip, c->port);
vlogprintf (E_NOTICE, "Lost connection to server... %s:%d\n", c->ip, c->port);
restart_connection (c);
}
extern FILE *log_net_f;
void try_write (struct connection *c) {
if (verbosity) {
logprintf ( "try write: fd = %d\n", c->fd);
}
//extern FILE *log_net_f;
static void try_write (struct connection *c) {
vlogprintf (E_DEBUG, "try write: fd = %d\n", c->fd);
int x = 0;
while (c->out_head) {
int r = write (c->fd, c->out_head->rptr, c->out_head->wptr - c->out_head->rptr);
if (r > 0 && log_net_f) {
fprintf (log_net_f, "%.02lf %d OUT %s:%d", get_utime (CLOCK_REALTIME), r, c->ip, c->port);
int i;
for (i = 0; i < r; i++) {
fprintf (log_net_f, " %02x", *(unsigned char *)(c->out_head->rptr + i));
}
fprintf (log_net_f, "\n");
fflush (log_net_f);
}
if (r >= 0) {
x += r;
c->out_head->rptr += r;
@ -410,9 +425,7 @@ void try_write (struct connection *c) {
delete_connection_buffer (b);
} else {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
if (verbosity) {
logprintf ("fail_connection: write_error %m\n");
}
vlogprintf (E_NOTICE, "fail_connection: write_error %m\n");
fail_connection (c);
return;
} else {
@ -420,95 +433,59 @@ void try_write (struct connection *c) {
}
}
}
if (verbosity) {
logprintf ( "Sent %d bytes to %d\n", x, c->fd);
}
vlogprintf (E_DEBUG, "Sent %d bytes to %d\n", x, c->fd);
c->out_bytes -= x;
}
void hexdump_buf (struct connection_buffer *b) {
int pos = 0;
int rem = 8;
while (b) {
unsigned char *c = b->rptr;
while (c != b->wptr) {
if (rem == 8) {
if (pos) { printf ("\n"); }
printf ("%04d", pos);
}
printf (" %02x", (int)*c);
rem --;
pos ++;
if (!rem) {
rem = 8;
}
c ++;
}
b = b->next;
}
printf ("\n");
}
void try_rpc_read (struct connection *c) {
static void try_rpc_read (struct connection *c) {
assert (c->in_head);
if (verbosity >= 3) {
hexdump_buf (c->in_head);
}
while (1) {
if (c->in_bytes < 1) { return; }
unsigned len = 0;
unsigned t = 0;
assert (read_in_lookup (c, &len, 1) == 1);
assert (tgln_read_in_lookup (c, &len, 1) == 1);
if (len >= 1 && len <= 0x7e) {
if (c->in_bytes < (int)(1 + 4 * len)) { return; }
} else {
if (c->in_bytes < 4) { return; }
assert (read_in_lookup (c, &len, 4) == 4);
assert (tgln_read_in_lookup (c, &len, 4) == 4);
len = (len >> 8);
if (c->in_bytes < (int)(4 + 4 * len)) { return; }
len = 0x7f;
}
if (len >= 1 && len <= 0x7e) {
assert (read_in (c, &t, 1) == 1);
assert (tgln_read_in (c, &t, 1) == 1);
assert (t == len);
assert (len >= 1);
} else {
assert (len == 0x7f);
assert (read_in (c, &len, 4) == 4);
assert (tgln_read_in (c, &len, 4) == 4);
len = (len >> 8);
assert (len >= 1);
}
len *= 4;
int op;
assert (read_in_lookup (c, &op, 4) == 4);
assert (tgln_read_in_lookup (c, &op, 4) == 4);
c->methods->execute (c, op, len);
}
}
void try_read (struct connection *c) {
if (verbosity) {
logprintf ( "try read: fd = %d\n", c->fd);
}
static void try_read (struct connection *c) {
vlogprintf (E_DEBUG, "try read: fd = %d\n", c->fd);
if (!c->in_tail) {
c->in_head = c->in_tail = new_connection_buffer (1 << 20);
}
#ifdef EVENT_V1
struct timeval tv = {5, 0};
event_add (c->read_ev, &tv);
#endif
int x = 0;
while (1) {
int r = read (c->fd, c->in_tail->wptr, c->in_tail->end - c->in_tail->wptr);
if (r > 0 && log_net_f) {
fprintf (log_net_f, "%.02lf %d IN %s:%d", get_utime (CLOCK_REALTIME), r, c->ip, c->port);
int i;
for (i = 0; i < r; i++) {
fprintf (log_net_f, " %02x", *(unsigned char *)(c->in_tail->wptr + i));
}
fprintf (log_net_f, "\n");
fflush (log_net_f);
}
if (r > 0) {
c->last_receive_time = get_double_time ();
c->last_receive_time = tglt_get_double_time ();
stop_ping_timer (c);
start_ping_timer (c);
}
@ -523,9 +500,7 @@ void try_read (struct connection *c) {
c->in_tail = b;
} else {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
if (verbosity) {
logprintf ("fail_connection: read_error %m\n");
}
vlogprintf (E_NOTICE, "fail_connection: read_error %m\n");
fail_connection (c);
return;
} else {
@ -533,16 +508,14 @@ void try_read (struct connection *c) {
}
}
}
if (verbosity) {
logprintf ( "Received %d bytes from %d\n", x, c->fd);
}
vlogprintf (E_DEBUG, "Received %d bytes from %d\n", x, c->fd);
c->in_bytes += x;
if (x) {
try_rpc_read (c);
}
}
int connections_make_poll_array (struct pollfd *fds, int max) {
int tgl_connections_make_poll_array (struct pollfd *fds, int max) {
int _max = max;
int i;
for (i = 0; i <= max_connection_fd; i++) {
@ -561,16 +534,10 @@ int connections_make_poll_array (struct pollfd *fds, int 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 >= 10) {
logprintf ( "connections_poll_result: max = %d\n", max);
}
void tgl_connections_poll_result (struct pollfd *fds, int max) {
int i;
for (i = 0; i < max; i++) {
struct connection *c = Connections[fds[i].fd];
@ -578,15 +545,13 @@ void connections_poll_result (struct pollfd *fds, int max) {
try_read (c);
}
if (fds[i].revents & (POLLHUP | POLLERR | POLLRDHUP)) {
if (verbosity) {
logprintf ("fail_connection: events_mask=0x%08x\n", fds[i].revents);
}
vlogprintf (E_NOTICE, "fail_connection: events_mask=0x%08x\n", fds[i].revents);
fail_connection (c);
} else if (fds[i].revents & POLLOUT) {
if (c->state == conn_connecting) {
logprintf ("connection ready\n");
vlogprintf (E_DEBUG, "connection ready\n");
c->state = conn_ready;
c->last_receive_time = get_double_time ();
c->last_receive_time = tglt_get_double_time ();
}
if (c->out_bytes) {
try_write (c);
@ -595,53 +560,50 @@ void connections_poll_result (struct pollfd *fds, int max) {
}
}
int send_all_acks (struct session *S) {
clear_packet ();
out_int (CODE_msgs_ack);
out_int (CODE_vector);
out_int (tree_count_long (S->ack_tree));
while (S->ack_tree) {
long long x = tree_get_min_long (S->ack_tree);
out_long (x);
S->ack_tree = tree_delete_long (S->ack_tree, x);
}
encrypt_send_message (S->c, packet_buffer, packet_ptr - packet_buffer, 0);
return 0;
static void incr_out_packet_num (struct connection *c) {
c->out_packet_num ++;
}
void insert_msg_id (struct session *S, long long id) {
if (!S->ack_tree) {
S->ev.alarm = (void *)send_all_acks;
S->ev.self = (void *)S;
S->ev.timeout = get_double_time () + ACK_TIMEOUT;
insert_event_timer (&S->ev);
}
if (!tree_lookup_long (S->ack_tree, id)) {
S->ack_tree = tree_insert_long (S->ack_tree, id, lrand48 ());
}
static struct tgl_dc *get_dc (struct connection *c) {
return c->dc;
}
extern struct dc *DC_list[];
struct dc *alloc_dc (int id, char *ip, int port UU) {
assert (!DC_list[id]);
struct dc *DC = talloc0 (sizeof (*DC));
DC->id = id;
DC->ip = ip;
DC->port = port;
DC_list[id] = DC;
return DC;
static struct tgl_session *get_session (struct connection *c) {
return c->session;
}
void dc_create_session (struct dc *DC) {
struct session *S = talloc0 (sizeof (*S));
assert (RAND_pseudo_bytes ((unsigned char *) &S->session_id, 8) >= 0);
S->dc = DC;
S->c = create_connection (DC->ip, DC->port, S, &auth_methods);
if (!S->c) {
logprintf ("Can not create connection to DC. Is network down?\n");
exit (1);
static void tgln_free (struct connection *c) {
if (c->ip) { tfree_str (c->ip); }
struct connection_buffer *b = c->out_head;
while (b) {
struct connection_buffer *d = b;
b = b->next;
delete_connection_buffer (d);
}
assert (!DC->sessions[0]);
DC->sessions[0] = S;
b = c->in_head;
while (b) {
struct connection_buffer *d = b;
b = b->next;
delete_connection_buffer (d);
}
if (c->ping_ev) { event_free (c->ping_ev); }
if (c->fail_ev) { event_free (c->fail_ev); }
if (c->read_ev) { event_free (c->read_ev); }
if (c->write_ev) { event_free (c->write_ev); }
if (c->fd >= 0) { close (c->fd); }
tfree (c, sizeof (*c));
}
struct tgl_net_methods tgl_conn_methods = {
.write_out = tgln_write_out,
.read_in = tgln_read_in,
.read_in_lookup = tgln_read_in_lookup,
.flush_out = tgln_flush_out,
.incr_out_packet_num = incr_out_packet_num,
.get_dc = get_dc,
.get_session = get_session,
.create_connection = tgln_create_connection,
.free = tgln_free
};

118
net.h
View file

@ -1,88 +1,33 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#ifndef __NET_H__
#define __NET_H__
#include <poll.h>
struct dc;
#include "queries.h"
#define TG_SERVER "173.240.5.1"
#define TG_SERVER_TEST "173.240.5.253"
#define TG_APP_HASH "36722c72256a24c1225de00eb6a1ca74"
#define TG_APP_ID 2899
#define TG_BUILD "209"
#define TG_VERSION "0.01-beta"
#define ACK_TIMEOUT 1
#define MAX_DC_ID 10
enum dc_state {
st_init,
st_reqpq_sent,
st_reqdh_sent,
st_client_dh_sent,
st_authorized,
st_error
} ;
struct connection;
struct connection_methods {
int (*ready) (struct connection *c);
int (*close) (struct connection *c);
int (*execute) (struct connection *c, int op, int len);
};
#define MAX_DC_SESSIONS 3
struct session {
struct dc *dc;
long long session_id;
int seq_no;
struct connection *c;
struct tree_long *ack_tree;
struct event_timer ev;
};
struct dc {
int id;
int port;
int flags;
char *ip;
char *user;
struct session *sessions[MAX_DC_SESSIONS];
char auth_key[256];
long long auth_key_id;
long long server_salt;
int server_time_delta;
double server_time_udelta;
int has_auth;
};
#define DC_SERIALIZED_MAGIC 0x64582faa
#define DC_SERIALIZED_MAGIC_V2 0x94032abb
#define STATE_FILE_MAGIC 0x84217a0d
#define SECRET_CHAT_FILE_MAGIC 0xa9840add
struct dc_serialized {
struct tgl_dc_serialized {
int magic;
int port;
char ip[64];
@ -125,27 +70,34 @@ struct connection {
int out_packet_num;
int last_connect_time;
int in_fail_timer;
struct connection_methods *methods;
struct session *session;
struct mtproto_methods *methods;
struct tgl_session *session;
struct tgl_dc *dc;
void *extra;
struct event_timer ev;
struct event *ping_ev;
struct event *fail_ev;
struct event *read_ev;
struct event *write_ev;
double last_receive_time;
};
extern struct connection *Connections[];
//extern struct connection *Connections[];
int write_out (struct connection *c, const void *data, int len);
void flush_out (struct connection *c);
int read_in (struct connection *c, void *data, int len);
int tgln_write_out (struct connection *c, const void *data, int len);
void tgln_flush_out (struct connection *c);
int tgln_read_in (struct connection *c, void *data, int len);
int tgln_read_in_lookup (struct connection *c, void *data, int len);
void create_all_outbound_connections (void);
void tgln_insert_msg_id (struct tgl_session *S, long long id);
struct connection *create_connection (const char *host, int port, struct session *session, struct connection_methods *methods);
int connections_make_poll_array (struct pollfd *fds, int max);
void connections_poll_result (struct pollfd *fds, int max);
void dc_create_session (struct dc *DC);
void insert_msg_id (struct session *S, long long id);
struct dc *alloc_dc (int id, char *ip, int port);
extern struct tgl_net_methods tgl_conn_methods;
//void create_all_outbound_connections (void);
//struct connection *create_connection (const char *host, int port, struct tgl_session *session, struct connection_methods *methods);
struct tgl_dc *tgln_alloc_dc (int id, char *ip, int port);
void tgln_dc_create_session (struct tgl_dc *DC, struct mtproto_methods *methods);
struct connection *tgln_create_connection (const char *host, int port, struct tgl_session *session, struct tgl_dc *dc, struct mtproto_methods *methods);
#define GET_DC(c) (c->session->dc)
#endif

View file

@ -1,20 +1,21 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
// Just sample jpg file 90x90

2858
queries.c

File diff suppressed because it is too large Load diff

118
queries.h
View file

@ -1,39 +1,40 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#include "net.h"
//#include "net.h"
#ifndef __QUERIES_H__
#define __QUERIES_H__
#include "structures.h"
#include "auto.h"
#include "tgl-layout.h"
struct event;
#define QUERY_ACK_RECEIVED 1
#define QUERY_FORCE_SEND 2
struct query;
struct query_methods {
int (*on_answer)(struct query *q);
int (*on_error)(struct query *q, int error_code, int len, char *error);
int (*on_timeout)(struct query *q);
};
struct event_timer {
double timeout;
int (*alarm)(void *self);
void *self;
struct paramed_type *type;
};
struct query {
@ -41,83 +42,36 @@ struct query {
int data_len;
int flags;
int seq_no;
long long session_id;
void *data;
struct query_methods *methods;
struct event_timer ev;
struct dc *DC;
struct session *session;
struct event *ev;
struct tgl_dc *DC;
struct tgl_session *session;
struct paramed_type *type;
void *extra;
void *callback;
void *callback_extra;
};
struct query *send_query (struct dc *DC, int len, void *data, struct query_methods *methods, void *extra);
void query_ack (long long id);
void query_error (long long id);
void query_result (long long id);
void query_restart (long long id);
struct query *tglq_send_query (struct tgl_dc *DC, int len, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra);
void tglq_query_ack (long long id);
void tglq_query_error (long long id);
void tglq_query_result (long long id);
void tglq_query_restart (long long id);
void insert_event_timer (struct event_timer *ev);
void remove_event_timer (struct event_timer *ev);
double next_timer_in (void);
void work_timers (void);
extern struct query_methods help_get_config_methods;
//extern struct query_methods help_get_config_methods;
void do_send_code (const char *user);
void do_phone_call (const char *user);
int do_send_code_result (const char *code);
double get_double_time (void);
void do_update_contact_list (void);
union user_chat;
void do_send_message (peer_id_t id, const char *msg, int len);
void do_send_text (peer_id_t id, char *file);
void do_get_history (peer_id_t id, int limit);
void do_get_dialog_list (void);
void do_get_dialog_list_ex (void);
void do_send_photo (int type, peer_id_t to_id, char *file_name);
void do_get_chat_info (peer_id_t id);
void do_get_user_list_info_silent (int num, int *list);
void do_get_user_info (peer_id_t id);
void do_forward_message (peer_id_t id, int n);
void do_rename_chat (peer_id_t id, char *name);
void do_load_encr_video (struct encr_video *V, int next);
void do_create_encr_chat_request (int user_id);
void do_create_secret_chat (peer_id_t id);
void do_create_group_chat (peer_id_t id, char *chat_topic);
void do_get_suggested (void);
struct photo;
struct video;
void do_load_photo (struct photo *photo, int next);
void do_load_video_thumb (struct video *video, int next);
void do_load_audio (struct video *V, int next);
void do_load_video (struct video *V, int next);
void do_load_document (struct document *V, int next);
void do_load_document_thumb (struct document *video, int next);
void do_help_get_config (void);
int do_auth_check_phone (const char *user);
int do_get_nearest_dc (void);
int do_send_code_result_auth (const char *code, const char *first_name, const char *last_name);
void do_import_auth (int num);
void do_export_auth (int num);
void 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 do_msg_search (peer_id_t id, int from, int to, int limit, const char *s);
void do_accept_encr_chat_request (struct secret_chat *E);
void do_get_difference (void);
void do_mark_read (peer_id_t id);
void do_visualize_key (peer_id_t id);
void do_create_keys_end (struct secret_chat *U);
void do_add_user_to_chat (peer_id_t chat_id, peer_id_t id, int limit);
void do_del_user_from_chat (peer_id_t chat_id, peer_id_t id);
void do_update_status (int online);
void do_contacts_search (int limit, const char *s);
void do_send_msg (struct message *M);
void do_delete_msg (long long id);
void do_restore_msg (long long id);
void tgl_do_send_bind_temp_key (struct tgl_dc *D, long long nonce, int expires_at, void *data, int len, long long msg_id);
// 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

1
scheme.tl Symbolic link
View file

@ -0,0 +1 @@
scheme16.tl

505
scheme12.tl Normal file
View file

@ -0,0 +1,505 @@
int ?= Int;
long ?= Long;
double ?= Double;
string ?= String;
bytes string = Bytes;
boolFalse#bc799737 = Bool;
boolTrue#997275b5 = Bool;
vector#1cb5c415 {t:Type} # [ t ] = Vector t;
error#c4b9f9bb code:int text:string = Error;
null#56730bcc = Null;
inputPeerEmpty#7f3b18ea = InputPeer;
inputPeerSelf#7da07ec9 = InputPeer;
inputPeerContact#1023dbe8 user_id:int = InputPeer;
inputPeerForeign#9b447325 user_id:int access_hash:long = InputPeer;
inputPeerChat#179be863 chat_id:int = InputPeer;
inputUserEmpty#b98886cf = InputUser;
inputUserSelf#f7c1b13f = InputUser;
inputUserContact#86e94f65 user_id:int = InputUser;
inputUserForeign#655e74ff user_id:int access_hash:long = InputUser;
inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact;
inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile;
inputMediaEmpty#9664f57f = InputMedia;
inputMediaUploadedPhoto#2dc53a7d file:InputFile = InputMedia;
inputMediaPhoto#8f2ab2ec id:InputPhoto = InputMedia;
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
inputMediaContact#a6e45987 phone_number:string first_name:string last_name:string = InputMedia;
inputMediaUploadedVideo#4847d92a file:InputFile duration:int w:int h:int = InputMedia;
inputMediaUploadedThumbVideo#e628a145 file:InputFile thumb:InputFile duration:int w:int h:int = InputMedia;
inputMediaVideo#7f023ae6 id:InputVideo = InputMedia;
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
inputChatUploadedPhoto#94254732 file:InputFile crop:InputPhotoCrop = InputChatPhoto;
inputChatPhoto#b2e1bf08 id:InputPhoto crop:InputPhotoCrop = InputChatPhoto;
inputGeoPointEmpty#e4c123d6 = InputGeoPoint;
inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint;
inputPhotoEmpty#1cd7bf0d = InputPhoto;
inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto;
inputVideoEmpty#5508ec75 = InputVideo;
inputVideo#ee579652 id:long access_hash:long = InputVideo;
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
inputVideoFileLocation#3d0364ec id:long access_hash:long = InputFileLocation;
inputPhotoCropAuto#ade6b004 = InputPhotoCrop;
inputPhotoCrop#d9915325 crop_left:double crop_top:double crop_width:double = InputPhotoCrop;
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
peerUser#9db1bc6d user_id:int = Peer;
peerChat#bad0e5bb chat_id:int = Peer;
storage.fileUnknown#aa963b05 = storage.FileType;
storage.fileJpeg#7efe0e = storage.FileType;
storage.fileGif#cae1aadf = storage.FileType;
storage.filePng#a4f63c0 = storage.FileType;
storage.filePdf#ae1e508d = storage.FileType;
storage.fileMp3#528a0677 = storage.FileType;
storage.fileMov#4b09ebbc = storage.FileType;
storage.filePartial#40bc6f52 = storage.FileType;
storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;
fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileLocation;
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
userEmpty#200250ba id:int = User;
userSelf#720535ec id:int first_name:string last_name:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User;
userContact#f2fb8319 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userRequest#22e8ceb0 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userForeign#5214c89d id:int first_name:string last_name:string access_hash:long photo:UserProfilePhoto status:UserStatus = User;
userDeleted#b29ad7cc id:int first_name:string last_name:string = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
userStatusEmpty#9d05049 = UserStatus;
userStatusOnline#edb93949 expires:int = UserStatus;
userStatusOffline#8c703f was_online:int = UserStatus;
chatEmpty#9ba2d800 id:int = Chat;
chat#6e9c9bc7 id:int title:string photo:ChatPhoto participants_count:int date:int left:Bool version:int = Chat;
chatForbidden#fb0ccc41 id:int title:string date:int = Chat;
chatFull#630e61be id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings = ChatFull;
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
chatParticipantsForbidden#fd2bb8a chat_id:int = ChatParticipants;
chatParticipants#7841b415 chat_id:int admin_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants;
chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
messageEmpty#83e5de54 id:int = Message;
message#22eb6aba id:int from_id:int to_id:Peer out:Bool unread:Bool date:int message:string media:MessageMedia = Message;
messageForwarded#5f46804 id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer out:Bool unread:Bool date:int message:string media:MessageMedia = Message;
messageService#9f8d60bb id:int from_id:int to_id:Peer out:Bool unread:Bool date:int action:MessageAction = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
messageMediaPhoto#c8c45a2a photo:Photo = MessageMedia;
messageMediaVideo#a2d24290 video:Video = MessageMedia;
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
messageMediaUnsupported#29632a36 bytes:bytes = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
messageActionChatEditTitle#b5a1ce5a title:string = MessageAction;
messageActionChatEditPhoto#7fcb13a8 photo:Photo = MessageAction;
messageActionChatDeletePhoto#95e3fbef = MessageAction;
messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
dialog#214a8cdf peer:Peer top_message:int unread_count:int = Dialog;
photoEmpty#2331b22d id:long = Photo;
photo#22b56751 id:long access_hash:long user_id:int date:int caption:string geo:GeoPoint sizes:Vector<PhotoSize> = Photo;
photoSizeEmpty#e17e23c type:string = PhotoSize;
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
videoEmpty#c10658a8 id:long = Video;
video#5a04a49f id:long access_hash:long user_id:int date:int caption:string duration:int size:int thumb:PhotoSize dc_id:int w:int h:int = Video;
geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#2049d70c long:double lat:double = GeoPoint;
auth.checkedPhone#e300cc3b phone_registered:Bool phone_invited:Bool = auth.CheckedPhone;
auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
auth.authorization#f6b673a4 expires:int user:User = auth.Authorization;
auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorization;
inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
inputNotifyUsers#193b4417 = InputNotifyPeer;
inputNotifyChats#4a95e84e = InputNotifyPeer;
inputNotifyAll#a429b886 = InputNotifyPeer;
inputPeerNotifyEventsEmpty#f03064d8 = InputPeerNotifyEvents;
inputPeerNotifyEventsAll#e86a2c74 = InputPeerNotifyEvents;
inputPeerNotifySettings#46a2ce98 mute_until:int sound:string show_previews:Bool events_mask:int = InputPeerNotifySettings;
peerNotifyEventsEmpty#add53cb3 = PeerNotifyEvents;
peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents;
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
peerNotifySettings#8d5e11ee mute_until:int sound:string show_previews:Bool events_mask:int = PeerNotifySettings;
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
userFull#771095da user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool real_first_name:string real_last_name:string = UserFull;
contact#f911c994 user_id:int mutual:Bool = Contact;
importedContact#d0028438 user_id:int client_id:long = ImportedContact;
contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
contactFound#ea879f95 user_id:int = ContactFound;
contactSuggested#3de191a1 user_id:int mutual_contacts:int = ContactSuggested;
contactStatus#aa77b873 user_id:int expires:int = ContactStatus;
chatLocated#3631cf4c chat_id:int distance:int = ChatLocated;
contacts.foreignLinkUnknown#133421f8 = contacts.ForeignLink;
contacts.foreignLinkRequested#a7801f47 has_phone:Bool = contacts.ForeignLink;
contacts.foreignLinkMutual#1bea8ce1 = contacts.ForeignLink;
contacts.myLinkEmpty#d22a1c60 = contacts.MyLink;
contacts.myLinkRequested#6c69efee contact:Bool = contacts.MyLink;
contacts.myLinkContact#c240ebd9 = contacts.MyLink;
contacts.link#eccea3f5 my_link:contacts.MyLink foreign_link:contacts.ForeignLink user:User = contacts.Link;
contacts.contacts#6f8b8cb2 contacts:Vector<Contact> users:Vector<User> = contacts.Contacts;
contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
contacts.importedContacts#d1cd0a4c imported:Vector<ImportedContact> users:Vector<User> = contacts.ImportedContacts;
contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.found#566000e results:Vector<ContactFound> users:Vector<User> = contacts.Found;
contacts.suggested#5649dcc5 results:Vector<ContactSuggested> users:Vector<User> = contacts.Suggested;
messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messageEmpty#3f4e0648 = messages.Message;
messages.message#ff90c417 message:Message chats:Vector<Chat> users:Vector<User> = messages.Message;
messages.statedMessages#969478bb messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessages;
messages.statedMessage#d07ae726 message:Message chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessage;
messages.sentMessage#d1f4d35c id:int date:int pts:int seq:int = messages.SentMessage;
messages.chat#40e9002a chat:Chat users:Vector<User> = messages.Chat;
messages.chats#8150cbd8 chats:Vector<Chat> users:Vector<User> = messages.Chats;
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
messages.affectedHistory#b7de36f2 pts:int seq:int offset:int = messages.AffectedHistory;
inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
updateNewMessage#13abdb3 message:Message pts:int = Update;
updateMessageID#4e90bfd6 id:int random_id:long = Update;
updateReadMessages#c6649e31 messages:Vector<int> pts:int = Update;
updateDeleteMessages#a92bfe26 messages:Vector<int> pts:int = Update;
updateRestoreMessages#d15de04d messages:Vector<int> pts:int = Update;
updateUserTyping#6baa8508 user_id:int = Update;
updateChatUserTyping#3c46cfe6 chat_id:int user_id:int = Update;
updateChatParticipants#7761198 participants:ChatParticipants = Update;
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
updateUserName#da22d9ad user_id:int first_name:string last_name:string = Update;
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
updateActivation#6f690963 user_id:int = Update;
updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
updatesTooLong#e317af7e = Updates;
updateShortMessage#d3f45784 id:int from_id:int message:string pts:int date:int seq:int = Updates;
updateShortChatMessage#2b2fbd4e id:int from_id:int chat_id:int message:string pts:int date:int seq:int = Updates;
updateShort#78d4dec1 update:Update date:int = Updates;
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
photos.photos#8dca6aa5 photos:Vector<Photo> users:Vector<User> = photos.Photos;
photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> = photos.Photos;
photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
dcOption#2ec2a43c id:int hostname:string ip_address:string port:int = DcOption;
config#2e54dd74 date:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int = Config;
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
help.appUpdate#8987f311 id:int critical:Bool url:string text:string = help.AppUpdate;
help.noAppUpdate#c45a6536 = help.AppUpdate;
help.inviteText#18cb9f78 message:string = help.InviteText;
messages.statedMessagesLinks#3e74f5c6 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessages;
messages.statedMessageLink#a9af2881 message:Message chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessage;
messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector<contacts.Link> = messages.SentMessage;
inputGeoChat#74d456fa chat_id:int access_hash:long = InputGeoChat;
inputNotifyGeoChatPeer#4d8ddec8 peer:InputGeoChat = InputNotifyPeer;
geoChat#75eaea5a id:int access_hash:long title:string address:string venue:string geo:GeoPoint photo:ChatPhoto participants_count:int date:int checked_in:Bool version:int = Chat;
geoChatMessageEmpty#60311a9b chat_id:int id:int = GeoChatMessage;
geoChatMessage#4505f8e1 chat_id:int id:int from_id:int date:int message:string media:MessageMedia = GeoChatMessage;
geoChatMessageService#d34fa24e chat_id:int id:int from_id:int date:int action:MessageAction = GeoChatMessage;
geochats.statedMessage#17b1578b message:GeoChatMessage chats:Vector<Chat> users:Vector<User> seq:int = geochats.StatedMessage;
geochats.located#48feb267 results:Vector<ChatLocated> messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Located;
geochats.messages#d1526db1 messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
geochats.messagesSlice#bc5863e8 count:int messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
messageActionGeoChatCreate#6f038ebc title:string address:string = MessageAction;
messageActionGeoChatCheckin#c7d53de = MessageAction;
updateNewGeoChatMessage#5a68e3f7 message:GeoChatMessage = Update;
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
updateEncryptedMessagesRead#38fe25b7 chat_id:int max_date:int date:int = Update;
encryptedChatEmpty#ab7ec0a0 id:int = EncryptedChat;
encryptedChatWaiting#3bf703dc id:int access_hash:long date:int admin_id:int participant_id:int = EncryptedChat;
encryptedChatRequested#c878527e id:int access_hash:long date:int admin_id:int participant_id:int g_a:bytes = EncryptedChat;
encryptedChat#fa56ce36 id:int access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long = EncryptedChat;
encryptedChatDiscarded#13d6dd27 id:int = EncryptedChat;
inputEncryptedChat#f141b5e1 chat_id:int access_hash:long = InputEncryptedChat;
encryptedFileEmpty#c21f497e = EncryptedFile;
encryptedFile#4a70994c id:long access_hash:long size:int dc_id:int key_fingerprint:int = EncryptedFile;
inputEncryptedFileEmpty#1837c364 = InputEncryptedFile;
inputEncryptedFileUploaded#64bd0306 id:long parts:int md5_checksum:string key_fingerprint:int = InputEncryptedFile;
inputEncryptedFile#5a17b5e5 id:long access_hash:long = InputEncryptedFile;
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
encryptedMessage#ed18c118 random_id:long chat_id:int date:int bytes:bytes file:EncryptedFile = EncryptedMessage;
encryptedMessageService#23734b06 random_id:long chat_id:int date:int bytes:bytes = EncryptedMessage;
decryptedMessageLayer#99a438cf layer:int message:DecryptedMessage = DecryptedMessageLayer;
decryptedMessage#1f814f1f random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage;
decryptedMessageService#aa48327d random_id:long random_bytes:bytes action:DecryptedMessageAction = DecryptedMessage;
decryptedMessageMediaEmpty#89f5c4a = DecryptedMessageMedia;
decryptedMessageMediaPhoto#32798a8c thumb:bytes thumb_w:int thumb_h:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaVideo#4cee6ef3 thumb:bytes thumb_w:int thumb_h:int duration:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaGeoPoint#35480a59 lat:double long:double = DecryptedMessageMedia;
decryptedMessageMediaContact#588a0a97 phone_number:string first_name:string last_name:string user_id:int = DecryptedMessageMedia;
decryptedMessageActionSetMessageTTL#a1733aec ttl_seconds:int = DecryptedMessageAction;
messages.dhConfigNotModified#c0e24635 random:bytes = messages.DhConfig;
messages.dhConfig#2c221edd g:int p:bytes version:int random:bytes = messages.DhConfig;
messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
inputEncryptedFileBigUploaded#2dc173c8 id:long parts:int key_fingerprint:int = InputEncryptedFile;
updateChatParticipantAdd#3a0eeb22 chat_id:int user_id:int inviter_id:int version:int = Update;
updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update;
updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
inputMediaUploadedAudio#61a6d436 file:InputFile duration:int = InputMedia;
inputMediaAudio#89938781 id:InputAudio = InputMedia;
inputMediaUploadedDocument#34e794bd file:InputFile file_name:string mime_type:string = InputMedia;
inputMediaUploadedThumbDocument#3e46de5d file:InputFile thumb:InputFile file_name:string mime_type:string = InputMedia;
inputMediaDocument#d184e841 id:InputDocument = InputMedia;
messageMediaDocument#2fda2204 document:Document = MessageMedia;
messageMediaAudio#c6b68300 audio:Audio = MessageMedia;
inputAudioEmpty#d95adc84 = InputAudio;
inputAudio#77d440ff id:long access_hash:long = InputAudio;
inputDocumentEmpty#72f0eaae = InputDocument;
inputDocument#18798952 id:long access_hash:long = InputDocument;
inputAudioFileLocation#74dc404d id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
decryptedMessageMediaDocument#b095434b thumb:bytes thumb_w:int thumb_h:int file_name:string mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaAudio#6080758f duration:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
audioEmpty#586988d8 id:long = Audio;
audio#427425e7 id:long access_hash:long user_id:int date:int duration:int size:int dc_id:int = Audio;
documentEmpty#36f8c871 id:long = Document;
document#9efc6326 id:long access_hash:long user_id:int date:int file_name:string mime_type:string size:int thumb:PhotoSize dc_id:int = Document;
help.support#17c6b5f6 phone_number:string user:User = help.Support;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode;
auth.sendCall#3c51564 phone_number:string phone_code_hash:string = Bool;
auth.signUp#1b067634 phone_number:string phone_code_hash:string phone_code:string first_name:string last_name:string = auth.Authorization;
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
auth.logOut#5717da40 = Bool;
auth.resetAuthorizations#9fab0d1a = Bool;
auth.sendInvites#771c1d97 phone_numbers:Vector<string> message:string = Bool;
auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
auth.importAuthorization#e3ef9613 id:int bytes:bytes = auth.Authorization;
account.registerDevice#446c712c token_type:int token:string device_model:string system_version:string app_version:string app_sandbox:Bool lang_code:string = Bool;
account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
account.resetNotifySettings#db7e1747 = Bool;
account.updateProfile#f0888d68 first_name:string last_name:string = User;
account.updateStatus#6628562c offline:Bool = Bool;
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
contacts.getContacts#22c6aa08 hash:string = contacts.Contacts;
contacts.importContacts#da30b32d contacts:Vector<InputContact> replace:Bool = contacts.ImportedContacts;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.getSuggested#cd773428 limit:int = contacts.Suggested;
contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
contacts.block#332b49fc id:InputUser = Bool;
contacts.unblock#e54100bd id:InputUser = Bool;
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
messages.getDialogs#eccf1df6 offset:int max_id:int limit:int = messages.Dialogs;
messages.getHistory#92a1df2f peer:InputPeer offset:int max_id:int limit:int = messages.Messages;
messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
messages.readHistory#b04f2510 peer:InputPeer max_id:int offset:int = messages.AffectedHistory;
messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
messages.deleteMessages#14f2dd0a id:Vector<int> = Vector<int>;
messages.restoreMessages#395f9d7e id:Vector<int> = Vector<int>;
messages.receivedMessages#28abcb68 max_id:int = Vector<int>;
messages.setTyping#719839e9 peer:InputPeer typing:Bool = Bool;
messages.sendMessage#4cde0aab peer:InputPeer message:string random_id:long = messages.SentMessage;
messages.sendMedia#a3c85d76 peer:InputPeer media:InputMedia random_id:long = messages.StatedMessage;
messages.forwardMessages#514cd10f peer:InputPeer id:Vector<int> = messages.StatedMessages;
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
messages.editChatTitle#b4bc68b5 chat_id:int title:string = messages.StatedMessage;
messages.editChatPhoto#d881821d chat_id:int photo:InputChatPhoto = messages.StatedMessage;
messages.addChatUser#2ee9ee9e chat_id:int user_id:InputUser fwd_limit:int = messages.StatedMessage;
messages.deleteChatUser#c3c5cd23 chat_id:int user_id:InputUser = messages.StatedMessage;
messages.createChat#419d9aee users:Vector<InputUser> title:string = messages.StatedMessage;
updates.getState#edd4882a = updates.State;
updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;
photos.updateProfilePhoto#eef579a0 id:InputPhoto crop:InputPhotoCrop = UserProfilePhoto;
photos.uploadProfilePhoto#d50f9c88 file:InputFile caption:string geo_point:InputGeoPoint crop:InputPhotoCrop = photos.Photo;
upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload.File;
help.getConfig#c4f9186b = Config;
help.getNearestDc#1fb33026 = NearestDc;
help.getAppUpdate#c812ac7e device_model:string system_version:string app_version:string lang_code:string = help.AppUpdate;
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getInviteText#a4a95186 lang_code:string = help.InviteText;
photos.getUserPhotos#b7ee553c user_id:InputUser offset:int max_id:int limit:int = photos.Photos;
messages.forwardMessage#3f3f4f2 peer:InputPeer id:int random_id:long = messages.StatedMessage;
messages.sendBroadcast#41bb0972 contacts:Vector<InputUser> message:string media:InputMedia = messages.StatedMessages;
geochats.getLocated#7f192d8f geo_point:InputGeoPoint radius:int limit:int = geochats.Located;
geochats.getRecents#e1427e6f offset:int limit:int = geochats.Messages;
geochats.checkin#55b3e8fb peer:InputGeoChat = geochats.StatedMessage;
geochats.getFullChat#6722dd6f peer:InputGeoChat = messages.ChatFull;
geochats.editChatTitle#4c8e2273 peer:InputGeoChat title:string address:string = geochats.StatedMessage;
geochats.editChatPhoto#35d81a95 peer:InputGeoChat photo:InputChatPhoto = geochats.StatedMessage;
geochats.search#cfcdc44d peer:InputGeoChat q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = geochats.Messages;
geochats.getHistory#b53f7a68 peer:InputGeoChat offset:int max_id:int limit:int = geochats.Messages;
geochats.setTyping#8b8a729 peer:InputGeoChat typing:Bool = Bool;
geochats.sendMessage#61b0044 peer:InputGeoChat message:string random_id:long = geochats.StatedMessage;
geochats.sendMedia#b8f0deff peer:InputGeoChat media:InputMedia random_id:long = geochats.StatedMessage;
geochats.createGeoChat#e092e16 title:string geo_point:InputGeoPoint address:string venue:string = geochats.StatedMessage;
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
messages.discardEncryption#edd923c5 chat_id:int = Bool;
messages.setEncryptedTyping#791451ed peer:InputEncryptedChat typing:Bool = Bool;
messages.readEncryptedHistory#7f4b690a peer:InputEncryptedChat max_date:int = Bool;
messages.sendEncrypted#a9776773 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
messages.sendEncryptedFile#9a901b66 peer:InputEncryptedChat random_id:long data:bytes file:InputEncryptedFile = messages.SentEncryptedMessage;
messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
help.getSupport#9cdf08cd = help.Support;
invokeWithLayer12#dda60d3c {X:Type} query:!X = X;

522
scheme15.tl Normal file
View file

@ -0,0 +1,522 @@
int ?= Int;
long ?= Long;
double ?= Double;
string ?= String;
bytes string = Bytes;
boolFalse#bc799737 = Bool;
boolTrue#997275b5 = Bool;
vector#1cb5c415 {t:Type} # [ t ] = Vector t;
error#c4b9f9bb code:int text:string = Error;
null#56730bcc = Null;
inputPeerEmpty#7f3b18ea = InputPeer;
inputPeerSelf#7da07ec9 = InputPeer;
inputPeerContact#1023dbe8 user_id:int = InputPeer;
inputPeerForeign#9b447325 user_id:int access_hash:long = InputPeer;
inputPeerChat#179be863 chat_id:int = InputPeer;
inputUserEmpty#b98886cf = InputUser;
inputUserSelf#f7c1b13f = InputUser;
inputUserContact#86e94f65 user_id:int = InputUser;
inputUserForeign#655e74ff user_id:int access_hash:long = InputUser;
inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact;
inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile;
inputMediaEmpty#9664f57f = InputMedia;
inputMediaUploadedPhoto#2dc53a7d file:InputFile = InputMedia;
inputMediaPhoto#8f2ab2ec id:InputPhoto = InputMedia;
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
inputMediaContact#a6e45987 phone_number:string first_name:string last_name:string = InputMedia;
inputMediaUploadedVideo#133ad6f6 file:InputFile duration:int w:int h:int mime_type:string = InputMedia;
inputMediaUploadedThumbVideo#9912dabf file:InputFile thumb:InputFile duration:int w:int h:int mime_type:string = InputMedia;
inputMediaVideo#7f023ae6 id:InputVideo = InputMedia;
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
inputChatUploadedPhoto#94254732 file:InputFile crop:InputPhotoCrop = InputChatPhoto;
inputChatPhoto#b2e1bf08 id:InputPhoto crop:InputPhotoCrop = InputChatPhoto;
inputGeoPointEmpty#e4c123d6 = InputGeoPoint;
inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint;
inputPhotoEmpty#1cd7bf0d = InputPhoto;
inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto;
inputVideoEmpty#5508ec75 = InputVideo;
inputVideo#ee579652 id:long access_hash:long = InputVideo;
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
inputVideoFileLocation#3d0364ec id:long access_hash:long = InputFileLocation;
inputPhotoCropAuto#ade6b004 = InputPhotoCrop;
inputPhotoCrop#d9915325 crop_left:double crop_top:double crop_width:double = InputPhotoCrop;
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
peerUser#9db1bc6d user_id:int = Peer;
peerChat#bad0e5bb chat_id:int = Peer;
storage.fileUnknown#aa963b05 = storage.FileType;
storage.fileJpeg#007efe0e = storage.FileType;
storage.fileGif#cae1aadf = storage.FileType;
storage.filePng#0a4f63c0 = storage.FileType;
storage.filePdf#ae1e508d = storage.FileType;
storage.fileMp3#528a0677 = storage.FileType;
storage.fileMov#4b09ebbc = storage.FileType;
storage.filePartial#40bc6f52 = storage.FileType;
storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;
fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileLocation;
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
userEmpty#200250ba id:int = User;
userSelf#720535ec id:int first_name:string last_name:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User;
userContact#f2fb8319 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userRequest#22e8ceb0 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userForeign#5214c89d id:int first_name:string last_name:string access_hash:long photo:UserProfilePhoto status:UserStatus = User;
userDeleted#b29ad7cc id:int first_name:string last_name:string = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
userStatusEmpty#09d05049 = UserStatus;
userStatusOnline#edb93949 expires:int = UserStatus;
userStatusOffline#008c703f was_online:int = UserStatus;
chatEmpty#9ba2d800 id:int = Chat;
chat#6e9c9bc7 id:int title:string photo:ChatPhoto participants_count:int date:int left:Bool version:int = Chat;
chatForbidden#fb0ccc41 id:int title:string date:int = Chat;
chatFull#630e61be id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings = ChatFull;
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
chatParticipantsForbidden#0fd2bb8a chat_id:int = ChatParticipants;
chatParticipants#7841b415 chat_id:int admin_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants;
chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
messageEmpty#83e5de54 id:int = Message;
message#22eb6aba id:int from_id:int to_id:Peer out:Bool unread:Bool date:int message:string media:MessageMedia = Message;
messageForwarded#05f46804 id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer out:Bool unread:Bool date:int message:string media:MessageMedia = Message;
messageService#9f8d60bb id:int from_id:int to_id:Peer out:Bool unread:Bool date:int action:MessageAction = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
messageMediaPhoto#c8c45a2a photo:Photo = MessageMedia;
messageMediaVideo#a2d24290 video:Video = MessageMedia;
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
messageMediaUnsupported#29632a36 bytes:bytes = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
messageActionChatEditTitle#b5a1ce5a title:string = MessageAction;
messageActionChatEditPhoto#7fcb13a8 photo:Photo = MessageAction;
messageActionChatDeletePhoto#95e3fbef = MessageAction;
messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
dialog#ab3a99ac peer:Peer top_message:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
photoEmpty#2331b22d id:long = Photo;
photo#22b56751 id:long access_hash:long user_id:int date:int caption:string geo:GeoPoint sizes:Vector<PhotoSize> = Photo;
photoSizeEmpty#0e17e23c type:string = PhotoSize;
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
videoEmpty#c10658a8 id:long = Video;
video#388fa391 id:long access_hash:long user_id:int date:int caption:string duration:int mime_type:string size:int thumb:PhotoSize dc_id:int w:int h:int = Video;
geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#2049d70c long:double lat:double = GeoPoint;
auth.checkedPhone#e300cc3b phone_registered:Bool phone_invited:Bool = auth.CheckedPhone;
auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
auth.authorization#f6b673a4 expires:int user:User = auth.Authorization;
auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorization;
inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
inputNotifyUsers#193b4417 = InputNotifyPeer;
inputNotifyChats#4a95e84e = InputNotifyPeer;
inputNotifyAll#a429b886 = InputNotifyPeer;
inputPeerNotifyEventsEmpty#f03064d8 = InputPeerNotifyEvents;
inputPeerNotifyEventsAll#e86a2c74 = InputPeerNotifyEvents;
inputPeerNotifySettings#46a2ce98 mute_until:int sound:string show_previews:Bool events_mask:int = InputPeerNotifySettings;
peerNotifyEventsEmpty#add53cb3 = PeerNotifyEvents;
peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents;
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
peerNotifySettings#8d5e11ee mute_until:int sound:string show_previews:Bool events_mask:int = PeerNotifySettings;
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
userFull#771095da user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool real_first_name:string real_last_name:string = UserFull;
contact#f911c994 user_id:int mutual:Bool = Contact;
importedContact#d0028438 user_id:int client_id:long = ImportedContact;
contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
contactFound#ea879f95 user_id:int = ContactFound;
contactSuggested#3de191a1 user_id:int mutual_contacts:int = ContactSuggested;
contactStatus#aa77b873 user_id:int expires:int = ContactStatus;
chatLocated#3631cf4c chat_id:int distance:int = ChatLocated;
contacts.foreignLinkUnknown#133421f8 = contacts.ForeignLink;
contacts.foreignLinkRequested#a7801f47 has_phone:Bool = contacts.ForeignLink;
contacts.foreignLinkMutual#1bea8ce1 = contacts.ForeignLink;
contacts.myLinkEmpty#d22a1c60 = contacts.MyLink;
contacts.myLinkRequested#6c69efee contact:Bool = contacts.MyLink;
contacts.myLinkContact#c240ebd9 = contacts.MyLink;
contacts.link#eccea3f5 my_link:contacts.MyLink foreign_link:contacts.ForeignLink user:User = contacts.Link;
contacts.contacts#6f8b8cb2 contacts:Vector<Contact> users:Vector<User> = contacts.Contacts;
contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
contacts.importedContacts#ad524315 imported:Vector<ImportedContact> retry_contacts:Vector<long> users:Vector<User> = contacts.ImportedContacts;
contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.found#0566000e results:Vector<ContactFound> users:Vector<User> = contacts.Found;
contacts.suggested#5649dcc5 results:Vector<ContactSuggested> users:Vector<User> = contacts.Suggested;
messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#0b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messageEmpty#3f4e0648 = messages.Message;
messages.message#ff90c417 message:Message chats:Vector<Chat> users:Vector<User> = messages.Message;
messages.statedMessages#969478bb messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessages;
messages.statedMessage#d07ae726 message:Message chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessage;
messages.sentMessage#d1f4d35c id:int date:int pts:int seq:int = messages.SentMessage;
messages.chat#40e9002a chat:Chat users:Vector<User> = messages.Chat;
messages.chats#8150cbd8 chats:Vector<Chat> users:Vector<User> = messages.Chats;
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
messages.affectedHistory#b7de36f2 pts:int seq:int offset:int = messages.AffectedHistory;
inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
updateNewMessage#013abdb3 message:Message pts:int = Update;
updateMessageID#4e90bfd6 id:int random_id:long = Update;
updateReadMessages#c6649e31 messages:Vector<int> pts:int = Update;
updateDeleteMessages#a92bfe26 messages:Vector<int> pts:int = Update;
updateRestoreMessages#d15de04d messages:Vector<int> pts:int = Update;
updateUserTyping#6baa8508 user_id:int = Update;
updateChatUserTyping#3c46cfe6 chat_id:int user_id:int = Update;
updateChatParticipants#07761198 participants:ChatParticipants = Update;
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
updateUserName#da22d9ad user_id:int first_name:string last_name:string = Update;
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
updateActivation#6f690963 user_id:int = Update;
updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
updates.difference#00f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
updatesTooLong#e317af7e = Updates;
updateShortMessage#d3f45784 id:int from_id:int message:string pts:int date:int seq:int = Updates;
updateShortChatMessage#2b2fbd4e id:int from_id:int chat_id:int message:string pts:int date:int seq:int = Updates;
updateShort#78d4dec1 update:Update date:int = Updates;
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
photos.photos#8dca6aa5 photos:Vector<Photo> users:Vector<User> = photos.Photos;
photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> = photos.Photos;
photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
upload.file#096a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
dcOption#2ec2a43c id:int hostname:string ip_address:string port:int = DcOption;
config#2e54dd74 date:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int = Config;
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
help.appUpdate#8987f311 id:int critical:Bool url:string text:string = help.AppUpdate;
help.noAppUpdate#c45a6536 = help.AppUpdate;
help.inviteText#18cb9f78 message:string = help.InviteText;
messages.statedMessagesLinks#3e74f5c6 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessages;
messages.statedMessageLink#a9af2881 message:Message chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessage;
messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector<contacts.Link> = messages.SentMessage;
inputGeoChat#74d456fa chat_id:int access_hash:long = InputGeoChat;
inputNotifyGeoChatPeer#4d8ddec8 peer:InputGeoChat = InputNotifyPeer;
geoChat#75eaea5a id:int access_hash:long title:string address:string venue:string geo:GeoPoint photo:ChatPhoto participants_count:int date:int checked_in:Bool version:int = Chat;
geoChatMessageEmpty#60311a9b chat_id:int id:int = GeoChatMessage;
geoChatMessage#4505f8e1 chat_id:int id:int from_id:int date:int message:string media:MessageMedia = GeoChatMessage;
geoChatMessageService#d34fa24e chat_id:int id:int from_id:int date:int action:MessageAction = GeoChatMessage;
geochats.statedMessage#17b1578b message:GeoChatMessage chats:Vector<Chat> users:Vector<User> seq:int = geochats.StatedMessage;
geochats.located#48feb267 results:Vector<ChatLocated> messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Located;
geochats.messages#d1526db1 messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
geochats.messagesSlice#bc5863e8 count:int messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
messageActionGeoChatCreate#6f038ebc title:string address:string = MessageAction;
messageActionGeoChatCheckin#0c7d53de = MessageAction;
updateNewGeoChatMessage#5a68e3f7 message:GeoChatMessage = Update;
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
updateEncryptedMessagesRead#38fe25b7 chat_id:int max_date:int date:int = Update;
encryptedChatEmpty#ab7ec0a0 id:int = EncryptedChat;
encryptedChatWaiting#3bf703dc id:int access_hash:long date:int admin_id:int participant_id:int = EncryptedChat;
encryptedChatRequested#c878527e id:int access_hash:long date:int admin_id:int participant_id:int g_a:bytes = EncryptedChat;
encryptedChat#fa56ce36 id:int access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long = EncryptedChat;
encryptedChatDiscarded#13d6dd27 id:int = EncryptedChat;
inputEncryptedChat#f141b5e1 chat_id:int access_hash:long = InputEncryptedChat;
encryptedFileEmpty#c21f497e = EncryptedFile;
encryptedFile#4a70994c id:long access_hash:long size:int dc_id:int key_fingerprint:int = EncryptedFile;
inputEncryptedFileEmpty#1837c364 = InputEncryptedFile;
inputEncryptedFileUploaded#64bd0306 id:long parts:int md5_checksum:string key_fingerprint:int = InputEncryptedFile;
inputEncryptedFile#5a17b5e5 id:long access_hash:long = InputEncryptedFile;
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
encryptedMessage#ed18c118 random_id:long chat_id:int date:int bytes:bytes file:EncryptedFile = EncryptedMessage;
encryptedMessageService#23734b06 random_id:long chat_id:int date:int bytes:bytes = EncryptedMessage;
decryptedMessageLayer#99a438cf layer:int message:DecryptedMessage = DecryptedMessageLayer;
decryptedMessage#1f814f1f random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage;
decryptedMessageService#aa48327d random_id:long random_bytes:bytes action:DecryptedMessageAction = DecryptedMessage;
decryptedMessageMediaEmpty#089f5c4a = DecryptedMessageMedia;
decryptedMessageMediaPhoto#32798a8c thumb:bytes thumb_w:int thumb_h:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaVideo#524a415d thumb:bytes thumb_w:int thumb_h:int duration:int mime_type:string w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaGeoPoint#35480a59 lat:double long:double = DecryptedMessageMedia;
decryptedMessageMediaContact#588a0a97 phone_number:string first_name:string last_name:string user_id:int = DecryptedMessageMedia;
decryptedMessageActionSetMessageTTL#a1733aec ttl_seconds:int = DecryptedMessageAction;
messages.dhConfigNotModified#c0e24635 random:bytes = messages.DhConfig;
messages.dhConfig#2c221edd g:int p:bytes version:int random:bytes = messages.DhConfig;
messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
inputEncryptedFileBigUploaded#2dc173c8 id:long parts:int key_fingerprint:int = InputEncryptedFile;
updateChatParticipantAdd#3a0eeb22 chat_id:int user_id:int inviter_id:int version:int = Update;
updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update;
updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
inputMediaUploadedAudio#4e498cab file:InputFile duration:int mime_type:string = InputMedia;
inputMediaAudio#89938781 id:InputAudio = InputMedia;
inputMediaUploadedDocument#34e794bd file:InputFile file_name:string mime_type:string = InputMedia;
inputMediaUploadedThumbDocument#3e46de5d file:InputFile thumb:InputFile file_name:string mime_type:string = InputMedia;
inputMediaDocument#d184e841 id:InputDocument = InputMedia;
messageMediaDocument#2fda2204 document:Document = MessageMedia;
messageMediaAudio#c6b68300 audio:Audio = MessageMedia;
inputAudioEmpty#d95adc84 = InputAudio;
inputAudio#77d440ff id:long access_hash:long = InputAudio;
inputDocumentEmpty#72f0eaae = InputDocument;
inputDocument#18798952 id:long access_hash:long = InputDocument;
inputAudioFileLocation#74dc404d id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
decryptedMessageMediaDocument#b095434b thumb:bytes thumb_w:int thumb_h:int file_name:string mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
decryptedMessageMediaAudio#57e0a9cb duration:int mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
audioEmpty#586988d8 id:long = Audio;
audio#c7ac6496 id:long access_hash:long user_id:int date:int duration:int mime_type:string size:int dc_id:int = Audio;
documentEmpty#36f8c871 id:long = Document;
document#9efc6326 id:long access_hash:long user_id:int date:int file_name:string mime_type:string size:int thumb:PhotoSize dc_id:int = Document;
help.support#17c6b5f6 phone_number:string user:User = help.Support;
decryptedMessageActionReadMessages#0c4f40be random_ids:Vector<long> = DecryptedMessageAction;
decryptedMessageActionDeleteMessages#65614304 random_ids:Vector<long> = DecryptedMessageAction;
decryptedMessageActionScreenshotMessages#8ac1f475 random_ids:Vector<long> = DecryptedMessageAction;
decryptedMessageActionFlushHistory#6719e45c = DecryptedMessageAction;
decryptedMessageActionNotifyLayer#f3048883 layer:int = DecryptedMessageAction;
notifyPeer#9fd40bd8 peer:Peer = NotifyPeer;
notifyUsers#b4c83b4c = NotifyPeer;
notifyChats#c007cec3 = NotifyPeer;
notifyAll#74d07c60 = NotifyPeer;
updateUserBlocked#80ece81a user_id:int blocked:Bool = Update;
updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update;
za int = Z 0;
zb {n:#} int %(Vector int) = Z (n + 1);
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode;
auth.sendCall#03c51564 phone_number:string phone_code_hash:string = Bool;
auth.signUp#1b067634 phone_number:string phone_code_hash:string phone_code:string first_name:string last_name:string = auth.Authorization;
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
auth.logOut#5717da40 = Bool;
auth.resetAuthorizations#9fab0d1a = Bool;
auth.sendInvites#771c1d97 phone_numbers:Vector<string> message:string = Bool;
auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
auth.importAuthorization#e3ef9613 id:int bytes:bytes = auth.Authorization;
account.registerDevice#446c712c token_type:int token:string device_model:string system_version:string app_version:string app_sandbox:Bool lang_code:string = Bool;
account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
account.resetNotifySettings#db7e1747 = Bool;
account.updateProfile#f0888d68 first_name:string last_name:string = User;
account.updateStatus#6628562c offline:Bool = Bool;
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
users.getUsers#0d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
contacts.getContacts#22c6aa08 hash:string = contacts.Contacts;
contacts.importContacts#da30b32d contacts:Vector<InputContact> replace:Bool = contacts.ImportedContacts;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.getSuggested#cd773428 limit:int = contacts.Suggested;
contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
contacts.block#332b49fc id:InputUser = Bool;
contacts.unblock#e54100bd id:InputUser = Bool;
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
messages.getDialogs#eccf1df6 offset:int max_id:int limit:int = messages.Dialogs;
messages.getHistory#92a1df2f peer:InputPeer offset:int max_id:int limit:int = messages.Messages;
messages.search#07e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
messages.readHistory#b04f2510 peer:InputPeer max_id:int offset:int = messages.AffectedHistory;
messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
messages.deleteMessages#14f2dd0a id:Vector<int> = Vector<int>;
messages.restoreMessages#395f9d7e id:Vector<int> = Vector<int>;
messages.receivedMessages#28abcb68 max_id:int = Vector<int>;
messages.setTyping#719839e9 peer:InputPeer typing:Bool = Bool;
messages.sendMessage#4cde0aab peer:InputPeer message:string random_id:long = messages.SentMessage;
messages.sendMedia#a3c85d76 peer:InputPeer media:InputMedia random_id:long = messages.StatedMessage;
messages.forwardMessages#514cd10f peer:InputPeer id:Vector<int> = messages.StatedMessages;
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
messages.editChatTitle#b4bc68b5 chat_id:int title:string = messages.StatedMessage;
messages.editChatPhoto#d881821d chat_id:int photo:InputChatPhoto = messages.StatedMessage;
messages.addChatUser#2ee9ee9e chat_id:int user_id:InputUser fwd_limit:int = messages.StatedMessage;
messages.deleteChatUser#c3c5cd23 chat_id:int user_id:InputUser = messages.StatedMessage;
messages.createChat#419d9aee users:Vector<InputUser> title:string = messages.StatedMessage;
updates.getState#edd4882a = updates.State;
updates.getDifference#0a041495 pts:int date:int qts:int = updates.Difference;
photos.updateProfilePhoto#eef579a0 id:InputPhoto crop:InputPhotoCrop = UserProfilePhoto;
photos.uploadProfilePhoto#d50f9c88 file:InputFile caption:string geo_point:InputGeoPoint crop:InputPhotoCrop = photos.Photo;
upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload.File;
help.getConfig#c4f9186b = Config;
help.getNearestDc#1fb33026 = NearestDc;
help.getAppUpdate#c812ac7e device_model:string system_version:string app_version:string lang_code:string = help.AppUpdate;
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getInviteText#a4a95186 lang_code:string = help.InviteText;
photos.getUserPhotos#b7ee553c user_id:InputUser offset:int max_id:int limit:int = photos.Photos;
messages.forwardMessage#03f3f4f2 peer:InputPeer id:int random_id:long = messages.StatedMessage;
messages.sendBroadcast#41bb0972 contacts:Vector<InputUser> message:string media:InputMedia = messages.StatedMessages;
geochats.getLocated#7f192d8f geo_point:InputGeoPoint radius:int limit:int = geochats.Located;
geochats.getRecents#e1427e6f offset:int limit:int = geochats.Messages;
geochats.checkin#55b3e8fb peer:InputGeoChat = geochats.StatedMessage;
geochats.getFullChat#6722dd6f peer:InputGeoChat = messages.ChatFull;
geochats.editChatTitle#4c8e2273 peer:InputGeoChat title:string address:string = geochats.StatedMessage;
geochats.editChatPhoto#35d81a95 peer:InputGeoChat photo:InputChatPhoto = geochats.StatedMessage;
geochats.search#cfcdc44d peer:InputGeoChat q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = geochats.Messages;
geochats.getHistory#b53f7a68 peer:InputGeoChat offset:int max_id:int limit:int = geochats.Messages;
geochats.setTyping#08b8a729 peer:InputGeoChat typing:Bool = Bool;
geochats.sendMessage#061b0044 peer:InputGeoChat message:string random_id:long = geochats.StatedMessage;
geochats.sendMedia#b8f0deff peer:InputGeoChat media:InputMedia random_id:long = geochats.StatedMessage;
geochats.createGeoChat#0e092e16 title:string geo_point:InputGeoPoint address:string venue:string = geochats.StatedMessage;
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
messages.discardEncryption#edd923c5 chat_id:int = Bool;
messages.setEncryptedTyping#791451ed peer:InputEncryptedChat typing:Bool = Bool;
messages.readEncryptedHistory#7f4b690a peer:InputEncryptedChat max_date:int = Bool;
messages.sendEncrypted#a9776773 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
messages.sendEncryptedFile#9a901b66 peer:InputEncryptedChat random_id:long data:bytes file:InputEncryptedFile = messages.SentEncryptedMessage;
messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
help.getSupport#9cdf08cd = help.Support;
invokeWithLayer15#b4418b64 {X:Type} query:!X = X;

504
scheme16.tl Normal file
View file

@ -0,0 +1,504 @@
int ?= Int;
long ?= Long;
double ?= Double;
string ?= String;
bytes string = Bytes;
boolFalse#bc799737 = Bool;
boolTrue#997275b5 = Bool;
vector#1cb5c415 {t:Type} # [ t ] = Vector t;
error#c4b9f9bb code:int text:string = Error;
null#56730bcc = Null;
inputPeerEmpty#7f3b18ea = InputPeer;
inputPeerSelf#7da07ec9 = InputPeer;
inputPeerContact#1023dbe8 user_id:int = InputPeer;
inputPeerForeign#9b447325 user_id:int access_hash:long = InputPeer;
inputPeerChat#179be863 chat_id:int = InputPeer;
inputUserEmpty#b98886cf = InputUser;
inputUserSelf#f7c1b13f = InputUser;
inputUserContact#86e94f65 user_id:int = InputUser;
inputUserForeign#655e74ff user_id:int access_hash:long = InputUser;
inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact;
inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile;
inputMediaEmpty#9664f57f = InputMedia;
inputMediaUploadedPhoto#2dc53a7d file:InputFile = InputMedia;
inputMediaPhoto#8f2ab2ec id:InputPhoto = InputMedia;
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
inputMediaContact#a6e45987 phone_number:string first_name:string last_name:string = InputMedia;
inputMediaUploadedVideo#133ad6f6 file:InputFile duration:int w:int h:int mime_type:string = InputMedia;
inputMediaUploadedThumbVideo#9912dabf file:InputFile thumb:InputFile duration:int w:int h:int mime_type:string = InputMedia;
inputMediaVideo#7f023ae6 id:InputVideo = InputMedia;
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
inputChatUploadedPhoto#94254732 file:InputFile crop:InputPhotoCrop = InputChatPhoto;
inputChatPhoto#b2e1bf08 id:InputPhoto crop:InputPhotoCrop = InputChatPhoto;
inputGeoPointEmpty#e4c123d6 = InputGeoPoint;
inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint;
inputPhotoEmpty#1cd7bf0d = InputPhoto;
inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto;
inputVideoEmpty#5508ec75 = InputVideo;
inputVideo#ee579652 id:long access_hash:long = InputVideo;
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
inputVideoFileLocation#3d0364ec id:long access_hash:long = InputFileLocation;
inputPhotoCropAuto#ade6b004 = InputPhotoCrop;
inputPhotoCrop#d9915325 crop_left:double crop_top:double crop_width:double = InputPhotoCrop;
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
peerUser#9db1bc6d user_id:int = Peer;
peerChat#bad0e5bb chat_id:int = Peer;
storage.fileUnknown#aa963b05 = storage.FileType;
storage.fileJpeg#7efe0e = storage.FileType;
storage.fileGif#cae1aadf = storage.FileType;
storage.filePng#a4f63c0 = storage.FileType;
storage.filePdf#ae1e508d = storage.FileType;
storage.fileMp3#528a0677 = storage.FileType;
storage.fileMov#4b09ebbc = storage.FileType;
storage.filePartial#40bc6f52 = storage.FileType;
storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;
fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileLocation;
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
userEmpty#200250ba id:int = User;
userSelf#720535ec id:int first_name:string last_name:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User;
userContact#f2fb8319 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userRequest#22e8ceb0 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userForeign#5214c89d id:int first_name:string last_name:string access_hash:long photo:UserProfilePhoto status:UserStatus = User;
userDeleted#b29ad7cc id:int first_name:string last_name:string = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
userStatusEmpty#9d05049 = UserStatus;
userStatusOnline#edb93949 expires:int = UserStatus;
userStatusOffline#8c703f was_online:int = UserStatus;
chatEmpty#9ba2d800 id:int = Chat;
chat#6e9c9bc7 id:int title:string photo:ChatPhoto participants_count:int date:int left:Bool version:int = Chat;
chatForbidden#fb0ccc41 id:int title:string date:int = Chat;
chatFull#630e61be id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings = ChatFull;
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
chatParticipantsForbidden#fd2bb8a chat_id:int = ChatParticipants;
chatParticipants#7841b415 chat_id:int admin_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants;
chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
messageEmpty#83e5de54 id:int = Message;
message#22eb6aba id:int from_id:int to_id:Peer out:Bool unread:Bool date:int message:string media:MessageMedia = Message;
messageForwarded#5f46804 id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer out:Bool unread:Bool date:int message:string media:MessageMedia = Message;
messageService#9f8d60bb id:int from_id:int to_id:Peer out:Bool unread:Bool date:int action:MessageAction = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
messageMediaPhoto#c8c45a2a photo:Photo = MessageMedia;
messageMediaVideo#a2d24290 video:Video = MessageMedia;
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
messageMediaUnsupported#29632a36 bytes:bytes = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
messageActionChatEditTitle#b5a1ce5a title:string = MessageAction;
messageActionChatEditPhoto#7fcb13a8 photo:Photo = MessageAction;
messageActionChatDeletePhoto#95e3fbef = MessageAction;
messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
dialog#ab3a99ac peer:Peer top_message:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
photoEmpty#2331b22d id:long = Photo;
photo#22b56751 id:long access_hash:long user_id:int date:int caption:string geo:GeoPoint sizes:Vector<PhotoSize> = Photo;
photoSizeEmpty#e17e23c type:string = PhotoSize;
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
videoEmpty#c10658a8 id:long = Video;
video#388fa391 id:long access_hash:long user_id:int date:int caption:string duration:int mime_type:string size:int thumb:PhotoSize dc_id:int w:int h:int = Video;
geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#2049d70c long:double lat:double = GeoPoint;
auth.checkedPhone#e300cc3b phone_registered:Bool phone_invited:Bool = auth.CheckedPhone;
auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
auth.authorization#f6b673a4 expires:int user:User = auth.Authorization;
auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorization;
inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
inputNotifyUsers#193b4417 = InputNotifyPeer;
inputNotifyChats#4a95e84e = InputNotifyPeer;
inputNotifyAll#a429b886 = InputNotifyPeer;
inputPeerNotifyEventsEmpty#f03064d8 = InputPeerNotifyEvents;
inputPeerNotifyEventsAll#e86a2c74 = InputPeerNotifyEvents;
inputPeerNotifySettings#46a2ce98 mute_until:int sound:string show_previews:Bool events_mask:int = InputPeerNotifySettings;
peerNotifyEventsEmpty#add53cb3 = PeerNotifyEvents;
peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents;
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
peerNotifySettings#8d5e11ee mute_until:int sound:string show_previews:Bool events_mask:int = PeerNotifySettings;
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
userFull#771095da user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool real_first_name:string real_last_name:string = UserFull;
contact#f911c994 user_id:int mutual:Bool = Contact;
importedContact#d0028438 user_id:int client_id:long = ImportedContact;
contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
contactFound#ea879f95 user_id:int = ContactFound;
contactSuggested#3de191a1 user_id:int mutual_contacts:int = ContactSuggested;
contactStatus#aa77b873 user_id:int expires:int = ContactStatus;
chatLocated#3631cf4c chat_id:int distance:int = ChatLocated;
contacts.foreignLinkUnknown#133421f8 = contacts.ForeignLink;
contacts.foreignLinkRequested#a7801f47 has_phone:Bool = contacts.ForeignLink;
contacts.foreignLinkMutual#1bea8ce1 = contacts.ForeignLink;
contacts.myLinkEmpty#d22a1c60 = contacts.MyLink;
contacts.myLinkRequested#6c69efee contact:Bool = contacts.MyLink;
contacts.myLinkContact#c240ebd9 = contacts.MyLink;
contacts.link#eccea3f5 my_link:contacts.MyLink foreign_link:contacts.ForeignLink user:User = contacts.Link;
contacts.contacts#6f8b8cb2 contacts:Vector<Contact> users:Vector<User> = contacts.Contacts;
contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
contacts.importedContacts#ad524315 imported:Vector<ImportedContact> retry_contacts:Vector<long> users:Vector<User> = contacts.ImportedContacts;
contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.found#566000e results:Vector<ContactFound> users:Vector<User> = contacts.Found;
contacts.suggested#5649dcc5 results:Vector<ContactSuggested> users:Vector<User> = contacts.Suggested;
messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messageEmpty#3f4e0648 = messages.Message;
messages.message#ff90c417 message:Message chats:Vector<Chat> users:Vector<User> = messages.Message;
messages.statedMessages#969478bb messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessages;
messages.statedMessage#d07ae726 message:Message chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessage;
messages.sentMessage#d1f4d35c id:int date:int pts:int seq:int = messages.SentMessage;
messages.chat#40e9002a chat:Chat users:Vector<User> = messages.Chat;
messages.chats#8150cbd8 chats:Vector<Chat> users:Vector<User> = messages.Chats;
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
messages.affectedHistory#b7de36f2 pts:int seq:int offset:int = messages.AffectedHistory;
inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
updateNewMessage#13abdb3 message:Message pts:int = Update;
updateMessageID#4e90bfd6 id:int random_id:long = Update;
updateReadMessages#c6649e31 messages:Vector<int> pts:int = Update;
updateDeleteMessages#a92bfe26 messages:Vector<int> pts:int = Update;
updateRestoreMessages#d15de04d messages:Vector<int> pts:int = Update;
updateUserTyping#6baa8508 user_id:int = Update;
updateChatUserTyping#3c46cfe6 chat_id:int user_id:int = Update;
updateChatParticipants#7761198 participants:ChatParticipants = Update;
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
updateUserName#da22d9ad user_id:int first_name:string last_name:string = Update;
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
updateActivation#6f690963 user_id:int = Update;
updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
updates.differenceEmpty#5d75a138 date:int seq:int = updates.Difference;
updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> state:updates.State = updates.Difference;
updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
updatesTooLong#e317af7e = Updates;
updateShortMessage#d3f45784 id:int from_id:int message:string pts:int date:int seq:int = Updates;
updateShortChatMessage#2b2fbd4e id:int from_id:int chat_id:int message:string pts:int date:int seq:int = Updates;
updateShort#78d4dec1 update:Update date:int = Updates;
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
photos.photos#8dca6aa5 photos:Vector<Photo> users:Vector<User> = photos.Photos;
photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> = photos.Photos;
photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
dcOption#2ec2a43c id:int hostname:string ip_address:string port:int = DcOption;
config#2e54dd74 date:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int = Config;
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
help.appUpdate#8987f311 id:int critical:Bool url:string text:string = help.AppUpdate;
help.noAppUpdate#c45a6536 = help.AppUpdate;
help.inviteText#18cb9f78 message:string = help.InviteText;
messages.statedMessagesLinks#3e74f5c6 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessages;
messages.statedMessageLink#a9af2881 message:Message chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessage;
messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector<contacts.Link> = messages.SentMessage;
inputGeoChat#74d456fa chat_id:int access_hash:long = InputGeoChat;
inputNotifyGeoChatPeer#4d8ddec8 peer:InputGeoChat = InputNotifyPeer;
geoChat#75eaea5a id:int access_hash:long title:string address:string venue:string geo:GeoPoint photo:ChatPhoto participants_count:int date:int checked_in:Bool version:int = Chat;
geoChatMessageEmpty#60311a9b chat_id:int id:int = GeoChatMessage;
geoChatMessage#4505f8e1 chat_id:int id:int from_id:int date:int message:string media:MessageMedia = GeoChatMessage;
geoChatMessageService#d34fa24e chat_id:int id:int from_id:int date:int action:MessageAction = GeoChatMessage;
geochats.statedMessage#17b1578b message:GeoChatMessage chats:Vector<Chat> users:Vector<User> seq:int = geochats.StatedMessage;
geochats.located#48feb267 results:Vector<ChatLocated> messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Located;
geochats.messages#d1526db1 messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
geochats.messagesSlice#bc5863e8 count:int messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
messageActionGeoChatCreate#6f038ebc title:string address:string = MessageAction;
messageActionGeoChatCheckin#c7d53de = MessageAction;
updateNewGeoChatMessage#5a68e3f7 message:GeoChatMessage = Update;
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
updateEncryptedMessagesRead#38fe25b7 chat_id:int max_date:int date:int = Update;
encryptedChatEmpty#ab7ec0a0 id:int = EncryptedChat;
encryptedChatWaiting#3bf703dc id:int access_hash:long date:int admin_id:int participant_id:int = EncryptedChat;
encryptedChatRequested#c878527e id:int access_hash:long date:int admin_id:int participant_id:int g_a:bytes = EncryptedChat;
encryptedChat#fa56ce36 id:int access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long = EncryptedChat;
encryptedChatDiscarded#13d6dd27 id:int = EncryptedChat;
inputEncryptedChat#f141b5e1 chat_id:int access_hash:long = InputEncryptedChat;
encryptedFileEmpty#c21f497e = EncryptedFile;
encryptedFile#4a70994c id:long access_hash:long size:int dc_id:int key_fingerprint:int = EncryptedFile;
inputEncryptedFileEmpty#1837c364 = InputEncryptedFile;
inputEncryptedFileUploaded#64bd0306 id:long parts:int md5_checksum:string key_fingerprint:int = InputEncryptedFile;
inputEncryptedFile#5a17b5e5 id:long access_hash:long = InputEncryptedFile;
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
encryptedMessage#ed18c118 random_id:long chat_id:int date:int bytes:bytes file:EncryptedFile = EncryptedMessage;
encryptedMessageService#23734b06 random_id:long chat_id:int date:int bytes:bytes = EncryptedMessage;
messages.dhConfigNotModified#c0e24635 random:bytes = messages.DhConfig;
messages.dhConfig#2c221edd g:int p:bytes version:int random:bytes = messages.DhConfig;
messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
inputEncryptedFileBigUploaded#2dc173c8 id:long parts:int key_fingerprint:int = InputEncryptedFile;
updateChatParticipantAdd#3a0eeb22 chat_id:int user_id:int inviter_id:int version:int = Update;
updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update;
updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
inputMediaUploadedAudio#4e498cab file:InputFile duration:int mime_type:string = InputMedia;
inputMediaAudio#89938781 id:InputAudio = InputMedia;
inputMediaUploadedDocument#34e794bd file:InputFile file_name:string mime_type:string = InputMedia;
inputMediaUploadedThumbDocument#3e46de5d file:InputFile thumb:InputFile file_name:string mime_type:string = InputMedia;
inputMediaDocument#d184e841 id:InputDocument = InputMedia;
messageMediaDocument#2fda2204 document:Document = MessageMedia;
messageMediaAudio#c6b68300 audio:Audio = MessageMedia;
inputAudioEmpty#d95adc84 = InputAudio;
inputAudio#77d440ff id:long access_hash:long = InputAudio;
inputDocumentEmpty#72f0eaae = InputDocument;
inputDocument#18798952 id:long access_hash:long = InputDocument;
inputAudioFileLocation#74dc404d id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
audioEmpty#586988d8 id:long = Audio;
audio#c7ac6496 id:long access_hash:long user_id:int date:int duration:int mime_type:string size:int dc_id:int = Audio;
documentEmpty#36f8c871 id:long = Document;
document#9efc6326 id:long access_hash:long user_id:int date:int file_name:string mime_type:string size:int thumb:PhotoSize dc_id:int = Document;
help.support#17c6b5f6 phone_number:string user:User = help.Support;
notifyPeer#9fd40bd8 peer:Peer = NotifyPeer;
notifyUsers#b4c83b4c = NotifyPeer;
notifyChats#c007cec3 = NotifyPeer;
notifyAll#74d07c60 = NotifyPeer;
updateUserBlocked#80ece81a user_id:int blocked:Bool = Update;
updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update;
auth.sentAppCode#e325edcf phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode;
auth.sendCall#3c51564 phone_number:string phone_code_hash:string = Bool;
auth.signUp#1b067634 phone_number:string phone_code_hash:string phone_code:string first_name:string last_name:string = auth.Authorization;
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
auth.logOut#5717da40 = Bool;
auth.resetAuthorizations#9fab0d1a = Bool;
auth.sendInvites#771c1d97 phone_numbers:Vector<string> message:string = Bool;
auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
auth.importAuthorization#e3ef9613 id:int bytes:bytes = auth.Authorization;
auth.bindTempAuthKey#cdd42a05 perm_auth_key_id:long nonce:long expires_at:int encrypted_message:bytes = Bool;
account.registerDevice#446c712c token_type:int token:string device_model:string system_version:string app_version:string app_sandbox:Bool lang_code:string = Bool;
account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
account.resetNotifySettings#db7e1747 = Bool;
account.updateProfile#f0888d68 first_name:string last_name:string = User;
account.updateStatus#6628562c offline:Bool = Bool;
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
contacts.getContacts#22c6aa08 hash:string = contacts.Contacts;
contacts.importContacts#da30b32d contacts:Vector<InputContact> replace:Bool = contacts.ImportedContacts;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.getSuggested#cd773428 limit:int = contacts.Suggested;
contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
contacts.block#332b49fc id:InputUser = Bool;
contacts.unblock#e54100bd id:InputUser = Bool;
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
contacts.exportCard#84e53737 = Vector<int>;
contacts.importCard#4fe196fe export_card:Vector<int> = User;
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
messages.getDialogs#eccf1df6 offset:int max_id:int limit:int = messages.Dialogs;
messages.getHistory#92a1df2f peer:InputPeer offset:int max_id:int limit:int = messages.Messages;
messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
messages.readHistory#b04f2510 peer:InputPeer max_id:int offset:int = messages.AffectedHistory;
messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
messages.deleteMessages#14f2dd0a id:Vector<int> = Vector<int>;
messages.restoreMessages#395f9d7e id:Vector<int> = Vector<int>;
messages.receivedMessages#28abcb68 max_id:int = Vector<int>;
messages.setTyping#719839e9 peer:InputPeer typing:Bool = Bool;
messages.sendMessage#4cde0aab peer:InputPeer message:string random_id:long = messages.SentMessage;
messages.sendMedia#a3c85d76 peer:InputPeer media:InputMedia random_id:long = messages.StatedMessage;
messages.forwardMessages#514cd10f peer:InputPeer id:Vector<int> = messages.StatedMessages;
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
messages.editChatTitle#b4bc68b5 chat_id:int title:string = messages.StatedMessage;
messages.editChatPhoto#d881821d chat_id:int photo:InputChatPhoto = messages.StatedMessage;
messages.addChatUser#2ee9ee9e chat_id:int user_id:InputUser fwd_limit:int = messages.StatedMessage;
messages.deleteChatUser#c3c5cd23 chat_id:int user_id:InputUser = messages.StatedMessage;
messages.createChat#419d9aee users:Vector<InputUser> title:string = messages.StatedMessage;
updates.getState#edd4882a = updates.State;
updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;
photos.updateProfilePhoto#eef579a0 id:InputPhoto crop:InputPhotoCrop = UserProfilePhoto;
photos.uploadProfilePhoto#d50f9c88 file:InputFile caption:string geo_point:InputGeoPoint crop:InputPhotoCrop = photos.Photo;
upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload.File;
help.getConfig#c4f9186b = Config;
help.getNearestDc#1fb33026 = NearestDc;
help.getAppUpdate#c812ac7e device_model:string system_version:string app_version:string lang_code:string = help.AppUpdate;
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getInviteText#a4a95186 lang_code:string = help.InviteText;
photos.getUserPhotos#b7ee553c user_id:InputUser offset:int max_id:int limit:int = photos.Photos;
messages.forwardMessage#3f3f4f2 peer:InputPeer id:int random_id:long = messages.StatedMessage;
messages.sendBroadcast#41bb0972 contacts:Vector<InputUser> message:string media:InputMedia = messages.StatedMessages;
geochats.getLocated#7f192d8f geo_point:InputGeoPoint radius:int limit:int = geochats.Located;
geochats.getRecents#e1427e6f offset:int limit:int = geochats.Messages;
geochats.checkin#55b3e8fb peer:InputGeoChat = geochats.StatedMessage;
geochats.getFullChat#6722dd6f peer:InputGeoChat = messages.ChatFull;
geochats.editChatTitle#4c8e2273 peer:InputGeoChat title:string address:string = geochats.StatedMessage;
geochats.editChatPhoto#35d81a95 peer:InputGeoChat photo:InputChatPhoto = geochats.StatedMessage;
geochats.search#cfcdc44d peer:InputGeoChat q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = geochats.Messages;
geochats.getHistory#b53f7a68 peer:InputGeoChat offset:int max_id:int limit:int = geochats.Messages;
geochats.setTyping#8b8a729 peer:InputGeoChat typing:Bool = Bool;
geochats.sendMessage#61b0044 peer:InputGeoChat message:string random_id:long = geochats.StatedMessage;
geochats.sendMedia#b8f0deff peer:InputGeoChat media:InputMedia random_id:long = geochats.StatedMessage;
geochats.createGeoChat#e092e16 title:string geo_point:InputGeoPoint address:string venue:string = geochats.StatedMessage;
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
messages.discardEncryption#edd923c5 chat_id:int = Bool;
messages.setEncryptedTyping#791451ed peer:InputEncryptedChat typing:Bool = Bool;
messages.readEncryptedHistory#7f4b690a peer:InputEncryptedChat max_date:int = Bool;
messages.sendEncrypted#a9776773 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
messages.sendEncryptedFile#9a901b66 peer:InputEncryptedChat random_id:long data:bytes file:InputEncryptedFile = messages.SentEncryptedMessage;
messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
help.getSupport#9cdf08cd = help.Support;
auth.sendSms#da9f3e8 phone_number:string phone_code_hash:string = Bool;
invokeWithLayer16#cf5f0987 {X:Type} query:!X = X;

206
start-telegram-daemon Executable file
View file

@ -0,0 +1,206 @@
#!/usr/bin/perl -w
# start-engine
# derived from start-memcached
# 2003/2004 - Jay Bonci <jaybonci@debian.org>
# This script handles the parsing of the /etc/memcached.conf file
# and was originally created for the Debian distribution.
# Anyone may use this little script under the same terms as
# memcached itself.
# a bit changed it for telegram-daemon to generate config before start (Vitaly Valtman)
use POSIX qw(strftime);
use strict;
my $id = defined($ARGV[0]) ? $ARGV[0] : '';
my $idx = $id eq '' ? '' : " '$id'";
my $idl = ($id =~ /^\.(.*)$/ ? "-$1" : $id);
my $root = "";
my $params; my $etchandle; my $etcfile = "$root/etc/telegram-daemon/telegram-daemon$id.conf";
# This script assumes that engine is located at /usr/bin/engine, and
# that the pidfile is writable at /var/run/engine.pid
my $engine_pfx = "$root/usr/share/telegram-daemon/bin/";
my $pidfile = "$root/var/run/telegram-daemon$id.pid";
# If we don't get a valid logfile parameter in the /etc/engine.conf file,
# we'll just throw away all of our in-daemon output. We need to re-tie it so
# that non-bash shells will not hang on logout. Thanks to Michael Renner for
# the tip
my $fd_reopened = "/dev/null";
$fd_reopened = "$root/var/log/telegram-daemon/telegram-daemon$idl.log" if -d "$root/var/log/telegram-daemon/";
sub handle_logfile
{
my ($logfile) = @_;
$logfile = "$root/var/log/telegram-daemon/$logfile" unless $logfile =~ /\//;
$fd_reopened = $logfile;
}
sub reopen_logfile
{
my ($logfile) = @_;
open *STDERR, ">>$logfile";
open *STDOUT, ">>$logfile";
open *STDIN, ">>/dev/null";
chown 239, 239, $logfile;
$fd_reopened = $logfile;
}
sub adjust_arg
{
my ($arg) = @_;
if ($arg =~ /^newest:(.*)$/) {
my @L = split /:/, $1;
my $x = $arg;
my $xt = 0;
for my $y (@L) {
my @S = stat($y);
if (scalar @S && $S[9] > $xt) {
$x = $y;
$xt = $S[9];
}
}
return $x;
}
return $arg;
}
# This is set up in place here to support other non -[a-z] directives
my $conf_directives = {
"logfile" => \&handle_logfile,
};
my %Vars = (
"execute" => "msg-search-engine",
"work_dir" => "$root/var/lib/telegram-daemon"
);
my $have_c = 0;
my $have_l = 0;
my $have_u = 0;
my $have_aes = 0;
if(open $etchandle, $etcfile)
{
foreach my $line (<$etchandle>)
{
$line ||= "";
$line =~ s/\#.*//g;
$line =~ s/\s+$//g;
$line =~ s/^\s+//g;
next unless $line;
next if $line =~ /^\-[dh]/;
if($line =~ /^[^\-]/)
{
my ($directive, $int, $arg) = $line =~ /^(.*?)(\s+|\s*=\s*)(.*)/;
next unless $directive;
if (exists $conf_directives->{$directive}) {
$conf_directives->{$directive}->($arg);
} else {
$Vars{$directive} = $arg;
}
next;
}
$have_l = 1 if $line =~ /^-L\s/;
$have_c = 1 if $line =~ /^-c\s/;
$have_u = 1 if $line =~ /^-u\s/;
push @$params, $line;
}
}else{
$params = [];
}
push @$params, "-u telegramd" unless($have_u);
push @$params, "-L $fd_reopened" unless($have_l);
push @$params, "-c config$idl" unless($have_c);
$params = join " ", @$params;
if(-e $pidfile)
{
open PIDHANDLE, "$pidfile";
my $localpid = <PIDHANDLE>;
close PIDHANDLE;
if ($localpid && $localpid =~ /(\d+)/) { $localpid = $1; } else { $localpid = -1; }
if (-d "/proc/$localpid")
{
print STDERR "telegram-daemon$idl is already running.\n";
exit;
} else {
print STDERR "removing stale $pidfile.\n";
`rm -f $pidfile`;
}
}
if (exists $Vars{'quit'}) {
print STDERR "telegram-daemon$idl disabled\n";
exit(0);
}
my $engine = $engine_pfx.$Vars{'execute'};
my $wdir = $Vars{'work_dir'};
chdir $wdir if -d $wdir;
unless (-x $engine) {
print STDERR "executable $engine not found\n";
exit(1);
}
unless (-d $wdir) {
print STDERR "work directory $wdir not found\n";
exit(1);
}
for my $x ('s', 0 .. 9) {
if (defined($Vars{"arg$x"})) {
$params .= " ".adjust_arg($Vars{"arg$x"});
}
}
my $pid = fork();
if (!$pid) {
reopen_logfile ($fd_reopened);
chdir $wdir;
open(my $fh, '>', "config$idl");
my $text = <<"END_MSG"
config_directory="$wdir";
test=false;
msg_num=true;
binlog_enabled=true;
binlog="binlog$idl.bin";
pfs_enabled=true;
log_level = 0;
lua_script="script$idl.lua";
END_MSG
;
print $fh $text;
close $fh;
my $t;
$t = strftime ("%Y-%m-%d %H:%M:%S %Z", localtime);
print STDERR "[$t] invoking telegram-daemon$idl: $engine $params\n";
exec "$engine $params";
exit (0);
} else {
if (open PIDHANDLE,">$pidfile") {
print PIDHANDLE $pid;
close PIDHANDLE;
} else {
print STDERR "Can't write pidfile to $pidfile.\n";
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,413 +1,55 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#ifndef __STRUCTURES_H__
#define __STRUCTURES_H__
#include <assert.h>
typedef struct { int type; int id; } peer_id_t;
#include "tgl-layout.h"
#include "tgl-fetch.h"
//#define FLAG_EMPTY 1
#define FLAG_MESSAGE_EMPTY 1
#define FLAG_DELETED 2
#define FLAG_FORBIDDEN 4
#define FLAG_HAS_PHOTO 8
#define FLAG_CREATED 16
#define FLAG_USER_SELF 128
#define FLAG_USER_FOREIGN 256
#define FLAG_USER_CONTACT 512
#define FLAG_USER_IN_CONTACT 1024
#define FLAG_USER_OUT_CONTACT 2048
#define FLAG_CHAT_IN_CHAT 128
#define FLAG_ENCRYPTED 4096
#define FLAG_PENDING 8192
struct file_location {
int dc;
long long volume;
int local_id;
long long secret;
};
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 encr_photo {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
unsigned char *key;
unsigned char *iv;
int w;
int h;
};
struct encr_video {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
unsigned char *key;
unsigned char *iv;
int w;
int h;
int duration;
};
struct encr_audio {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
unsigned char *key;
unsigned char *iv;
int duration;
};
struct encr_document {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
unsigned char *key;
unsigned char *iv;
char *file_name;
char *mime_type;
};
struct encr_file {
char *filename;
unsigned char *key;
unsigned char *iv;
};
char *tgls_default_create_print_name (tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
struct user_status {
int online;
int when;
};
void tgls_free_user (struct tgl_user *U);
void tgls_free_chat (struct tgl_chat *U);
void tgls_free_photo (struct tgl_photo *P);
void tgls_free_message (struct tgl_message *M);
void tgls_clear_message (struct tgl_message *M);
struct user {
peer_id_t id;
int flags;
struct message *last;
char *print_name;
int structure_version;
struct file_location photo_big;
struct file_location photo_small;
long long photo_id;
struct photo photo;
char *first_name;
char *last_name;
char *phone;
long long access_hash;
struct user_status status;
int blocked;
char *real_first_name;
char *real_last_name;
};
struct tgl_message *tglm_message_alloc (long long id);
void tglm_message_insert_tree (struct tgl_message *M);
void tglm_update_message_id (struct tgl_message *M, long long id);
void tglm_message_insert (struct tgl_message *M);
void tglm_message_insert_unsent (struct tgl_message *M);
void tglm_message_remove_unsent (struct tgl_message *M);
void tglm_send_all_unsent (void);
void tglm_message_remove_tree (struct tgl_message *M);
void tglm_message_add_peer (struct tgl_message *M);
void tglm_message_del_peer (struct tgl_message *M);
void tglm_message_del_use (struct tgl_message *M);
void tglm_message_add_use (struct tgl_message *M);
struct chat_user {
int user_id;
int inviter_id;
int date;
};
struct chat {
peer_id_t id;
int flags;
struct message *last;
char *print_title;
int structure_version;
struct file_location photo_big;
struct file_location photo_small;
struct photo photo;
char *title;
int users_num;
int user_list_size;
int user_list_version;
struct chat_user *user_list;
int date;
int version;
int admin_id;
};
enum secret_chat_state {
sc_none,
sc_waiting,
sc_request,
sc_ok,
sc_deleted
};
struct secret_chat {
peer_id_t id;
int flags;
struct message *last;
char *print_name;
int structure_version;
struct file_location photo_big;
struct file_location photo_small;
struct photo photo;
int user_id;
int admin_id;
int date;
int ttl;
long long access_hash;
unsigned char *g_key;
unsigned char *nonce;
enum secret_chat_state state;
int key[64];
long long key_fingerprint;
};
typedef union peer {
struct {
peer_id_t id;
int flags;
struct message *last;
char *print_name;
int structure_version;
struct file_location photo_big;
struct file_location photo_small;
struct photo photo;
};
struct user user;
struct chat chat;
struct secret_chat encr_chat;
} peer_t;
struct video {
long long id;
long long access_hash;
int user_id;
int date;
int size;
int dc_id;
struct photo_size thumb;
char *caption;
int duration;
int w;
int h;
};
struct audio {
long long id;
long long access_hash;
int user_id;
int date;
int size;
int dc_id;
int duration;
};
struct document {
long long id;
long long access_hash;
int user_id;
int date;
int size;
int dc_id;
struct photo_size thumb;
char *caption;
char *mime_type;
};
struct message_action {
unsigned type;
union {
struct {
char *title;
int user_num;
int *users;
};
char *new_title;
struct photo photo;
int user;
int ttl;
};
};
struct message_media {
unsigned type;
union {
struct photo photo;
struct video video;
struct audio audio;
struct document document;
struct geo geo;
struct {
char *phone;
char *first_name;
char *last_name;
int user_id;
};
struct encr_photo encr_photo;
struct encr_video encr_video;
struct encr_audio encr_audio;
struct encr_document encr_document;
struct encr_file encr_file;
struct {
void *data;
int data_size;
};
};
};
struct message {
struct message *next_use, *prev_use;
struct message *next, *prev;
long long id;
int flags;
peer_id_t fwd_from_id;
int fwd_date;
peer_id_t from_id;
peer_id_t to_id;
int out;
int unread;
int date;
int service;
union {
struct message_action action;
struct {
char *message;
int message_len;
struct message_media media;
};
};
};
int fetch_file_location (struct file_location *loc);
int fetch_user_status (struct user_status *S);
int fetch_user (struct user *U);
struct user *fetch_alloc_user (void);
struct user *fetch_alloc_user_full (void);
struct chat *fetch_alloc_chat (void);
struct chat *fetch_alloc_chat_full (void);
struct secret_chat *fetch_alloc_encrypted_chat (void);
struct message *fetch_alloc_message (void);
struct message *fetch_alloc_geo_message (void);
struct message *fetch_alloc_message_short (void);
struct message *fetch_alloc_message_short_chat (void);
struct message *fetch_alloc_encrypted_message (void);
void fetch_encrypted_message_file (struct message_media *M);
void fetch_skip_encrypted_message_file (void);
void fetch_encrypted_message_file (struct message_media *M);
void fetch_message_action_encrypted (struct message_action *M);
peer_id_t fetch_peer_id (void);
void fetch_message_media (struct message_media *M);
void fetch_message_media_encrypted (struct message_media *M);
void fetch_message_action (struct message_action *M);
void message_insert_tree (struct message *M);
void free_user (struct user *U);
void free_chat (struct chat *U);
char *create_print_name (peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
int print_stat (char *s, int len);
peer_t *user_chat_get (peer_id_t id);
struct message *message_get (long long id);
void update_message_id (struct message *M, long long id);
void message_insert (struct message *M);
void free_photo (struct photo *P);
void fetch_photo (struct photo *P);
void insert_encrypted_chat (peer_t *P);
void insert_user (peer_t *P);
void insert_chat (peer_t *P);
void fetch_photo (struct photo *P);
void free_photo (struct photo *P);
void message_insert_unsent (struct message *M);
void message_remove_unsent (struct message *M);
void send_all_unsent (void);
void message_remove_tree (struct message *M);
void message_add_peer (struct message *M);
void message_del_peer (struct message *M);
void free_message (struct message *M);
void message_del_use (struct message *M);
void peer_insert_name (peer_t *P);
void peer_delete_name (peer_t *P);
peer_t *peer_lookup_name (const char *s);
#define PEER_USER 1
#define PEER_CHAT 2
#define PEER_GEO_CHAT 3
#define PEER_ENCR_CHAT 4
#define PEER_UNKNOWN 0
#define MK_USER(id) set_peer_id (PEER_USER,id)
#define MK_CHAT(id) set_peer_id (PEER_CHAT,id)
#define MK_GEO_CHAT(id) set_peer_id (PEER_GEO_CHAT,id)
#define MK_ENCR_CHAT(id) set_peer_id (PEER_ENCR_CHAT,id)
static inline int get_peer_type (peer_id_t id) {
return id.type;
}
static inline int get_peer_id (peer_id_t id) {
return id.id;
}
static inline peer_id_t set_peer_id (int type, int id) {
peer_id_t ID;
ID.id = id;
ID.type = type;
return ID;
}
static inline int cmp_peer_id (peer_id_t a, peer_id_t b) {
return memcmp (&a, &b, sizeof (a));
}
void tglp_peer_insert_name (tgl_peer_t *P);
void tglp_peer_delete_name (tgl_peer_t *P);
void tglp_insert_encrypted_chat (tgl_peer_t *P);
void tglp_insert_user (tgl_peer_t *P);
void tglp_insert_chat (tgl_peer_t *P);
#endif

332
telegram-daemon Executable file
View file

@ -0,0 +1,332 @@
#!/bin/bash
### BEGIN INIT INFO
# Provides: engine
# Required-Start: $local_fs $syslog
# Required-Stop: $local_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: KittenDB Meta Engine
### END INIT INFO
#
# run script for KittenDB Engine
# author: kot
# author: burunduk
# author: burunduk
#
# Version: 2013-06-06
#
# Features added:
# -- flock to avoid parallel execution
# -- checks to avoid creating empty engine configuration files
# a bit changed it for telegram-daemon to use different folders
# and to have posiiblilities to have fake root
# Vitaly Valtman
ROOT=""
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMONDIR=$ROOT/usr/share/telegram-daemon/bin
DAEMONBOOTSTRAP=$ROOT/usr/share/telegram-daemon/bin/start-telegram-daemon
NAME=telegram-daemon
DESC="KOT's meta engine"
PIDFILE=$ROOT/var/run/$NAME
LOCKFILE=$ROOT/var/lock/$NAME
CONFFILE=$ROOT/etc/telegram-daemon/$NAME
LOCK_WAIT=5
STOP_TIMEOUT=5
KILL_TIMEOUT=5
test -x $DAEMONDIR || exit 0
test -x $DAEMONBOOTSTRAP || exit 0
set -e
## Utilitary functions
# Send information to stderr
function echo_stderr() {
echo "$*" 1>&2
}
# Get engine status. Returns 0 on running engine, 1 otherwise.
function engine_status() {
local id="$1"
local pif="$PIDFILE.$id.pid"
if ! [ -f "$pif" ] ; then
echo "stopped"
return 1
fi
local pid="$(<$pif)"
if [ -z "$pid" ]; then
echo "corrupt pid file"
return 1
fi
if [ -d "/proc/$pid/" ]; then
echo "$pid"
return 0
else
echo "failed (pid $pid)"
return 1
fi
}
# Start engine. Usage: engine_start <eid>
function engine_start() {
local eid="$1"
local r=''
local pid=''
pid="$(engine_status "$eid")" && r='ok' || r='fail'
if [ "$r" == 'ok' ] ; then
echo_stderr "telegram-daemon-$eid: already running ($pid)"
else
start-stop-daemon --start --quiet --exec $DAEMONBOOTSTRAP -- .$eid 100> /dev/null
fi
return 0
}
# Stop engine. Usage: engine_stop <eid>
function engine_stop() {
local eid="$1"
local r=''
local status="$(engine_status "$eid")" && r='ok' || r='fail'
local pif="$PIDFILE.$eid.pid"
if [ "$r" == 'ok' ] ; then
start-stop-daemon --stop --quiet --oknodo --pidfile "$pif"
local ti=0
while [ $ti -lt $((10 * $STOP_TIMEOUT)) ] ; do
status="$(engine_status "$eid")" && r='ok' || r='fail'
if [ "$r" == 'fail' ]; then
break
fi
sleep 0.1
ti=$(($ti + 1))
done
if [ "$r" == 'ok' ] ; then
echo_stderr "telegram-daemon-$eid: not stopped, sending SIGKILL..."
start-stop-daemon --stop --quiet --oknodo --pidfile "$pif" --signal KILL
ti=0
while [ $ti -lt $((10 * $KILL_TIMEOUT)) ] ; do
status="$(engine_status "$eid")" && r='ok' || r='fail'
if [ "$r" == 'fail' ]; then
break
fi
sleep 0.1
ti=$(($ti + 1))
done
fi
if [ "$r" == 'ok' ] ; then
echo_stderr "telegram-daemon-$eid: not stopped with SIGKILL, giving up"
return 1
else
if [ -f "$pif" ] ; then
rm "$pif"
fi
echo "telegram-daemon-$eid: stopped"
fi
else
echo_stderr "telegram-daemon-$eid: not running: $status"
fi
return 0
}
# usage: engine_disable <id>
function engine_disable() {
local eid="$1"
local conf="$CONFFILE.$eid.conf"
[ -e "$conf" ] || return 1 # work only with existing engines
if grep -E '^quit 1$' "$conf" > /dev/null ; then
echo_stderr "telegram-daemon-$eid: already disabled"
else
echo 'quit 1' >> "$conf"
fi
return 0
}
# usage: engine_enable <id>
function engine_enable() {
local eid="$1"
local conf="$CONFFILE.$eid.conf"
[ -e "$conf" ] || return 1 # work only with existing engines
if ! grep -E '^quit' "$conf" > /dev/null ; then
echo_stderr "telegram-daemon-$eid: already enabled"
else
sed -i~ -e '/^quit/d' -- "$conf"
fi
return 0
}
# Wait for engine's command to be completed
function engine_wait() {
local eid="$1"
(
flock -x -w $(($LOCK_WAIT + $STOP_TIMEOUT + $KILL_TIMEOUT)) 100 || exit 1
) 100> $LOCKFILE.$eid.lock || echo "Unable to wait for $eid"
return 0
}
# Run a single command
# Only one instance of this command per engine is supposed to work
function run_one() {
local eid="$1"
shift
local command="$*"
[ "${#eid}" -gt 5 ] && return 0 # avoid long engine ids
(
flock -x -w $LOCK_WAIT 100 || exit 1
$command "$eid"
) 100> $LOCKFILE.$eid.lock
return 0
}
# Run commands
function run() {
local mode="$1"
shift
local command="$*"
local eid=''
if [ "$mode" == 'parallel' ] ; then
for eid in $arguments ; do
run_one "$eid" "$command" &
done
sleep 0.1
for eid in $arguments ; do
engine_wait "$eid"
done
else
for eid in $arguments ; do
run_one "$eid" "$command"
done
fi
return 0
}
# Get all actual engine ids
function arguments_all() {
local file=''
local id=''
local list=''
for file in $(ls $CONFFILE.?*.conf 2> /dev/null) ; do
id=${file#$CONFFILE.}
id=${id%.conf}
list="$list $id"
done
for file in $(ls $PIDFILE.?*.pid 2> /dev/null) ; do
id=${file#$PIDFILE.}
id=${id%.pid}
list="$list $id"
done
local f=''
for f in $list ; do echo "$f" ; done | sort -u
return 0
}
## Commands
# Start engine.
function engine_command_start() {
local eid="$1"
engine_start "$eid"
}
# Stop engine.
function engine_command_stop() {
local eid="$1"
engine_stop "$eid"
}
# Enable engine.
function engine_command_enable() {
local eid="$1"
engine_enable "$eid"
engine_start "$eid"
}
# Disable engine.
function engine_command_disable() {
local eid="$1"
engine_disable "$eid"
engine_stop "$eid"
}
# Restart engine.
function engine_command_restart() {
local eid="$1"
engine_stop "$eid"
echo "restarting telegram-daemon-$eid..."
engine_start "$eid"
}
# Send signal to engine. Usage: engine_command_signal <signal> <id>
function engine_command_signal() {
local id="$2"
local signal="$1"
local r=''
local comment="$(engine_status "$id")" && r='ok' || r='fail'
local res=''
if [ "$r" == 'ok' ]; then
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE.$id.pid --signal "$signal"
else
echo_stderr "telegram-daemon-$id: not running: $comment"
fi
return 0
}
# Get engine status
function engine_command_status() {
local id="$1"
local res="telegram-daemon-$id: "
local r=''
local pid=''
pid="$(engine_status "$id")" && r='ok' || r='fail'
if [ "$r" == 'ok' ]; then
res="$res $(COLUMNS=10000 ps -o pid,c,stime,time,cmd --no-header --pid $pid | sed -e 's/\/usr\/share\/telegram-daemon\/bin\///')"
else
res="$res $pid"
fi
echo "$res"
return 0
}
## Entry point
command="$1"
shift
arguments="$*"
if [ -z "$arguments" ] ; then
if [ "$command" == "status" -o "$command" == "start" -o "$command" == "rotate-logs" -o "$command" == "stop" ] ; then
arguments="$(arguments_all)"
fi
elif [ "$arguments" == "all" ] ; then
arguments="$(arguments_all)"
fi
if [ -z "$arguments" ] ; then
echo "nothing to do"
exit 0
fi
case "$command" in
('disable') run parallel engine_command_disable ;;
('enable') run parallel engine_command_enable ;;
#
('start') run parallel engine_command_start ;;
('status') run normal engine_command_status ;;
('stop') run parallel engine_command_stop ;;
#
('rotate-logs') run parallel engine_command_signal USR1 ;;
#
('restart'|'force-reload') run parallel engine_command_restart ;;
(*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|rotate-logs|status} [<ids...>|all]" >&2
echo " additional commands: disable <ids...>, enable <ids...>, reindex <ids...> (use with caution)" >&2
exit 1
;;
esac
exit 0

View file

@ -1,24 +1,22 @@
/*
This file is part of telegram-client.
This file is part of telegram-cli.
Telegram-client is free software: you can redistribute it and/or modify
Telegram-cli is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
Telegram-cli is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
along with this telegram-cli. If not, see <http://www.gnu.org/licenses/>.
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#define MAX_DC_NUM 9
#define MAX_PEER_NUM 100000
#ifndef PROG_NAME
#define PROG_NAME "telegram"
#define PROG_NAME "telegram-cli"
#endif

View file

@ -40,7 +40,34 @@ end
print ("HI, this is lua script")
function ok_cb(extra, success, result)
end
-- Notification code {{{
function get_title (P, Q)
if (Q.type == 'user') then
return P.first_name .. " " .. P.last_name
elseif (Q.type == 'chat') then
return Q.title
elseif (Q.type == 'encr_chat') then
return 'Secret chat with ' .. P.first_name .. ' ' .. P.last_name
else
return ''
end
end
local lgi = require ('lgi')
local notify = lgi.require('Notify')
notify.init ("Telegram updates")
local icon = os.getenv("HOME") .. "/.telegram-cli/telegram-pics/telegram_64.png"
function do_notify (user, msg)
local n = notify.Notification.new(user, msg, icon)
n:show ()
end
-- }}}
function on_msg_receive (msg)
if started == 0 then
@ -49,13 +76,13 @@ function on_msg_receive (msg)
if msg.out then
return
end
do_notify (get_title (msg.from, msg.to), msg.text)
if (msg.text == 'ping') then
if (msg.to.id == our_id) then
print ('sending pong to ' .. tostring (msg.from.print_name))
send_msg (msg.from.print_name, 'pong')
send_msg (msg.from.print_name, 'pong', ok_cb, false)
else
print ('sending pong to ' .. tostring (msg.to.print_name))
send_msg (msg.to.print_name, 'pong')
send_msg (msg.to.print_name, 'pong', ok_cb, false)
end
return
end
@ -67,29 +94,33 @@ function on_msg_receive (msg)
end
return
end
--vardump (msg)
--print ( "Message # " .. msg.id .. " (flags " .. msg.flags .. ")")
end
function on_our_id (id)
our_id = id
end
function on_secret_chat_created (peer)
--vardump (peer)
end
function on_user_update (user)
function on_user_update (user, what)
--vardump (user)
end
function on_chat_update (user)
--vardump (user)
function on_chat_update (chat, what)
--vardump (chat)
end
function on_secret_chat_update (schat, what)
--vardump (schat)
end
function on_get_difference_end ()
end
function cron()
-- do something
postpone (cron, false, 1.0)
end
function on_binlog_replay_end ()
started = 1
postpone (cron, false, 1.0)
end

53
tgl-fetch.h Normal file
View file

@ -0,0 +1,53 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2014
*/
#ifndef __TGL_FETCH_H__
#define __TGL_FETCH_H__
int tglf_fetch_file_location (struct tgl_file_location *loc);
int tglf_fetch_user_status (struct tgl_user_status *S);
int tglf_fetch_user (struct tgl_user *U);
struct tgl_user *tglf_fetch_alloc_user (void);
struct tgl_user *tglf_fetch_alloc_user_full (void);
struct tgl_chat *tglf_fetch_alloc_chat (void);
struct tgl_chat *tglf_fetch_alloc_chat_full (void);
struct tgl_secret_chat *tglf_fetch_alloc_encrypted_chat (void);
struct tgl_message *tglf_fetch_alloc_message (void);
struct tgl_message *tglf_fetch_alloc_geo_message (void);
struct tgl_message *tglf_fetch_alloc_message_short (void);
struct tgl_message *tglf_fetch_alloc_message_short_chat (void);
struct tgl_message *tglf_fetch_alloc_encrypted_message (void);
void tglf_fetch_encrypted_message_file (struct tgl_message_media *M);
tgl_peer_id_t tglf_fetch_peer_id (void);
void tglf_fetch_message_media (struct tgl_message_media *M);
void tglf_fetch_message_media_encrypted (struct tgl_message_media *M);
void tglf_fetch_message_action (struct tgl_message_action *M);
void tglf_fetch_message_action_encrypted (struct tgl_message_action *M);
void tglf_fetch_photo (struct tgl_photo *P);
void tglf_fetch_chat (struct tgl_chat *C);
void tglf_fetch_chat_full (struct tgl_chat *C);
void tglf_fetch_audio (struct tgl_audio *V);
void tglf_fetch_video (struct tgl_video *V);
void tglf_fetch_document (struct tgl_document *V);
void tglf_fetch_message (struct tgl_message *M);
void tglf_fetch_geo_message (struct tgl_message *M);
#endif

31
tgl-inner.h Normal file
View file

@ -0,0 +1,31 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2014
*/
#ifndef __TGL_INNER_H__
#define __TGL_INNER_H__
#define vlogprintf(verbosity_level,...) \
do { \
if (tgl_state.verbosity >= verbosity_level) { \
tgl_state.callback.logprintf (__VA_ARGS__); \
} \
} while (0)
#endif

422
tgl-layout.h Normal file
View file

@ -0,0 +1,422 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2014
*/
#ifndef __TGL_LAYOUT_H__
#define __TGL_LAYOUT_H__
#define FLAG_MESSAGE_EMPTY 1
#define FLAG_DELETED 2
#define FLAG_FORBIDDEN 4
#define FLAG_HAS_PHOTO 8
#define FLAG_CREATED 16
#define FLAG_USER_SELF 128
#define FLAG_USER_FOREIGN 256
#define FLAG_USER_CONTACT 512
#define FLAG_USER_IN_CONTACT 1024
#define FLAG_USER_OUT_CONTACT 2048
#define FLAG_CHAT_IN_CHAT 128
#define FLAG_ENCRYPTED 4096
#define FLAG_PENDING 8192
#pragma pack(push,4)
typedef struct { int type; int id; } tgl_peer_id_t;
enum tgl_dc_state {
st_init,
st_reqpq_sent,
st_reqdh_sent,
st_client_dh_sent,
st_init_temp,
st_reqpq_sent_temp,
st_reqdh_sent_temp,
st_client_dh_sent_temp,
st_authorized,
st_error
};
#define MAX_DC_SESSIONS 3
struct tgl_session {
struct tgl_dc *dc;
long long session_id;
int seq_no;
struct connection *c;
struct tree_long *ack_tree;
struct event *ev;
//struct event_timer ev;
};
struct tgl_dc {
int id;
int port;
int flags;
enum tgl_dc_state state;
char *ip;
//char *user;
struct tgl_session *sessions[MAX_DC_SESSIONS];
char auth_key[256];
char temp_auth_key[256];
char nonce[256];
char new_nonce[256];
char server_nonce[256];
long long auth_key_id;
long long temp_auth_key_id;
long long server_salt;
struct event *ev;
int server_time_delta;
double server_time_udelta;
int has_auth;
};
enum tgl_message_media_type {
tgl_message_media_none,
tgl_message_media_photo,
tgl_message_media_video,
tgl_message_media_audio,
tgl_message_media_document,
tgl_message_media_geo,
tgl_message_media_contact,
tgl_message_media_unsupported,
tgl_message_media_photo_encr,
tgl_message_media_video_encr,
tgl_message_media_audio_encr,
tgl_message_media_document_encr,
};
enum tgl_message_action_type {
tgl_message_action_none,
tgl_message_action_geo_chat_create,
tgl_message_action_geo_chat_checkin,
tgl_message_action_chat_create,
tgl_message_action_chat_edit_title,
tgl_message_action_chat_edit_photo,
tgl_message_action_chat_delete_photo,
tgl_message_action_chat_add_user,
tgl_message_action_chat_delete_user,
tgl_message_action_set_message_ttl,
tgl_message_action_read_messages,
tgl_message_action_delete_messages,
tgl_message_action_screenshot_messages,
tgl_message_action_flush_history,
tgl_message_action_notify_layer
};
struct tgl_file_location {
int dc;
long long volume;
int local_id;
long long secret;
};
struct tgl_photo_size {
char *type;
struct tgl_file_location loc;
int w;
int h;
int size;
char *data;
};
struct tgl_geo {
double longitude;
double latitude;
};
struct tgl_photo {
long long id;
long long access_hash;
int user_id;
int date;
char *caption;
struct tgl_geo geo;
int sizes_num;
struct tgl_photo_size *sizes;
};
struct tgl_encr_photo {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
unsigned char *key;
unsigned char *iv;
int w;
int h;
};
struct tgl_encr_video {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
unsigned char *key;
unsigned char *iv;
int w;
int h;
int duration;
char *mime_type;
};
struct tgl_encr_audio {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
unsigned char *key;
unsigned char *iv;
int duration;
char *mime_type;
};
struct tgl_encr_document {
long long id;
long long access_hash;
int dc_id;
int size;
int key_fingerprint;
unsigned char *key;
unsigned char *iv;
char *file_name;
char *mime_type;
};
struct tgl_encr_file {
char *filename;
unsigned char *key;
unsigned char *iv;
};
struct tgl_user_status {
int online;
int when;
};
struct tgl_user {
tgl_peer_id_t id;
int flags;
struct tgl_message *last;
char *print_name;
int structure_version;
struct tgl_file_location photo_big;
struct tgl_file_location photo_small;
long long photo_id;
struct tgl_photo photo;
char *first_name;
char *last_name;
char *phone;
long long access_hash;
struct tgl_user_status status;
int blocked;
char *real_first_name;
char *real_last_name;
};
struct tgl_chat_user {
int user_id;
int inviter_id;
int date;
};
struct tgl_chat {
tgl_peer_id_t id;
int flags;
struct tgl_message *last;
char *print_title;
int structure_version;
struct tgl_file_location photo_big;
struct tgl_file_location photo_small;
struct tgl_photo photo;
char *title;
int users_num;
int user_list_size;
int user_list_version;
struct tgl_chat_user *user_list;
int date;
int version;
int admin_id;
};
enum tgl_secret_chat_state {
sc_none,
sc_waiting,
sc_request,
sc_ok,
sc_deleted
};
struct tgl_secret_chat {
tgl_peer_id_t id;
int flags;
struct tgl_message *last;
char *print_name;
int structure_version;
struct tgl_file_location photo_big;
struct tgl_file_location photo_small;
struct tgl_photo photo;
int user_id;
int admin_id;
int date;
int ttl;
int layer;
long long access_hash;
unsigned char *g_key;
unsigned char *nonce;
enum tgl_secret_chat_state state;
int key[64];
long long key_fingerprint;
};
typedef union tgl_peer {
struct {
tgl_peer_id_t id;
int flags;
struct tgl_message *last;
char *print_name;
int structure_version;
struct tgl_file_location photo_big;
struct tgl_file_location photo_small;
struct tgl_photo photo;
};
struct tgl_user user;
struct tgl_chat chat;
struct tgl_secret_chat encr_chat;
} tgl_peer_t;
struct tgl_video {
long long id;
long long access_hash;
int user_id;
int date;
int size;
int dc_id;
struct tgl_photo_size thumb;
char *caption;
int duration;
int w;
int h;
char *mime_type;
};
struct tgl_audio {
long long id;
long long access_hash;
int user_id;
int date;
int size;
int dc_id;
int duration;
char *mime_type;
};
struct tgl_document {
long long id;
long long access_hash;
int user_id;
int date;
int size;
int dc_id;
struct tgl_photo_size thumb;
char *caption;
char *mime_type;
};
struct tgl_message_action {
enum tgl_message_action_type type;
union {
struct {
char *title;
int user_num;
int *users;
};
char *new_title;
struct tgl_photo photo;
int user;
int ttl;
int layer;
int read_cnt;
int delete_cnt;
int screenshot_cnt;
};
};
struct tgl_message_media {
enum tgl_message_media_type type;
union {
struct tgl_photo photo;
struct tgl_video video;
struct tgl_audio audio;
struct tgl_document document;
struct tgl_geo geo;
struct {
char *phone;
char *first_name;
char *last_name;
int user_id;
};
struct tgl_encr_photo encr_photo;
struct tgl_encr_video encr_video;
struct tgl_encr_audio encr_audio;
struct tgl_encr_document encr_document;
struct tgl_encr_file encr_file;
struct {
void *data;
int data_size;
};
};
};
struct tgl_message {
struct tgl_message *next_use, *prev_use;
struct tgl_message *next, *prev;
long long id;
int flags;
tgl_peer_id_t fwd_from_id;
int fwd_date;
tgl_peer_id_t from_id;
tgl_peer_id_t to_id;
int out;
int unread;
int date;
int service;
union {
struct tgl_message_action action;
struct {
char *message;
int message_len;
struct tgl_message_media media;
};
};
};
#pragma pack(pop)
#endif

93
tgl.c Normal file
View file

@ -0,0 +1,93 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2014
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "tgl.h"
#include "tools.h"
#include "mtproto-client.h"
#include "structures.h"
#include "net.h"
#ifdef EVENT_V2
#include <event2/event.h>
#else
#include <event.h>
#include "event-old.h"
#endif
#include <assert.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);
}
void tgl_set_callback (struct tgl_update_callback *cb) {
tgl_state.callback = *cb;
}
void tgl_set_rsa_key (const char *key) {
assert (tgl_state.rsa_key_num < TGL_MAX_RSA_KEYS_NUM);
tgl_state.rsa_key_list[tgl_state.rsa_key_num ++] = tstrdup (key);
}
void tgl_init (void) {
tgl_state.ev_base = event_base_new ();
if (!tgl_state.net_methods) {
tgl_state.net_methods = &tgl_conn_methods;
}
if (!tgl_state.callback.create_print_name) {
tgl_state.callback.create_print_name = tgls_default_create_print_name;
}
if (!tgl_state.temp_key_expire_time) {
tgl_state.temp_key_expire_time = 100000;
}
tglmp_on_start ();
}
int tgl_authorized_dc (struct tgl_dc *DC) {
assert (DC);
return (DC->flags & 4) != 0;//DC->auth_key_id;
}
int tgl_signed_dc (struct tgl_dc *DC) {
assert (DC);
return DC->has_auth;
}

330
tgl.h Normal file
View file

@ -0,0 +1,330 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2014
*/
#ifndef __TGL_H__
#define __TGL_H__
#include <tgl-layout.h>
#include <string.h>
#define TGL_MAX_DC_NUM 100
#define TG_SERVER "149.154.167.50"
#define TG_SERVER_TEST "149.154.167.40"
#define TG_SERVER_DC 2
#define TG_SERVER_TEST_DC 2
// JUST RANDOM STRING
#define TGL_BUILD "2014"
#define TGL_VERSION "1.0.5"
#define TGL_ENCRYPTED_LAYER 16
struct connection;
struct mtproto_methods;
struct tgl_session;
struct tgl_dc;
#define TGL_UPDATE_CREATED 1
#define TGL_UPDATE_DELETED 2
#define TGL_UPDATE_PHONE 4
#define TGL_UPDATE_CONTACT 8
#define TGL_UPDATE_PHOTO 16
#define TGL_UPDATE_BLOCKED 32
#define TGL_UPDATE_REAL_NAME 64
#define TGL_UPDATE_NAME 128
#define TGL_UPDATE_REQUESTED 256
#define TGL_UPDATE_WORKING 512
#define TGL_UPDATE_FLAGS 1024
#define TGL_UPDATE_TITLE 2048
#define TGL_UPDATE_ADMIN 4096
#define TGL_UPDATE_MEMBERS 8192
#define TGL_UPDATE_ACCESS_HASH 16384
struct tgl_allocator {
void *(*alloc)(size_t size);
void *(*realloc)(void *ptr, size_t old_size, size_t size);
void (*free)(void *ptr, int size);
void (*check)(void);
void (*exists)(void *ptr, int size);
};
extern struct tgl_allocator tgl_allocator_release;
extern struct tgl_allocator tgl_allocator_debug;
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)(struct tgl_user *U);
void (*type_in_chat_notification)(struct tgl_user *U, struct tgl_chat *C);
void (*type_in_secret_chat_notification)(struct tgl_secret_chat *E);
void (*status_notification)(struct tgl_user *U);
void (*user_registered)(struct tgl_user *U);
void (*user_activated)(struct tgl_user *U);
void (*new_authorization)(const char *device, const char *location);
//void (*secret_chat_created)(struct tgl_secret_chat *E);
//void (*secret_chat_request)(struct tgl_secret_chat *E);
//void (*secret_chat_established)(struct tgl_secret_chat *E);
//void (*secret_chat_deleted)(struct tgl_secret_chat *E);
//void (*secret_chat_accepted)(struct tgl_secret_chat *E);
//void (*new_user)(struct tgl_user *U);
//void (*delete_user)(struct tgl_user *U);
//void (*update_user_info)(struct tgl_user *U);
//void (*secret_chat_delete)(struct tgl_secret_chat *U);
//void (*secret_chat_requested)(struct tgl_secret_chat *U);
//void (*secret_chat_accepted)(struct tgl_secret_chat *U);
//void (*secret_chat_created)(struct tgl_secret_chat *U);
void (*chat_update)(struct tgl_chat *C, unsigned flags);
void (*user_update)(struct tgl_user *C, unsigned flags);
void (*secret_chat_update)(struct tgl_secret_chat *C, unsigned flags);
void (*msg_receive)(struct tgl_message *M);
void (*our_id)(int id);
char *(*create_print_name) (tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
};
struct tgl_net_methods {
int (*write_out) (struct connection *c, const void *data, int len);
int (*read_in) (struct connection *c, void *data, int len);
int (*read_in_lookup) (struct connection *c, void *data, int len);
void (*flush_out) (struct connection *c);
void (*incr_out_packet_num) (struct connection *c);
void (*free) (struct connection *c);
struct tgl_dc *(*get_dc) (struct connection *c);
struct tgl_session *(*get_session) (struct connection *c);
struct connection *(*create_connection) (const char *host, int port, struct tgl_session *session, struct tgl_dc *dc, struct mtproto_methods *methods);
};
#define E_ERROR 0
#define E_WARNING 1
#define E_NOTICE 2
#define E_DEBUG 6
#define TGL_LOCK_DIFF 1
#define TGL_MAX_RSA_KEYS_NUM 10
// Do not modify this structure, unless you know what you do
struct tgl_state {
int our_id; // ID of logged in user
int encr_root;
unsigned char *encr_prime;
int encr_param_version;
int pts;
int qts;
int date;
int seq;
int binlog_enabled;
int test_mode;
int verbosity;
int unread_messages;
int active_queries;
int max_msg_id;
int started;
long long locks;
struct tgl_dc *DC_list[TGL_MAX_DC_NUM];
struct tgl_dc *DC_working;
int max_dc_num;
int dc_working_num;
int enable_pfs;
int temp_key_expire_time;
long long cur_uploading_bytes;
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;
struct tgl_net_methods *net_methods;
struct event_base *ev_base;
char *rsa_key_list[TGL_MAX_RSA_KEYS_NUM];
int rsa_key_num;
struct bignum_ctx *BN_ctx;
struct tgl_allocator allocator;
};
extern struct tgl_state tgl_state;
void tgl_reopen_binlog_for_writing (void);
void tgl_replay_log (void);
int tgl_print_stat (char *s, int len);
tgl_peer_t *tgl_peer_get (tgl_peer_id_t id);
tgl_peer_t *tgl_peer_get_by_name (const char *s);
struct tgl_message *tgl_message_get (long long id);
void tgl_peer_iterator_ex (void (*it)(tgl_peer_t *P, void *extra), void *extra);
int tgl_complete_user_list (int index, const char *text, int len, char **R);
int tgl_complete_chat_list (int index, const char *text, int len, char **R);
int tgl_complete_encr_chat_list (int index, const char *text, int len, char **R);
int tgl_complete_peer_list (int index, const char *text, int len, char **R);
#define TGL_PEER_USER 1
#define TGL_PEER_CHAT 2
#define TGL_PEER_GEO_CHAT 3
#define TGL_PEER_ENCR_CHAT 4
#define TGL_PEER_UNKNOWN 0
#define TGL_MK_USER(id) tgl_set_peer_id (TGL_PEER_USER,id)
#define TGL_MK_CHAT(id) tgl_set_peer_id (TGL_PEER_CHAT,id)
#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);
void tgl_set_callback (struct tgl_update_callback *cb);
void tgl_set_rsa_key (const char *key);
static inline int tgl_get_peer_type (tgl_peer_id_t id) {
return id.type;
}
static inline int tgl_get_peer_id (tgl_peer_id_t id) {
return id.id;
}
static inline tgl_peer_id_t tgl_set_peer_id (int type, int id) {
tgl_peer_id_t ID;
ID.id = id;
ID.type = type;
return ID;
}
static inline int tgl_cmp_peer_id (tgl_peer_id_t a, tgl_peer_id_t b) {
return memcmp (&a, &b, sizeof (a));
}
static inline void tgl_incr_verbosity (void) {
tgl_state.verbosity ++;
}
static inline void tgl_set_verbosity (int val) {
tgl_state.verbosity = val;
}
static inline void tgl_enable_pfs (void) {
tgl_state.enable_pfs = 1;
}
static inline void tgl_set_test_mode (void) {
tgl_state.test_mode ++;
}
struct pollfd;
int tgl_connections_make_poll_array (struct pollfd *fds, int max);
void tgl_connections_poll_result (struct pollfd *fds, int max);
void tgl_do_help_get_config (void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_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, const char *hash, void (*callback)(void *callback_extra, int success), void *callback_extra);
int tgl_do_send_code_result (const char *user, const char *hash, 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 *hash, 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_history_ext (tgl_peer_id_t id, int offset, 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 (enum tgl_message_media_type 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_set_chat_photo (tgl_peer_id_t chat_id, char *file_name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_set_profile_photo (char *file_name, void (*callback)(void *callback_extra, int success), 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_audio *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, int offset, 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_lookup_state (void);
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_create_group_chat_ex (int users_num, tgl_peer_id_t ids[], 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_help_get_config_dc (struct tgl_dc *D, void (*callback)(void *, int), void *callback_extra);
void tgl_do_export_card (void (*callback)(void *callback_extra, int success, int size, int *card), void *callback_extra);
void tgl_do_import_card (int size, int *card, void (*callback)(void *callback_extra, int success, struct tgl_user *U), void *callback_extra);
void tgl_do_send_contact (tgl_peer_id_t id, const char *phone, int phone_len, const char *first_name, int first_name_len, const char *last_name, int last_name_len, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_forward_media (tgl_peer_id_t id, int n, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_del_contact (tgl_peer_id_t id, void (*callback)(void *callback_extra, int success), void *callback_extra);
void tgl_do_set_encr_chat_ttl (struct tgl_secret_chat *E, int ttl, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra);
void tgl_do_visualize_key (tgl_peer_id_t id, unsigned char buf[16]);
void tgl_do_send_ping (struct connection *c);
int tgl_authorized_dc (struct tgl_dc *DC);
int tgl_signed_dc (struct tgl_dc *DC);
//void tgl_do_get_suggested (void);
void tgl_do_create_keys_end (struct tgl_secret_chat *U);
void tgl_do_send_encr_chat_layer (struct tgl_secret_chat *E);
struct mtproto_methods {
int (*ready) (struct connection *c);
int (*close) (struct connection *c);
int (*execute) (struct connection *c, int op, int len);
};
void tgl_init (void);
void tgl_dc_authorize (struct tgl_dc *DC);
void tgl_dc_iterator (void (*iterator)(struct tgl_dc *DC));
void tgl_dc_iterator_ex (void (*iterator)(struct tgl_dc *DC, void *extra), void *extra);
double tglt_get_double_time (void);
void tgl_insert_empty_user (int id);
void tgl_insert_empty_chat (int id);
int tglf_extf_autocomplete (const char *text, int text_len, int index, char **R, char *data, int data_len);
struct paramed_type *tglf_extf_store (const char *data, int data_len);
void tgl_do_send_extf (char *data, int data_len, void (*callback)(void *callback_extra, int success, char *data), void *callback_extra);
char *tglf_extf_fetch (struct paramed_type *T);
void tgl_free_all (void);
#endif

3077
tl-parser.c Normal file

File diff suppressed because it is too large Load diff

206
tl-parser.h Normal file
View file

@ -0,0 +1,206 @@
/*
This file is part of tgl-libary/tlc
Tgl-library/tlc is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Tgl-library/tlc is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this tgl-library/tlc. If not, see <http://www.gnu.org/licenses/>.
Copyright Vitaly Valtman 2014
It is derivative work of VK/KittenPHP-DB-Engine (https://github.com/vk-com/kphp-kdb/)
Copyright 2012-2013 Vkontakte Ltd
2012-2013 Vitaliy Valtman
*/
#ifndef __TL_PARSER_NEW_H__
#define __TL_PARSER_NEW_H__
enum lex_type {
lex_error,
lex_char,
lex_triple_minus,
lex_uc_ident,
lex_lc_ident,
lex_eof,
lex_final,
lex_new,
lex_none,
lex_num,
lex_empty
};
struct curlex {
char *ptr;
int len;
enum lex_type type;
int flags;
};
struct parse {
char *text;
int pos;
int len;
int line;
int line_pos;
struct curlex lex;
};
enum tree_type {
type_tl_program,
type_fun_declarations,
type_constr_declarations,
type_declaration,
type_combinator_decl,
type_equals,
type_partial_app_decl,
type_final_decl,
type_full_combinator_id,
type_opt_args,
type_args,
type_args1,
type_args2,
type_args3,
type_args4,
type_boxed_type_ident,
type_subexpr,
type_partial_comb_app_decl,
type_partial_type_app_decl,
type_final_new,
type_final_final,
type_final_empty,
// type_type,
type_var_ident,
type_var_ident_opt,
type_multiplicity,
type_type_term,
type_term,
type_percent,
type_result_type,
type_expr,
type_nat_term,
type_combinator_id,
type_nat_const,
type_type_ident,
type_builtin_combinator_decl,
type_exclam,
type_optional_arg_def
};
struct tree {
char *text;
int len;
enum tree_type type;
int lex_line;
int lex_line_pos;
int flags;
int size;
int nc;
struct tree **c;
};
#define TL_ACT(x) (x == act_var ? "act_var" : x == act_field ? "act_field" : x == act_plus ? "act_plus" : x == act_type ? "act_type" : x == act_nat_const ? "act_nat_const" : x == act_array ? "act_array" : x == act_question_mark ? "act_question_mark" : \
x == act_union ? "act_union" : x == act_arg ? "act_arg" : x == act_opt_field ? "act_opt_field" : "act_unknown")
#define TL_TYPE(x) (x == type_num ? "type_num" : x == type_type ? "type_type" : x == type_list_item ? "type_list_item" : x == type_list ? "type_list" : x == type_num_value ? "type_num_value" : "type_unknown")
enum combinator_tree_action {
act_var,
act_field,
act_plus,
act_type,
act_nat_const,
act_array,
act_question_mark,
act_union,
act_arg,
act_opt_field
};
enum combinator_tree_type {
type_num,
type_num_value,
type_type,
type_list_item,
type_list
};
struct tl_combinator_tree {
enum combinator_tree_action act;
struct tl_combinator_tree *left, *right;
char *name;
void *data;
long long flags;
enum combinator_tree_type type;
int type_len;
long long type_flags;
};
struct tl_program {
int types_num;
int functions_num;
int constructors_num;
struct tl_type **types;
struct tl_function **functions;
// struct tl_constuctor **constructors;
};
struct tl_type {
char *id;
char *print_id;
char *real_id;
unsigned name;
int flags;
int params_num;
long long params_types;
int constructors_num;
struct tl_constructor **constructors;
};
struct tl_constructor {
char *id;
char *print_id;
char *real_id;
unsigned name;
struct tl_type *type;
struct tl_combinator_tree *left;
struct tl_combinator_tree *right;
};
struct tl_var {
char *id;
struct tl_combinator_tree *ptr;
int type;
int flags;
};
struct parse *tl_init_parse_file (const char *fname);
struct tree *tl_parse_lex (struct parse *P);
void tl_print_parse_error (void);
struct tl_program *tl_parse (struct tree *T);
void write_types (int f);
#define FLAG_BARE 1
#define FLAG_OPT_VAR (1 << 17)
#define FLAG_EXCL (1 << 18)
#define FLAG_OPT_FIELD (1 << 20)
#define FLAG_IS_VAR (1 << 21)
#define FLAG_DEFAULT_CONSTRUCTOR (1 << 25)
#define FLAG_EMPTY (1 << 10)
#endif

52
tl-tl.h Normal file
View file

@ -0,0 +1,52 @@
/*
This file is part of VK/KittenPHP-DB-Engine.
VK/KittenPHP-DB-Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
VK/KittenPHP-DB-Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with VK/KittenPHP-DB-Engine. If not, see <http://www.gnu.org/licenses/>.
This program is released under the GPL with the additional exemption
that compiling, linking, and/or using OpenSSL is allowed.
You are free to remove this exemption from derived works.
Copyright 2012-2013 Vkontakte Ltd
2012-2013 Vitaliy Valtman
*/
#ifndef __TL_TL_H__
#define __TL_TL_H__
#define TLS_SCHEMA 0xf19d9e38
#define TLS_TYPE 0x12eb4386
#define TLS_COMBINATOR 0x5c0a1ed5
#define TLS_COMBINATOR_LEFT_BUILTIN 0xcd211f63
#define TLS_COMBINATOR_LEFT 0x4c12c6d9
#define TLS_COMBINATOR_RIGHT 0xd325b367
#define TLS_ARG 0x46afe232
#define TLS_TREE_NAT_CONST 0xc09f07d7
#define TLS_TREE_NAT_VAR 0x90ea6f58
#define TLS_TREE_TYPE_VAR 0x1caa237a
#define TLS_TREE_ARRAY 0x80479360
#define TLS_TREE_TYPE 0x10f32190
#define TLS_SCHEMA_V2 0x3a2f9be2
#define TLS_COMBINATOR_RIGHT_V2 0x2c064372
#define TLS_ARG_V2 0x29dfe61b
#define TLS_EXPR_TYPE 0xecc9da78
#define TLS_EXPR_NAT 0xdcb49bd8
#define TLS_NAT_CONST 0xdcb49bd8
#define TLS_NAT_VAR 0x4e8a14f0
#define TLS_TYPE_VAR 0x0142ceae
#define TLS_ARRAY 0xd9fb20de
#define TLS_TYPE_EXPR 0xc1863d08
#endif

165
tlc.c Normal file
View file

@ -0,0 +1,165 @@
/*
This file is part of tgl-libary/tlc
Tgl-library/tlc is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Tgl-library/tlc is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this tgl-library/tlc. If not, see <http://www.gnu.org/licenses/>.
Copyright Vitaly Valtman 2014
It is derivative work of VK/KittenPHP-DB-Engine (https://github.com/vk-com/kphp-kdb/)
Copyright 2012-2013 Vkontakte Ltd
2012-2013 Vitaliy Valtman
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "tl-parser.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include "config.h"
#include <execinfo.h>
#include <stdarg.h>
int verbosity;
int output_expressions;
int schema_version = 2;
void usage (void) {
printf ("usage: tlc [-v] [-h] <TL-schema-file>\n"
"\tTL compiler\n"
"\t-v\toutput statistical and debug information into stderr\n"
"\t-E\twhenever is possible output to stdout expressions\n"
"\t-e <file>\texport serialized schema to file\n"
"\t-w\t custom version of serialized schema (0 - very old, 1 - old, 2 - current (default))\n"
);
exit (2);
}
int vkext_write (const char *filename) {
int f = open (filename, O_CREAT | O_WRONLY | O_TRUNC, 0640);
assert (f >= 0);
write_types (f);
close (f);
return 0;
}
void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
void logprintf (const char *format __attribute__ ((unused)), ...) {
va_list ap;
va_start (ap, format);
vfprintf (stderr, format, ap);
va_end (ap);
}
void hexdump (int *in_ptr, int *in_end) {
int *ptr = in_ptr;
while (ptr < in_end) { printf (" %08x", *(ptr ++)); }
printf ("\n");
}
#ifdef HAVE_EXECINFO_H
void print_backtrace (void) {
void *buffer[255];
const int calls = backtrace (buffer, sizeof (buffer) / sizeof (void *));
backtrace_symbols_fd (buffer, calls, 1);
}
#else
void print_backtrace (void) {
if (write (1, "No libexec. Backtrace disabled\n", 32) < 0) {
// Sad thing
}
}
#endif
void sig_segv_handler (int signum __attribute__ ((unused))) {
if (write (1, "SIGSEGV received\n", 18) < 0) {
// Sad thing
}
print_backtrace ();
exit (EXIT_FAILURE);
}
void sig_abrt_handler (int signum __attribute__ ((unused))) {
if (write (1, "SIGABRT received\n", 18) < 0) {
// Sad thing
}
print_backtrace ();
exit (EXIT_FAILURE);
}
int main (int argc, char **argv) {
signal (SIGSEGV, sig_segv_handler);
signal (SIGABRT, sig_abrt_handler);
int i;
char *vkext_file = 0;
while ((i = getopt (argc, argv, "Ehve:w:")) != -1) {
switch (i) {
case 'E':
output_expressions++;
break;
case 'h':
usage ();
return 2;
case 'e':
vkext_file = optarg;
break;
case 'w':
schema_version = atoi (optarg);
break;
case 'v':
verbosity++;
break;
}
}
if (argc != optind + 1) {
usage ();
}
struct parse *P = tl_init_parse_file (argv[optind]);
if (!P) {
return 0;
}
struct tree *T;
if (!(T = tl_parse_lex (P))) {
fprintf (stderr, "Error in parse:\n");
tl_print_parse_error ();
return 0;
} else {
if (verbosity) {
fprintf (stderr, "Parse ok\n");
}
if (!tl_parse (T)) {
if (verbosity) {
fprintf (stderr, "Fail\n");
}
return 1;
} else {
if (verbosity) {
fprintf (stderr, "Ok\n");
}
}
}
if (vkext_file) {
vkext_write (vkext_file);
}
return 0;
}

226
tools.c
View file

@ -1,20 +1,21 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#ifdef HAVE_CONFIG_H
@ -28,31 +29,47 @@
#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <zlib.h>
#include <time.h>
#include <sys/time.h>
#include "interface.h"
//#include "interface.h"
#include "tools.h"
#ifdef DEBUG
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#ifdef __MACH__
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
#endif
#define RES_PRE 8
#define RES_AFTER 8
#define MAX_BLOCKS 1000000
void *blocks[MAX_BLOCKS];
void *free_blocks[MAX_BLOCKS];
int used_blocks;
int free_blocks_cnt;
#endif
static void *blocks[MAX_BLOCKS];
static void *free_blocks[MAX_BLOCKS];
static int used_blocks;
static int free_blocks_cnt;
extern int verbosity;
static long long total_allocated_bytes;
long long total_allocated_bytes;
static void out_of_memory (void) {
fprintf (stderr, "Out of memory\n");
exit (1);
void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2), weak));
void logprintf (const char *format, ...) {
va_list ap;
va_start (ap, format);
vfprintf (stdout, format, ap);
va_end (ap);
}
int tsnprintf (char *buf, int len, const char *format, ...) {
//extern int verbosity;
//static long long total_allocated_bytes;
int tgl_snprintf (char *buf, int len, const char *format, ...) {
va_list ap;
va_start (ap, format);
int r = vsnprintf (buf, len, format, ap);
@ -61,7 +78,7 @@ int tsnprintf (char *buf, int len, const char *format, ...) {
return r;
}
int tasprintf (char **res, const char *format, ...) {
int tgl_asprintf (char **res, const char *format, ...) {
va_list ap;
va_start (ap, format);
int r = vasprintf (res, format, ap);
@ -74,9 +91,7 @@ int tasprintf (char **res, const char *format, ...) {
return r;
}
void print_backtrace (void);
void tfree (void *ptr, int size __attribute__ ((unused))) {
#ifdef DEBUG
void tgl_free_debug (void *ptr, int size __attribute__ ((unused))) {
total_allocated_bytes -= size;
ptr -= RES_PRE;
if (size != (int)((*(int *)ptr) ^ 0xbedabeda)) {
@ -100,36 +115,28 @@ void tfree (void *ptr, int size __attribute__ ((unused))) {
memset (ptr, 0, size + RES_PRE + RES_AFTER);
*(int *)ptr = size + 12;
free_blocks[free_blocks_cnt ++] = ptr;
#else
}
void tgl_free_release (void *ptr, int size) {
free (ptr);
#endif
}
void tfree_str (void *ptr) {
if (!ptr) { return; }
tfree (ptr, strlen (ptr) + 1);
}
void tfree_secure (void *ptr, int size) {
memset (ptr, 0, size);
tfree (ptr, size);
}
void *trealloc (void *ptr, size_t old_size __attribute__ ((unused)), size_t size) {
#ifdef DEBUG
void *tgl_realloc_debug (void *ptr, size_t old_size __attribute__ ((unused)), size_t size) {
void *p = talloc (size);
memcpy (p, ptr, size >= old_size ? old_size : size);
tfree (ptr, old_size);
return p;
#else
}
void *tgl_realloc_release (void *ptr, size_t old_size __attribute__ ((unused)), size_t size) {
void *p = realloc (ptr, size);
ensure_ptr (p);
return p;
#endif
}
void *talloc (size_t size) {
#ifdef DEBUG
void *tgl_alloc_debug (size_t size) {
total_allocated_bytes += size;
void *p = malloc (size + RES_PRE + RES_AFTER);
ensure_ptr (p);
@ -138,67 +145,44 @@ void *talloc (size_t size) {
*(int *)(p + RES_PRE + size) = size ^ 0x7bed7bed;
*(int *)(p + RES_AFTER + 4 + size) = used_blocks;
blocks[used_blocks ++] = p;
if (used_blocks - 1 == 24867) {
assert (0);
}
tcheck ();
return p + 8;
#else
}
void *tgl_alloc_release (size_t size) {
void *p = malloc (size);
ensure_ptr (p);
return p;
#endif
}
void *talloc0 (size_t size) {
void *tgl_alloc0 (size_t size) {
void *p = talloc (size);
memset (p, 0, size);
return p;
}
char *tstrdup (const char *s) {
#ifdef DEBUG
char *tgl_strdup (const char *s) {
int l = strlen (s);
char *p = talloc (l + 1);
memcpy (p, s, l + 1);
return p;
#else
char *p = strdup (s);
if (p == NULL) {
out_of_memory ();
}
return p;
#endif
}
char *tstrndup (const char *s, size_t n) {
#ifdef DEBUG
char *tgl_strndup (const char *s, size_t n) {
size_t l = 0;
for (l = 0; l < n && s[l]; l++) { }
char *p = talloc (l + 1);
memcpy (p, s, l);
p[l] = 0;
return p;
#else
char *p = strndup (s, n);
if (p == NULL) {
out_of_memory ();
}
return p;
#endif
}
void ensure (int r) {
if (!r) {
logprintf ("Open SSL error\n");
ERR_print_errors_fp (stderr);
assert (0);
}
}
void ensure_ptr (void *p) {
if (p == NULL) {
out_of_memory ();
}
}
int tinflate (void *input, int ilen, void *output, int olen) {
int tgl_inflate (void *input, int ilen, void *output, int olen) {
z_stream strm;
memset (&strm, 0, sizeof (strm));
assert (inflateInit2 (&strm, 16 + MAX_WBITS) == Z_OK);
@ -206,30 +190,29 @@ int tinflate (void *input, int ilen, void *output, int olen) {
strm.next_in = input;
strm.avail_out = olen ;
strm.next_out = output;
int err = inflate (&strm, Z_FINISH), total_out = 0;
if (err == Z_OK || err == Z_STREAM_END) {
total_out = (int) strm.total_out;
if (err == Z_STREAM_END && verbosity >= 2) {
logprintf ( "inflated %d bytes\n", (int) strm.total_out);
}
}
if (verbosity && err != Z_STREAM_END) {
int err = inflate (&strm, Z_FINISH);
int total_out = strm.total_out;
if (err != Z_OK && err != Z_STREAM_END) {
logprintf ( "inflate error = %d\n", err);
logprintf ( "inflated %d bytes\n", (int) strm.total_out);
total_out = 0;
}
inflateEnd (&strm);
return total_out;
}
#ifdef DEBUG
void tcheck (void) {
void tgl_check_debug (void) {
int i;
for (i = 0; i < used_blocks; i++) {
void *ptr = blocks[i];
int size = (*(int *)ptr) ^ 0xbedabeda;
assert (*(int *)(ptr + 4) == size);
assert (*(int *)(ptr + RES_PRE + size) == (size ^ 0x7bed7bed));
assert (*(int *)(ptr + RES_PRE + 4 + size) == i);
if (!(*(int *)(ptr + 4) == size) ||
!(*(int *)(ptr + RES_PRE + size) == (size ^ 0x7bed7bed)) ||
!(*(int *)(ptr + RES_PRE + 4 + size) == i)) {
logprintf ("Bad block at address %p (size %d, num %d)\n", ptr, size, i);
assert (0 && "Bad block");
}
}
for (i = 0; i < free_blocks_cnt; i++) {
void *ptr = free_blocks[i];
@ -243,10 +226,10 @@ void tcheck (void) {
}
}
}
logprintf ("ok. Used_blocks = %d. Free blocks = %d\n", used_blocks, free_blocks_cnt);
//logprintf ("ok. Used_blocks = %d. Free blocks = %d\n", used_blocks, free_blocks_cnt);
}
void texists (void *ptr, int size) {
void tgl_exists_debug (void *ptr, int size) {
ptr -= RES_PRE;
if (size != (int)((*(int *)ptr) ^ 0xbedabeda)) {
logprintf ("size = %d, ptr = %d\n", size, (*(int *)ptr) ^ 0xbedabeda);
@ -260,4 +243,55 @@ void texists (void *ptr, int size) {
}
assert (block_num < used_blocks);
}
void tgl_exists_release (void *ptr, int size) {}
void tgl_check_release (void) {}
void tgl_my_clock_gettime (int clock_id, struct timespec *T) {
#ifdef __MACH__
// We are ignoring MONOTONIC and hope time doesn't go back too often
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
T->tv_sec = mts.tv_sec;
T->tv_nsec = mts.tv_nsec;
#else
assert (clock_gettime(clock_id, T) >= 0);
#endif
}
double tglt_get_double_time (void) {
struct timespec tv;
tgl_my_clock_gettime (CLOCK_REALTIME, &tv);
return tv.tv_sec + 1e-9 * tv.tv_nsec;
}
void tglt_secure_random (void *s, int l) {
if (RAND_bytes (s, l) <= 0) {
/*if (allow_weak_random) {
RAND_pseudo_bytes (s, l);
} else {*/
assert (0 && "End of random. If you want, you can start with -w");
//}
}
}
struct tgl_allocator tgl_allocator_debug = {
.alloc = tgl_alloc_debug,
.realloc = tgl_realloc_debug,
.free = tgl_free_debug,
.check = tgl_check_debug,
.exists = tgl_exists_debug
};
struct tgl_allocator tgl_allocator_release = {
.alloc = tgl_alloc_release,
.realloc = tgl_realloc_release,
.free = tgl_free_release,
.check = tgl_check_release,
.exists = tgl_exists_release
};
struct tgl_allocator *tgl_allocator = &tgl_allocator_release;

111
tools.h
View file

@ -19,26 +19,101 @@
#ifndef __TOOLS_H__
#define __TOOLS_H__
#include <time.h>
#include <openssl/err.h>
#include <assert.h>
#include "tgl.h"
void *talloc (size_t size);
void *trealloc (void *ptr, size_t old_size, size_t size);
void *talloc0 (size_t size);
char *tstrdup (const char *s);
char *tstrndup (const char *s, size_t n);
int tinflate (void *input, int ilen, void *output, int olen);
void ensure (int r);
void ensure_ptr (void *p);
void tfree (void *ptr, int size);
void tfree_str (void *ptr);
void tfree_secure (void *ptr, int size);
#define talloc tgl_allocator->alloc
#define talloc0 tgl_alloc0
#define tfree tgl_allocator->free
#define tfree_str tgl_free_str
#define tfree_secure tgl_free_secure
#define trealloc tgl_allocator->realloc
#define tcheck tgl_allocator->check
#define texists tgl_allocator->exists
#define tstrdup tgl_strdup
#define tstrndup tgl_strndup
#define tasprintf tgl_asprintf
#define tsnprintf tgl_snprintf
int tsnprintf (char *buf, int len, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
int tasprintf (char **res, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
struct tgl_allocator *tgl_allocator;
double tglt_get_double_time (void);
int tgl_inflate (void *input, int ilen, void *output, int olen);
//void ensure (int r);
//void ensure_ptr (void *p);
static inline void out_of_memory (void) {
fprintf (stderr, "Out of memory\n");
exit (1);
}
static inline void ensure (int r) {
if (!r) {
fprintf (stderr, "Open SSL error\n");
ERR_print_errors_fp (stderr);
assert (0);
}
}
static inline void ensure_ptr (void *p) {
if (p == NULL) {
out_of_memory ();
}
}
void *tgl_alloc_debug (size_t size);
void *tgl_alloc_release (size_t size);
void *tgl_realloc_debug (void *ptr, size_t old_size, size_t size);
void *tgl_realloc_release (void *ptr, size_t old_size, size_t size);
void *tgl_alloc0 (size_t size);
char *tgl_strdup (const char *s);
char *tgl_strndup (const char *s, size_t n);
void tgl_free_debug (void *ptr, int size);
void tgl_free_release (void *ptr, int size);
//void tgl_free_str (void *ptr);
//void tgl_free_secure (void *ptr, int size);
void tgl_check_debug (void);
void tgl_exists_debug (void *ptr, int size);
void tgl_check_release (void);
void tgl_exists_release (void *ptr, int size);
int tgl_snprintf (char *buf, int len, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
int tgl_asprintf (char **res, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
void tglt_secure_random (void *s, int l);
void tgl_my_clock_gettime (int clock_id, struct timespec *T);
static inline void tgl_free_str (void *ptr) {
if (!ptr) { return; }
tfree (ptr, strlen (ptr) + 1);
}
static inline void tgl_free_secure (void *ptr, int size) {
memset (ptr, 0, size);
tfree (ptr, size);
}
static inline void hexdump (void *ptr, void *end_ptr) {
int total = 0;
while (ptr < end_ptr) {
fprintf (stderr, "%08x", (int)*(char *)ptr);
ptr ++;
total ++;
if (total == 16) {
fprintf (stderr, "\n");
total = 0;
}
}
if (total) { fprintf (stderr, "\n"); }
}
#ifdef DEBUG
void tcheck (void);
void texists (void *ptr, int size);
#endif
#endif

74
tree.h
View file

@ -1,28 +1,29 @@
/*
This file is part of telegram-client.
/*
This file is part of tgl-library
Telegram-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
Telegram-client is distributed in the hope that it will be useful,
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU General Public License
along with this telegram-client. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013
Copyright Vitaly Valtman 2013-2014
*/
#ifndef __TREE_H__
#define __TREE_H__
#include <stdio.h>
#include <memory.h>
#include <tools.h>
#include <assert.h>
#include "tools.h"
#pragma pack(push,4)
#define DEFINE_TREE(X_NAME, X_TYPE, X_CMP, X_UNSET) \
@ -32,7 +33,7 @@ struct tree_ ## X_NAME { \
int y;\
};\
\
struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
static struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
struct tree_ ## X_NAME *T = talloc (sizeof (*T));\
T->x = x;\
T->y = y;\
@ -40,11 +41,11 @@ struct tree_ ## X_NAME *new_tree_node_ ## X_NAME (X_TYPE x, int y) {\
return T;\
}\
\
void delete_tree_node_ ## X_NAME (struct tree_ ## X_NAME *T) {\
static void delete_tree_node_ ## X_NAME (struct tree_ ## X_NAME *T) {\
tfree (T, sizeof (*T));\
}\
\
void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## X_NAME **L, struct tree_ ## X_NAME **R) {\
static void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ## X_NAME **L, struct tree_ ## X_NAME **R) {\
if (!T) {\
*L = *R = 0;\
} else {\
@ -59,8 +60,8 @@ void tree_split_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, struct tree_ ##
}\
}\
\
struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) __attribute__ ((warn_unused_result));\
struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) {\
static struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) __attribute__ ((warn_unused_result,unused));\
static struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x, int y) {\
if (!T) {\
return new_tree_node_ ## X_NAME (x, y);\
} else {\
@ -81,7 +82,7 @@ struct tree_ ## X_NAME *tree_insert_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP
}\
}\
\
struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct tree_ ## X_NAME *R) {\
static struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct tree_ ## X_NAME *R) {\
if (!L || !R) {\
return L ? L : R;\
} else {\
@ -95,8 +96,8 @@ struct tree_ ## X_NAME *tree_merge_ ## X_NAME (struct tree_ ## X_NAME *L, struct
}\
}\
\
struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((warn_unused_result));\
struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
static struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((warn_unused_result,unused));\
static struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
assert (T);\
int c = X_CMP (x, T->x);\
if (!c) {\
@ -113,13 +114,15 @@ struct tree_ ## X_NAME *tree_delete_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYP
}\
}\
\
X_TYPE tree_get_min_ ## X_NAME (struct tree_ ## X_NAME *T) {\
static X_TYPE tree_get_min_ ## X_NAME (struct tree_ ## X_NAME *t) __attribute__ ((unused));\
static X_TYPE tree_get_min_ ## X_NAME (struct tree_ ## X_NAME *T) {\
if (!T) { return X_UNSET; } \
while (T->left) { T = T->left; }\
return T->x; \
} \
\
X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
static X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) __attribute__ ((unused));\
static X_TYPE tree_lookup_ ## X_NAME (struct tree_ ## X_NAME *T, X_TYPE x) {\
int c;\
while (T && (c = X_CMP (x, T->x))) {\
T = (c < 0 ? T->left : T->right);\
@ -127,18 +130,29 @@ 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)) {\
static void tree_act_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE)) __attribute__ ((unused));\
static 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) { \
static void tree_act_ex_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE, void *), void *extra) __attribute__ ((unused));\
static void tree_act_ex_ ## X_NAME (struct tree_ ## X_NAME *T, void (*act)(X_TYPE, void *), void *extra) {\
if (!T) { return; } \
tree_act_ex_ ## X_NAME (T->left, act, extra); \
act (T->x, extra); \
tree_act_ex_ ## X_NAME (T->right, act, extra); \
}\
\
static int tree_count_ ## X_NAME (struct tree_ ## X_NAME *T) __attribute__ ((unused));\
static 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); \
}\
void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \
static void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) __attribute__ ((unused));\
static void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return; }\
if (T->left) { \
assert (T->left->y <= T->y);\
@ -151,6 +165,14 @@ void tree_check_ ## X_NAME (struct tree_ ## X_NAME *T) { \
tree_check_ ## X_NAME (T->left); \
tree_check_ ## X_NAME (T->right); \
}\
static struct tree_ ## X_NAME *tree_clear_ ## X_NAME (struct tree_ ## X_NAME *T) __attribute__ ((unused));\
static struct tree_ ## X_NAME *tree_clear_ ## X_NAME (struct tree_ ## X_NAME *T) { \
if (!T) { return 0; }\
tree_clear_ ## X_NAME (T->left); \
tree_clear_ ## X_NAME (T->right); \
delete_tree_node_ ## X_NAME (T); \
return 0; \
} \
#define int_cmp(a,b) ((a) - (b))
#pragma pack(pop)

520
updates.c Normal file
View file

@ -0,0 +1,520 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013-2014
*/
#include "tgl.h"
#include "updates.h"
#include "mtproto-common.h"
#include "binlog.h"
#include "auto.h"
#include "structures.h"
#include <assert.h>
void tglu_fetch_pts (void) {
int p = fetch_int ();
if (p <= tgl_state.pts) { return; }
bl_do_set_pts (p);
}
void tglu_fetch_qts (void) {
int p = fetch_int ();
if (p <= tgl_state.qts) { return; }
bl_do_set_qts (p);
}
void tglu_fetch_date (void) {
int p = fetch_int ();
if (p > tgl_state.date) {
//tgl_state.date = p;
bl_do_set_date (tgl_state.date);
}
}
static void fetch_dc_option (void) {
assert (fetch_int () == CODE_dc_option);
int id = fetch_int ();
int l1 = prefetch_strlen ();
char *name = fetch_str (l1);
int l2 = prefetch_strlen ();
char *ip = fetch_str (l2);
int port = fetch_int ();
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);
}
void tglu_work_update (struct connection *c, long long msg_id) {
unsigned op = fetch_int ();
switch (op) {
case CODE_update_new_message:
{
struct tgl_message *M = tglf_fetch_alloc_message ();
assert (M);
tglu_fetch_pts ();
bl_do_msg_update (M->id);
break;
};
case CODE_update_message_i_d:
{
int id = fetch_int (); // id
int new = fetch_long (); // random_id
struct tgl_message *M = tgl_message_get (new);
if (M) {
bl_do_set_msg_id (M, id);
}
}
break;
case CODE_update_read_messages:
{
assert (fetch_int () == (int)CODE_vector);
int n = fetch_int ();
//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);
}
}
tglu_fetch_pts ();
}
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 (tgl_state.callback.type_notification && U) {
tgl_state.callback.type_notification ((void *)U);
}
}
break;
case CODE_update_chat_user_typing:
{
tgl_peer_id_t chat_id = TGL_MK_CHAT (fetch_int ());
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 (U && C) {
if (tgl_state.callback.type_in_chat_notification) {
tgl_state.callback.type_in_chat_notification ((void *)U, (void *)C);
}
}
}
break;
case CODE_update_user_status:
{
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *U = tgl_peer_get (user_id);
if (U) {
tglf_fetch_user_status (&U->user.status);
if (tgl_state.callback.status_notification) {
tgl_state.callback.status_notification ((void *)U);
}
} else {
struct tgl_user_status t;
tglf_fetch_user_status (&t);
}
}
break;
case CODE_update_user_name:
{
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *UC = tgl_peer_get (user_id);
if (UC && (UC->flags & FLAG_CREATED)) {
int l1 = prefetch_strlen ();
char *f = fetch_str (l1);
int l2 = prefetch_strlen ();
char *l = fetch_str (l2);
struct tgl_user *U = &UC->user;
bl_do_user_set_real_name (U, f, l1, l, l2);
} else {
fetch_skip_str ();
fetch_skip_str ();
}
}
break;
case CODE_update_user_photo:
{
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *UC = tgl_peer_get (user_id);
tglu_fetch_date ();
if (UC && (UC->flags & FLAG_CREATED)) {
struct tgl_user *U = &UC->user;
unsigned y = fetch_int ();
long long photo_id;
struct tgl_file_location big;
struct tgl_file_location small;
memset (&big, 0, sizeof (big));
memset (&small, 0, sizeof (small));
if (y == CODE_user_profile_photo_empty) {
photo_id = 0;
big.dc = -2;
small.dc = -2;
} else {
assert (y == CODE_user_profile_photo);
photo_id = fetch_long ();
tglf_fetch_file_location (&small);
tglf_fetch_file_location (&big);
}
bl_do_set_user_profile_photo (U, photo_id, &big, &small);
} else {
struct tgl_file_location t;
unsigned y = fetch_int ();
if (y == CODE_user_profile_photo_empty) {
} else {
assert (y == CODE_user_profile_photo);
fetch_long (); // photo_id
tglf_fetch_file_location (&t);
tglf_fetch_file_location (&t);
}
}
fetch_bool ();
}
break;
case CODE_update_restore_messages:
{
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
fetch_skip (n);
tglu_fetch_pts ();
}
break;
case CODE_update_delete_messages:
{
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
fetch_skip (n);
tglu_fetch_pts ();
}
break;
case CODE_update_chat_participants:
{
unsigned x = fetch_int ();
assert (x == CODE_chat_participants || x == CODE_chat_participants_forbidden);
tgl_peer_id_t chat_id = TGL_MK_CHAT (fetch_int ());
int n = 0;
tgl_peer_t *C = tgl_peer_get (chat_id);
if (C && (C->flags & FLAG_CREATED)) {
if (x == CODE_chat_participants) {
bl_do_chat_set_admin (&C->chat, fetch_int ());
assert (fetch_int () == CODE_vector);
n = fetch_int ();
struct tgl_chat_user *users = talloc (12 * n);
int i;
for (i = 0; i < n; i++) {
assert (fetch_int () == (int)CODE_chat_participant);
users[i].user_id = fetch_int ();
users[i].inviter_id = fetch_int ();
users[i].date = fetch_int ();
}
int version = fetch_int ();
bl_do_chat_set_participants (&C->chat, version, n, users);
}
} else {
if (x == CODE_chat_participants) {
fetch_int (); // admin_id
assert (fetch_int () == CODE_vector);
n = fetch_int ();
fetch_skip (n * 4);
fetch_int (); // version
}
}
}
break;
case CODE_update_contact_registered:
{
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *U = tgl_peer_get (user_id);
fetch_int (); // date
if (tgl_state.callback.user_registered && U) {
tgl_state.callback.user_registered ((void *)U);
}
}
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);
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) {
fetch_bool (); // has_phone
}
t = fetch_int ();
assert (t == CODE_contacts_foreign_link_unknown || t == CODE_contacts_foreign_link_requested || t == CODE_contacts_foreign_link_mutual);
if (t == CODE_contacts_foreign_link_requested) {
fetch_bool (); // has_phone
}
if (U) {}
}
break;
case CODE_update_activation:
{
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_t *U = tgl_peer_get (user_id);
if (tgl_state.callback.user_activated && U) {
tgl_state.callback.user_activated ((void *)U);
}
}
break;
case CODE_update_new_authorization:
{
fetch_long (); // auth_key_id
fetch_int (); // date
char *s = fetch_str_dup ();
char *location = fetch_str_dup ();
if (tgl_state.callback.new_authorization) {
tgl_state.callback.new_authorization (s, location);
}
tfree_str (s);
tfree_str (location);
}
break;
case CODE_update_new_geo_chat_message:
{
struct tgl_message *M = tglf_fetch_alloc_geo_message ();
assert (M);
bl_do_msg_update (M->id);
}
break;
case CODE_update_new_encrypted_message:
{
struct tgl_message *M = tglf_fetch_alloc_encrypted_message ();
assert (M);
tglu_fetch_qts ();
bl_do_msg_update (M->id);
}
break;
case CODE_update_encryption:
{
struct tgl_secret_chat *E = tglf_fetch_alloc_encrypted_chat ();
vlogprintf (E_DEBUG, "Secret chat state = %d\n", E->state);
if (E->state == sc_ok) {
tgl_do_send_encr_chat_layer (E);
}
fetch_int (); // date
}
break;
case CODE_update_encrypted_chat_typing:
{
tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ());
tgl_peer_t *P = tgl_peer_get (id);
if (P) {
if (tgl_state.callback.type_in_secret_chat_notification) {
tgl_state.callback.type_in_secret_chat_notification ((void *)P);
}
}
}
break;
case CODE_update_encrypted_messages_read:
{
tgl_peer_id_t id = TGL_MK_ENCR_CHAT (fetch_int ()); // chat_id
fetch_int (); // max_date
fetch_int (); // date
tgl_peer_t *P = tgl_peer_get (id);
//int x = -1;
if (P && P->last) {
//x = 0;
struct tgl_message *M = P->last;
while (M && (!M->out || M->unread)) {
if (M->out) {
bl_do_set_unread (M, 0);
}
M = M->next;
}
}
}
break;
case CODE_update_chat_participant_add:
{
tgl_peer_id_t chat_id = TGL_MK_CHAT (fetch_int ());
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
tgl_peer_id_t inviter_id = TGL_MK_USER (fetch_int ());
int version = fetch_int ();
tgl_peer_t *C = tgl_peer_get (chat_id);
if (C && (C->flags & FLAG_CREATED)) {
bl_do_chat_add_user (&C->chat, version, tgl_get_peer_id (user_id), tgl_get_peer_id (inviter_id), time (0));
}
}
break;
case CODE_update_chat_participant_delete:
{
tgl_peer_id_t chat_id = TGL_MK_CHAT (fetch_int ());
tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ());
int version = fetch_int ();
tgl_peer_t *C = tgl_peer_get (chat_id);
if (C && (C->flags & FLAG_CREATED)) {
bl_do_chat_del_user (&C->chat, version, tgl_get_peer_id (user_id));
}
}
break;
case CODE_update_dc_options:
{
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
assert (n >= 0);
int i;
for (i = 0; i < n; i++) {
fetch_dc_option ();
}
}
break;
case CODE_update_user_blocked:
{
int id = fetch_int ();
int blocked = fetch_bool ();
tgl_peer_t *P = tgl_peer_get (TGL_MK_USER (id));
if (P && (P->flags & FLAG_CREATED)) {
bl_do_user_set_blocked (&P->user, blocked);
}
}
break;
case CODE_update_notify_settings:
{
assert (skip_type_any (TYPE_TO_PARAM (notify_peer)) >= 0);
assert (skip_type_any (TYPE_TO_PARAM (peer_notify_settings)) >= 0);
}
break;
default:
vlogprintf (E_ERROR, "Unknown update type %08x\n", op);
;
}
}
void tglu_work_update_short (struct connection *c, long long msg_id) {
int *save = in_ptr;
assert (!skip_type_any (TYPE_TO_PARAM (updates)));
int *save_end = in_ptr;
in_ptr = save;
assert (fetch_int () == CODE_update_short);
tglu_work_update (c, msg_id);
tglu_fetch_date ();
assert (save_end == in_ptr);
}
static int do_skip_seq (int seq) {
if (tgl_state.seq) {
if (seq <= tgl_state.seq) {
vlogprintf (E_NOTICE, "Duplicate message with seq=%d\n", seq);
return -1;
}
if (seq > tgl_state.seq + 1) {
vlogprintf (E_NOTICE, "Hole in seq (seq = %d, cur_seq = %d)\n", seq, tgl_state.seq);
//vlogprintf (E_NOTICE, "lock_diff = %s\n", (tgl_state.locks & TGL_LOCK_DIFF) ? "true" : "false");
tgl_do_get_difference (0, 0, 0);
return -1;
}
if (tgl_state.locks & TGL_LOCK_DIFF) {
vlogprintf (E_DEBUG, "Update during get_difference. seq = %d\n", seq);
return -1;
}
vlogprintf (E_DEBUG, "Ok update. seq = %d\n", seq);
return 0;
} else {
return -1;
}
}
void tglu_work_updates (struct connection *c, long long msg_id) {
int *save = in_ptr;
assert (!skip_type_any (TYPE_TO_PARAM (updates)));
if (do_skip_seq (*(in_ptr - 1)) < 0) {
return;
}
int *save_end = in_ptr;
in_ptr = save;
assert (fetch_int () == CODE_updates);
assert (fetch_int () == CODE_vector);
int n = fetch_int ();
int i;
for (i = 0; i < n; i++) {
tglu_work_update (c, msg_id);
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
for (i = 0; i < n; i++) {
tglf_fetch_alloc_user ();
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
for (i = 0; i < n; i++) {
tglf_fetch_alloc_chat ();
}
bl_do_set_date (fetch_int ());
//bl_do_set_seq (fetch_int ());
int seq = fetch_int ();
assert (seq == tgl_state.seq + 1);
bl_do_set_seq (seq);
assert (save_end == in_ptr);
}
void tglu_work_update_short_message (struct connection *c, long long msg_id) {
int *save = in_ptr;
assert (!skip_type_any (TYPE_TO_PARAM (updates)));
if (do_skip_seq (*(in_ptr - 1)) < 0) {
return;
}
int *save_end = in_ptr;
in_ptr = save;
assert (fetch_int () == (int)CODE_update_short_message);
struct tgl_message *M = tglf_fetch_alloc_message_short ();
assert (M);
assert (save_end == in_ptr);
if (!(tgl_state.locks & TGL_LOCK_DIFF)) {
bl_do_msg_seq_update (M->id);
}
}
void tglu_work_update_short_chat_message (struct connection *c, long long msg_id) {
int *save = in_ptr;
assert (!skip_type_any (TYPE_TO_PARAM (updates)));
if (do_skip_seq (*(in_ptr - 1)) < 0) {
return;
}
int *save_end = in_ptr;
in_ptr = save;
assert (fetch_int () == CODE_update_short_chat_message);
struct tgl_message *M = tglf_fetch_alloc_message_short_chat ();
assert (M);
assert (save_end == in_ptr);
if (!(tgl_state.locks & TGL_LOCK_DIFF)) {
bl_do_msg_seq_update (M->id);
}
}
void tglu_work_updates_to_long (struct connection *c, long long msg_id) {
assert (fetch_int () == (int)CODE_updates_too_long);
vlogprintf (E_NOTICE, "updates too long... Getting difference\n");
tgl_do_get_difference (0, 0, 0);
}

35
updates.h Normal file
View file

@ -0,0 +1,35 @@
/*
This file is part of tgl-library
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright Vitaly Valtman 2013-2014
*/
#ifndef __UPDATES_H__
#define __UPDATES_H__
struct connection;
void tglu_work_update (struct connection *c, long long msg_id);
void tglu_work_updates_to_long (struct connection *c, long long msg_id);
void tglu_work_update_short_chat_message (struct connection *c, long long msg_id);
void tglu_work_update_short_message (struct connection *c, long long msg_id);
void tglu_work_update_short (struct connection *c, long long msg_id);
void tglu_work_updates (struct connection *c, long long msg_id);
void tglu_fetch_pts (void);
void tglu_fetch_qts (void);
void tglu_fetch_seq (void);
void tglu_fetch_date (void);
#endif