diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..dffe6ca --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tgl"] + path = tgl + url = https://github.com/vysheng/tgl.git diff --git a/Makefile.in b/Makefile.in index 817b847..d9034bd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -10,24 +10,16 @@ EXTRA_LIBS=@LIBS@ @EXTRA_LIBS@ @OPENSSL_LIBS@ LOCAL_LDFLAGS=-rdynamic -ggdb -levent ${EXTRA_LIBS} LINK_FLAGS=${LDFLAGS} ${LOCAL_LDFLAGS} -DEP=${srcdir}/dep -AUTO=${srcdir}/auto -EXE=${srcdir}/bin -OBJ=${srcdir}/objs -LIB=${srcdir}/libs +DEP=dep +AUTO=auto +EXE=bin +OBJ=objs +LIB=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 +EXE_LIST=${EXE}/telegram-cli -TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/net.o ${OBJ}/lua-tg.o ${OBJ}/tgl-timers.o -TGL_OBJECTS=${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 -TLD_OBJECTS=${OBJ}/dump-tl-file.o -GENERATE_OBJECTS=${OBJ}/generate.o -COMMON_OBJECTS=${OBJ}/tools.o -OBJ_LIST=${TG_OBJECTS} ${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS} ${TLD_OBJECTS} -OBJ_C=${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS} ${TLD_OBJECTS} +TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/lua-tg.o DEPENDENCE=$(subst ${OBJ}/,${DEP}/,$(patsubst %.o,%.d,${OBJ_LIST})) DEPENDENCE_LIST=${DEPENDENCE} @@ -39,56 +31,24 @@ CC=@CC@ .SUFFIXES: .c .h .o -all: ${EXE_LIST} ${DIR_LIST} ${LIB_LIST} +all: ${EXE_LIST} ${DIR_LIST} create_dirs_and_headers: ${DIR_LIST} ${AUTO}/auto.c ${AUTO}/auto-header.h ${AUTO}/constants.h create_dirs: ${DIR_LIST} dump-tl: ${EXE}/dump-tl-file +include ${srcdir}/Makefile.tl-parser +include ${srcdir}/Makefile.tgl + ${DIR_LIST}: @test -d $@ || mkdir -p $@ -include ${DEPENDENCE_LIST} -${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 < $< > $@ - -${EXE}/dump-tl-file: ${OBJ}/auto/auto.o ${TLD_OBJECTS} - ${CC} ${OBJ}/auto/auto.o ${TLD_OBJECTS} ${LINK_FLAGS} -o $@ +${EXE}/telegram-cli: ${TG_OBJECTS} ${LIB}/libtgl.a + ${CC} $^ ${LINK_FLAGS} -o $@ clean: rm -rf ${DIR_LIST} config.log config.status > /dev/null || echo "all clean" diff --git a/Makefile.tgl b/Makefile.tgl new file mode 100644 index 0000000..4ed85b6 --- /dev/null +++ b/Makefile.tgl @@ -0,0 +1,47 @@ +TGL_OBJECTS=${OBJ}/mtproto-common.o ${OBJ}/mtproto-client.o ${OBJ}/queries.o ${OBJ}/structures.o ${OBJ}/binlog.o ${OBJ}/tgl.o ${OBJ}/updates.o ${OBJ}/tgl-net.o ${OBJ}/tgl-timers.o +TLD_OBJECTS=${OBJ}/dump-tl-file.o +GENERATE_OBJECTS=${OBJ}/generate.o +TGL_COMMON_OBJECTS=${OBJ}/tools.o +TGL_OBJ_C=${GENERATE_OBJECTS} ${TGL_COMMON_OBJECTS} ${TGL_OBJECTS} ${TLD_OBJECTS} + +.SUFFIXES: + +.SUFFIXES: .c .h .o + +dump-tl: ${EXE}/dump-tl-file + +${OBJ}/auto/auto.o ${TGL_OBJECTS}: ${AUTO}/constants.h ${AUTO}/auto-header.h + +${TGL_OBJ_C}: ${OBJ}/%.o: ${srcdir}/tgl/%.c | create_dirs + ${CC} ${INCLUDE} ${COMPILE_FLAGS} -iquote ${srcdir}/tgl -c -MP -MD -MF ${DEP}/$*.d -MQ ${OBJ}/$*.o -o $@ $< + +${OBJ}/auto/auto.o: ${AUTO}/auto.c + ${CC} ${INCLUDE} ${COMPILE_FLAGS} -iquote ${srcdir}/tgl -c -MP -MD -MF ${DEP}/auto/auto.d -MQ ${OBJ}/auto/auto.o -o $@ $< + +${LIB}/libtgl.a: ${TGL_OBJECTS} ${TGL_COMMON_OBJECTS} ${OBJ}/auto/auto.o + ar ruv $@ $^ + +${EXE}/generate: ${GENERATE_OBJECTS} ${TGL_COMMON_OBJECTS} + ${CC} ${GENERATE_OBJECTS} ${TGL_COMMON_OBJECTS} ${LINK_FLAGS} -o $@ + +${AUTO}/scheme.tlo: ${AUTO}/scheme.tl ${EXE}/tl-parser + ${EXE}/tl-parser -e $@ ${AUTO}/scheme.tl + +${AUTO}/scheme.tl: ${srcdir}/tgl/scheme.tl ${srcdir}/tgl/encrypted_scheme.tl ${srcdir}/tgl/binlog.tl ${srcdir}/tgl/append.tl | ${AUTO} + cat $^ > $@ + +${AUTO}/scheme2.tl: ${AUTO}/scheme.tl ${EXE}/tl-parser + ${EXE}/tl-parser -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}/tgl/gen_constants_h.awk + awk -f ${srcdir}/tgl/gen_constants_h.awk < $< > $@ + +${EXE}/dump-tl-file: ${OBJ}/auto/auto.o ${TLD_OBJECTS} + ${CC} ${OBJ}/auto/auto.o ${TLD_OBJECTS} ${LINK_FLAGS} -o $@ + diff --git a/Makefile.tl-parser b/Makefile.tl-parser new file mode 100644 index 0000000..eb3284d --- /dev/null +++ b/Makefile.tl-parser @@ -0,0 +1,7 @@ +TL_PARSER_OBJECTS=${OBJ}/tl-parser.o ${OBJ}/tlc.o ${OBJ}/crc32.o + +${TL_PARSER_OBJECTS}: ${OBJ}/%.o: ${srcdir}/tgl/tl-parser/%.c | create_dirs + ${CC} ${INCLUDE} ${COMPILE_FLAGS} -iquote ${srcdir}/tgl/tl-parser -c -MP -MD -MF ${DEP}/$*.d -MQ ${OBJ}/$*.o -o $@ $< + +${EXE}/tl-parser: ${TL_PARSER_OBJECTS} + ${CC} $^ ${LINK_FLAGS} -o $@ diff --git a/README.md b/README.md index 656c612..abecd53 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,7 @@ Fourth, in peer_name '#' are substitued to '@'. (Not applied to appending of '#% Clone GitHub Repository - git clone https://github.com/vysheng/tg.git && cd tg - -or download and extract zip - - wget https://github.com/vysheng/tg/archive/master.zip -O tg-master.zip - unzip tg-master.zip && cd tg-master + git clone --recursive https://github.com/vysheng/tg.git && cd tg #### Linux and BSDs diff --git a/append.tl b/append.tl deleted file mode 100644 index 0b5711b..0000000 --- a/append.tl +++ /dev/null @@ -1,2 +0,0 @@ -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; diff --git a/binlog.tl b/binlog.tl deleted file mode 100644 index 9557b0c..0000000 --- a/binlog.tl +++ /dev/null @@ -1,83 +0,0 @@ ----types--- -binlog.fileLocation dc:int volume:long local_id:int secret:long = binlog.FileLocation; -binlog.chatParticipant user:int inviter:int date:int = binlog.ChatParticipant; - -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; - -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.userSetUsername id:int username:string = 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.encrChatUpdateSeq id:int in_seq_no:int out_seq_no:int = binlog.Update; -binlog.encrChatSetSeq id:int in_seq_no:int last_in_seq_no:int out_seq_no:int = 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; diff --git a/crc32.c b/crc32.c deleted file mode 100644 index 1fc4e61..0000000 --- a/crc32.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - 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 . - - Copyright 2009-2012 Vkontakte Ltd - 2009-2012 Nikolai Durov - 2009-2012 Andrei Lopatin - 2012 Anton Maydell -*/ - -#include -#include -#include -#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; -} diff --git a/crc32.h b/crc32.h deleted file mode 100644 index fdf8da8..0000000 --- a/crc32.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 . - - 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 diff --git a/encrypted_scheme.tl b/encrypted_scheme.tl deleted file mode 120000 index b45af3d..0000000 --- a/encrypted_scheme.tl +++ /dev/null @@ -1 +0,0 @@ -encrypted_scheme17.tl \ No newline at end of file diff --git a/encrypted_scheme16.tl b/encrypted_scheme16.tl deleted file mode 100644 index eb58ed4..0000000 --- a/encrypted_scheme16.tl +++ /dev/null @@ -1,22 +0,0 @@ ----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 = DecryptedMessageAction; -decryptedMessageActionDeleteMessages#65614304 random_ids:Vector = DecryptedMessageAction; -decryptedMessageActionScreenshotMessages#8ac1f475 random_ids:Vector = DecryptedMessageAction; -decryptedMessageActionFlushHistory#6719e45c = DecryptedMessageAction; -decryptedMessageActionNotifyLayer#f3048883 layer:int = DecryptedMessageAction; ----functions--- diff --git a/encrypted_scheme17.tl b/encrypted_scheme17.tl deleted file mode 100644 index 95e661b..0000000 --- a/encrypted_scheme17.tl +++ /dev/null @@ -1,31 +0,0 @@ ----types--- -decryptedMessageLayer#1be31789 layer:int message:DecryptedMessage = DecryptedMessageLayer; -decryptedMessage_l16#1f814f1f random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage; -decryptedMessageService_l16#aa48327d random_id:long random_bytes:bytes action:DecryptedMessageAction = DecryptedMessage; - -decryptedMessage#204d3878 in_seq_no:int out_seq_no:int ttl:int random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage; -decryptedMessageService#73164160 in_seq_no:int out_seq_no:int 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 = DecryptedMessageAction; -decryptedMessageActionDeleteMessages#65614304 random_ids:Vector = DecryptedMessageAction; -decryptedMessageActionScreenshotMessages#8ac1f475 random_ids:Vector = DecryptedMessageAction; -decryptedMessageActionFlushHistory#6719e45c = DecryptedMessageAction; -decryptedMessageActionNotifyLayer#f3048883 layer:int = DecryptedMessageAction; - -decryptedMessageActionResend#511110b0 start_seq_no:int end_seq_no:int = DecryptedMessageAction; - -decryptedMessageActionTyping#ccb27641 action:SendMessageAction = DecryptedMessageAction; - ----functions--- diff --git a/gen_constants_h.awk b/gen_constants_h.awk deleted file mode 100644 index 17e7e12..0000000 --- a/gen_constants_h.awk +++ /dev/null @@ -1,37 +0,0 @@ -BEGIN { - print "/*"; - print " This file is part of telegram-client."; - print ""; - print " Telegram-client is free software: you can redistribute it and/or modify"; - print " it under the terms of the GNU General Public License as published by"; - print " the Free Software Foundation, either version 2 of the License, or"; - print " (at your option) any later version."; - print ""; - print " Telegram-client is distributed in the hope that it will be useful,"; - print " but WITHOUT ANY WARRANTY; without even the implied warranty of"; - print " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"; - print " GNU General Public License for more details."; - print ""; - print " You should have received a copy of the GNU General Public License"; - print " along with this telegram-client. If not, see ."; - print ""; - print " Copyright Vitaly Valtman 2013"; - print "*/"; - print "#ifndef CONSTANTS_H"; - print "#define CONSTANTS_H"; -} -// { - if (split ($1, a, "#") == 2) { - 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/" - exit 1; - } - h[a[2]] = a[1]; - print "#define", "CODE_" tolower(a[1]), "0x" a[2]; - } -} -END { - print "#endif"; -} diff --git a/generate.c b/generate.c deleted file mode 100644 index f42177c..0000000 --- a/generate.c +++ /dev/null @@ -1,1829 +0,0 @@ -/* - 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 . - - 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 -*/ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tl-tl.h" -#include "generate.h" - -#include "tree.h" -#include "config.h" - -int header; - -#define tl_type_name_cmp(a,b) (a->name > b->name ? 1 : a->name < b->name ? -1 : 0) - -DEFINE_TREE (tl_type, struct tl_type *, tl_type_name_cmp, 0) -DEFINE_TREE (tl_combinator, struct tl_combinator *, tl_type_name_cmp, 0) - -struct tree_tl_type *type_tree; -struct tree_tl_combinator *function_tree; - -void tl_function_insert_by_name (struct tl_combinator *c) { - function_tree = tree_insert_tl_combinator (function_tree, c, lrand48 ()); -} - -struct tl_type *tl_type_get_by_name (int name) { - static struct tl_type t; - t.name = name; - - return tree_lookup_tl_type (type_tree, &t); -} - -void tl_type_insert_by_name (struct tl_type *t) { - type_tree = tree_insert_tl_type (type_tree, t, lrand48 ()); -} - -int is_empty (struct tl_type *t) { - if (t->name == NAME_INT || t->name == NAME_LONG || t->name == NAME_DOUBLE || t->name == NAME_STRING) { return 1; } - if (t->constructors_num != 1) { return 0; } - int count = 0; - int i; - struct tl_combinator *c = t->constructors[0]; - for (i = 0; i < c->args_num; i++) { - if (!(c->args[i]->flags & FLAG_OPT_VAR)) { count ++; } - } - return count == 1; -} - - -static char buf[1 << 20]; -int buf_size; -int *buf_ptr = (int *)buf; -int *buf_end; -#ifndef DISABLE_EXTF -int skip_only = 0; -#else -int skip_only = 1; -#endif - -int verbosity; - -int get_int (void) { - assert (buf_ptr < buf_end); - return *(buf_ptr ++); -} - -long long get_long (void) { - assert (buf_ptr + 1 < buf_end); - long long r = *(long long *)buf_ptr; - buf_ptr += 2; - return r; -} - -static void *malloc0 (int size) { - void *r = malloc (size); - assert (r); - memset (r, 0, size); - return r; -} - -char *get_string (void) { - int l = *(unsigned char *)buf_ptr; - assert (l != 0xff); - - char *res; - int tlen = 0; - if (l == 0xfe) { - l = ((unsigned)get_int ()) >> 8; - res = (char *)buf_ptr; - tlen = l; - } else { - res = ((char *)buf_ptr) + 1; - tlen = 1 + l; - } - - int len = l; - - tlen += ((-tlen) & 3); - assert (!(tlen & 3)); - - buf_ptr += tlen / 4; - assert (buf_ptr <= buf_end); - - char *r = strndup (res, len); - assert (r); - return r; -} - - -int tn, fn, cn; -struct tl_type **tps; -struct tl_combinator **fns; - -struct tl_tree *read_tree (int *var_num); -struct tl_tree *read_nat_expr (int *var_num); -struct tl_tree *read_type_expr (int *var_num); -int read_args_list (struct arg **args, int args_num, int *var_num); - -#define use_var_nat_full_form(x) 0 - -void *int_to_var_nat_const_init (long long x) { - if (use_var_nat_full_form (x)) { - struct tl_tree_nat_const *T = malloc (sizeof (*T)); - assert (T); - T->self.flags = 0; - T->self.methods = &tl_pnat_const_full_methods; - T->value = x; - return T; - } else { - return (void *)(long)(x * 2 - 0x80000001l); - } -} - -long long var_nat_const_to_int (void *x) { - if (((long)x) & 1) { - return (((long)x) + 0x80000001l) / 2; - } else { - return ((struct tl_tree_nat_const *)x)->value; - } -} - -int tl_tree_type_type (struct tl_tree *x) { - return NODE_TYPE_TYPE; -} - -int tl_tree_type_array (struct tl_tree *x) { - return NODE_TYPE_ARRAY; -} - -int tl_tree_type_nat_const (struct tl_tree *x) { - return NODE_TYPE_NAT_CONST; -} - -int tl_tree_type_var_num (struct tl_tree *x) { - return NODE_TYPE_VAR_NUM; -} - -int tl_tree_type_var_type (struct tl_tree *x) { - return NODE_TYPE_VAR_TYPE; -} - -struct tl_tree_methods tl_var_num_methods = { - .type = tl_tree_type_var_num -}; - -struct tl_tree_methods tl_var_type_methods = { - .type = tl_tree_type_var_type -}; - -struct tl_tree_methods tl_type_methods = { - .type = tl_tree_type_type -}; - -struct tl_tree_methods tl_nat_const_methods = { - .type = tl_tree_type_nat_const -}; - -struct tl_tree_methods tl_array_methods = { - .type = tl_tree_type_array -}; - -struct tl_tree_methods tl_ptype_methods = { - .type = tl_tree_type_type -}; - -struct tl_tree_methods tl_parray_methods = { - .type = tl_tree_type_array -}; - -struct tl_tree_methods tl_pvar_num_methods = { - .type = tl_tree_type_var_num -}; - -struct tl_tree_methods tl_pvar_type_methods = { - .type = tl_tree_type_var_type -}; - -struct tl_tree_methods tl_nat_const_full_methods = { - .type = tl_tree_type_nat_const -}; - -struct tl_tree_methods tl_pnat_const_full_methods = { - .type = tl_tree_type_nat_const -}; - -struct tl_tree *read_num_const (int *var_num) { - return (void *)int_to_var_nat_const_init (get_int ()); -} - - -int gen_uni_skip (struct tl_tree *t, char *cur_name, int *vars, int first, int fun) { - assert (t); - int x = TL_TREE_METHODS (t)->type (t); - int l = 0; - int i; - int j; - struct tl_tree_type *t1; - struct tl_tree_array *t2; - int y; - int L = strlen (cur_name); - char *fail = fun ? "return 0;" : "return -1;"; - switch (x) { - case NODE_TYPE_TYPE: - t1 = (void *)t; - if (!first) { - printf (" if (ODDP(%s) || %s->type->name != 0x%08x) { %s }\n", cur_name, cur_name, t1->type->name, fail); - } else { - printf (" if (ODDP(%s) || (%s->type->name != 0x%08x && %s->type->name != 0x%08x)) { %s }\n", cur_name, cur_name, t1->type->name, cur_name, ~t1->type->name, fail); - } - for (i = 0; i < t1->children_num; i++) { - sprintf (cur_name + L, "->params[%d]", i); - gen_uni_skip (t1->children[i], cur_name, vars, 0, fun); - cur_name[L] = 0; - } - return 0; - case NODE_TYPE_NAT_CONST: - printf (" if (EVENP(%s) || ((long)%s) != %lld) { %s }\n", cur_name, cur_name, var_nat_const_to_int (t) * 2 + 1, fail); - return 0; - case NODE_TYPE_ARRAY: - printf (" if (ODDP(%s) || %s->type->name != TL_TYPE_ARRAY) { %s }\n", cur_name, cur_name, fail); - t2 = (void *)t; - - sprintf (cur_name + L, "->params[0]"); - y = gen_uni_skip (t2->multiplicity, cur_name, vars, 0, fun); - cur_name[L] = 0; - - sprintf (cur_name + L, "->params[1]"); - y += gen_uni_skip (t2->args[0]->type, cur_name, vars, 0, fun); - cur_name[L] = 0; - return 0; - case NODE_TYPE_VAR_TYPE: - printf (" if (ODDP(%s)) { %s }\n", cur_name, fail); - i = ((struct tl_tree_var_type *)t)->var_num; - if (!vars[i]) { - printf (" struct paramed_type *var%d = %s; assert (var%d);\n", i, cur_name, i); - vars[i] = 1; - } else if (vars[i] == 1) { - printf (" if (compare_types (var%d, %s) < 0) { %s }\n", i, cur_name, fail); - } else { - assert (0); - return -1; - } - return l; - case NODE_TYPE_VAR_NUM: - printf (" if (EVENP(%s)) { %s }\n", cur_name, fail); - i = ((struct tl_tree_var_num *)t)->var_num; - j = ((struct tl_tree_var_num *)t)->dif; - if (!vars[i]) { - printf (" struct paramed_type *var%d = ((void *)%s) + %d; assert (var%d);\n", i, cur_name, 2 * j, i); - vars[i] = 2; - } else if (vars[i] == 2) { - printf (" if (var%d != ((void *)%s) + %d) { %s }\n", i, cur_name, 2 * j, fail); - } else { - assert (0); - return -1; - } - return 0; - default: - assert (0); - return -1; - } -} - -void print_offset (int len) { - int i; - for (i = 0; i < len; i++) { printf (" "); } -} - -int gen_create (struct tl_tree *t, int *vars, int offset) { - int x = TL_TREE_METHODS (t)->type (t); - int i; - struct tl_tree_type *t1; - struct tl_tree_array *t2; - switch (x) { - case NODE_TYPE_TYPE: - print_offset (offset); - printf ("&(struct paramed_type){\n"); - print_offset (offset + 2); - t1 = (void *)t; - if (t1->self.flags & FLAG_BARE) { - printf (".type = &(struct tl_type_descr) {.name = 0x%08x, .id = \"Bare_%s\", .params_num = %d, .params_types = %lld},\n", ~t1->type->name, t1->type->id, t1->type->arity, t1->type->params_types); - } else { - printf (".type = &(struct tl_type_descr) {.name = 0x%08x, .id = \"%s\", .params_num = %d, .params_types = %lld},\n", t1->type->name, t1->type->id, t1->type->arity, t1->type->params_types); - } - if (t1->children_num) { - print_offset (offset + 2); - printf (".params = (struct paramed_type *[]){\n"); - for (i = 0; i < t1->children_num; i++) { - assert (gen_create (t1->children[i], vars, offset + 4) >= 0); - printf (",\n"); - } - print_offset (offset + 2); - printf ("}\n"); - } else { - print_offset (offset + 2); - printf (".params = 0,\n"); - } - print_offset (offset); - printf ("}"); - return 0; - case NODE_TYPE_NAT_CONST: - print_offset (offset); - printf ("INT2PTR (%d)", (int)var_nat_const_to_int (t)); - return 0; - case NODE_TYPE_ARRAY: - print_offset (offset); - printf ("&(struct paramed_type){\n"); - print_offset (offset + 2); - t2 = (void *)t; - printf (".type = &(struct tl_type_descr) {.name = NAME_ARRAY, .id = \"array\", .params_num = 2, .params_types = 1},\n"); - print_offset (offset + 2); - printf (".params = (struct paramed_type **){\n"); - gen_create (t2->multiplicity, vars, offset + 4); - printf (",\n"); - gen_create (t2->args[0]->type, vars, offset + 4); - printf (",\n"); - print_offset (offset + 2); - printf ("}\n"); - print_offset (offset); - printf ("}"); - return 0; - case NODE_TYPE_VAR_TYPE: - print_offset (offset); - printf ("var%d", ((struct tl_tree_var_type *)t)->var_num); - return 0; - case NODE_TYPE_VAR_NUM: - print_offset (offset); - printf ("((void *)var%d) + %d", ((struct tl_tree_var_type *)t)->var_num, 2 * ((struct tl_tree_var_num *)t)->dif); - return 0; - default: - assert (0); - return -1; - } -} - -int gen_field_skip (struct arg *arg, int *vars, int num) { - assert (arg); - char *offset = " "; - int o = 0; - if (arg->exist_var_num >= 0) { - printf (" if (PTR2INT (var%d) & (1 << %d)) {\n", arg->exist_var_num, arg->exist_var_bit); - offset = " "; - o = 2; - } - if (arg->var_num >= 0) { - assert (TL_TREE_METHODS (arg->type)->type (arg->type) == NODE_TYPE_TYPE); - int t = ((struct tl_tree_type *)arg->type)->type->name; - if (t == NAME_VAR_TYPE) { - fprintf (stderr, "Not supported yet\n"); - assert (0); - } else { - assert (t == NAME_VAR_NUM); - if (vars[arg->var_num] == 0) { - printf ("%sif (in_remaining () < 4) { return -1;}\n", offset); - printf ("%sstruct paramed_type *var%d = INT2PTR (fetch_int ());\n", offset, arg->var_num); - vars[arg->var_num] = 2; - } else if (vars[arg->var_num] == 2) { - printf ("%sif (in_remaining () < 4) { return -1;}\n", offset); - printf ("%sif (vars%d != INT2PTR (fetch_int ())) { return -1; }\n", offset, arg->var_num); - } else { - assert (0); - return -1; - } - } - } else { - int t = TL_TREE_METHODS (arg->type)->type (arg->type); - if (t == NODE_TYPE_TYPE || t == NODE_TYPE_VAR_TYPE) { - printf ("%sstruct paramed_type *field%d = \n", offset, num); - assert (gen_create (arg->type, vars, 2 + o) >= 0); - printf (";\n"); - int bare = arg->flags & FLAG_BARE; - if (!bare && t == NODE_TYPE_TYPE) { - bare = ((struct tl_tree_type *)arg->type)->self.flags & FLAG_BARE; - } - if (!bare) { - printf ("%sif (skip_type_%s (field%d) < 0) { return -1;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num); - } else { - printf ("%sif (skip_type_bare_%s (field%d) < 0) { return -1;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num); - } - } else { - assert (t == NODE_TYPE_ARRAY); - printf ("%sint multiplicity%d = PTR2INT (\n", offset, num); - assert (gen_create (((struct tl_tree_array *)arg->type)->multiplicity, vars, 2 + o) >= 0); - printf ("%s);\n", offset); - printf ("%sstruct paramed_type *field%d = \n", offset, num); - assert (gen_create (((struct tl_tree_array *)arg->type)->args[0]->type, vars, 2 + o) >= 0); - printf (";\n"); - printf ("%swhile (multiplicity%d -- > 0) {\n", offset, num); - printf ("%s if (skip_type_%s (field%d) < 0) { return -1;}\n", offset, "any", num); - printf ("%s}\n", offset); - } - } - if (arg->exist_var_num >= 0) { - printf (" }\n"); - } - return 0; -} - -int gen_field_fetch (struct arg *arg, int *vars, int num, int empty) { - assert (arg); - char *offset = " "; - int o = 0; - if (arg->exist_var_num >= 0) { - printf (" if (PTR2INT (var%d) & (1 << %d)) {\n", arg->exist_var_num, arg->exist_var_bit); - offset = " "; - o = 2; - } - if (!empty) { - printf("%sif (multiline_output >= 2) { print_offset (); }\n", offset); - } - if (arg->id && strlen (arg->id) && !empty) { - printf ("%sif (!disable_field_names) { eprintf (\" %s :\"); }\n", offset, arg->id); - } - if (arg->var_num >= 0) { - assert (TL_TREE_METHODS (arg->type)->type (arg->type) == NODE_TYPE_TYPE); - int t = ((struct tl_tree_type *)arg->type)->type->name; - if (t == NAME_VAR_TYPE) { - fprintf (stderr, "Not supported yet\n"); - assert (0); - } else { - assert (t == NAME_VAR_NUM); - if (vars[arg->var_num] == 0) { - printf ("%sif (in_remaining () < 4) { return -1;}\n", offset); - printf ("%seprintf (\" %%d\", prefetch_int ());\n", offset); - printf ("%sstruct paramed_type *var%d = INT2PTR (fetch_int ());\n", offset, arg->var_num); - vars[arg->var_num] = 2; - } else if (vars[arg->var_num] == 2) { - printf ("%sif (in_remaining () < 4) { return -1;}\n", offset); - printf ("%seprintf (\" %%d\", prefetch_int ());\n", offset); - printf ("%sif (vars%d != INT2PTR (fetch_int ())) { return -1; }\n", offset, arg->var_num); - } else { - assert (0); - return -1; - } - } - } else { - int t = TL_TREE_METHODS (arg->type)->type (arg->type); - if (t == NODE_TYPE_TYPE || t == NODE_TYPE_VAR_TYPE) { - printf ("%sstruct paramed_type *field%d = \n", offset, num); - assert (gen_create (arg->type, vars, 2 + o) >= 0); - printf (";\n"); - int bare = arg->flags & FLAG_BARE; - if (!bare && t == NODE_TYPE_TYPE) { - bare = ((struct tl_tree_type *)arg->type)->self.flags & FLAG_BARE; - } - if (!bare) { - printf ("%sif (fetch_type_%s (field%d) < 0) { return -1;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num); - } else { - printf ("%sif (fetch_type_bare_%s (field%d) < 0) { return -1;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num); - } - } else { - assert (t == NODE_TYPE_ARRAY); - printf ("%sint multiplicity%d = PTR2INT (\n", offset, num); - assert (gen_create (((struct tl_tree_array *)arg->type)->multiplicity, vars, 2 + o) >= 0); - printf ("%s);\n", offset); - printf ("%sstruct paramed_type *field%d = \n", offset, num); - assert (gen_create (((struct tl_tree_array *)arg->type)->args[0]->type, vars, 2 + o) >= 0); - printf (";\n"); - printf ("%seprintf (\" [\");\n", offset); - printf ("%sif (multiline_output >= 1) { eprintf (\"\\n\"); }\n", offset); - printf ("%sif (multiline_output >= 1) { multiline_offset += multiline_offset_size;}\n", offset); - printf ("%swhile (multiplicity%d -- > 0) {\n", offset, num); - printf ("%s if (multiline_output >= 1) { print_offset (); }\n", offset); - printf ("%s if (fetch_type_%s (field%d) < 0) { return -1;}\n", offset, "any", num); - printf ("%s if (multiline_output >= 1) { eprintf (\"\\n\"); }\n", offset); - printf ("%s}\n", offset); - printf ("%sif (multiline_output >= 1) { multiline_offset -= multiline_offset_size; print_offset ();}\n", offset); - printf ("%seprintf (\" ]\");\n", offset); - } - } - if (!empty) { - printf("%sif (multiline_output >= 2) { eprintf (\"\\n\"); }\n", offset); - } - if (arg->exist_var_num >= 0) { - printf (" }\n"); - } - return 0; -} - -int gen_field_store (struct arg *arg, int *vars, int num, int from_func) { - assert (arg); - char *offset = " "; - int o = 0; - if (arg->exist_var_num >= 0) { - printf (" if (PTR2INT (var%d) & (1 << %d)) {\n", arg->exist_var_num, arg->exist_var_bit); - offset = " "; - o = 2; - } - char *fail = from_func ? "0" : "-1"; - char *expect = from_func ? "expect_token_ptr" : "expect_token"; - if (arg->id && strlen (arg->id) > 0) { - printf ("%sif (cur_token_len >= 0 && cur_token_len == %d && !cur_token_quoted && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", offset, (int)(strlen (arg->id)), arg->id); - printf ("%s local_next_token ();\n", offset); - printf ("%s %s (\":\", 1);\n", offset, expect); - printf ("%s}\n", offset); - } - if (arg->var_num >= 0) { - printf ("%sif (cur_token_len < 0) { return %s; }\n", offset, fail); - assert (TL_TREE_METHODS (arg->type)->type (arg->type) == NODE_TYPE_TYPE); - int t = ((struct tl_tree_type *)arg->type)->type->name; - if (t == NAME_VAR_TYPE) { - fprintf (stderr, "Not supported yet\n"); - assert (0); - } else { - assert (t == NAME_VAR_NUM); - if (vars[arg->var_num] == 0) { - printf ("%sif (!is_int ()) { return %s;}\n", offset, fail); - printf ("%sstruct paramed_type *var%d = INT2PTR (get_int ());\n", offset, arg->var_num); - printf ("%sout_int (get_int ());\n", offset); - printf ("%sassert (var%d);\n", offset, arg->var_num); - printf ("%slocal_next_token ();\n", offset); - vars[arg->var_num] = 2; - } else if (vars[arg->var_num] == 2) { - printf ("%sif (!is_int ()) { return %s;}\n", offset, fail); - printf ("%sif (vars%d != INT2PTR (get_int ())) { return %s; }\n", offset, arg->var_num, fail); - printf ("%sout_int (get_int ());\n", offset); - printf ("%slocal_next_token ();\n", offset); - } else { - assert (0); - return -1; - } - } - } else { - int t = TL_TREE_METHODS (arg->type)->type (arg->type); - if (t == NODE_TYPE_TYPE || t == NODE_TYPE_VAR_TYPE) { - printf ("%sstruct paramed_type *field%d = \n", offset, num); - assert (gen_create (arg->type, vars, 2 + o) >= 0); - printf (";\n"); - int bare = arg->flags & FLAG_BARE; - if (!bare && t == NODE_TYPE_TYPE) { - bare = ((struct tl_tree_type *)arg->type)->self.flags & FLAG_BARE; - } - if (!bare) { - printf ("%sif (store_type_%s (field%d) < 0) { return %s;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num, fail); - } else { - printf ("%sif (store_type_bare_%s (field%d) < 0) { return %s;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num, fail); - } - } else { - printf ("%s%s (\"[\", 1);\n", offset, expect); - - assert (t == NODE_TYPE_ARRAY); - printf ("%sint multiplicity%d = PTR2INT (\n", offset, num); - assert (gen_create (((struct tl_tree_array *)arg->type)->multiplicity, vars, 2 + o) >= 0); - printf ("%s);\n", offset); - printf ("%sstruct paramed_type *field%d = \n", offset, num); - assert (gen_create (((struct tl_tree_array *)arg->type)->args[0]->type, vars, 2 + o) >= 0); - printf (";\n"); - printf ("%swhile (multiplicity%d -- > 0) {\n", offset, num); - printf ("%s if (store_type_%s (field%d) < 0) { return %s;}\n", offset, "any", num, fail); - printf ("%s}\n", offset); - - printf ("%s%s (\"]\", 1);\n", offset, expect); - } - } - if (arg->exist_var_num >= 0) { - printf (" }\n"); - } - return 0; -} - -int gen_field_autocomplete (struct arg *arg, int *vars, int num, int from_func) { - assert (arg); - char *offset = " "; - int o = 0; - if (arg->exist_var_num >= 0) { - printf (" if (PTR2INT (var%d) & (1 << %d)) {\n", arg->exist_var_num, arg->exist_var_bit); - offset = " "; - o = 2; - } - char *fail = from_func ? "0" : "-1"; - char *expect = from_func ? "expect_token_ptr_autocomplete" : "expect_token_autocomplete"; - if (arg->id && strlen (arg->id) > 0) { - printf ("%sif (cur_token_len == -3 && cur_token_real_len <= %d && !cur_token_quoted && !memcmp (cur_token, \"%s\", cur_token_real_len)) {\n", offset, (int)(strlen (arg->id)), arg->id); - printf ("%s set_autocomplete_string (\"%s\");\n", offset, arg->id); - printf ("%s return %s;\n", offset, fail); - printf ("%s}\n", offset); - - printf ("%sif (cur_token_len >= 0 && cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", offset, (int)(strlen (arg->id)), arg->id); - printf ("%s local_next_token ();\n", offset); - printf ("%s %s (\":\", 1);\n", offset, expect); - printf ("%s}\n", offset); - } - if (arg->var_num >= 0) { - printf ("%sif (cur_token_len < 0) { return %s; }\n", offset, fail); - assert (TL_TREE_METHODS (arg->type)->type (arg->type) == NODE_TYPE_TYPE); - int t = ((struct tl_tree_type *)arg->type)->type->name; - if (t == NAME_VAR_TYPE) { - fprintf (stderr, "Not supported yet\n"); - assert (0); - } else { - assert (t == NAME_VAR_NUM); - if (vars[arg->var_num] == 0) { - printf ("%sif (!is_int ()) { return %s;}\n", offset, fail); - printf ("%sstruct paramed_type *var%d = INT2PTR (get_int ());\n", offset, arg->var_num); - printf ("%sassert (var%d);\n", offset, arg->var_num); - printf ("%slocal_next_token ();\n", offset); - vars[arg->var_num] = 2; - } else if (vars[arg->var_num] == 2) { - printf ("%sif (!is_int ()) { return %s;}\n", offset, fail); - printf ("%sif (vars%d != INT2PTR (get_int ())) { return %s; }\n", offset, arg->var_num, fail); - printf ("%slocal_next_token ();\n", offset); - } else { - assert (0); - return -1; - } - } - } else { - int t = TL_TREE_METHODS (arg->type)->type (arg->type); - if (t == NODE_TYPE_TYPE || t == NODE_TYPE_VAR_TYPE) { - printf ("%sstruct paramed_type *field%d = \n", offset, num); - assert (gen_create (arg->type, vars, 2 + o) >= 0); - printf (";\n"); - int bare = arg->flags & FLAG_BARE; - if (!bare && t == NODE_TYPE_TYPE) { - bare = ((struct tl_tree_type *)arg->type)->self.flags & FLAG_BARE; - } - if (!bare) { - printf ("%sif (autocomplete_type_%s (field%d) < 0) { return %s;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num, fail); - } else { - printf ("%sif (autocomplete_type_bare_%s (field%d) < 0) { return %s;}\n", offset, t == NODE_TYPE_VAR_TYPE ? "any" : ((struct tl_tree_type *)arg->type)->type->print_id, num, fail); - } - } else { - printf ("%s%s (\"[\", 1);\n", offset, expect); - - assert (t == NODE_TYPE_ARRAY); - printf ("%sint multiplicity%d = PTR2INT (\n", offset, num); - assert (gen_create (((struct tl_tree_array *)arg->type)->multiplicity, vars, 2 + o) >= 0); - printf ("%s);\n", offset); - printf ("%sstruct paramed_type *field%d = \n", offset, num); - assert (gen_create (((struct tl_tree_array *)arg->type)->args[0]->type, vars, 2 + o) >= 0); - printf (";\n"); - printf ("%swhile (multiplicity%d -- > 0) {\n", offset, num); - printf ("%s if (autocomplete_type_%s (field%d) < 0) { return %s;}\n", offset, "any", num, fail); - printf ("%s}\n", offset); - - printf ("%s%s (\"]\", 1);\n", offset, expect); - } - } - if (arg->exist_var_num >= 0) { - printf (" }\n"); - } - return 0; -} - -int gen_field_autocomplete_excl (struct arg *arg, int *vars, int num, int from_func) { - assert (arg); - assert (arg->var_num < 0); - char *offset = " "; - if (arg->exist_var_num >= 0) { - printf (" if (PTR2INT (var%d) & (1 << %d)) {\n", arg->exist_var_num, arg->exist_var_bit); - offset = " "; - } - char *fail = from_func ? "0" : "-1"; - char *expect = from_func ? "expect_token_ptr_autocomplete" : "expect_token_autocomplete"; - if (arg->id && strlen (arg->id) > 0) { - printf ("%sif (cur_token_len == -3 && cur_token_real_len <= %d && !cur_token_quoted && !memcmp (cur_token, \"%s\", cur_token_real_len)) {\n", offset, (int)(strlen (arg->id)), arg->id); - printf ("%s set_autocomplete_string (\"%s\");\n", offset, arg->id); - printf ("%s return %s;\n", offset, fail); - printf ("%s}\n", offset); - - printf ("%sif (cur_token_len >= 0 && cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", offset, (int)(strlen (arg->id)), arg->id); - printf ("%s local_next_token ();\n", offset); - printf ("%s %s (\":\", 1);\n", offset, expect); - printf ("%s}\n", offset); - } - int t = TL_TREE_METHODS (arg->type)->type (arg->type); - assert (t == NODE_TYPE_TYPE || t == NODE_TYPE_VAR_TYPE); - printf ("%sstruct paramed_type *field%d = autocomplete_function_any ();\n", offset, num); - printf ("%sif (!field%d) { return 0; }\n", offset, num); - printf ("%sadd_var_to_be_freed (field%d);\n", offset, num); - static char s[20]; - sprintf (s, "field%d", num); - gen_uni_skip (arg->type, s, vars, 1, 1); - if (arg->exist_var_num >= 0) { - printf (" }\n"); - } - return 0; -} - -int gen_field_store_excl (struct arg *arg, int *vars, int num, int from_func) { - assert (arg); - assert (arg->var_num < 0); - char *offset = " "; - if (arg->exist_var_num >= 0) { - printf (" if (PTR2INT (var%d) & (1 << %d)) {\n", arg->exist_var_num, arg->exist_var_bit); - offset = " "; - } - char *expect = from_func ? "expect_token_ptr" : "expect_token"; - if (arg->id && strlen (arg->id) > 0) { - printf ("%sif (cur_token_len >= 0 && cur_token_len == %d && !cur_token_quoted && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", offset, (int)(strlen (arg->id)), arg->id); - printf ("%s local_next_token ();\n", offset); - printf ("%s %s (\":\", 1);\n", offset, expect); - printf ("%s}\n", offset); - } - int t = TL_TREE_METHODS (arg->type)->type (arg->type); - assert (t == NODE_TYPE_TYPE || t == NODE_TYPE_VAR_TYPE); - printf ("%sstruct paramed_type *field%d = store_function_any ();\n", offset, num); - printf ("%sif (!field%d) { return 0; }\n", offset, num); - static char s[20]; - sprintf (s, "field%d", num); - gen_uni_skip (arg->type, s, vars, 1, 1); - if (arg->exist_var_num >= 0) { - printf (" }\n"); - } - return 0; -} - -void gen_constructor_skip (struct tl_combinator *c) { - printf ("int skip_constructor_%s (struct paramed_type *T) {\n", c->print_id); - int i; - for (i = 0; i < c->args_num; i++) if (c->args[i]->flags & FLAG_EXCL) { - printf (" return -1;\n"); - printf ("}\n"); - return; - } - static char s[10000]; - sprintf (s, "T"); - - int *vars = malloc0 (c->var_num * 4);; - gen_uni_skip (c->result, s, vars, 1, 0); - - if (c->name == NAME_INT) { - printf (" if (in_remaining () < 4) { return -1;}\n"); - printf (" fetch_int ();\n"); - printf (" return 0;\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_LONG) { - printf (" if (in_remaining () < 8) { return -1;}\n"); - printf (" fetch_long ();\n"); - printf (" return 0;\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_STRING) { - printf (" int l = prefetch_strlen ();\n"); - printf (" if (l < 0) { return -1;}\n"); - printf (" fetch_str (l);\n"); - printf (" return 0;\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_DOUBLE) { - printf (" if (in_remaining () < 8) { return -1;}\n"); - printf (" fetch_double ();\n"); - printf (" return 0;\n"); - printf ("}\n"); - return; - } - - for (i = 0; i < c->args_num; i++) if (!(c->args[i]->flags & FLAG_OPT_VAR)) { - assert (gen_field_skip (c->args[i], vars, i + 1) >= 0); - } - free (vars); - printf (" return 0;\n"); - printf ("}\n"); -} - -void gen_constructor_fetch (struct tl_combinator *c) { - printf ("int fetch_constructor_%s (struct paramed_type *T) {\n", c->print_id); - int i; - for (i = 0; i < c->args_num; i++) if (c->args[i]->flags & FLAG_EXCL) { - printf (" return -1;\n"); - printf ("}\n"); - return; - } - static char s[10000]; - sprintf (s, "T"); - - int *vars = malloc0 (c->var_num * 4);; - gen_uni_skip (c->result, s, vars, 1, 0); - - if (c->name == NAME_INT) { - printf (" if (in_remaining () < 4) { return -1;}\n"); - printf (" eprintf (\" %%d\", fetch_int ());\n"); - printf (" return 0;\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_LONG) { - printf (" if (in_remaining () < 8) { return -1;}\n"); - printf (" eprintf (\" %%lld\", fetch_long ());\n"); - printf (" return 0;\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_STRING) { - printf (" static char buf[1 << 22];\n"); - printf (" int l = prefetch_strlen ();\n"); - printf (" if (l < 0 || (l >= (1 << 22) - 2)) { return -1; }\n"); - printf (" memcpy (buf, fetch_str (l), l);\n"); - printf (" buf[l] = 0;\n"); - printf (" print_escaped_string (buf, l);\n"); - printf (" return 0;\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_DOUBLE) { - printf (" if (in_remaining () < 8) { return -1;}\n"); - printf (" eprintf (\" %%lf\", fetch_double ());\n"); - printf (" return 0;\n"); - printf ("}\n"); - return; - } - - assert (c->result->methods->type (c->result) == NODE_TYPE_TYPE); - int empty = is_empty (((struct tl_tree_type *)c->result)->type); - if (!empty) { - printf (" eprintf (\" %s\");\n", c->id); - printf (" if (multiline_output >= 2) { eprintf (\"\\n\"); }\n"); - } - - - for (i = 0; i < c->args_num; i++) if (!(c->args[i]->flags & FLAG_OPT_VAR)) { - assert (gen_field_fetch (c->args[i], vars, i + 1, empty) >= 0); - } - free (vars); - printf (" return 0;\n"); - printf ("}\n"); -} - -void gen_constructor_store (struct tl_combinator *c) { - printf ("int store_constructor_%s (struct paramed_type *T) {\n", c->print_id); - int i; - for (i = 0; i < c->args_num; i++) if (c->args[i]->flags & FLAG_EXCL) { - printf (" return -1;\n"); - printf ("}\n"); - return; - } - static char s[10000]; - sprintf (s, "T"); - - int *vars = malloc0 (c->var_num * 4);; - assert (c->var_num <= 10); - gen_uni_skip (c->result, s, vars, 1, 0); - - if (c->name == NAME_INT) { - printf (" if (is_int ()) {\n"); - printf (" out_int (get_int ());\n"); - printf (" local_next_token ();\n"); - printf (" return 0;\n"); - printf (" } else {\n"); - printf (" return -1;\n"); - printf (" }\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_LONG) { - printf (" if (is_int ()) {\n"); - printf (" out_long (get_int ());\n"); - printf (" local_next_token ();\n"); - printf (" return 0;\n"); - printf (" } else {\n"); - printf (" return -1;\n"); - printf (" }\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_STRING) { - printf (" if (cur_token_len >= 0) {\n"); - printf (" out_cstring (cur_token, cur_token_len);\n"); - printf (" local_next_token ();\n"); - printf (" return 0;\n"); - printf (" } else {\n"); - printf (" return -1;\n"); - printf (" }\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_DOUBLE) { - printf (" if (is_double ()) {\n"); - printf (" out_double (get_double());\n"); - printf (" local_next_token ();\n"); - printf (" return 0;\n"); - printf (" } else {\n"); - printf (" return -1;\n"); - printf (" }\n"); - printf ("}\n"); - return; - } - - for (i = 0; i < c->args_num; i++) if (!(c->args[i]->flags & FLAG_OPT_VAR)) { - assert (gen_field_store (c->args[i], vars, i + 1, 0) >= 0); - } - - free (vars); - printf (" return 0;\n"); - printf ("}\n"); -} - -void gen_constructor_autocomplete (struct tl_combinator *c) { - printf ("int autocomplete_constructor_%s (struct paramed_type *T) {\n", c->print_id); - int i; - for (i = 0; i < c->args_num; i++) if (c->args[i]->flags & FLAG_EXCL) { - printf (" return -1;\n"); - printf ("}\n"); - return; - } - static char s[10000]; - sprintf (s, "T"); - - int *vars = malloc0 (c->var_num * 4);; - assert (c->var_num <= 10); - gen_uni_skip (c->result, s, vars, 1, 0); - - if (c->name == NAME_INT) { - printf (" if (is_int ()) {\n"); - printf (" local_next_token ();\n"); - printf (" return 0;\n"); - printf (" } else {\n"); - printf (" return -1;\n"); - printf (" }\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_LONG) { - printf (" if (is_int ()) {\n"); - printf (" local_next_token ();\n"); - printf (" return 0;\n"); - printf (" } else {\n"); - printf (" return -1;\n"); - printf (" }\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_STRING) { - printf (" if (cur_token_len >= 0) {\n"); - printf (" local_next_token ();\n"); - printf (" return 0;\n"); - printf (" } else {\n"); - printf (" return -1;\n"); - printf (" }\n"); - printf ("}\n"); - return; - } else if (c->name == NAME_DOUBLE) { - printf (" if (is_double ()) {\n"); - printf (" local_next_token ();\n"); - printf (" return 0;\n"); - printf (" } else {\n"); - printf (" return -1;\n"); - printf (" }\n"); - printf ("}\n"); - return; - } - - for (i = 0; i < c->args_num; i++) if (!(c->args[i]->flags & FLAG_OPT_VAR)) { - assert (gen_field_autocomplete (c->args[i], vars, i + 1, 0) >= 0); - } - - free (vars); - printf (" return 0;\n"); - printf ("}\n"); -} - -void gen_type_skip (struct tl_type *t) { - printf ("int skip_type_%s (struct paramed_type *T) {\n", t->print_id); - printf (" if (in_remaining () < 4) { return -1;}\n"); - printf (" int magic = fetch_int ();\n"); - printf (" switch (magic) {\n"); - int i; - for (i = 0; i < t->constructors_num; i++) { - printf (" case 0x%08x: return skip_constructor_%s (T);\n", t->constructors[i]->name, t->constructors[i]->print_id); - } - printf (" default: return -1;\n"); - printf (" }\n"); - printf ("}\n"); - printf ("int skip_type_bare_%s (struct paramed_type *T) {\n", t->print_id); - if (t->constructors_num > 1) { - printf (" int *save_in_ptr = in_ptr;\n"); - for (i = 0; i < t->constructors_num; i++) { - printf (" if (skip_constructor_%s (T) >= 0) { return 0; }\n", t->constructors[i]->print_id); - printf (" in_ptr = save_in_ptr;\n"); - } - } else { - for (i = 0; i < t->constructors_num; i++) { - printf (" if (skip_constructor_%s (T) >= 0) { return 0; }\n", t->constructors[i]->print_id); - } - } - printf (" return -1;\n"); - printf ("}\n"); -} - -void gen_type_fetch (struct tl_type *t) { - int empty = is_empty (t);; - printf ("int fetch_type_%s (struct paramed_type *T) {\n", t->print_id); - printf (" if (in_remaining () < 4) { return -1;}\n"); - if (!empty) { - printf (" if (multiline_output >= 2) { multiline_offset += multiline_offset_size; }\n"); - printf (" eprintf (\" (\");\n"); - } - printf (" int magic = fetch_int ();\n"); - printf (" int res = -1;\n"); - printf (" switch (magic) {\n"); - int i; - for (i = 0; i < t->constructors_num; i++) { - printf (" case 0x%08x: res = fetch_constructor_%s (T); break;\n", t->constructors[i]->name, t->constructors[i]->print_id); - } - printf (" default: return -1;\n"); - printf (" }\n"); - if (!empty) { - printf (" if (res >= 0) {\n"); - printf (" if (multiline_output >= 2) { multiline_offset -= multiline_offset_size; print_offset (); }\n"); - printf (" eprintf (\" )\");\n"); - //printf (" if (multiline_output >= 2) { printf (\"\\n\"); }\n"); - printf (" }\n"); - } - printf (" return res;\n"); - printf ("}\n"); - printf ("int fetch_type_bare_%s (struct paramed_type *T) {\n", t->print_id); - if (t->constructors_num > 1) { - printf (" int *save_in_ptr = in_ptr;\n"); - - if (!empty) { - printf (" if (multiline_output >= 2) { multiline_offset += multiline_offset_size; }\n"); - } - for (i = 0; i < t->constructors_num; i++) { - printf (" if (skip_constructor_%s (T) >= 0) { in_ptr = save_in_ptr; %sassert (!fetch_constructor_%s (T)); %sreturn 0; }\n", t->constructors[i]->print_id, empty ? "" : "eprintf (\" (\"); ", t->constructors[i]->print_id , empty ? "" : "if (multiline_output >= 2) { multiline_offset -= multiline_offset_size; print_offset (); } eprintf (\" )\");"); - printf (" in_ptr = save_in_ptr;\n"); - } - } else { - for (i = 0; i < t->constructors_num; i++) { - if (!empty) { - printf (" if (multiline_output >= 2) { multiline_offset += multiline_offset_size; }\n"); - printf (" eprintf (\" (\");\n"); - } - printf (" if (fetch_constructor_%s (T) >= 0) { %sreturn 0; }\n", t->constructors[i]->print_id, empty ? "" : "if (multiline_output >= 2) { multiline_offset -= multiline_offset_size; print_offset (); } eprintf (\" )\");" ); - } - } - printf (" return -1;\n"); - printf ("}\n"); -} - -void gen_type_store (struct tl_type *t) { - int empty = is_empty (t);; - int k = 0; - for (k = 0; k < 2; k++) { - printf ("int store_type_%s%s (struct paramed_type *T) {\n", k == 0 ? "" : "bare_", t->print_id); - if (empty) { - printf (" if (store_constructor_%s (T) < 0) { return -1; }\n", t->constructors[0]->print_id); - printf (" return 0;\n"); - printf ("}\n"); - } else { - printf (" expect_token (\"(\", 1);\n"); - printf (" if (cur_token_len < 0) { return -1; }\n"); - printf (" if (cur_token_len < 0) { return -1; }\n"); - int i; - for (i = 0; i < t->constructors_num; i++) { - printf (" if (cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", (int)strlen (t->constructors[i]->id), t->constructors[i]->id); - if (!k) { - printf (" out_int (0x%08x);\n", t->constructors[i]->name); - } - printf (" local_next_token ();\n"); - printf (" if (store_constructor_%s (T) < 0) { return -1; }\n", t->constructors[i]->print_id); - printf (" expect_token (\")\", 1);\n"); - printf (" return 0;\n"); - printf (" }\n"); - } - /*if (t->constructors_num == 1) { - printf (" if (!force) {\n"); - if (!k) { - printf (" out_int (0x%08x);\n", t->constructors[0]->name); - } - printf (" if (store_constructor_%s (T) < 0) { return -1; }\n", t->constructors[0]->print_id); - printf (" expect_token (\")\", 1);\n"); - printf (" return 0;\n"); - printf (" }\n"); - }*/ - printf (" return -1;\n"); - printf ("}\n"); - } - } -} - -void gen_type_autocomplete (struct tl_type *t) { - int empty = is_empty (t);; - int k = 0; - for (k = 0; k < 2; k++) { - printf ("int autocomplete_type_%s%s (struct paramed_type *T) {\n", k == 0 ? "" : "bare_", t->print_id); - if (empty) { - printf (" if (autocomplete_constructor_%s (T) < 0) { return -1; }\n", t->constructors[0]->print_id); - printf (" return 0;\n"); - printf ("}\n"); - } else { - printf (" expect_token_autocomplete (\"(\", 1);\n"); - printf (" if (cur_token_len == -3) { set_autocomplete_type (do_autocomplete_type_%s); return -1; }\n", t->print_id); - printf (" if (cur_token_len < 0) { return -1; }\n"); - int i; - for (i = 0; i < t->constructors_num; i++) { - printf (" if (cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", (int)strlen (t->constructors[i]->id), t->constructors[i]->id); - printf (" local_next_token ();\n"); - printf (" if (autocomplete_constructor_%s (T) < 0) { return -1; }\n", t->constructors[i]->print_id); - printf (" expect_token_autocomplete (\")\", 1);\n"); - printf (" return 0;\n"); - printf (" }\n"); - } - /*if (t->constructors_num == 1) { - printf (" if (!force) {\n"); - printf (" if (autocomplete_constructor_%s (T) < 0) { return -1; }\n", t->constructors[0]->print_id); - printf (" expect_token_autocomplete (\")\", 1);\n"); - printf (" return 0;\n"); - printf (" }\n"); - }*/ - printf (" return -1;\n"); - printf ("}\n"); - } - } -} - -void gen_function_store (struct tl_combinator *f) { - printf ("struct paramed_type *store_function_%s (void) {\n", f->print_id); - int i; - - int *vars = malloc0 (f->var_num * 4);; - assert (f->var_num <= 10); - - for (i = 0; i < f->args_num; i++) if (!(f->args[i]->flags & FLAG_OPT_VAR)) { - if (f->args[i]->flags & FLAG_EXCL) { - assert (gen_field_store_excl (f->args[i], vars, i + 1, 1) >= 0); - } else { - assert (gen_field_store (f->args[i], vars, i + 1, 1) >= 0); - } - } - - - printf (" struct paramed_type *R = \n"); - assert (gen_create (f->result, vars, 2) >= 0); - printf (";\n"); - - free (vars); - printf (" return paramed_type_dup (R);\n"); - printf ("}\n"); -} - -void gen_function_autocomplete (struct tl_combinator *f) { - printf ("struct paramed_type *autocomplete_function_%s (void) {\n", f->print_id); - int i; - - int *vars = malloc0 (f->var_num * 4);; - assert (f->var_num <= 10); - - for (i = 0; i < f->args_num; i++) if (!(f->args[i]->flags & FLAG_OPT_VAR)) { - if (f->args[i]->flags & FLAG_EXCL) { - assert (gen_field_autocomplete_excl (f->args[i], vars, i + 1, 1) >= 0); - } else { - assert (gen_field_autocomplete (f->args[i], vars, i + 1, 1) >= 0); - } - } - - printf (" struct paramed_type *R = \n"); - assert (gen_create (f->result, vars, 2) >= 0); - printf (";\n"); - - free (vars); - printf (" return paramed_type_dup (R);\n"); - printf ("}\n"); -} - -void gen_type_do_autocomplete (struct tl_type *t) { - printf ("int do_autocomplete_type_%s (const char *text, int text_len, int index, char **R) {\n", t->print_id); - printf (" index ++;\n"); - int i; - for (i = 0; i < t->constructors_num; i++) { - printf (" if (index == %d) { if (!strncmp (text, \"%s\", text_len)) { *R = tstrdup (\"%s\"); return index; } else { index ++; }}\n", i, t->constructors[i]->id, t->constructors[i]->id); - } - printf (" *R = 0;\n"); - printf (" return 0;\n"); - printf ("}\n"); -} - -struct tl_tree *read_num_var (int *var_num) { - struct tl_tree_var_num *T = malloc0 (sizeof (*T)); - T->self.flags = 0; - T->self.methods = &tl_pvar_num_methods;; - T->dif = get_int (); - T->var_num = get_int (); - - if (T->var_num >= *var_num) { - *var_num = T->var_num + 1; - } - assert (!(T->self.flags & FLAG_NOVAR)); - return (void *)T; -} - -struct tl_tree *read_type_var (int *var_num) { - struct tl_tree_var_type *T = malloc0 (sizeof (*T)); - T->self.methods = &tl_pvar_type_methods; - T->var_num = get_int (); - T->self.flags = get_int (); - if (T->var_num >= *var_num) { - *var_num = T->var_num + 1; - } - assert (!(T->self.flags & (FLAG_NOVAR | FLAG_BARE))); - return (void *)T; -} - -struct tl_tree *read_array (int *var_num) { - struct tl_tree_array *T = malloc0 (sizeof (*T)); - T->self.methods = &tl_parray_methods; - T->self.flags = 0; - T->multiplicity = read_nat_expr (var_num); - assert (T->multiplicity); - - T->args_num = get_int (); - assert (T->args_num >= 0 && T->args_num <= 1000); - T->args = malloc0 (sizeof (void *) * T->args_num); - - assert (read_args_list (T->args, T->args_num, var_num) >= 0); - T->self.flags |= FLAG_NOVAR; - int i; - for (i = 0; i < T->args_num; i++) { - if (!(T->args[i]->flags & FLAG_NOVAR)) { - T->self.flags &= ~FLAG_NOVAR; - } - } - return (void *)T; -} - -struct tl_tree *read_type (int *var_num) { - struct tl_tree_type *T = malloc0 (sizeof (*T)); - T->self.methods = &tl_ptype_methods; - - T->type = tl_type_get_by_name (get_int ()); - assert (T->type); - T->self.flags = get_int (); - T->children_num = get_int (); - assert (T->type->arity == T->children_num); - T->children = malloc0 (sizeof (void *) * T->children_num); - int i; - T->self.flags |= FLAG_NOVAR; - for (i = 0; i < T->children_num; i++) { - int t = get_int (); - if (t == (int)TLS_EXPR_NAT) { - assert ((T->type->params_types & (1 << i))); - T->children[i] = read_nat_expr (var_num); - } else if (t == (int)TLS_EXPR_TYPE) { - assert (!(T->type->params_types & (1 << i))); - T->children[i] = read_type_expr (var_num); - } else { - assert (0); - } - if (!TL_IS_NAT_VAR (T->children[i]) && !(T->children[i]->flags & FLAG_NOVAR)) { - T->self.flags &= ~FLAG_NOVAR; - } - } - return (void *)T; -} - -struct tl_tree *read_tree (int *var_num) { - int x = get_int (); - if (verbosity >= 2) { - fprintf (stderr, "read_tree: constructor = 0x%08x\n", x); - } - switch (x) { - case TLS_TREE_NAT_CONST: - return read_num_const (var_num); - case TLS_TREE_NAT_VAR: - return read_num_var (var_num); - case TLS_TREE_TYPE_VAR: - return read_type_var (var_num); - case TLS_TREE_TYPE: - return read_type (var_num); - case TLS_TREE_ARRAY: - return read_array (var_num); - default: - if (verbosity) { - fprintf (stderr, "x = %d\n", x); - } - assert (0); - return 0; - } -} - -struct tl_tree *read_type_expr (int *var_num) { - int x = get_int (); - if (verbosity >= 2) { - fprintf (stderr, "read_type_expr: constructor = 0x%08x\n", x); - } - switch (x) { - case TLS_TYPE_VAR: - return read_type_var (var_num); - case TLS_TYPE_EXPR: - return read_type (var_num); - case TLS_ARRAY: - return read_array (var_num); - default: - if (verbosity) { - fprintf (stderr, "x = %d\n", x); - } - assert (0); - return 0; - } -} - -struct tl_tree *read_nat_expr (int *var_num) { - int x = get_int (); - if (verbosity >= 2) { - fprintf (stderr, "read_nat_expr: constructor = 0x%08x\n", x); - } - switch (x) { - case TLS_NAT_CONST: - return read_num_const (var_num); - case TLS_NAT_VAR: - return read_num_var (var_num); - default: - if (verbosity) { - fprintf (stderr, "x = %d\n", x); - } - assert (0); - return 0; - } -} - -struct tl_tree *read_expr (int *var_num) { - int x = get_int (); - if (verbosity >= 2) { - fprintf (stderr, "read_nat_expr: constructor = 0x%08x\n", x); - } - switch (x) { - case TLS_EXPR_NAT: - return read_nat_expr (var_num); - case TLS_EXPR_TYPE: - return read_type_expr (var_num); - default: - if (verbosity) { - fprintf (stderr, "x = %d\n", x); - } - assert (0); - return 0; - } -} - -int read_args_list (struct arg **args, int args_num, int *var_num) { - int i; - for (i = 0; i < args_num; i++) { - args[i] = malloc0 (sizeof (struct arg)); - args[i]->exist_var_num = -1; - args[i]->exist_var_bit = 0; - assert (get_int () == TLS_ARG_V2); - args[i]->id = get_string (); - args[i]->flags = get_int (); - - if (args[i]->flags & 2) { - args[i]->flags &= ~2; - args[i]->flags |= (1 << 20); - } - if (args[i]->flags & 4) { - args[i]->flags &= ~4; - args[i]->var_num = get_int (); - } else { - args[i]->var_num = -1; - } - - int x = args[i]->flags & 6; - args[i]->flags &= ~6; - if (x & 2) { args[i]->flags |= 4; } - if (x & 4) { args[i]->flags |= 2; } - - if (args[i]->var_num >= *var_num) { - *var_num = args[i]->var_num + 1; - } - if (args[i]->flags & FLAG_OPT_FIELD) { - args[i]->exist_var_num = get_int (); - args[i]->exist_var_bit = get_int (); - } - args[i]->type = read_type_expr (var_num); - assert (args[i]->type); - - if (args[i]->var_num < 0 && args[i]->exist_var_num < 0 && (TL_IS_NAT_VAR(args[i]->type) || (args[i]->type->flags & FLAG_NOVAR))) { - args[i]->flags |= FLAG_NOVAR; - } - } - return 1; -} - -int read_combinator_args_list (struct tl_combinator *c) { - c->args_num = get_int (); - if (verbosity >= 2) { - fprintf (stderr, "c->id = %s, c->args_num = %d\n", c->id, c->args_num); - } - assert (c->args_num >= 0 && c->args_num <= 1000); - c->args = malloc0 (sizeof (void *) * c->args_num); - c->var_num = 0; - return read_args_list (c->args, c->args_num, &c->var_num); -} - -int read_combinator_right (struct tl_combinator *c) { - assert (get_int () == TLS_COMBINATOR_RIGHT_V2); - c->result = read_type_expr (&c->var_num); - assert (c->result); - return 1; -} - -int read_combinator_left (struct tl_combinator *c) { - int x = get_int (); - - if (x == (int)TLS_COMBINATOR_LEFT_BUILTIN) { - c->args_num = 0; - c->var_num = 0; - c->args = 0; - return 1; - } else if (x == TLS_COMBINATOR_LEFT) { - return read_combinator_args_list (c); - } else { - assert (0); - return -1; - } -} - -char *gen_print_id (const char *id) { - static char s[1000]; - char *ptr = s; - int first = 1; - while (*id) { - if (*id == '.') { - *(ptr ++) = '_'; - } else if (*id >= 'A' && *id <= 'Z') { - if (!first && *(ptr - 1) != '_') { - *(ptr ++) = '_'; - } - *(ptr ++) = *id - 'A' + 'a'; - } else { - *(ptr ++) = *id; - } - id ++; - first = 0; - } - *ptr = 0; - return s; -} - -struct tl_combinator *read_combinators (int v) { - struct tl_combinator *c = malloc0 (sizeof (*c)); - c->name = get_int (); - c->id = get_string (); - c->print_id = strdup (gen_print_id (c->id)); - assert (c->print_id); - //char *s = c->id; - //while (*s) { if (*s == '.') { *s = '_'; } ; s ++;} - int x = get_int (); - struct tl_type *t = tl_type_get_by_name (x); - assert (t || (!x && v == 3)); - - if (v == 2) { - assert (t->extra < t->constructors_num); - t->constructors[t->extra ++] = c; - c->is_fun = 0; - } else { - assert (v == 3); - tl_function_insert_by_name (c); - c->is_fun = 1; - } - assert (read_combinator_left (c) >= 0); - assert (read_combinator_right (c) >= 0); - return c; -} - -struct tl_type *read_types (void) { - struct tl_type *t = malloc0 (sizeof (*t)); - t->name = get_int (); - t->id = get_string (); - t->print_id = strdup (gen_print_id (t->id)); - assert (t->print_id); - - t->constructors_num = get_int (); - assert (t->constructors_num >= 0 && t->constructors_num <= 1000); - - t->constructors = malloc0 (sizeof (void *) * t->constructors_num); - t->flags = get_int (); - t->arity = get_int (); - t->params_types = get_long (); // params_types - t->extra = 0; - tl_type_insert_by_name (t); - return t; -} - - - -int parse_tlo_file (void) { - buf_end = buf_ptr + (buf_size / 4); - assert (get_int () == TLS_SCHEMA_V2); - - get_int (); // version - get_int (); // date - - tn = 0; - fn = 0; - cn = 0; - int i; - - tn = get_int (); - assert (tn >= 0 && tn < 10000); - tps = malloc0 (sizeof (void *) * tn); - - if (verbosity >= 2) { - fprintf (stderr, "Found %d types\n", tn); - } - - for (i = 0; i < tn; i++) { - assert (get_int () == TLS_TYPE); - tps[i] = read_types (); - assert (tps[i]); - } - - cn = get_int (); - assert (cn >= 0); - - if (verbosity >= 2) { - fprintf (stderr, "Found %d constructors\n", cn); - } - - for (i = 0; i < cn; i++) { - assert (get_int () == TLS_COMBINATOR); - assert (read_combinators (2)); - } - - fn = get_int (); - assert (fn >= 0 && fn < 10000); - - fns = malloc0 (sizeof (void *) * fn); - - if (verbosity >= 2) { - fprintf (stderr, "Found %d functions\n", fn); - } - - for (i = 0; i < fn; i++) { - assert (get_int () == TLS_COMBINATOR); - fns[i] = read_combinators (3); - assert (fns[i]); - } - - assert (buf_ptr == buf_end); - - - int j; - for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type")) { - tps[i]->name = 0; - for (j = 0; j < tps[i]->constructors_num; j ++) { - tps[i]->name ^= tps[i]->constructors[j]->name; - } - } - - if (!header) { - printf ("#include \"auto.h\"\n"); - printf ("#include \n"); - - - printf ("#include \"auto-static.c\"\n"); - for (i = 0; i < tn; i++) { - for (j = 0; j < tps[i]->constructors_num; j ++) { - gen_constructor_skip (tps[i]->constructors[j]); - if (!skip_only) { - gen_constructor_store (tps[i]->constructors[j]); - gen_constructor_fetch (tps[i]->constructors[j]); - gen_constructor_autocomplete (tps[i]->constructors[j]); - } - } - } - for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type")) { - gen_type_skip (tps[i]); - if (!skip_only) { - gen_type_store (tps[i]); - gen_type_fetch (tps[i]); - gen_type_autocomplete (tps[i]); - gen_type_do_autocomplete (tps[i]); - } - } - if (!skip_only) { - for (i = 0; i < fn; i++) { - gen_function_store (fns[i]); - gen_function_autocomplete (fns[i]); - } - } - printf ("int skip_type_any (struct paramed_type *T) {\n"); - printf (" switch (T->type->name) {\n"); - for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type") && tps[i]->name) { - printf (" case 0x%08x: return skip_type_%s (T);\n", tps[i]->name, tps[i]->print_id); - printf (" case 0x%08x: return skip_type_bare_%s (T);\n", ~tps[i]->name, tps[i]->print_id); - } - printf (" default: return -1; }\n"); - printf ("}\n"); - if (!skip_only) { - printf ("int store_type_any (struct paramed_type *T) {\n"); - printf (" switch (T->type->name) {\n"); - for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type") && tps[i]->name) { - printf (" case 0x%08x: return store_type_%s (T);\n", tps[i]->name, tps[i]->print_id); - printf (" case 0x%08x: return store_type_bare_%s (T);\n", ~tps[i]->name, tps[i]->print_id); - } - printf (" default: return -1; }\n"); - printf ("}\n"); - printf ("int fetch_type_any (struct paramed_type *T) {\n"); - printf (" switch (T->type->name) {\n"); - for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type") && tps[i]->name) { - printf (" case 0x%08x: return fetch_type_%s (T);\n", tps[i]->name, tps[i]->print_id); - printf (" case 0x%08x: return fetch_type_bare_%s (T);\n", ~tps[i]->name, tps[i]->print_id); - } - printf (" default: return -1; }\n"); - printf ("}\n"); - printf ("int autocomplete_type_any (struct paramed_type *T) {\n"); - printf (" switch (T->type->name) {\n"); - for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type") && tps[i]->name) { - printf (" case 0x%08x: return autocomplete_type_%s (T);\n", tps[i]->name, tps[i]->print_id); - printf (" case 0x%08x: return autocomplete_type_bare_%s (T);\n", ~tps[i]->name, tps[i]->print_id); - } - printf (" default: return -1; }\n"); - printf ("}\n"); - printf ("struct paramed_type *store_function_any (void) {\n"); - printf (" if (cur_token_len != 1 || *cur_token != '(') { return 0; }\n"); - printf (" local_next_token ();\n"); - printf (" if (cur_token_len == 1 || *cur_token == '.') { \n"); - printf (" local_next_token ();\n"); - printf (" if (cur_token_len != 1 || *cur_token != '=') { return 0; }\n"); - printf (" local_next_token ();\n"); - printf (" };\n"); - printf (" if (cur_token_len < 0) { return 0; }\n"); - for (i = 0; i < fn; i++) { - printf (" if (cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", (int)strlen (fns[i]->id), fns[i]->id); - printf (" out_int (0x%08x);\n", fns[i]->name); - printf (" local_next_token ();\n"); - printf (" struct paramed_type *P = store_function_%s ();\n", fns[i]->print_id); - printf (" if (!P) { return 0; }\n"); - printf (" if (cur_token_len != 1 || *cur_token != ')') { return 0; }\n"); - printf (" local_next_token ();\n"); - printf (" return P;\n"); - printf (" }\n"); - } - printf (" return 0;\n"); - printf ("}\n"); - printf ("int do_autocomplete_function (const char *text, int text_len, int index, char **R) {\n"); - printf (" index ++;\n"); - int i; - for (i = 0; i < fn; i++) { - printf (" if (index == %d) { if (!strncmp (text, \"%s\", text_len)) { *R = tstrdup (\"%s\"); return index; } else { index ++; }}\n", i, fns[i]->id, fns[i]->id); - } - printf (" *R = 0;\n"); - printf (" return 0;\n"); - printf ("}\n"); - printf ("struct paramed_type *autocomplete_function_any (void) {\n"); - printf (" expect_token_ptr_autocomplete (\"(\", 1);\n"); - printf (" if (cur_token_len == -3) { set_autocomplete_type (do_autocomplete_function); }\n"); - printf (" if (cur_token_len < 0) { return 0; }\n"); - for (i = 0; i < fn; i++) { - printf (" if (cur_token_len == %d && !memcmp (cur_token, \"%s\", cur_token_len)) {\n", (int)strlen (fns[i]->id), fns[i]->id); - printf (" local_next_token ();\n"); - printf (" struct paramed_type *P = autocomplete_function_%s ();\n", fns[i]->print_id); - printf (" if (!P) { return 0; }\n"); - printf (" expect_token_ptr_autocomplete (\")\", 1);\n"); - printf (" return P;\n"); - printf (" }\n"); - } - printf (" return 0;\n"); - printf ("}\n"); - } - } else { - for (i = 0; i < tn; i++) { - for (j = 0; j < tps[i]->constructors_num; j ++) { - printf ("int skip_constructor_%s (struct paramed_type *T);\n", tps[i]->constructors[j]->print_id); - printf ("int store_constructor_%s (struct paramed_type *T);\n", tps[i]->constructors[j]->print_id); - printf ("int fetch_constructor_%s (struct paramed_type *T);\n", tps[i]->constructors[j]->print_id); - printf ("int autocomplete_constructor_%s (struct paramed_type *T);\n", tps[i]->constructors[j]->print_id); - } - } - for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type")) { - printf ("int skip_type_%s (struct paramed_type *T);\n", tps[i]->print_id); - printf ("int skip_type_bare_%s (struct paramed_type *T);\n", tps[i]->print_id); - printf ("int store_type_%s (struct paramed_type *T);\n", tps[i]->print_id); - printf ("int store_type_bare_%s (struct paramed_type *T);\n", tps[i]->print_id); - printf ("int fetch_type_%s (struct paramed_type *T);\n", tps[i]->print_id); - printf ("int fetch_type_bare_%s (struct paramed_type *T);\n", tps[i]->print_id); - printf ("int autocomplete_type_%s (struct paramed_type *T);\n", tps[i]->print_id); - printf ("int do_autocomplete_type_%s (const char *text, int len, int index, char **R);\n", tps[i]->print_id); - printf ("int autocomplete_type_bare_%s (struct paramed_type *T);\n", tps[i]->print_id); - } - for (i = 0; i < fn; i++) { - printf ("struct paramed_type *store_function_%s (void);\n", fns[i]->print_id); - printf ("struct paramed_type *autocomplete_function_%s (void);\n", fns[i]->print_id); - } - printf ("int skip_type_any (struct paramed_type *T);\n"); - printf ("int store_type_any (struct paramed_type *T);\n"); - printf ("int fetch_type_any (struct paramed_type *T);\n"); - printf ("int autocomplete_type_any (struct paramed_type *T);\n"); - printf ("struct paramed_type *store_function_any (void);\n"); - printf ("struct paramed_type *autocomplete_function_any (void);\n"); - - /*for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#') { - printf ("extern struct tl_type tl_type_%s;\n", tps[i]->id); - }*/ - for (i = 0; i < tn; i++) if (tps[i]->id[0] != '#' && strcmp (tps[i]->id, "Type")) { - printf ("static struct tl_type_descr tl_type_%s __attribute__ ((unused));\n", tps[i]->print_id); - printf ("static struct tl_type_descr tl_type_%s = {\n", tps[i]->print_id); - printf (" .name = 0x%08x,\n", tps[i]->name); - printf (" .id = \"%s\"\n,", tps[i]->id); - printf (" .params_num = %d,\n", tps[i]->arity); - printf (" .params_types = %lld\n", tps[i]->params_types); - printf ("};\n"); - printf ("static struct tl_type_descr tl_type_bare_%s __attribute__ ((unused));\n", tps[i]->print_id); - printf ("static struct tl_type_descr tl_type_bare_%s = {\n", tps[i]->print_id); - printf (" .name = 0x%08x,\n", ~tps[i]->name); - printf (" .id = \"Bare_%s\",\n", tps[i]->id); - printf (" .params_num = %d,\n", tps[i]->arity); - printf (" .params_types = %lld\n", tps[i]->params_types); - printf ("};\n"); - } - } - - - return 0; -} - -void usage (void) { - printf ("usage: generate [-v] [-h] \n" - ); - exit (2); -} - -void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2))); -void logprintf (const char *format __attribute__ ((unused)), ...) { -} -/* -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; - while ((i = getopt (argc, argv, "vhH")) != -1) { - switch (i) { - case 'h': - usage (); - return 2; - case 'v': - verbosity++; - break; - case 'H': - header ++; - break; - } - } - - if (argc != optind + 1) { - usage (); - } - - int fd = open (argv[optind], O_RDONLY); - if (fd < 0) { - fprintf (stderr, "Can not open file '%s'. Error %m\n", argv[optind]); - exit (1); - } - buf_size = read (fd, buf, (1 << 20)); - if (fd == (1 << 20)) { - fprintf (stderr, "Too big tlo file\n"); - exit (2); - } - return parse_tlo_file (); -} diff --git a/generate.h b/generate.h deleted file mode 100644 index be5bc94..0000000 --- a/generate.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - 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 . - - 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 diff --git a/include.h b/include.h deleted file mode 100644 index bf290a1..0000000 --- a/include.h +++ /dev/null @@ -1,24 +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 . - - Copyright Vitaly Valtman 2013 -*/ -#ifndef __INCLUDE_H__ -#define __INCLUDE_H__ - -#define UU __attribute__ ((unused)) - -#endif diff --git a/interface.c b/interface.c index 8c7e225..057b0e0 100644 --- a/interface.c +++ b/interface.c @@ -38,7 +38,6 @@ #endif #include -#include "include.h" //#include "queries.h" #include "interface.h" @@ -62,7 +61,7 @@ //#include "mtproto-common.h" -#include "tgl.h" +#include #include "loop.h" #ifndef PATH_MAX @@ -496,7 +495,7 @@ char *get_default_prompt (void) { return buf; } -char *complete_none (const char *text UU, int state UU) { +char *complete_none (const char *text, int state) { return 0; } @@ -1371,7 +1370,7 @@ char *command_generator (const char *text, int state) { } } -char **complete_text (char *text, int start UU, int end UU) { +char **complete_text (char *text, int start, int end) { return (char **) rl_completion_matches (text, command_generator); } @@ -2045,7 +2044,7 @@ struct tgl_update_callback upd_cb = { }; -void interpreter_ex (char *line UU, void *ex) { +void interpreter_ex (char *line, void *ex) { force_end_mode = 1; assert (!in_readline); in_readline = 1; @@ -2279,7 +2278,7 @@ void interpreter_ex (char *line UU, void *ex) { in_readline = 0; } -void interpreter (char *line UU) { +void interpreter (char *line) { interpreter_ex (line, 0); } diff --git a/interface.h b/interface.h index 81fa41b..cc9c64c 100644 --- a/interface.h +++ b/interface.h @@ -18,8 +18,8 @@ */ #ifndef __INTERFACE_H__ #define __INTERFACE_H__ -#include "structures.h" -#include "tgl-layout.h" +#include +#include #define COLOR_RED "\033[0;31m" #define COLOR_REDB "\033[1;31m" diff --git a/loop.c b/loop.c index 65e6335..1c7892e 100644 --- a/loop.c +++ b/loop.c @@ -57,10 +57,10 @@ #include "telegram.h" #include "loop.h" #include "lua-tg.h" -#include "tgl.h" -#include "binlog.h" -#include "net.h" -#include "tgl-timers.h" +#include +#include +#include +#include int verbosity; extern int readline_disabled; @@ -708,6 +708,7 @@ int loop (void) { tgl_set_ev_base (TLS, ev); tgl_set_net_methods (TLS, &tgl_conn_methods); tgl_set_timer_methods (TLS, &tgl_libevent_timers); + assert (TLS->timer_methods); tgl_set_download_directory (TLS, get_downloads_directory ()); tgl_init (TLS); diff --git a/lua-tg.c b/lua-tg.c index f27ccb0..57bb119 100644 --- a/lua-tg.c +++ b/lua-tg.c @@ -24,7 +24,6 @@ #ifdef USE_LUA #include "lua-tg.h" -#include "include.h" #include #include @@ -42,7 +41,7 @@ lua_State *luaState; //#include "interface.h" //#include "auto/constants.h" -#include "tgl.h" +#include #include "interface.h" #include @@ -52,7 +51,7 @@ extern struct tgl_state *TLS; static int have_file; #define my_lua_checkstack(L,x) assert (lua_checkstack (L, x)) -void push_user (tgl_peer_t *P UU); +void push_user (tgl_peer_t *P); void push_peer (tgl_peer_id_t id, tgl_peer_t *P); void lua_add_string_field (const char *name, const char *value) { @@ -96,7 +95,7 @@ void push_tgl_peer_type (int x) { } } -void push_user (tgl_peer_t *P UU) { +void push_user (tgl_peer_t *P) { my_lua_checkstack (luaState, 4); lua_add_string_field ("first_name", P->user.first_name); lua_add_string_field ("last_name", P->user.last_name); @@ -387,7 +386,7 @@ void lua_our_id (int id) { } } -void lua_new_msg (struct tgl_message *M UU) { +void lua_new_msg (struct tgl_message *M) { if (!have_file) { return; } lua_settop (luaState, 0); //lua_checkstack (luaState, 20); diff --git a/lua-tg.h b/lua-tg.h index 65346a6..2db43b8 100644 --- a/lua-tg.h +++ b/lua-tg.h @@ -20,8 +20,7 @@ #define __LUA_TG_H__ #include -#include "lua-tg.h" -#include "tgl.h" +#include void lua_init (const char *file); void lua_new_msg (struct tgl_message *M); diff --git a/main.c b/main.c index 83fa3c1..16e2bf9 100644 --- a/main.c +++ b/main.c @@ -64,13 +64,13 @@ #include "telegram.h" #include "loop.h" #include "interface.h" -#include "tools.h" +#include #ifdef USE_LUA # include "lua-tg.h" #endif -#include "tgl.h" +#include #define PROGNAME "telegram-cli" #define VERSION "0.07" diff --git a/mtproto-client.c b/mtproto-client.c deleted file mode 100644 index e97423e..0000000 --- a/mtproto-client.c +++ /dev/null @@ -1,1462 +0,0 @@ -/* - 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 Nikolay Durov, Andrey Lopatin 2012-2013 - Vitaly Valtman 2013-2014 -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _FILE_OFFSET_BITS 64 - -#include -#include -#include -#include -#include -#include -#include -#if defined(__FreeBSD__) || defined(__OpenBSD__) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#include "telegram.h" -#include "include.h" -#include "queries.h" -//#include "loop.h" -#include "structures.h" -#include "binlog.h" -#include "auto.h" -#include "tgl.h" -#include "mtproto-client.h" -#include "tools.h" -#include "tree.h" -#include "updates.h" - -#if defined(__FreeBSD__) -#define __builtin_bswap32(x) bswap32(x) -#endif - -#if defined(__OpenBSD__) -#define __builtin_bswap32(x) __swap32gen(x) -#endif - -#define sha1 SHA1 - -#include "mtproto-common.h" - -#define MAX_NET_RES (1L << 16) -//extern int log_level; - -#if !defined(HAVE___BUILTIN_BSWAP32) && !defined(__FreeBSD__) && !defined(__OpenBSD__) -static inline unsigned __builtin_bswap32(unsigned x) { - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff ); -} -#endif - -//int verbosity; -//static enum tgl_dc_state c_state; -//extern int binlog_enabled; -//extern int disable_auto_accept; -//extern int allow_weak_random; - -static int total_packets_sent; -static long long total_data_sent; - - -static int rpc_execute (struct tgl_state *TLS, struct connection *c, int op, int len); -static int rpc_becomes_ready (struct tgl_state *TLS, struct connection *c); -static int rpc_close (struct tgl_state *TLS, struct connection *c); - -static long long precise_time; - -static double get_utime (int clock_id) { - struct timespec T; - tgl_my_clock_gettime (clock_id, &T); - double res = T.tv_sec + (double) T.tv_nsec * 1e-9; - if (clock_id == CLOCK_REALTIME) { - precise_time = (long long) (res * (1LL << 32)); - } - return res; -} - - -//#define STATS_BUFF_SIZE (64 << 10) -//static int stats_buff_len; -//static char stats_buff[STATS_BUFF_SIZE]; - -#define MAX_RESPONSE_SIZE (1L << 24) - -//static int Response_len; - -/* - * - * STATE MACHINE - * - */ - -#define TG_SERVER_PUBKEY_FILENAME "tg-server.pub" -//static char *rsa_public_key_name; // = TG_SERVER_PUBKEY_FILENAME; -//static RSA *pubKey; -static long long pk_fingerprint; - -static int rsa_load_public_key (struct tgl_state *TLS, const char *public_key_name) { - TLS->pubKey = NULL; - FILE *f = fopen (public_key_name, "r"); - if (f == NULL) { - vlogprintf (E_WARNING, "Couldn't open public key file: %s\n", public_key_name); - return -1; - } - TLS->pubKey = PEM_read_RSAPublicKey (f, NULL, NULL, NULL); - fclose (f); - if (TLS->pubKey == NULL) { - vlogprintf (E_WARNING, "PEM_read_RSAPublicKey returns NULL.\n"); - return -1; - } - - vlogprintf (E_WARNING, "public key '%s' loaded successfully\n", public_key_name); - - return 0; -} - - - - - -/* - * - * UNAUTHORIZED (DH KEY EXCHANGE) PROTOCOL PART - * - */ - -static BIGNUM dh_prime, dh_g, g_a, auth_key_num; -static char s_power [256]; - -static struct { - long long auth_key_id; - long long out_msg_id; - int msg_len; -} unenc_msg_header; - - -#define ENCRYPT_BUFFER_INTS 16384 -static int encrypt_buffer[ENCRYPT_BUFFER_INTS]; - -#define DECRYPT_BUFFER_INTS 16384 -static int decrypt_buffer[ENCRYPT_BUFFER_INTS]; - -static int encrypt_packet_buffer (struct tgl_state *TLS) { - return tgl_pad_rsa_encrypt (TLS, (char *) packet_buffer, (packet_ptr - packet_buffer) * 4, (char *) encrypt_buffer, ENCRYPT_BUFFER_INTS * 4, ((RSA *)TLS->pubKey)->n, ((RSA *)TLS->pubKey)->e); -} - -static int encrypt_packet_buffer_aes_unauth (const char server_nonce[16], const char hidden_client_nonce[32]) { - tgl_init_aes_unauth (server_nonce, hidden_client_nonce, AES_ENCRYPT); - return tgl_pad_aes_encrypt ((char *) packet_buffer, (packet_ptr - packet_buffer) * 4, (char *) encrypt_buffer, ENCRYPT_BUFFER_INTS * 4); -} - - -static int rpc_send_packet (struct tgl_state *TLS, struct connection *c) { - int len = (packet_ptr - packet_buffer) * 4; - //c->out_packet_num ++; - TLS->net_methods->incr_out_packet_num (c); - long long next_msg_id = (long long) ((1LL << 32) * get_utime (CLOCK_REALTIME)) & -4; - if (next_msg_id <= unenc_msg_header.out_msg_id) { - unenc_msg_header.out_msg_id += 4; - } else { - unenc_msg_header.out_msg_id = next_msg_id; - } - unenc_msg_header.msg_len = len; - - int total_len = len + 20; - assert (total_len > 0 && !(total_len & 0xfc000003)); - total_len >>= 2; - vlogprintf (E_DEBUG, "writing packet: total_len = %d, len = %d\n", total_len, len); - if (total_len < 0x7f) { - assert (TLS->net_methods->write_out (c, &total_len, 1) == 1); - } else { - total_len = (total_len << 8) | 0x7f; - assert (TLS->net_methods->write_out (c, &total_len, 4) == 4); - } - TLS->net_methods->write_out (c, &unenc_msg_header, 20); - TLS->net_methods->write_out (c, packet_buffer, len); - TLS->net_methods->flush_out (c); - - total_packets_sent ++; - total_data_sent += total_len; - return 1; -} - -static int rpc_send_message (struct tgl_state *TLS, struct connection *c, void *data, int len) { - assert (len > 0 && !(len & 0xfc000003)); - int total_len = len >> 2; - if (total_len < 0x7f) { - assert (TLS->net_methods->write_out (c, &total_len, 1) == 1); - } else { - total_len = (total_len << 8) | 0x7f; - assert (TLS->net_methods->write_out (c, &total_len, 4) == 4); - } - - TLS->net_methods->incr_out_packet_num (c); - assert (TLS->net_methods->write_out (c, data, len) == len); - TLS->net_methods->flush_out (c); - - total_packets_sent ++; - total_data_sent += total_len; - return 1; -} - -static int send_req_pq_packet (struct tgl_state *TLS, struct connection *c) { - struct tgl_dc *D = TLS->net_methods->get_dc (c); - assert (D->state == st_init); - - tglt_secure_random (D->nonce, 16); - unenc_msg_header.out_msg_id = 0; - clear_packet (); - out_int (CODE_req_pq); - out_ints ((int *)D->nonce, 4); - rpc_send_packet (TLS, c); - - D->state = st_reqpq_sent; - return 1; -} - -static int send_req_pq_temp_packet (struct tgl_state *TLS, struct connection *c) { - struct tgl_dc *D = TLS->net_methods->get_dc (c); - assert (D->state == st_authorized); - - tglt_secure_random (D->nonce, 16); - unenc_msg_header.out_msg_id = 0; - clear_packet (); - out_int (CODE_req_pq); - out_ints ((int *)D->nonce, 4); - rpc_send_packet (TLS, c); - - D->state = st_reqpq_sent_temp; - return 1; -} - - -static unsigned long long gcd (unsigned long long a, unsigned long long b) { - return b ? gcd (b, a % b) : a; -} - -//typedef unsigned int uint128_t __attribute__ ((mode(TI))); - -static int process_respq_answer (struct tgl_state *TLS, struct connection *c, char *packet, int len, int temp_key) { - struct tgl_dc *D = TLS->net_methods->get_dc (c); - unsigned long long what; - unsigned p1, p2; - int i; - - long long packet_auth_key_id = *(long long *)packet; - if (packet_auth_key_id) { - assert (temp_key); - vlogprintf (E_WARNING, "received packet during creation of temp auth key. Probably answer on old query. Drop\n"); - return 0; - } - vlogprintf (E_DEBUG, "process_respq_answer(), len=%d, op=0x%08x\n", len, *(int *)(packet + 20)); - assert (len >= 76); - assert (!*(long long *) packet); - assert (*(int *) (packet + 16) == len - 20); - assert (!(len & 3)); - assert (*(int *) (packet + 20) == CODE_resPQ); - assert (!memcmp (packet + 24, D->nonce, 16)); - memcpy (D->server_nonce, packet + 40, 16); - char *from = packet + 56; - int clen = *from++; - assert (clen <= 8); - what = 0; - for (i = 0; i < clen; i++) { - what = (what << 8) + (unsigned char)*from++; - } - - while (((unsigned long)from) & 3) ++from; - - p1 = 0, p2 = 0; - - int it = 0; - unsigned long long g = 0; - for (i = 0; i < 3 || it < 1000; i++) { - int q = ((lrand48() & 15) + 17) % what; - unsigned long long x = (long long)lrand48 () % (what - 1) + 1, y = x; - int lim = 1 << (i + 18); - int j; - for (j = 1; j < lim; j++) { - ++it; - unsigned long long a = x, b = x, c = q; - while (b) { - if (b & 1) { - c += a; - if (c >= what) { - c -= what; - } - } - a += a; - if (a >= what) { - a -= what; - } - b >>= 1; - } - x = c; - unsigned long long z = x < y ? what + x - y : x - y; - g = gcd (z, what); - if (g != 1) { - break; - } - if (!(j & (j - 1))) { - y = x; - } - } - if (g > 1 && g < what) break; - } - - assert (g > 1 && g < what); - p1 = g; - p2 = what / g; - if (p1 > p2) { - unsigned t = p1; p1 = p2; p2 = t; - } - - - /// ++p1; /// - - assert (*(int *) (from) == CODE_vector); - int fingerprints_num = *(int *)(from + 4); - assert (fingerprints_num >= 1 && fingerprints_num <= 64 && len == fingerprints_num * 8 + 8 + (from - packet)); - long long *fingerprints = (long long *) (from + 8); - for (i = 0; i < fingerprints_num; i++) { - if (fingerprints[i] == pk_fingerprint) { - //logprintf ( "found our public key at position %d\n", i); - break; - } - } - if (i == fingerprints_num) { - vlogprintf (E_ERROR, "fatal: don't have any matching keys (%016llx expected)\n", pk_fingerprint); - exit (2); - } - // create inner part (P_Q_inner_data) - clear_packet (); - packet_ptr += 5; - out_int (temp_key ? CODE_p_q_inner_data_temp : CODE_p_q_inner_data); - out_cstring (packet + 57, clen); - //out_int (0x0f01); // pq=15 - - if (p1 < 256) { - clen = 1; - } else if (p1 < 65536) { - clen = 2; - } else if (p1 < 16777216) { - clen = 3; - } else { - clen = 4; - } - p1 = __builtin_bswap32 (p1); - out_cstring ((char *)&p1 + 4 - clen, clen); - p1 = __builtin_bswap32 (p1); - - if (p2 < 256) { - clen = 1; - } else if (p2 < 65536) { - clen = 2; - } else if (p2 < 16777216) { - clen = 3; - } else { - clen = 4; - } - p2 = __builtin_bswap32 (p2); - out_cstring ((char *)&p2 + 4 - clen, clen); - p2 = __builtin_bswap32 (p2); - - //out_int (0x0301); // p=3 - //out_int (0x0501); // q=5 - out_ints ((int *) D->nonce, 4); - out_ints ((int *) D->server_nonce, 4); - tglt_secure_random (D->new_nonce, 32); - out_ints ((int *) D->new_nonce, 8); - if (temp_key) { - out_int (TLS->temp_key_expire_time); - } - sha1 ((unsigned char *) (packet_buffer + 5), (packet_ptr - packet_buffer - 5) * 4, (unsigned char *) packet_buffer); - - int l = encrypt_packet_buffer (TLS); - - clear_packet (); - out_int (CODE_req_DH_params); - out_ints ((int *) D->nonce, 4); - out_ints ((int *) D->server_nonce, 4); - //out_int (0x0301); // p=3 - //out_int (0x0501); // q=5 - if (p1 < 256) { - clen = 1; - } else if (p1 < 65536) { - clen = 2; - } else if (p1 < 16777216) { - clen = 3; - } else { - clen = 4; - } - p1 = __builtin_bswap32 (p1); - out_cstring ((char *)&p1 + 4 - clen, clen); - p1 = __builtin_bswap32 (p1); - if (p2 < 256) { - clen = 1; - } else if (p2 < 65536) { - clen = 2; - } else if (p2 < 16777216) { - clen = 3; - } else { - clen = 4; - } - p2 = __builtin_bswap32 (p2); - out_cstring ((char *)&p2 + 4 - clen, clen); - p2 = __builtin_bswap32 (p2); - - out_long (pk_fingerprint); - out_cstring ((char *) encrypt_buffer, l); - - D->state = temp_key ? st_reqdh_sent_temp : st_reqdh_sent; - - return rpc_send_packet (TLS, c); -} - -static int check_prime (struct tgl_state *TLS, BIGNUM *p) { - int r = BN_is_prime (p, BN_prime_checks, 0, TLS->BN_ctx, 0); - ensure (r >= 0); - return r; -} - -int tglmp_check_DH_params (struct tgl_state *TLS, BIGNUM *p, int g) { - if (g < 2 || g > 7) { return -1; } - if (BN_num_bits (p) != 2048) { return -1; } - BIGNUM t; - BN_init (&t); - - BN_init (&dh_g); - ensure (BN_set_word (&dh_g, 4 * g)); - - ensure (BN_mod (&t, p, &dh_g, TLS->BN_ctx)); - int x = BN_get_word (&t); - assert (x >= 0 && x < 4 * g); - - BN_free (&dh_g); - - switch (g) { - case 2: - if (x != 7) { return -1; } - break; - case 3: - if (x % 3 != 2 ) { return -1; } - break; - case 4: - break; - case 5: - if (x % 5 != 1 && x % 5 != 4) { return -1; } - break; - case 6: - if (x != 19 && x != 23) { return -1; } - break; - case 7: - if (x % 7 != 3 && x % 7 != 5 && x % 7 != 6) { return -1; } - break; - } - - if (!check_prime (TLS, p)) { return -1; } - - BIGNUM b; - BN_init (&b); - ensure (BN_set_word (&b, 2)); - ensure (BN_div (&t, 0, p, &b, TLS->BN_ctx)); - if (!check_prime (TLS, &t)) { return -1; } - BN_free (&b); - BN_free (&t); - return 0; -} - -int tglmp_check_g (struct tgl_state *TLS, unsigned char p[256], BIGNUM *g) { - static unsigned char s[256]; - memset (s, 0, 256); - assert (BN_num_bytes (g) <= 256); - BN_bn2bin (g, s + (256 - BN_num_bytes (g))); - int ok = 0; - int i; - for (i = 0; i < 64; i++) { - if (s[i]) { - ok = 1; - break; - } - } - if (!ok) { return -1; } - ok = 0; - for (i = 0; i < 64; i++) { - if (s[255 - i]) { - ok = 1; - break; - } - } - if (!ok) { return -1; } - ok = 0; - for (i = 0; i < 64; i++) { - if (s[i] < p[i]) { - ok = 1; - break; - } else if (s[i] > p[i]) { - vlogprintf (E_WARNING, "i = %d (%d %d)\n", i, (int)s[i], (int)p[i]); - return -1; - } - } - if (!ok) { return -1; } - return 0; -} - -int tglmp_check_g_bn (struct tgl_state *TLS, BIGNUM *p, BIGNUM *g) { - static unsigned char s[256]; - memset (s, 0, 256); - assert (BN_num_bytes (p) == 256); - BN_bn2bin (p, s); - return tglmp_check_g (TLS, s, g); -} - -static int process_dh_answer (struct tgl_state *TLS, struct connection *c, char *packet, int len, int temp_key) { - struct tgl_dc *D = TLS->net_methods->get_dc (c); - vlogprintf (E_DEBUG, "process_dh_answer(), len=%d\n", len); - //if (len < 116) { - // vlogprintf (E_ERROR, "%u * %u = %llu", p1, p2, what); - //} - long long packet_auth_key_id = *(long long *)packet; - if (packet_auth_key_id) { - assert (temp_key); - vlogprintf (E_WARNING, "received packet during creation of temp auth key. Probably answer on old query. Drop\n"); - return 0; - } - assert (len >= 116); - assert (!*(long long *) packet); - assert (*(int *) (packet + 16) == len - 20); - assert (!(len & 3)); - assert (*(int *) (packet + 20) == (int)CODE_server_DH_params_ok); - assert (!memcmp (packet + 24, D->nonce, 16)); - assert (!memcmp (packet + 40, D->server_nonce, 16)); - tgl_init_aes_unauth (D->server_nonce, D->new_nonce, AES_DECRYPT); - in_ptr = (int *)(packet + 56); - in_end = (int *)(packet + len); - int l = prefetch_strlen (); - assert (l > 0); - l = tgl_pad_aes_decrypt (fetch_str (l), l, (char *) decrypt_buffer, DECRYPT_BUFFER_INTS * 4 - 16); - assert (in_ptr == in_end); - assert (l >= 60); - assert (decrypt_buffer[5] == (int)CODE_server_DH_inner_data); - assert (!memcmp (decrypt_buffer + 6, D->nonce, 16)); - assert (!memcmp (decrypt_buffer + 10, D->server_nonce, 16)); - int g = decrypt_buffer[14]; - in_ptr = decrypt_buffer + 15; - in_end = decrypt_buffer + (l >> 2); - BN_init (&dh_prime); - BN_init (&g_a); - assert (fetch_bignum (&dh_prime) > 0); - assert (fetch_bignum (&g_a) > 0); - assert (tglmp_check_g_bn (TLS, &dh_prime, &g_a) >= 0); - int server_time = *in_ptr++; - assert (in_ptr <= in_end); - - assert (tglmp_check_DH_params (TLS, &dh_prime, g) >= 0); - - static char sha1_buffer[20]; - sha1 ((unsigned char *) decrypt_buffer + 20, (in_ptr - decrypt_buffer - 5) * 4, (unsigned char *) sha1_buffer); - assert (!memcmp (decrypt_buffer, sha1_buffer, 20)); - assert ((char *) in_end - (char *) in_ptr < 16); - - D->server_time_delta = server_time - time (0); - D->server_time_udelta = server_time - get_utime (CLOCK_MONOTONIC); - //logprintf ( "server time is %d, delta = %d\n", server_time, server_time_delta); - - // Build set_client_DH_params answer - clear_packet (); - packet_ptr += 5; - out_int (CODE_client_DH_inner_data); - out_ints ((int *) D->nonce, 4); - out_ints ((int *) D->server_nonce, 4); - out_long (0LL); - - BN_init (&dh_g); - ensure (BN_set_word (&dh_g, g)); - - tglt_secure_random (s_power, 256); - BIGNUM *dh_power = BN_bin2bn ((unsigned char *)s_power, 256, 0); - ensure_ptr (dh_power); - - BIGNUM *y = BN_new (); - ensure_ptr (y); - ensure (BN_mod_exp (y, &dh_g, dh_power, &dh_prime, TLS->BN_ctx)); - out_bignum (y); - BN_free (y); - - BN_init (&auth_key_num); - ensure (BN_mod_exp (&auth_key_num, &g_a, dh_power, &dh_prime, TLS->BN_ctx)); - l = BN_num_bytes (&auth_key_num); - assert (l >= 250 && l <= 256); - assert (BN_bn2bin (&auth_key_num, (unsigned char *)(temp_key ? D->temp_auth_key : D->auth_key))); - if (l < 256) { - char *key = temp_key ? D->temp_auth_key : D->auth_key; - memmove (key + 256 - l, key, l); - memset (key, 0, 256 - l); - } - - BN_free (dh_power); - BN_free (&auth_key_num); - BN_free (&dh_g); - BN_free (&g_a); - BN_free (&dh_prime); - - //hexdump (auth_key, auth_key + 256); - - sha1 ((unsigned char *) (packet_buffer + 5), (packet_ptr - packet_buffer - 5) * 4, (unsigned char *) packet_buffer); - - //hexdump ((char *)packet_buffer, (char *)packet_ptr); - - l = encrypt_packet_buffer_aes_unauth (D->server_nonce, D->new_nonce); - - clear_packet (); - out_int (CODE_set_client_DH_params); - out_ints ((int *) D->nonce, 4); - out_ints ((int *) D->server_nonce, 4); - out_cstring ((char *) encrypt_buffer, l); - - D->state = temp_key ? st_client_dh_sent_temp : st_client_dh_sent;; - - return rpc_send_packet (TLS, c); -} - -static void create_temp_auth_key (struct tgl_state *TLS, struct connection *c) { - send_req_pq_temp_packet (TLS, c); -} - -int tglmp_encrypt_inner_temp (struct tgl_state *TLS, struct connection *c, int *msg, int msg_ints, int useful, void *data, long long msg_id); -static long long generate_next_msg_id (struct tgl_state *TLS, struct tgl_dc *DC); -static long long msg_id_override; -static void mpc_on_get_config (struct tgl_state *TLS, void *extra, int success); -static int process_auth_complete (struct tgl_state *TLS, struct connection *c UU, char *packet, int len, int temp_key) { - struct tgl_dc *D = TLS->net_methods->get_dc (c); - vlogprintf (E_DEBUG - 1, "process_dh_answer(), len=%d\n", len); - - long long packet_auth_key_id = *(long long *)packet; - if (packet_auth_key_id) { - assert (temp_key); - vlogprintf (E_WARNING, "received packet during creation of temp auth key. Probably answer on old query. Drop\n"); - return 0; - } - assert (len == 72); - assert (!*(long long *) packet); - assert (*(int *) (packet + 16) == len - 20); - assert (!(len & 3)); - assert (*(int *) (packet + 20) == CODE_dh_gen_ok); - assert (!memcmp (packet + 24, D->nonce, 16)); - assert (!memcmp (packet + 40, D->server_nonce, 16)); - static unsigned char tmp[44], sha1_buffer[20]; - memcpy (tmp, D->new_nonce, 32); - tmp[32] = 1; - //GET_DC(c)->auth_key_id = *(long long *)(sha1_buffer + 12); - - if (!temp_key) { - bl_do_set_auth_key_id (TLS, D->id, (unsigned char *)D->auth_key); - sha1 ((unsigned char *)D->auth_key, 256, sha1_buffer); - } else { - sha1 ((unsigned char *)D->temp_auth_key, 256, sha1_buffer); - D->temp_auth_key_id = *(long long *)(sha1_buffer + 12); - } - - memcpy (tmp + 33, sha1_buffer, 8); - sha1 (tmp, 41, sha1_buffer); - assert (!memcmp (packet + 56, sha1_buffer + 4, 16)); - D->server_salt = *(long long *)D->server_nonce ^ *(long long *)D->new_nonce; - - //kprintf ("OK\n"); - - //c->status = conn_error; - //sleep (1); - - D->state = st_authorized; - //return 1; - vlogprintf (E_DEBUG, "Auth success\n"); - if (temp_key) { - //D->flags |= 2; - - long long msg_id = generate_next_msg_id (TLS, D); - clear_packet (); - out_int (CODE_bind_auth_key_inner); - long long rand; - tglt_secure_random (&rand, 8); - out_long (rand); - out_long (D->temp_auth_key_id); - out_long (D->auth_key_id); - - struct tgl_session *S = TLS->net_methods->get_session (c); - if (!S->session_id) { - tglt_secure_random (&S->session_id, 8); - } - out_long (S->session_id); - int expires = time (0) + D->server_time_delta + TLS->temp_key_expire_time; - out_int (expires); - - static int data[1000]; - int len = tglmp_encrypt_inner_temp (TLS, c, packet_buffer, packet_ptr - packet_buffer, 0, data, msg_id); - msg_id_override = msg_id; - tgl_do_send_bind_temp_key (TLS, D, rand, expires, (void *)data, len, msg_id); - msg_id_override = 0; - } else { - D->flags |= 1; - if (TLS->enable_pfs) { - create_temp_auth_key (TLS, c); - } else { - D->temp_auth_key_id = D->auth_key_id; - memcpy (D->temp_auth_key, D->auth_key, 256); - D->flags |= 2; - if (!(D->flags & 4)) { - tgl_do_help_get_config_dc (TLS, D, mpc_on_get_config, D); - } - } - } - - //write_auth_file (); - - return 1; -} - -/* - * - * AUTHORIZED (MAIN) PROTOCOL PART - * - */ - -static struct encrypted_message enc_msg; - -static long long client_last_msg_id, server_last_msg_id; - -static double get_server_time (struct tgl_dc *DC) { - if (!DC->server_time_udelta) { - DC->server_time_udelta = get_utime (CLOCK_REALTIME) - get_utime (CLOCK_MONOTONIC); - } - return get_utime (CLOCK_MONOTONIC) + DC->server_time_udelta; -} - -static long long generate_next_msg_id (struct tgl_state *TLS, struct tgl_dc *DC) { - long long next_id = (long long) (get_server_time (DC) * (1LL << 32)) & -4; - if (next_id <= client_last_msg_id) { - next_id = client_last_msg_id += 4; - } else { - client_last_msg_id = next_id; - } - return next_id; -} - -static void init_enc_msg (struct tgl_state *TLS, struct tgl_session *S, int useful) { - struct tgl_dc *DC = S->dc; - assert (DC->state == st_authorized); - //assert (DC->flags & 2); - assert (DC->temp_auth_key_id); - vlogprintf (E_DEBUG, "temp_auth_key_id = 0x%016llx, auth_key_id = 0x%016llx\n", DC->temp_auth_key_id, DC->auth_key_id); - enc_msg.auth_key_id = DC->temp_auth_key_id; -// assert (DC->server_salt); - enc_msg.server_salt = DC->server_salt; - if (!S->session_id) { - tglt_secure_random (&S->session_id, 8); - } - enc_msg.session_id = S->session_id; - //enc_msg.auth_key_id2 = auth_key_id; - enc_msg.msg_id = msg_id_override ? msg_id_override : generate_next_msg_id (TLS, DC); - //enc_msg.msg_id -= 0x10000000LL * (lrand48 () & 15); - //kprintf ("message id %016llx\n", enc_msg.msg_id); - enc_msg.seq_no = S->seq_no; - if (useful) { - enc_msg.seq_no |= 1; - } - S->seq_no += 2; -}; - -static void init_enc_msg_inner_temp (struct tgl_dc *DC, long long msg_id) { - enc_msg.auth_key_id = DC->auth_key_id; - tglt_secure_random (&enc_msg.server_salt, 8); - tglt_secure_random (&enc_msg.session_id, 8); - enc_msg.msg_id = msg_id; - enc_msg.seq_no = 0; -}; - - -static int aes_encrypt_message (struct tgl_state *TLS, char *key, struct encrypted_message *enc) { - unsigned char sha1_buffer[20]; - const int MINSZ = offsetof (struct encrypted_message, message); - const int UNENCSZ = offsetof (struct encrypted_message, server_salt); - int enc_len = (MINSZ - UNENCSZ) + enc->msg_len; - assert (enc->msg_len >= 0 && enc->msg_len <= MAX_MESSAGE_INTS * 4 - 16 && !(enc->msg_len & 3)); - sha1 ((unsigned char *) &enc->server_salt, enc_len, sha1_buffer); - //printf ("enc_len is %d\n", enc_len); - vlogprintf (E_DEBUG, "sending message with sha1 %08x\n", *(int *)sha1_buffer); - memcpy (enc->msg_key, sha1_buffer + 4, 16); - tgl_init_aes_auth (key, enc->msg_key, AES_ENCRYPT); - //hexdump ((char *)enc, (char *)enc + enc_len + 24); - return tgl_pad_aes_encrypt ((char *) &enc->server_salt, enc_len, (char *) &enc->server_salt, MAX_MESSAGE_INTS * 4 + (MINSZ - UNENCSZ)); -} - -long long tglmp_encrypt_send_message (struct tgl_state *TLS, struct connection *c, int *msg, int msg_ints, int flags) { - struct tgl_dc *DC = TLS->net_methods->get_dc (c); - if (!(DC->flags & 4) && !(flags & 2)) { - return generate_next_msg_id (TLS, DC); - } - struct tgl_session *S = TLS->net_methods->get_session (c); - assert (S); - - const int UNENCSZ = offsetof (struct encrypted_message, server_salt); - if (msg_ints <= 0 || msg_ints > MAX_MESSAGE_INTS - 4) { - return -1; - } - if (msg) { - memcpy (enc_msg.message, msg, msg_ints * 4); - enc_msg.msg_len = msg_ints * 4; - } else { - if ((enc_msg.msg_len & 0x80000003) || enc_msg.msg_len > MAX_MESSAGE_INTS * 4 - 16) { - return -1; - } - } - init_enc_msg (TLS, S, flags & 1); - - //hexdump ((char *)msg, (char *)msg + (msg_ints * 4)); - int l = aes_encrypt_message (TLS, DC->temp_auth_key, &enc_msg); - //hexdump ((char *)&enc_msg, (char *)&enc_msg + l + 24); - assert (l > 0); - vlogprintf (E_DEBUG, "Sending message to DC%d: %s:%d with key_id=%lld\n", DC->id, DC->ip, DC->port, enc_msg.auth_key_id); - rpc_send_message (TLS, c, &enc_msg, l + UNENCSZ); - - - return client_last_msg_id; -} - -int tglmp_encrypt_inner_temp (struct tgl_state *TLS, struct connection *c, int *msg, int msg_ints, int useful, void *data, long long msg_id) { - struct tgl_dc *DC = TLS->net_methods->get_dc (c); - struct tgl_session *S = TLS->net_methods->get_session (c); - assert (S); - - const int UNENCSZ = offsetof (struct encrypted_message, server_salt); - if (msg_ints <= 0 || msg_ints > MAX_MESSAGE_INTS - 4) { - return -1; - } - memcpy (enc_msg.message, msg, msg_ints * 4); - enc_msg.msg_len = msg_ints * 4; - - init_enc_msg_inner_temp (DC, msg_id); - - int l = aes_encrypt_message (TLS, DC->auth_key, &enc_msg); - assert (l > 0); - //rpc_send_message (c, &enc_msg, l + UNENCSZ); - memcpy (data, &enc_msg, l + UNENCSZ); - - return l + UNENCSZ; -} - -static int good_messages; - -static void rpc_execute_answer (struct tgl_state *TLS, struct connection *c, long long msg_id UU); - -//int unread_messages; -//int pts; -//int qts; -//int last_date; -//int seq; - -static void work_container (struct tgl_state *TLS, struct connection *c, long long msg_id UU) { - vlogprintf (E_DEBUG, "work_container: msg_id = %lld\n", msg_id); - assert (fetch_int () == CODE_msg_container); - int n = fetch_int (); - int i; - for (i = 0; i < n; i++) { - long long id = fetch_long (); - //int seqno = fetch_int (); - fetch_int (); // seq_no - if (id & 1) { - tgln_insert_msg_id (TLS, TLS->net_methods->get_session (c), id); - } - int bytes = fetch_int (); - int *t = in_end; - in_end = in_ptr + (bytes / 4); - rpc_execute_answer (TLS, c, id); - assert (in_ptr == in_end); - in_end = t; - } -} - -static void work_new_session_created (struct tgl_state *TLS, struct connection *c, long long msg_id UU) { - vlogprintf (E_DEBUG, "work_new_session_created: msg_id = %lld\n", msg_id); - assert (fetch_int () == (int)CODE_new_session_created); - fetch_long (); // first message id - //DC->session_id = fetch_long (); - fetch_long (); // unique_id - TLS->net_methods->get_dc (c)->server_salt = fetch_long (); - if (TLS->started && !(TLS->locks & TGL_LOCK_DIFF)) { - tgl_do_get_difference (TLS, 0, 0, 0); - } -} - -static void work_msgs_ack (struct tgl_state *TLS, struct connection *c UU, long long msg_id UU) { - vlogprintf (E_DEBUG, "work_msgs_ack: msg_id = %lld\n", msg_id); - assert (fetch_int () == CODE_msgs_ack); - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - int i; - for (i = 0; i < n; i++) { - long long id = fetch_long (); - vlogprintf (E_DEBUG + 1, "ack for %lld\n", id); - tglq_query_ack (TLS, id); - } -} - -static void work_rpc_result (struct tgl_state *TLS, struct connection *c UU, long long msg_id UU) { - vlogprintf (E_DEBUG, "work_rpc_result: msg_id = %lld\n", msg_id); - assert (fetch_int () == (int)CODE_rpc_result); - long long id = fetch_long (); - int op = prefetch_int (); - if (op == CODE_rpc_error) { - tglq_query_error (TLS, id); - } else { - tglq_query_result (TLS, id); - } -} - -#define MAX_PACKED_SIZE (1 << 24) -static void work_packed (struct tgl_state *TLS, struct connection *c, long long msg_id) { - assert (fetch_int () == CODE_gzip_packed); - static int in_gzip; - static int buf[MAX_PACKED_SIZE >> 2]; - assert (!in_gzip); - in_gzip = 1; - - int l = prefetch_strlen (); - char *s = fetch_str (l); - - int total_out = tgl_inflate (s, l, buf, MAX_PACKED_SIZE); - int *end = in_ptr; - int *eend = in_end; - //assert (total_out % 4 == 0); - in_ptr = buf; - in_end = in_ptr + total_out / 4; - rpc_execute_answer (TLS, c, msg_id); - in_ptr = end; - in_end = eend; - in_gzip = 0; -} - -static void work_bad_server_salt (struct tgl_state *TLS, struct connection *c UU, long long msg_id UU) { - assert (fetch_int () == (int)CODE_bad_server_salt); - long long id = fetch_long (); - tglq_query_restart (TLS, id); - fetch_int (); // seq_no - fetch_int (); // error_code - long long new_server_salt = fetch_long (); - TLS->net_methods->get_dc (c)->server_salt = new_server_salt; -} - -static void work_pong (struct tgl_state *TLS, struct connection *c UU, long long msg_id UU) { - assert (fetch_int () == CODE_pong); - fetch_long (); // msg_id - fetch_long (); // ping_id -} - -static void work_detailed_info (struct tgl_state *TLS, struct connection *c UU, long long msg_id UU) { - assert (fetch_int () == CODE_msg_detailed_info); - fetch_long (); // msg_id - fetch_long (); // answer_msg_id - fetch_int (); // bytes - fetch_int (); // status -} - -static void work_new_detailed_info (struct tgl_state *TLS, struct connection *c UU, long long msg_id UU) { - assert (fetch_int () == (int)CODE_msg_new_detailed_info); - fetch_long (); // answer_msg_id - fetch_int (); // bytes - fetch_int (); // status -} - -static void work_bad_msg_notification (struct tgl_state *TLS, struct connection *c UU, long long msg_id UU) { - assert (fetch_int () == (int)CODE_bad_msg_notification); - long long m1 = fetch_long (); - int s = fetch_int (); - int e = fetch_int (); - vlogprintf (E_NOTICE, "bad_msg_notification: msg_id = %lld, seq = %d, error = %d\n", m1, s, e); -} - -static void rpc_execute_answer (struct tgl_state *TLS, struct connection *c, long long msg_id UU) { - int op = prefetch_int (); - switch (op) { - case CODE_msg_container: - work_container (TLS, c, msg_id); - return; - case CODE_new_session_created: - work_new_session_created (TLS, c, msg_id); - return; - case CODE_msgs_ack: - work_msgs_ack (TLS, c, msg_id); - return; - case CODE_rpc_result: - work_rpc_result (TLS, c, msg_id); - return; - case CODE_update_short: - tglu_work_update_short (TLS, c, msg_id); - return; - case CODE_updates: - tglu_work_updates (TLS, c, msg_id); - return; - case CODE_update_short_message: - tglu_work_update_short_message (TLS, c, msg_id); - return; - case CODE_update_short_chat_message: - tglu_work_update_short_chat_message (TLS, c, msg_id); - return; - case CODE_gzip_packed: - work_packed (TLS, c, msg_id); - return; - case CODE_bad_server_salt: - work_bad_server_salt (TLS, c, msg_id); - return; - case CODE_pong: - work_pong (TLS, c, msg_id); - return; - case CODE_msg_detailed_info: - work_detailed_info (TLS, c, msg_id); - return; - case CODE_msg_new_detailed_info: - work_new_detailed_info (TLS, c, msg_id); - return; - case CODE_updates_too_long: - tglu_work_updates_to_long (TLS, c, msg_id); - return; - case CODE_bad_msg_notification: - work_bad_msg_notification (TLS, c, msg_id); - return; - } - vlogprintf (E_WARNING, "Unknown message: %08x\n", op); - in_ptr = in_end; // Will not fail due to assertion in_ptr == in_end -} - -static int process_rpc_message (struct tgl_state *TLS, struct connection *c UU, struct encrypted_message *enc, int len) { - const int MINSZ = offsetof (struct encrypted_message, message); - const int UNENCSZ = offsetof (struct encrypted_message, server_salt); - vlogprintf (E_DEBUG, "process_rpc_message(), len=%d\n", len); - assert (len >= MINSZ && (len & 15) == (UNENCSZ & 15)); - struct tgl_dc *DC = TLS->net_methods->get_dc (c); - if (enc->auth_key_id != DC->temp_auth_key_id && enc->auth_key_id != DC->auth_key_id) { - vlogprintf (E_WARNING, "received msg from dc %d with auth_key_id %lld (perm_auth_key_id %lld temp_auth_key_id %lld). Dropping\n", - DC->id, enc->auth_key_id, DC->auth_key_id, DC->temp_auth_key_id); - return 0; - } - if (enc->auth_key_id == DC->temp_auth_key_id) { - assert (enc->auth_key_id == DC->temp_auth_key_id); - assert (DC->temp_auth_key_id); - tgl_init_aes_auth (DC->temp_auth_key + 8, enc->msg_key, AES_DECRYPT); - } else { - assert (enc->auth_key_id == DC->auth_key_id); - assert (DC->auth_key_id); - tgl_init_aes_auth (DC->auth_key + 8, enc->msg_key, AES_DECRYPT); - } - int l = tgl_pad_aes_decrypt ((char *)&enc->server_salt, len - UNENCSZ, (char *)&enc->server_salt, len - UNENCSZ); - assert (l == len - UNENCSZ); - //assert (enc->auth_key_id2 == enc->auth_key_id); - assert (!(enc->msg_len & 3) && enc->msg_len > 0 && enc->msg_len <= len - MINSZ && len - MINSZ - enc->msg_len <= 12); - static unsigned char sha1_buffer[20]; - sha1 ((void *)&enc->server_salt, enc->msg_len + (MINSZ - UNENCSZ), sha1_buffer); - assert (!memcmp (&enc->msg_key, sha1_buffer + 4, 16)); - //assert (enc->server_salt == server_salt); //in fact server salt can change - if (DC->server_salt != enc->server_salt) { - DC->server_salt = enc->server_salt; - //write_auth_file (); - } - - - int this_server_time = enc->msg_id >> 32LL; - if (!DC->server_time_delta) { - DC->server_time_delta = this_server_time - get_utime (CLOCK_REALTIME); - DC->server_time_udelta = this_server_time - get_utime (CLOCK_MONOTONIC); - } - double st = get_server_time (DC); - if (this_server_time < st - 300 || this_server_time > st + 30) { - vlogprintf (E_WARNING, "salt = %lld, session_id = %lld, msg_id = %lld, seq_no = %d, st = %lf, now = %lf\n", enc->server_salt, enc->session_id, enc->msg_id, enc->seq_no, st, get_utime (CLOCK_REALTIME)); - return 0; - } - - - assert (this_server_time >= st - 300 && this_server_time <= st + 30); - //assert (enc->msg_id > server_last_msg_id && (enc->msg_id & 3) == 1); - vlogprintf (E_DEBUG, "received mesage id %016llx\n", enc->msg_id); - server_last_msg_id = enc->msg_id; - - //*(long long *)(longpoll_query + 3) = *(long long *)((char *)(&enc->msg_id) + 0x3c); - //*(long long *)(longpoll_query + 5) = *(long long *)((char *)(&enc->msg_id) + 0x3c); - - assert (l >= (MINSZ - UNENCSZ) + 8); - //assert (enc->message[0] == CODE_rpc_result && *(long long *)(enc->message + 1) == client_last_msg_id); - ++good_messages; - - in_ptr = enc->message; - in_end = in_ptr + (enc->msg_len / 4); - - /*{ - assert (len <= 10000); - static char s[1 << 20]; - int p = 0; - int i; - //static int buf[10000]; - //assert (TLS->net_methods->read_in_lookup (c, buf, len) == len); - - for (i = 0; i < in_end - in_ptr; i++) { - p += sprintf (s + p, "%08x ", *(int *)(in_ptr + i)); - } - vlogprintf (E_DEBUG, "%s\n", s); - }*/ - - struct tgl_session *S = TLS->net_methods->get_session (c); - if (enc->msg_id & 1) { - tgln_insert_msg_id (TLS, S, enc->msg_id); - } - assert (S->session_id == enc->session_id); - rpc_execute_answer (TLS, c, enc->msg_id); - assert (in_ptr == in_end); - return 0; -} - - -static int rpc_execute (struct tgl_state *TLS, struct connection *c, int op, int len) { - struct tgl_dc *D = TLS->net_methods->get_dc (c); - vlogprintf (E_DEBUG, "outbound rpc connection from dc #%d (%s:%d) : received rpc answer %d with %d content bytes\n", D->id, D->ip, D->port, op, len); - - /*{ - assert (len <= 10000); - static char s[1 << 20]; - int p = 0; - int i; - static int buf[10000]; - assert (TLS->net_methods->read_in_lookup (c, buf, len) == len); - - for (i = 0; i < len / 4; i++) { - p += sprintf (s + p, "%08x ", *(int *)(buf + i)); - } - vlogprintf (E_DEBUG, "%s\n", s); - }*/ - /* if (op < 0) { - assert (TLS->net_methods->read_in (c, Response, Response_len) == Response_len); - return 0; - }*/ - - if (len >= MAX_RESPONSE_SIZE/* - 12*/ || len < 0/*12*/) { - vlogprintf (E_WARNING, "answer too long (%d bytes), skipping\n", len); - return 0; - } - - int Response_len = len; - - static char Response[MAX_RESPONSE_SIZE]; - vlogprintf (E_DEBUG, "Response_len = %d\n", Response_len); - assert (TLS->net_methods->read_in (c, Response, Response_len) == Response_len); - Response[Response_len] = 0; - -#if !defined(__MACH__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined (__CYGWIN__) -// setsockopt (c->fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){0}, 4); -#endif - int o = D->state; - //if (D->flags & 1) { o = st_authorized;} - switch (o) { - case st_reqpq_sent: - process_respq_answer (TLS, c, Response/* + 8*/, Response_len/* - 12*/, 0); - return 0; - case st_reqdh_sent: - process_dh_answer (TLS, c, Response/* + 8*/, Response_len/* - 12*/, 0); - return 0; - case st_client_dh_sent: - process_auth_complete (TLS, c, Response/* + 8*/, Response_len/* - 12*/, 0); - return 0; - case st_reqpq_sent_temp: - process_respq_answer (TLS, c, Response/* + 8*/, Response_len/* - 12*/, 1); - return 0; - case st_reqdh_sent_temp: - process_dh_answer (TLS, c, Response/* + 8*/, Response_len/* - 12*/, 1); - return 0; - case st_client_dh_sent_temp: - process_auth_complete (TLS, c, Response/* + 8*/, Response_len/* - 12*/, 1); - return 0; - case st_authorized: - if (op < 0 && op >= -999) { - vlogprintf (E_WARNING, "Server error %d\n", op); - } else { - process_rpc_message (TLS, c, (void *)(Response/* + 8*/), Response_len/* - 12*/); - } - return 0; - default: - vlogprintf (E_ERROR, "fatal: cannot receive answer in state %d\n", D->state); - exit (2); - } - - return 0; -} - - -static int tc_close (struct tgl_state *TLS, struct connection *c, int who) { - vlogprintf (E_DEBUG, "outbound rpc connection from dc #%d : closing by %d\n", TLS->net_methods->get_dc(c)->id, who); - return 0; -} - -static void mpc_on_get_config (struct tgl_state *TLS, void *extra, int success) { - assert (success); - struct tgl_dc *D = extra; - D->flags |= 4; -} - -static int tc_becomes_ready (struct tgl_state *TLS, struct connection *c) { - vlogprintf (E_DEBUG, "outbound rpc connection from dc #%d becomed ready\n", TLS->net_methods->get_dc(c)->id); - //char byte = 0xef; - //assert (TLS->net_methods->write_out (c, &byte, 1) == 1); - //TLS->net_methods->flush_out (c); - - struct tgl_dc *D = TLS->net_methods->get_dc (c); - if (D->flags & 1) { D->state = st_authorized; } - int o = D->state; - if (o == st_authorized && !TLS->enable_pfs) { - D->temp_auth_key_id = D->auth_key_id; - memcpy (D->temp_auth_key, D->auth_key, 256); - D->flags |= 2; - } - switch (o) { - case st_init: - send_req_pq_packet (TLS, c); - break; - case st_authorized: - if (!(D->flags & 2)) { - assert (!D->temp_auth_key_id); - create_temp_auth_key (TLS, c); - } else if (!(D->flags & 4)) { - tgl_do_help_get_config_dc (TLS, D, mpc_on_get_config, D); - } - break; - default: - vlogprintf (E_DEBUG, "c_state = %d\n", D->state); - assert (0); - } - return 0; -} - -static int rpc_becomes_ready (struct tgl_state *TLS, struct connection *c) { - return tc_becomes_ready (TLS, c); -} - -static int rpc_close (struct tgl_state *TLS, struct connection *c) { - return tc_close (TLS, c, 0); -} - - -#define RANDSEED_PASSWORD_FILENAME NULL -#define RANDSEED_PASSWORD_LENGTH 0 -void tglmp_on_start (struct tgl_state *TLS) { - tgl_prng_seed (TLS, RANDSEED_PASSWORD_FILENAME, RANDSEED_PASSWORD_LENGTH); - - int i; - int ok = 0; - for (i = 0; i < TLS->rsa_key_num; i++) { - char *key = TLS->rsa_key_list[i]; - if (rsa_load_public_key (TLS, key) < 0) { - vlogprintf (E_WARNING, "Can not load key %s\n", key); - } else { - ok = 1; - break; - } - } - - if (!ok) { - vlogprintf (E_ERROR, "No public keys found\n"); - exit (1); - } - - pk_fingerprint = tgl_do_compute_rsa_key_fingerprint (TLS->pubKey); -} - -void tgl_dc_authorize (struct tgl_state *TLS, struct tgl_dc *DC) { - //c_state = 0; - if (!DC->sessions[0]) { - tglmp_dc_create_session (TLS, DC); - } - vlogprintf (E_DEBUG, "Starting authorization for DC #%d: %s:%d\n", DC->id, DC->ip, DC->port); - //net_loop (0, auth_ok); -} - -#define long_cmp(a,b) ((a) > (b) ? 1 : (a) == (b) ? 0 : -1) -DEFINE_TREE(long,long long,long_cmp,0) - -static int send_all_acks (struct tgl_state *TLS, struct tgl_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); - } - tglmp_encrypt_send_message (TLS, S->c, packet_buffer, packet_ptr - packet_buffer, 0); - return 0; -} - -static void send_all_acks_gateway (struct tgl_state *TLS, void *arg) { - send_all_acks (TLS, arg); -} - - -void tgln_insert_msg_id (struct tgl_state *TLS, struct tgl_session *S, long long id) { - if (!S->ack_tree) { - TLS->timer_methods->insert (S->ev, ACK_TIMEOUT); - } - if (!tree_lookup_long (S->ack_tree, id)) { - S->ack_tree = tree_insert_long (S->ack_tree, id, lrand48 ()); - } -} - -//extern struct tgl_dc *DC_list[]; - - -static void regen_temp_key_gw (struct tgl_state *TLS, void *arg) { - tglmp_regenerate_temp_auth_key (TLS, arg); -} - -struct tgl_dc *tglmp_alloc_dc (struct tgl_state *TLS, int id, char *ip, int port UU) { - //assert (!TLS->DC_list[id]); - if (!TLS->DC_list[id]) { - struct tgl_dc *DC = talloc0 (sizeof (*DC)); - DC->id = id; - DC->ip = ip; - DC->port = port; - TLS->DC_list[id] = DC; - if (id > TLS->max_dc_num) { - TLS->max_dc_num = id; - } - DC->ev = TLS->timer_methods->alloc (TLS, regen_temp_key_gw, DC); - TLS->timer_methods->insert (DC->ev, 0); - return DC; - } else { - struct tgl_dc *DC = TLS->DC_list[id]; - tfree_str (DC->ip); - DC->ip = tstrdup (ip); - return DC; - } -} - -static struct mtproto_methods mtproto_methods = { - .execute = rpc_execute, - .ready = rpc_becomes_ready, - .close = rpc_close -}; - -void tglmp_dc_create_session (struct tgl_state *TLS, struct tgl_dc *DC) { - struct tgl_session *S = talloc0 (sizeof (*S)); - assert (RAND_pseudo_bytes ((unsigned char *) &S->session_id, 8) >= 0); - S->dc = DC; - S->c = TLS->net_methods->create_connection (TLS, DC->ip, DC->port, S, DC, &mtproto_methods); - if (!S->c) { - vlogprintf (E_DEBUG, "Can not create connection to DC. Is network down?\n"); - exit (1); - } - S->ev = TLS->timer_methods->alloc (TLS, send_all_acks_gateway, S); - assert (!DC->sessions[0]); - DC->sessions[0] = S; -} - -void tgl_do_send_ping (struct tgl_state *TLS, struct connection *c) { - int x[3]; - x[0] = CODE_ping; - *(long long *)(x + 1) = lrand48 () * (1ll << 32) + lrand48 (); - tglmp_encrypt_send_message (TLS, c, x, 3, 0); -} - -void tgl_dc_iterator (struct tgl_state *TLS, void (*iterator)(struct tgl_dc *DC)) { - int i; - for (i = 0; i <= TLS->max_dc_num; i++) { - iterator (TLS->DC_list[i]); - } -} - -void tgl_dc_iterator_ex (struct tgl_state *TLS, void (*iterator)(struct tgl_dc *DC, void *extra), void *extra) { - int i; - for (i = 0; i <= TLS->max_dc_num; i++) { - iterator (TLS->DC_list[i], extra); - } -} - - -void tglmp_regenerate_temp_auth_key (struct tgl_state *TLS, struct tgl_dc *D) { - D->flags &= ~6; - D->temp_auth_key_id = 0; - memset (D->temp_auth_key, 0, 256); - - if (!D->sessions[0]) { - tgl_dc_authorize (TLS, D); - return; - } - - - struct tgl_session *S = D->sessions[0]; - tglt_secure_random (&S->session_id, 8); - S->seq_no = 0; - - TLS->timer_methods->delete (S->ev); - S->ack_tree = tree_clear_long (S->ack_tree); - - if (D->state != st_authorized) { - return; - } - - if (S->c) { - create_temp_auth_key (TLS, S->c); - } -} - -void tgls_free_session (struct tgl_state *TLS, struct tgl_session *S) { - S->ack_tree = tree_clear_long (S->ack_tree); - if (S->ev) { TLS->timer_methods->free (S->ev); } - if (S->c) { - TLS->net_methods->free (S->c); - } - tfree (S, sizeof (*S)); -} - -void tgls_free_dc (struct tgl_state *TLS, struct tgl_dc *DC) { - if (DC->ip) { tfree_str (DC->ip); } - - struct tgl_session *S = DC->sessions[0]; - if (S) { tgls_free_session (TLS, S); } - - if (DC->ev) { TLS->timer_methods->free (DC->ev); } - tfree (DC, sizeof (*DC)); -} - -void tgls_free_pubkey (struct tgl_state *TLS) { - RSA_free (TLS->pubKey); -} diff --git a/mtproto-client.h b/mtproto-client.h deleted file mode 100644 index 692a4b8..0000000 --- a/mtproto-client.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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 Nikolay Durov, Andrey Lopatin 2012-2013 - Vitaly Valtman 2013-2014 -*/ -#ifndef __MTPROTO_CLIENT_H__ -#define __MTPROTO_CLIENT_H__ -//#include "net.h" -#include -//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 tgl_state *TLS, struct connection *c, int *msg, int msg_ints, int flags); -void tglmp_dc_create_session (struct tgl_state *TLS, struct tgl_dc *DC); -int tglmp_check_g (struct tgl_state *TLS, unsigned char p[256], BIGNUM *g); -int tglmp_check_DH_params (struct tgl_state *TLS, BIGNUM *p, int g); -struct tgl_dc *tglmp_alloc_dc (struct tgl_state *TLS, int id, char *ip, int port); -void tglmp_regenerate_temp_auth_key (struct tgl_state *TLS, struct tgl_dc *D); - -void tgln_insert_msg_id (struct tgl_state *TLS, struct tgl_session *S, long long id); -void tglmp_on_start (struct tgl_state *TLS); -void tgl_dc_authorize (struct tgl_state *TLS, struct tgl_dc *DC); -void tgls_free_dc (struct tgl_state *TLS, struct tgl_dc *DC); -void tgls_free_pubkey (struct tgl_state *TLS); -#endif diff --git a/mtproto-common.c b/mtproto-common.c deleted file mode 100644 index dd8caaf..0000000 --- a/mtproto-common.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - 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 Nikolay Durov, Andrey Lopatin 2012-2013 - Vitaly Valtman 2013-2014 -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _FILE_OFFSET_BITS 64 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mtproto-common.h" -#include "include.h" -#include "tools.h" - -#ifdef __MACH__ -#include -#include -#endif - - -static int __packet_buffer[PACKET_BUFFER_SIZE + 16]; -int *tgl_packet_ptr; -int *tgl_packet_buffer = __packet_buffer + 16; - -static long long rsa_encrypted_chunks, rsa_decrypted_chunks; - -//int verbosity; - -static int get_random_bytes (struct tgl_state *TLS, 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) { - vlogprintf (E_DEBUG, "added %d bytes of real entropy to secure random numbers seed\n", r); - } else { - r = 0; - } - close (h); - } - - if (r < n) { - h = open ("/dev/urandom", O_RDONLY); - if (h < 0) { - return r; - } - int s = read (h, buf + r, n - r); - close (h); - if (s > 0) { - r += s; - } - } - - if (r >= (int) sizeof (long)) { - *(long *)buf ^= lrand48 (); - srand48 (*(long *)buf); - } - - return r; -} - - -/* RDTSC */ -#if defined(__i386__) -#define HAVE_RDTSC -static __inline__ unsigned long long rdtsc (void) { - unsigned long long int x; - __asm__ volatile ("rdtsc" : "=A" (x)); - return x; -} -#elif defined(__x86_64__) -#define HAVE_RDTSC -static __inline__ unsigned long long rdtsc (void) { - unsigned hi, lo; - __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); - return ((unsigned long long) lo) | (((unsigned long long) hi) << 32); -} -#endif - -void tgl_prng_seed (struct tgl_state *TLS, const char *password_filename, int password_length) { - struct timespec T; - tgl_my_clock_gettime (CLOCK_REALTIME, &T); - RAND_add (&T, sizeof (T), 4.0); -#ifdef HAVE_RDTSC - unsigned long long r = rdtsc (); - RAND_add (&r, 8, 4.0); -#endif - unsigned short p = getpid (); - RAND_add (&p, sizeof (p), 0.0); - p = getppid (); - RAND_add (&p, sizeof (p), 0.0); - unsigned char rb[32]; - int s = get_random_bytes (TLS, rb, 32); - if (s > 0) { - RAND_add (rb, s, s); - } - memset (rb, 0, sizeof (rb)); - if (password_filename && password_length > 0) { - int fd = open (password_filename, O_RDONLY); - if (fd < 0) { - 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) { - vlogprintf (E_WARNING, "Warning: fail to read password file - \"%s\", %m.\n", password_filename); - } else { - vlogprintf (E_DEBUG, "read %d bytes from password file.\n", l); - RAND_add (a, l, l); - } - close (fd); - tfree_secure (a, password_length); - } - } - TLS->BN_ctx = BN_CTX_new (); - ensure_ptr (TLS->BN_ctx); -} - -int tgl_serialize_bignum (BIGNUM *b, char *buffer, int maxlen) { - int itslen = BN_num_bytes (b); - int reqlen; - if (itslen < 254) { - reqlen = itslen + 1; - } else { - reqlen = itslen + 4; - } - int newlen = (reqlen + 3) & -4; - int pad = newlen - reqlen; - reqlen = newlen; - if (reqlen > maxlen) { - return -reqlen; - } - if (itslen < 254) { - *buffer++ = itslen; - } else { - *(int *)buffer = (itslen << 8) + 0xfe; - buffer += 4; - } - int l = BN_bn2bin (b, (unsigned char *)buffer); - assert (l == itslen); - buffer += l; - while (pad --> 0) { - *buffer++ = 0; - } - return reqlen; -} - - -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 = tgl_serialize_bignum (key->n, tempbuff, 4096); - assert (l1 > 0); - 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 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; - if (len < 254) { - *dest++ = len; - } else { - *packet_ptr = (len << 8) + 0xfe; - dest += 4; - } - memcpy (dest, str, len); - dest += len; - while ((long) dest & 3) { - *dest++ = 0; - } - packet_ptr = (int *) dest; -} - -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; - if (len < 254) { - dest++; - if (dest != str) { - memmove (dest, str, len); - } - dest[-1] = len; - } else { - dest += 4; - if (dest != str) { - memmove (dest, str, len); - } - *packet_ptr = (len << 8) + 0xfe; - } - dest += len; - while ((long) dest & 3) { - *dest++ = 0; - } - packet_ptr = (int *) dest; -} - - -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 *tgl_in_ptr, *tgl_in_end; - -int tgl_fetch_bignum (BIGNUM *x) { - int l = prefetch_strlen (); - if (l < 0) { - return l; - } - char *str = fetch_str (l); - assert (BN_bin2bn ((unsigned char *) str, l, x) == x); - return l; -} - -int tgl_pad_rsa_encrypt (struct tgl_state *TLS, 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); - assert (bits >= 2041 && bits <= 2048); - assert (from_len > 0 && from_len <= 2550); - assert (size >= chunks * 256); - assert (RAND_pseudo_bytes ((unsigned char *) from + from_len, pad) >= 0); - int i; - BIGNUM x, y; - BN_init (&x); - BN_init (&y); - 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, TLS->BN_ctx) == 1); - unsigned l = 256 - BN_num_bytes (&y); - assert (l <= 256); - memset (to, 0, l); - BN_bn2bin (&y, (unsigned char *) to + l); - to += 256; - } - BN_free (&x); - BN_free (&y); - return chunks * 256; -} - -int tgl_pad_rsa_decrypt (struct tgl_state *TLS, 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; - } - int chunks = (from_len >> 8); - int bits = BN_num_bits (N); - assert (bits >= 2041 && bits <= 2048); - assert (size >= chunks * 255); - int i; - BIGNUM x, y; - BN_init (&x); - BN_init (&y); - for (i = 0; i < chunks; i++) { - ++rsa_decrypted_chunks; - BN_bin2bn ((unsigned char *) from, 256, &x); - assert (BN_mod_exp (&y, &x, D, N, TLS->BN_ctx) == 1); - int l = BN_num_bytes (&y); - if (l > 255) { - BN_free (&x); - BN_free (&y); - return -1; - } - assert (l >= 0 && l <= 255); - memset (to, 0, 255 - l); - BN_bn2bin (&y, (unsigned char *) to + 255 - l); - to += 255; - } - BN_free (&x); - BN_free (&y); - return chunks * 255; -} - -static unsigned char aes_key_raw[32], aes_iv[32]; -static AES_KEY aes_key; - -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); - SHA1 (buffer, 48, aes_key_raw); - memcpy (buffer + 32, hidden_client_nonce, 32); - SHA1 (buffer, 64, aes_iv + 8); - memcpy (buffer, server_nonce, 16); - memcpy (buffer + 16, hidden_client_nonce, 32); - SHA1 (buffer, 48, hash); - memcpy (aes_key_raw + 20, hash, 12); - memcpy (aes_iv, hash + 12, 8); - memcpy (aes_iv + 28, hidden_client_nonce, 4); - if (encrypt == AES_ENCRYPT) { - AES_set_encrypt_key (aes_key_raw, 32*8, &aes_key); - } else { - AES_set_decrypt_key (aes_key_raw, 32*8, &aes_key); - } - memset (aes_key_raw, 0, sizeof (aes_key_raw)); -} - -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)); - // sha1_с = SHA1 (substr (auth_key, 64, 32) + msg_key); - // sha1_d = SHA1 (msg_key + substr (auth_key, 96, 32)); - // aes_key = substr (sha1_a, 0, 8) + substr (sha1_b, 8, 12) + substr (sha1_c, 4, 12); - // aes_iv = substr (sha1_a, 8, 12) + substr (sha1_b, 0, 8) + substr (sha1_c, 16, 4) + substr (sha1_d, 0, 8); - memcpy (buffer, msg_key, 16); - memcpy (buffer + 16, auth_key, 32); - SHA1 (buffer, 48, hash); - memcpy (aes_key_raw, hash, 8); - memcpy (aes_iv, hash + 8, 12); - - memcpy (buffer, auth_key + 32, 16); - memcpy (buffer + 16, msg_key, 16); - memcpy (buffer + 32, auth_key + 48, 16); - SHA1 (buffer, 48, hash); - memcpy (aes_key_raw + 8, hash + 8, 12); - memcpy (aes_iv + 12, hash, 8); - - memcpy (buffer, auth_key + 64, 32); - memcpy (buffer + 32, msg_key, 16); - SHA1 (buffer, 48, hash); - memcpy (aes_key_raw + 20, hash + 4, 12); - memcpy (aes_iv + 20, hash + 16, 4); - - memcpy (buffer, msg_key, 16); - memcpy (buffer + 16, auth_key + 96, 32); - SHA1 (buffer, 48, hash); - memcpy (aes_iv + 24, hash, 8); - - if (encrypt == AES_ENCRYPT) { - AES_set_encrypt_key (aes_key_raw, 32*8, &aes_key); - } else { - AES_set_decrypt_key (aes_key_raw, 32*8, &aes_key); - } - memset (aes_key_raw, 0, sizeof (aes_key_raw)); -} - -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) { - assert (RAND_pseudo_bytes ((unsigned char *) from + from_len, padded_size - from_len) >= 0); - } - AES_ige_encrypt ((unsigned char *) from, (unsigned char *) to, padded_size, &aes_key, aes_iv, AES_ENCRYPT); - return padded_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; - } - AES_ige_encrypt ((unsigned char *) from, (unsigned char *) to, from_len, &aes_key, aes_iv, AES_DECRYPT); - return from_len; -} - - diff --git a/mtproto-common.h b/mtproto-common.h deleted file mode 100644 index a1d1ce5..0000000 --- a/mtproto-common.h +++ /dev/null @@ -1,384 +0,0 @@ -/* - 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 Nikolay Durov, Andrey Lopatin 2012-2013 - Vitaly Valtman 2013-2014 -*/ -#ifndef __MTPROTO_COMMON_H__ -#define __MTPROTO_COMMON_H__ - -#include -#include -#include -#include -#include -#include - -//#include "interface.h" -#include "tools.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 -#define CODE_set_client_DH_params 0xf5045f1f -#define CODE_client_DH_inner_data 0x6643b654 -#define CODE_dh_gen_ok 0x3bcbf734 -#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 -#define CODE_msg_container 0x73f1f8dc -#define CODE_msg_copy 0xe06046b2 -#define CODE_msgs_ack 0x62d6b459 -#define CODE_bad_msg_notification 0xa7eff811 -#define CODE_bad_server_salt 0xedab447b -#define CODE_msgs_state_req 0xda69fb52 -#define CODE_msgs_state_info 0x04deb57d -#define CODE_msgs_all_info 0x8cc0d131 -#define CODE_new_session_created 0x9ec20908 -#define CODE_msg_resend_req 0x7d861a08 -#define CODE_ping 0x7abe77ec -#define CODE_pong 0x347773c5 -#define CODE_destroy_session 0xe7512126 -#define CODE_destroy_session_ok 0xe22045fc -#define CODE_destroy_session_none 0x62d350c9 -#define CODE_destroy_sessions 0x9a6face8 -#define CODE_destroy_sessions_res 0xa8164668 -#define CODE_get_future_salts 0xb921bd04 -#define CODE_future_salt 0x0949d9dc -#define CODE_future_salts 0xae500895 -#define CODE_rpc_drop_answer 0x58e4a740 -#define CODE_rpc_answer_unknown 0x5e2ad36e -#define CODE_rpc_answer_dropped_running 0xcd78e586 -#define CODE_rpc_answer_dropped 0xa43ad8b7 -#define CODE_msg_detailed_info 0x276d3ec6 -#define CODE_msg_new_detailed_info 0x809db6df -#define CODE_ping_delay_disconnect 0xf3427b8c -#define CODE_gzip_packed 0x3072cfa1 - -#define CODE_input_peer_notify_settings_old 0x3cf4b1be -#define CODE_peer_notify_settings_old 0xddbcd4a5 -#define CODE_user_profile_photo_old 0x990d1493 -#define CODE_config_old 0x232d5905 - -#define CODE_msg_new_detailed_info 0x809db6df - -#define CODE_msg_detailed_info 0x276d3ec6 -/* not really a limit, for struct encrypted_message only */ -// #define MAX_MESSAGE_INTS 16384 -#define MAX_MESSAGE_INTS 1048576 -#define MAX_PROTO_MESSAGE_INTS 1048576 - -#define PACKET_BUFFER_SIZE (16384 * 100 + 16) // temp fix -#pragma pack(push,4) -struct encrypted_message { - // unencrypted header - long long auth_key_id; - char msg_key[16]; - // encrypted part, starts with encrypted header - long long server_salt; - long long session_id; - // long long auth_key_id2; // removed - // first message follows - long long msg_id; - int seq_no; - int msg_len; // divisible by 4 - int message[MAX_MESSAGE_INTS]; -}; - -#pragma pack(pop) - -//BN_CTX *BN_ctx; - -void tgl_prng_seed (struct tgl_state *TLS, 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); - -#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); - memcpy (packet_ptr, what, len * 4); - packet_ptr += len; -} - - -static inline void out_int (int x) { - assert (packet_ptr + 1 <= packet_buffer + PACKET_BUFFER_SIZE); - *packet_ptr++ = x; -} - - -static inline void out_long (long long x) { - assert (packet_ptr + 2 <= packet_buffer + PACKET_BUFFER_SIZE); - *(long long *)packet_ptr = 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 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 = tgl_serialize_bignum (n, (char *)packet_ptr, (PACKET_BUFFER_SIZE - (packet_ptr - packet_buffer)) * 4); - assert (l > 0); - packet_ptr += l >> 2; -} - -#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); -static inline int prefetch_strlen (void) { - if (in_ptr >= in_end) { - return -1; - } - unsigned l = *in_ptr; - if ((l & 0xff) < 0xfe) { - l &= 0xff; - return (in_end >= in_ptr + (l >> 2) + 1) ? (int)l : -1; - } else if ((l & 0xff) == 0xfe) { - l >>= 8; - return (l >= 254 && in_end >= in_ptr + ((l + 7) >> 2)) ? (int)l : -1; - } else { - return -1; - } -} - -static inline char *fetch_str (int len) { - assert (len >= 0); - if (len < 254) { - char *str = (char *) in_ptr + 1; - in_ptr += 1 + (len >> 2); - return str; - } else { - char *str = (char *) in_ptr + 4; - in_ptr += (len + 7) >> 2; - return str; - } -} - -static inline char *fetch_str_dup (void) { - int l = prefetch_strlen (); - assert (l >= 0); - int i; - char *s = fetch_str (l); - for (i = 0; i < l; i++) { - if (!s[i]) { break; } - } - char *r = talloc (i + 1); - memcpy (r, s, i); - r[i] = 0; - return r; -} - -static inline int fetch_update_str (char **s) { - if (!*s) { - *s = fetch_str_dup (); - return 1; - } - int l = prefetch_strlen (); - char *r = fetch_str (l); - if (memcmp (*s, r, l) || (*s)[l]) { - tfree_str (*s); - *s = talloc (l + 1); - memcpy (*s, r, l); - (*s)[l] = 0; - return 1; - } - return 0; -} - -static inline int fetch_update_int (int *value) { - if (*value == *in_ptr) { - in_ptr ++; - return 0; - } else { - *value = *(in_ptr ++); - return 1; - } -} - -static inline int fetch_update_long (long long *value) { - if (*value == *(long long *)in_ptr) { - in_ptr += 2; - return 0; - } else { - *value = *(long long *)(in_ptr); - in_ptr += 2; - return 1; - } -} - -static inline int set_update_int (int *value, int new_value) { - if (*value == new_value) { - return 0; - } else { - *value = new_value; - return 1; - } -} - -static inline void fetch_skip (int n) { - in_ptr += n; - assert (in_ptr <= in_end); -} - -static inline void fetch_skip_str (void) { - int l = prefetch_strlen (); - assert (l >= 0); - fetch_str (l); -} - -static inline long have_prefetch_ints (void) { - return in_end - in_ptr; -} - -int tgl_fetch_bignum (BIGNUM *x); -#define fetch_bignum tgl_fetch_bignum - -static inline int fetch_int (void) { - assert (in_ptr + 1 <= in_end); - return *(in_ptr ++); -} - -static inline int fetch_bool (void) { - 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; -} - -static inline int prefetch_int (void) { - assert (in_ptr < in_end); - return *(in_ptr); -} - -static inline void prefetch_data (void *data, int size) { - assert (in_ptr + (size >> 2) <= in_end); - memcpy (data, in_ptr, size); -} - -static inline void fetch_data (void *data, int size) { - assert (in_ptr + (size >> 2) <= in_end); - memcpy (data, in_ptr, size); - assert (!(size & 3)); - in_ptr += (size >> 2); -} - -static inline long long fetch_long (void) { - assert (in_ptr + 2 <= in_end); - long long r = *(long long *)in_ptr; - in_ptr += 2; - return r; -} - -static inline double fetch_double (void) { - assert (in_ptr + 2 <= in_end); - double r = *(double *)in_ptr; - in_ptr += 2; - return r; -} - -static inline void fetch_ints (void *data, int count) { - assert (in_ptr + count <= in_end); - 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); - } -} - -static inline int in_remaining (void) { - return 4 * (in_end - in_ptr); -} - -//int get_random_bytes (unsigned char *buf, int n); - -int tgl_pad_rsa_encrypt (struct tgl_state *TLS, char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *E); -int tgl_pad_rsa_decrypt (struct tgl_state *TLS, char *from, int from_len, char *to, int size, BIGNUM *N, BIGNUM *D); - -//extern long long rsa_encrypted_chunks, rsa_decrypted_chunks; - -//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 -#endif diff --git a/net.c b/net.c deleted file mode 100644 index 8f48e80..0000000 --- a/net.c +++ /dev/null @@ -1,623 +0,0 @@ -/* - 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 -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef EVENT_V2 -#include -#else -#include -#include "event-old.h" -#endif -#include -#include - -#include "net.h" -#include "include.h" -#include "tgl.h" -#include "tgl-inner.h" -//#include "mtproto-client.h" -//#include "mtproto-common.h" -#include "tree.h" -#include "tools.h" - -#ifndef POLLRDHUP -#define POLLRDHUP 0 -#endif - -//double get_utime (int clock_id); - -//extern struct mtproto_methods auth_methods; - -static void fail_connection (struct connection *c); - -#define PING_TIMEOUT 10 - -static void start_ping_timer (struct connection *c); -static void ping_alarm (evutil_socket_t fd, short what, void *arg) { - struct connection *c = arg; - struct tgl_state *TLS = c->TLS; - vlogprintf (E_DEBUG + 2,"ping alarm\n"); - assert (c->state == conn_ready || c->state == conn_connecting); - 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 (tglt_get_double_time () - c->last_receive_time > 3 * PING_TIMEOUT && c->state == conn_ready) { - tgl_do_send_ping (c->TLS, c); - start_ping_timer (c); - } else { - start_ping_timer (c); - } -} - -static void stop_ping_timer (struct connection *c) { - event_del (c->ping_ev); -} - -static void start_ping_timer (struct connection *c) { - static struct timeval ptimeout = { PING_TIMEOUT, 0}; - event_add (c->ping_ev, &ptimeout); -} - -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); -} - -static void start_fail_timer (struct connection *c) { - if (c->in_fail_timer) { return; } - c->in_fail_timer = 1; - - static struct timeval ptimeout = { 10, 0}; - event_add (c->fail_ev, &ptimeout); -} - -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; - b->rptr = b->wptr = b->start; - return b; -} - -static void delete_connection_buffer (struct connection_buffer *b) { - tfree (b->start, b->end - b->start); - tfree (b, sizeof (*b)); -} - -int tgln_write_out (struct connection *c, const void *_data, int len) { - struct tgl_state *TLS = c->TLS; - 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; - } - while (len) { - if (c->out_tail->end - c->out_tail->wptr >= len) { - memcpy (c->out_tail->wptr, data, len); - c->out_tail->wptr += len; - c->out_bytes += len; - return x + len; - } else { - int y = c->out_tail->end - c->out_tail->wptr; - assert (y < len); - memcpy (c->out_tail->wptr, data, y); - x += y; - len -= y; - data += y; - struct connection_buffer *b = new_connection_buffer (1 << 20); - c->out_tail->next = b; - b->next = 0; - c->out_tail = b; - c->out_bytes += y; - } - } - return x; -} - -int tgln_read_in (struct connection *c, void *_data, int len) { - unsigned char *data = _data; - if (!len) { return 0; } - assert (len > 0); - if (len > c->in_bytes) { - len = c->in_bytes; - } - int x = 0; - while (len) { - int y = c->in_head->wptr - c->in_head->rptr; - if (y > len) { - memcpy (data, c->in_head->rptr, len); - c->in_head->rptr += len; - c->in_bytes -= len; - return x + len; - } else { - memcpy (data, c->in_head->rptr, y); - c->in_bytes -= y; - x += y; - data += y; - len -= y; - void *old = c->in_head; - c->in_head = c->in_head->next; - if (!c->in_head) { - c->in_tail = 0; - } - delete_connection_buffer (old); - } - } - return x; -} - -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); - if (len > c->in_bytes) { - len = c->in_bytes; - } - int x = 0; - struct connection_buffer *b = c->in_head; - while (len) { - int y = b->wptr - b->rptr; - if (y >= len) { - memcpy (data, b->rptr, len); - return x + len; - } else { - memcpy (data, b->rptr, y); - x += y; - data += y; - len -= y; - b = b->next; - } - } - return x; -} - -void tgln_flush_out (struct connection *c UU) { -} - -#define MAX_CONNECTIONS 100 -static struct connection *Connections[MAX_CONNECTIONS]; -static int max_connection_fd; - -static void rotate_port (struct connection *c) { - switch (c->port) { - case 443: - c->port = 80; - break; - case 80: - c->port = 25; - break; - case 25: - c->port = 443; - break; - } -} - -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; - struct tgl_state *TLS = c->TLS; - 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; - struct tgl_state *TLS = c->TLS; - if (c->state == conn_connecting) { - c->state = conn_ready; - c->methods->ready (TLS, c); - } - try_write (c); - if (c->out_bytes) { - event_add (c->write_ev, 0); - } -} - -struct connection *tgln_create_connection (struct tgl_state *TLS, const char *host, int port, struct tgl_session *session, struct tgl_dc *dc, struct mtproto_methods *methods) { - struct connection *c = talloc0 (sizeof (*c)); - c->TLS = TLS; - int fd = socket (AF_INET, SOCK_STREAM, 0); - if (fd == -1) { - vlogprintf (E_ERROR, "Can not create socket: %m\n"); - exit (1); - } - assert (fd >= 0 && fd < MAX_CONNECTIONS); - if (fd > max_connection_fd) { - max_connection_fd = fd; - } - int flags = -1; - setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof (flags)); - setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof (flags)); - setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof (flags)); - - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons (port); - addr.sin_addr.s_addr = inet_addr (host); - - - 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) { - vlogprintf (E_ERROR, "Can not connect to %s:%d %m\n", host, port); - close (fd); - tfree (c, sizeof (*c)); - return 0; - } - } - - c->fd = fd; - c->state = conn_connecting; - c->last_receive_time = tglt_get_double_time (); - c->ip = tstrdup (host); - c->flags = 0; - c->port = port; - assert (!Connections[fd]); - Connections[fd] = c; - - c->ping_ev = evtimer_new (TLS->ev_base, ping_alarm, c); - c->fail_ev = evtimer_new (TLS->ev_base, fail_alarm, c); - c->write_ev = event_new (TLS->ev_base, c->fd, EV_WRITE, conn_try_write, c); - - struct timeval tv = {5, 0}; - c->read_ev = event_new (TLS->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; -} - -static void restart_connection (struct connection *c) { - struct tgl_state *TLS = c->TLS; - if (c->last_connect_time == time (0)) { - start_fail_timer (c); - return; - } - - c->last_connect_time = time (0); - int fd = socket (AF_INET, SOCK_STREAM, 0); - if (fd == -1) { - vlogprintf (E_ERROR, "Can not create socket: %m\n"); - exit (1); - } - assert (fd >= 0 && fd < MAX_CONNECTIONS); - if (fd > max_connection_fd) { - max_connection_fd = fd; - } - int flags = -1; - setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof (flags)); - setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof (flags)); - setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof (flags)); - - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons (c->port); - if (strcmp (c->ip, c->dc->ip)) { - tfree_str (c->ip); - c->ip = tstrdup (c->dc->ip); - } - addr.sin_addr.s_addr = inet_addr (c->ip); - - - fcntl (fd, F_SETFL, O_NONBLOCK); - - if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) == -1) { - if (errno != EINPROGRESS) { - vlogprintf (E_WARNING, "Can not connect to %s:%d %m\n", c->ip, c->port); - start_fail_timer (c); - close (fd); - return; - } - } - - c->fd = fd; - c->state = conn_connecting; - c->last_receive_time = tglt_get_double_time (); - start_ping_timer (c); - Connections[fd] = c; - - c->write_ev = event_new (TLS->ev_base, c->fd, EV_WRITE, conn_try_write, c); - - struct timeval tv = {5, 0}; - c->read_ev = event_new (TLS->ev_base, c->fd, EV_READ | EV_PERSIST, conn_try_read, c); - event_add (c->read_ev, &tv); - - char byte = 0xef; - assert (tgln_write_out (c, &byte, 1) == 1); - tgln_flush_out (c); -} - -static void fail_connection (struct connection *c) { - struct tgl_state *TLS = c->TLS; - 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) { - struct connection_buffer *d = b; - b = b->next; - delete_connection_buffer (d); - } - b = c->in_head; - while (b) { - struct connection_buffer *d = b; - b = b->next; - delete_connection_buffer (d); - } - c->out_head = c->out_tail = c->in_head = c->in_tail = 0; - c->state = conn_failed; - c->out_bytes = c->in_bytes = 0; - close (c->fd); - Connections[c->fd] = 0; - vlogprintf (E_NOTICE, "Lost connection to server... %s:%d\n", c->ip, c->port); - restart_connection (c); -} - -//extern FILE *log_net_f; -static void try_write (struct connection *c) { - struct tgl_state *TLS = c->TLS; - 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) { - x += r; - c->out_head->rptr += r; - if (c->out_head->rptr != c->out_head->wptr) { - break; - } - struct connection_buffer *b = c->out_head; - c->out_head = b->next; - if (!c->out_head) { - c->out_tail = 0; - } - delete_connection_buffer (b); - } else { - if (errno != EAGAIN && errno != EWOULDBLOCK) { - vlogprintf (E_NOTICE, "fail_connection: write_error %m\n"); - fail_connection (c); - return; - } else { - break; - } - } - } - vlogprintf (E_DEBUG, "Sent %d bytes to %d\n", x, c->fd); - c->out_bytes -= x; -} - -static void try_rpc_read (struct connection *c) { - assert (c->in_head); - struct tgl_state *TLS = c->TLS; - - while (1) { - if (c->in_bytes < 1) { return; } - unsigned len = 0; - unsigned t = 0; - 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 (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 (tgln_read_in (c, &t, 1) == 1); - assert (t == len); - assert (len >= 1); - } else { - assert (len == 0x7f); - assert (tgln_read_in (c, &len, 4) == 4); - len = (len >> 8); - assert (len >= 1); - } - len *= 4; - int op; - assert (tgln_read_in_lookup (c, &op, 4) == 4); - c->methods->execute (TLS, c, op, len); - } -} - -static void try_read (struct connection *c) { - struct tgl_state *TLS = c->TLS; - 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) { - c->last_receive_time = tglt_get_double_time (); - stop_ping_timer (c); - start_ping_timer (c); - } - if (r >= 0) { - c->in_tail->wptr += r; - x += r; - if (c->in_tail->wptr != c->in_tail->end) { - break; - } - struct connection_buffer *b = new_connection_buffer (1 << 20); - c->in_tail->next = b; - c->in_tail = b; - } else { - if (errno != EAGAIN && errno != EWOULDBLOCK) { - vlogprintf (E_NOTICE, "fail_connection: read_error %m\n"); - fail_connection (c); - return; - } else { - break; - } - } - } - vlogprintf (E_DEBUG, "Received %d bytes from %d\n", x, c->fd); - c->in_bytes += x; - if (x) { - try_rpc_read (c); - } -} -/* -int tgl_connections_make_poll_array (struct pollfd *fds, int max) { - int _max = max; - int i; - for (i = 0; i <= max_connection_fd; i++) { - if (Connections[i] && Connections[i]->state == conn_failed) { - restart_connection (Connections[i]); - } - if (Connections[i] && Connections[i]->state != conn_failed) { - assert (max > 0); - struct connection *c = Connections[i]; - fds[0].fd = c->fd; - fds[0].events = POLLERR | POLLHUP | POLLRDHUP | POLLIN; - if (c->out_bytes || c->state == conn_connecting) { - fds[0].events |= POLLOUT; - } - fds ++; - max --; - } - } - return _max - 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]; - if (fds[i].revents & POLLIN) { - try_read (c); - } - if (fds[i].revents & (POLLHUP | POLLERR | POLLRDHUP)) { - 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) { - vlogprintf (E_DEBUG, "connection ready\n"); - c->state = conn_ready; - c->last_receive_time = tglt_get_double_time (); - } - if (c->out_bytes) { - try_write (c); - } - } - } -}*/ - -static void incr_out_packet_num (struct connection *c) { - c->out_packet_num ++; -} - -static struct tgl_dc *get_dc (struct connection *c) { - return c->dc; -} - -static struct tgl_session *get_session (struct connection *c) { - return c->session; -} - -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); - } - 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 -}; diff --git a/net.h b/net.h deleted file mode 100644 index 00d7da2..0000000 --- a/net.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - 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 __NET_H__ -#define __NET_H__ - -struct connection_buffer { - unsigned char *start; - unsigned char *end; - unsigned char *rptr; - unsigned char *wptr; - struct connection_buffer *next; -}; - -enum conn_state { - conn_none, - conn_connecting, - conn_ready, - conn_failed, - conn_stopped -}; - -struct connection { - int fd; - char *ip; - int port; - int flags; - enum conn_state state; - int ipv6[4]; - struct connection_buffer *in_head; - struct connection_buffer *in_tail; - struct connection_buffer *out_head; - struct connection_buffer *out_tail; - int in_bytes; - int out_bytes; - int packet_num; - int out_packet_num; - int last_connect_time; - int in_fail_timer; - struct mtproto_methods *methods; - struct tgl_state *TLS; - struct tgl_session *session; - struct tgl_dc *dc; - void *extra; - struct event *ping_ev; - struct event *fail_ev; - struct event *read_ev; - struct event *write_ev; - double last_receive_time; -}; - -//extern struct connection *Connections[]; - -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 tgln_insert_msg_id (struct tgl_session *S, long long id); - -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 (struct tgl_state *TLS, 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 diff --git a/no-preview.h b/no-preview.h deleted file mode 100644 index 50d1274..0000000 --- a/no-preview.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - 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 -*/ - -// Just sample jpg file 90x90 - -int thumb_file_size = (82 * 6 - 2) * 4; -int thumb_file [] = { -0xe0ffd8ff, 0x464a1000, 0x01004649, 0x64000101, 0x00006400, 0xa002e2ff, -0x5f434349, 0x464f5250, 0x00454c49, 0x00000101, 0x636c9002, 0x3004736d, -0x6e6d0000, 0x47527274, 0x59582042, 0xdd07205a, 0x04000b00, 0x1b001600, -0x63612400, 0x50417073, 0x00004c50, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x0100d6f6, 0x00000000, 0x636c2dd3, -0x0000736d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x65640b00, 0x00006373, 0x00000801, 0x70633800, 0x00007472, 0x00004001, -0x74774e00, 0x00007470, 0x00009001, 0x68631400, 0x00006461, 0x0000a401, -0x58722c00, 0x00005a59, 0x0000d001, 0x58621400, 0x00005a59, 0x0000e401, -0x58671400, 0x00005a59, 0x0000f801, 0x54721400, 0x00004352, 0x00000c02, -0x54672000, 0x00004352, 0x00002c02, 0x54622000, 0x00004352, 0x00004c02, -0x68632000, 0x00006d72, 0x00006c02, 0x6c6d2400, 0x00006375, 0x00000000, -0x00000100, 0x6e650c00, 0x00005355, 0x00001c00, 0x73001c00, 0x47005200, -0x20004200, 0x75006200, 0x6c006900, 0x2d007400, 0x6e006900, 0x6c6d0000, -0x00006375, 0x00000000, 0x00000100, 0x6e650c00, 0x00005355, 0x00003200, -0x4e001c00, 0x20006f00, 0x6f006300, 0x79007000, 0x69007200, 0x68006700, -0x2c007400, 0x75002000, 0x65007300, 0x66002000, 0x65007200, 0x6c006500, -0x00007900, 0x59580000, 0x0000205a, 0x00000000, 0x0100d6f6, 0x00000000, -0x66732dd3, 0x00003233, 0x01000000, 0x00004a0c, 0xffffe305, 0x00002af3, -0x00009b07, 0xffff87fd, 0xffffa2fb, 0x0000a3fd, 0x0000d803, 0x595894c0, -0x0000205a, 0x00000000, 0x0000946f, 0x0000ee38, 0x59589003, 0x0000205a, -0x00000000, 0x00009d24, 0x0000830f, 0x5958beb6, 0x0000205a, 0x00000000, -0x0000a562, 0x000090b7, 0x6170de18, 0x00006172, 0x03000000, 0x02000000, -0x00006666, 0x0000a7f2, 0x0000590d, 0x0000d013, 0x61705b0a, 0x00006172, -0x03000000, 0x02000000, 0x00006666, 0x0000a7f2, 0x0000590d, 0x0000d013, -0x61705b0a, 0x00006172, 0x03000000, 0x02000000, 0x00006666, 0x0000a7f2, -0x0000590d, 0x0000d013, 0x68635b0a, 0x00006d72, 0x03000000, 0x00000000, -0x0000d7a3, 0x00007b54, 0x0000cd4c, 0x00009a99, 0x00006626, 0xdbff5c0f, -0x14004300, 0x0f120f0e, 0x1112140d, 0x14161712, 0x21331f18, 0x1f1c1c1f, -0x252f2d3f, 0x4e414a33, 0x4841494d, 0x765c5246, 0x6f575264, 0x66484658, -0x7a6f688c, 0x8485847d, 0x9b91634f, 0x769a808f, 0xff7f8481, 0x014300db, -0x1f171716, 0x213c1f1b, 0x547f3c21, 0x7f7f5448, 0x7f7f7f7f, 0x7f7f7f7f, -0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, -0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x1100c0ff, 0x005a0008, -0x2201035a, 0x01110200, 0xff011103, 0x001900c4, 0x01010101, 0x00000101, -0x00000000, 0x00000000, 0x02030400, 0xc4ff0605, 0x00103600, 0x02010401, -0x06050304, 0x00000306, 0x01000000, 0x11030200, 0x05211204, 0x13514131, -0x32146122, 0x23918171, 0x72423424, 0x432515a1, 0xa2827444, 0xc4fff0b3, -0x01011400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1400c4ff, -0x00000111, 0x00000000, 0x00000000, 0x00000000, 0xdaff0000, 0x01030c00, -0x03110200, 0x003f0011, 0x404434fb, 0xbcb4875c, 0x006b38b0, 0x03dcdb12, -0xf4637f74, 0xe519f153, 0x09d7c5c7, 0x47d29160, 0x20692f18, 0xd06d786a, -0x53f7f922, 0x17b3e260, 0x2fe8668c, 0x1786a473, 0x9775efbd, 0xe917e43a, -0x1d0a1bb0, 0x114d0f82, 0x14651110, 0x35f299ed, 0xe9b09680, 0xf5a4fc2f, -0xe975bd03, 0xb506737b, 0x04444440, 0x5c444044, 0x8e8dedbd, 0xc61adc7b, -0x689c738b, 0x92a0dc01, 0x58e2b77f, 0x7bfb37d1, 0xb5b5e79d, 0xdbf968cc, -0xead3f48d, 0x38ed1313, 0xdea77c86, 0xae089963, 0xc743435a, 0x403fe4ce, -0x392ee1b9, 0xed39e718, 0xd6517e2d, 0x7fc4aa03, 0xb7ad7590, 0x77e7e6ab, -0x34bf705d, 0x7c77ca53, 0x3dea1299, 0x7fb0bcf4, 0x241fadc5, 0x95a7a816, -0x13fbe6f3, 0x3182b135, 0xd1b4b224, 0x1b0d48a2, 0xbf9d26d8, 0x82dc3640, -0x63569a2a, 0xbbd224c3, 0xb9b4714c, 0x1680aec6, 0x3d311856, 0x9b59be91, -0x09876ca6, 0x61d86564, 0x5a9f06d2, 0x36f51b0d, 0x8682e476, 0xacb1b131, -0xd1584363, 0x00456b4d, 0x22d2053b, 0x22202202, 0xf3f30222, 0xe3e513e5, -0xf1e6e1f0, 0x2380496e, 0x5fdcdb68, 0x549b3a27, 0x825e6a6c, 0x6522028b, -0xaf91ccc8, 0x341cf26b, 0x58dbc4b5, 0xf2289add, 0x0854ddbd, 0x0b9247d5, -0xf02b5c54, 0x3f917f92, 0xaf56affd, 0xe3760637, 0x05cebde0, 0xed4c76ce, -0x3cef1b63, 0x7fd8aff8, 0xa0c902ea, 0x7e730d0a, 0x435834f3, 0x26edbb76, -0xd3ec00fd, 0x76d48efa, 0xa8560f2d, 0x0e766331, 0xd319993c, 0x20243209, -0x61b7e6c8, 0x998331d0, 0x640ee802, 0x47a3d493, 0xfab99413, 0x4fd871f1, -0xe9443792, 0x627e051c, 0xd8f3051c, 0x2f28f558, 0x64b51745, 0x1b2bfee3, -0xb8783953, 0x9900fff6, 0xd8176a65, 0x5a3bf56a, 0x1b331fdb, 0x64b3572f, -0xd59a3643, 0xaf3abce1, 0x11dd20bd, 0x01111110, 0x5c141011, 0xb3e3083f, -0xd9b19cc4, 0x17edb20e, 0xa78e9aa1, 0x4ef4de06, 0x00c0bfe7, 0x7e1e442d, -0x9221fe38, 0xedb5c7dc, 0x6338078a, 0x62495b8d, 0xc11d9b8c, 0x49e81b16, -0x51d02bea, 0x3eb86d70, 0xc8bc4f13, 0xa10ec758, 0xd40751c0, 0x5ac94710, -0xc4c8b080, 0x95492b83, 0x975ee696, 0xb7bd96b4, 0x17379cce, 0x82e856e8, -0xe4c2c82a, 0x398e935f, 0x632437ea, 0x7c9c87d2, 0xdc1ddb7c, 0x65a80a48, -0x2309f164, 0x51fab475, 0x081dc11d, 0xda45573b, 0x6622f3f3, 0x48f1b214, -0x676c4edb, 0x243468c7, 0x00ffde60, 0xf1630350, 0xa0076c1d, 0x8f2c0c8b, -0x2383c26b, 0x361a8f4e, 0xaceea6c9, 0x01dd5a5d, 0x11111011, 0xc3780c04, -0xbf093ee2, 0xc7972c0b, 0x00d99040, 0xc0c20eb7, 0x659d3bd4, 0x269ab85e, -0x468e114f, 0x11ad4fdb, 0x83d083d8, 0x8c52f4bd, 0x3c9664bf, 0xa4f9c77c, -0x22a68876, 0xadb18784, 0xf480be83, 0x885a00ea, 0x220e0a88, 0xc303e4f6, -0xc866e058, 0xdddbd661, 0xdf395db1, 0xbad64343, 0xe6e65b03, 0x668e81c3, -0xad619e98, 0xeeb94563, 0xd4d19a3c, 0x3316ce95, 0x9d65f1e1, 0x3bf324fe, -0x0e468f53, 0xc386068c, 0xa89e24f7, 0xf0c7c73b, 0xb60e391f, 0x1b8827cb, -0x58601954, 0xc54f90f9, 0x80886ec5, 0x88088888, 0x1b7bb980, 0xb4c71c23, -0xe6148e39, 0xb12358b8, 0xbd08225d, 0x0ffef085, 0x72b4f025, 0x635ce389, -0xb90277e4, 0x0d05e000, 0x9bf9dbb9, 0x8e749fbc, 0x7ee6abbf, 0x4ddbf4af, -0x728df7f3, 0x10b59adf, 0xe3c38f49, 0xb23c638a, 0xdb3d9349, 0x66899a64, -0x00004dd5, 0xf51b5adf, 0x2220a255, 0xd9ff0f22}; diff --git a/queries.c b/queries.c deleted file mode 100644 index a80c104..0000000 --- a/queries.c +++ /dev/null @@ -1,3879 +0,0 @@ -/* - 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 -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _FILE_OFFSET_BITS 64 -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "include.h" -#include "mtproto-client.h" -#include "queries.h" -#include "tree.h" -#include "mtproto-common.h" -//#include "telegram.h" -#include "structures.h" -//#include "interface.h" -//#include "net.h" -#include -#include -#include -#include -#include - -#include "no-preview.h" -#include "binlog.h" -#include "updates.h" -#include "auto.h" -#include "tgl.h" - -#define sha1 SHA1 - -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif - -//int want_dc_num; -//char *get_downloads_directory (void); -//extern int offline_mode; - -//long long cur_uploading_bytes; -//long long cur_uploaded_bytes; -//long long cur_downloading_bytes; -//long long cur_downloaded_bytes; - -//extern int binlog_enabled; -//extern int sync_from_start; - -//static int queries_num; - -static void out_peer_id (struct tgl_state *TLS, tgl_peer_id_t id); -#define QUERY_TIMEOUT 6.0 - -#define memcmp8(a,b) memcmp ((a), (b), 8) -DEFINE_TREE (query, struct query *, memcmp8, 0) ; - -struct query *tglq_query_get (struct tgl_state *TLS, long long id) { - return tree_lookup_query (TLS->queries_tree, (void *)&id); -} - -static int alarm_query (struct tgl_state *TLS, struct query *q) { - assert (q); - vlogprintf (E_DEBUG - 1, "Alarm query %lld\n", q->msg_id); - - TLS->timer_methods->insert (q->ev, QUERY_TIMEOUT); - - if (q->session->session_id == q->session_id) { - clear_packet (); - out_int (CODE_msg_container); - out_int (1); - out_long (q->msg_id); - out_int (q->seq_no); - out_int (4 * q->data_len); - out_ints (q->data, q->data_len); - - tglmp_encrypt_send_message (TLS, q->session->c, packet_buffer, packet_ptr - packet_buffer, q->flags & QUERY_FORCE_SEND); - } else { - q->flags &= ~QUERY_ACK_RECEIVED; - if (tree_lookup_query (TLS->queries_tree, q)) { - TLS->queries_tree = tree_delete_query (TLS->queries_tree, q); - } - q->msg_id = tglmp_encrypt_send_message (TLS, q->session->c, q->data, q->data_len, (q->flags & QUERY_FORCE_SEND) | 1); - TLS->queries_tree = tree_insert_query (TLS->queries_tree, q, lrand48 ()); - q->session_id = q->session->session_id; - if (!(q->session->dc->flags & 4) && !(q->flags & QUERY_FORCE_SEND)) { - q->session_id = 0; - } - } - return 0; -} - -void tglq_query_restart (struct tgl_state *TLS, long long id) { - struct query *q = tglq_query_get (TLS, id); - if (q) { - TLS->timer_methods->delete (q->ev); - alarm_query (TLS, q); - } -} - -static void alarm_query_gateway (struct tgl_state *TLS, void *arg) { - alarm_query (TLS, arg); -} - - -struct query *tglq_send_query_ex (struct tgl_state *TLS, struct tgl_dc *DC, int ints, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra, int flags) { - assert (DC); - assert (DC->auth_key_id); - if (!DC->sessions[0]) { - tglmp_dc_create_session (TLS, DC); - } - vlogprintf (E_DEBUG, "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port); - struct query *q = talloc0 (sizeof (*q)); - q->data_len = ints; - q->data = talloc (4 * ints); - memcpy (q->data, data, 4 * ints); - q->msg_id = tglmp_encrypt_send_message (TLS, DC->sessions[0]->c, data, ints, 1 | (flags & QUERY_FORCE_SEND)); - q->session = DC->sessions[0]; - q->seq_no = q->session->seq_no - 1; - q->session_id = q->session->session_id; - if (!(DC->flags & 4) && !(flags & QUERY_FORCE_SEND)) { - q->session_id = 0; - } - vlogprintf (E_DEBUG, "Msg_id is %lld %p\n", q->msg_id, q); - q->methods = methods; - q->type = methods->type; - q->DC = DC; - q->flags = flags & QUERY_FORCE_SEND; - if (TLS->queries_tree) { - vlogprintf (E_DEBUG + 2, "%lld %lld\n", q->msg_id, TLS->queries_tree->x->msg_id); - } - TLS->queries_tree = tree_insert_query (TLS->queries_tree, q, lrand48 ()); - - q->ev = TLS->timer_methods->alloc (TLS, alarm_query_gateway, q); - TLS->timer_methods->insert (q->ev, QUERY_TIMEOUT); - - q->extra = extra; - q->callback = callback; - q->callback_extra = callback_extra; - TLS->active_queries ++; - return q; -} - -struct query *tglq_send_query (struct tgl_state *TLS, struct tgl_dc *DC, int ints, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra) { - return tglq_send_query_ex (TLS, DC, ints, data, methods, extra, callback, callback_extra, 0); -} - -static int fail_on_error (struct tgl_state *TLS, struct query *q UU, int error_code UU, int l UU, char *error UU) { - fprintf (stderr, "error #%d: %.*s\n", error_code, l, error); - assert (0); - return 0; -} - -void tglq_query_ack (struct tgl_state *TLS, long long id) { - struct query *q = tglq_query_get (TLS, id); - if (q && !(q->flags & QUERY_ACK_RECEIVED)) { - assert (q->msg_id == id); - q->flags |= QUERY_ACK_RECEIVED; - TLS->timer_methods->delete (q->ev); - } -} - -void tglq_query_error (struct tgl_state *TLS, long long id) { - assert (fetch_int () == CODE_rpc_error); - int error_code = fetch_int (); - int error_len = prefetch_strlen (); - char *error = fetch_str (error_len); - vlogprintf (E_WARNING, "error for query #%lld: #%d :%.*s\n", id, error_code, error_len, error); - struct query *q = tglq_query_get (TLS, id); - if (!q) { - vlogprintf (E_WARNING, "No such query\n"); - } else { - if (!(q->flags & QUERY_ACK_RECEIVED)) { - TLS->timer_methods->delete (q->ev); - } - TLS->queries_tree = tree_delete_query (TLS->queries_tree, q); - int res = 0; - if (q->methods && q->methods->on_error && error_code != 500) { - res = q->methods->on_error (TLS, q, error_code, error_len, error); - } else { - if (error_code == 420 || error_code == 500) { - int wait; - if (error_code == 420) { - if (strncmp (error, "FLOOD_WAIT_", 11)) { - vlogprintf (E_ERROR, "error = '%s'\n", error); - wait = 10; - } else { - wait = atoll (error + 11); - } - } else { - wait = 10; - } - q->flags &= ~QUERY_ACK_RECEIVED; - TLS->timer_methods->insert (q->ev, wait); - q->session_id = 0; - res = 1; - } - } - if (res <= 0) { - tfree (q->data, q->data_len * 4); - TLS->timer_methods->free (q->ev); - } - } - TLS->active_queries --; -} - -#define MAX_PACKED_SIZE (1 << 24) -static int packed_buffer[MAX_PACKED_SIZE / 4]; - -void tglq_query_result (struct tgl_state *TLS, long long id UU) { - vlogprintf (E_DEBUG, "result for query #%lld. Size %ld bytes\n", id, (long)4 * (in_end - in_ptr)); - /*if (verbosity >= 4) { - logprintf ( "result: "); - hexdump_in (); - }*/ - int op = prefetch_int (); - int *end = 0; - int *eend = 0; - if (op == CODE_gzip_packed) { - fetch_int (); - int l = prefetch_strlen (); - char *s = fetch_str (l); - int total_out = tgl_inflate (s, l, packed_buffer, MAX_PACKED_SIZE); - vlogprintf (E_DEBUG, "inflated %d bytes\n", total_out); - end = in_ptr; - eend = in_end; - //assert (total_out % 4 == 0); - in_ptr = packed_buffer; - in_end = in_ptr + total_out / 4; - /*if (verbosity >= 4) { - logprintf ( "Unzipped data: "); - hexdump_in (); - }*/ - } - struct query *q = tglq_query_get (TLS, id); - if (!q) { - //if (verbosity) { - // logprintf ( "No such query\n"); - //} - vlogprintf (E_WARNING, "No such query\n"); - in_ptr = in_end; - } else { - if (!(q->flags & QUERY_ACK_RECEIVED)) { - TLS->timer_methods->delete (q->ev); - } - TLS->queries_tree = tree_delete_query (TLS->queries_tree, q); - if (q->methods && q->methods->on_answer) { - if (q->type) { - int *save = in_ptr; - vlogprintf (E_DEBUG, "in_ptr = %p, end_ptr = %p\n", in_ptr, in_end); - if (skip_type_any (q->type) < 0) { - vlogprintf (E_ERROR, "Skipped %ld int out of %ld (type %s)\n", (long)(in_ptr - save), (long)(in_end - save), q->type->type->id); - assert (0); - } - - assert (in_ptr == in_end); - in_ptr = save; - } - q->methods->on_answer (TLS, q); - assert (in_ptr == in_end); - } - tfree (q->data, 4 * q->data_len); - TLS->timer_methods->free (q->ev); - tfree (q, sizeof (*q)); - - } - if (end) { - in_ptr = end; - in_end = eend; - } - TLS->active_queries --; -} - - -//int max_chat_size; -//int max_bcast_size; -//int want_dc_num; -//int new_dc_num; -//extern struct tgl_dc *DC_list[]; -//extern struct tgl_dc *TLS->DC_working; - -static void out_random (int n) { - assert (n <= 32); - static char buf[32]; - tglt_secure_random (buf, n); - out_cstring (buf, n); -} - -int allow_send_linux_version; -void tgl_do_insert_header (void) { - out_int (CODE_invoke_with_layer18); - //out_int (0x50858a19); - out_int (CODE_init_connection); - out_int (TG_APP_ID); - if (allow_send_linux_version) { - struct utsname st; - uname (&st); - out_string (st.machine); - static char buf[4096]; - tsnprintf (buf, sizeof (buf), "%.999s %.999s %.999s\n", st.sysname, st.release, st.version); - out_string (buf); - out_string (TGL_VERSION " (build " TGL_BUILD ")"); - out_string ("En"); - } else { - out_string ("x86"); - out_string ("Linux"); - out_string (TGL_VERSION); - out_string ("en"); - } -} - -/* {{{ Get config */ - -static void fetch_dc_option (struct tgl_state *TLS) { - 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 (); - - bl_do_dc_option (TLS, id, l1, name, l2, ip, port); -} - -static int help_get_config_on_answer (struct tgl_state *TLS, struct query *q UU) { - unsigned op = fetch_int (); - assert (op == CODE_config || op == CODE_config_old); - fetch_int (); - - unsigned test_mode = fetch_int (); - assert (test_mode == CODE_bool_true || test_mode == CODE_bool_false); - assert (test_mode == CODE_bool_false || test_mode == CODE_bool_true); - int this_dc = fetch_int (); - vlogprintf (E_DEBUG, "this_dc = %d\n", this_dc); - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - assert (n <= 10); - int i; - for (i = 0; i < n; i++) { - fetch_dc_option (TLS); - } - int max_chat_size = fetch_int (); - int max_bcast_size = 0; - if (op == CODE_config) { - max_bcast_size = fetch_int (); - } - vlogprintf (E_DEBUG, "chat_size = %d, bcast_size = %d\n", max_chat_size, max_bcast_size); - - if (q->callback) { - ((void (*)(struct tgl_state *,void *, int))(q->callback))(TLS, q->callback_extra, 1); - } - return 0; -} - -static struct query_methods help_get_config_methods = { - .on_answer = help_get_config_on_answer, - .type = TYPE_TO_PARAM(config) -}; - -void tgl_do_help_get_config (struct tgl_state *TLS, void (*callback)(struct tgl_state *,void *, int), void *callback_extra) { - clear_packet (); - tgl_do_insert_header (); - out_int (CODE_help_get_config); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &help_get_config_methods, 0, callback, callback_extra); -} - -void tgl_do_help_get_config_dc (struct tgl_state *TLS, struct tgl_dc *D, void (*callback)(struct tgl_state *, void *, int), void *callback_extra) { - clear_packet (); - tgl_do_insert_header (); - out_int (CODE_help_get_config); - tglq_send_query_ex (TLS, D, packet_ptr - packet_buffer, packet_buffer, &help_get_config_methods, 0, callback, callback_extra, 2); -} -/* }}} */ - -/* {{{ Send code */ -static int send_code_on_answer (struct tgl_state *TLS, struct query *q UU) { - static char *phone_code_hash; - assert (fetch_int () == (int)CODE_auth_sent_code); - int registered = fetch_bool (); - int l = prefetch_strlen (); - char *s = fetch_str (l); - if (phone_code_hash) { - tfree_str (phone_code_hash); - } - phone_code_hash = tstrndup (s, l); - fetch_int (); - fetch_bool (); - tfree_str (q->extra); - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, int, const char *))(q->callback)) (TLS, q->callback_extra, 1, registered, phone_code_hash); - } - return 0; -} - -static int send_code_on_error (struct tgl_state *TLS, struct query *q UU, int error_code, int l, char *error) { - int s = strlen ("PHONE_MIGRATE_"); - int s2 = strlen ("NETWORK_MIGRATE_"); - int want_dc_num = 0; - if (l >= s && !memcmp (error, "PHONE_MIGRATE_", s)) { - int i = error[s] - '0'; - want_dc_num = i; - } else if (l >= s2 && !memcmp (error, "NETWORK_MIGRATE_", s2)) { - int i = error[s2] - '0'; - want_dc_num = i; - } else { - vlogprintf (E_ERROR, "error_code = %d, error = %.*s\n", error_code, l, error); - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, int, const char *))(q->callback)) (TLS, q->callback_extra, 0, 0, 0); - } - return 0; - } - bl_do_set_working_dc (TLS, want_dc_num); - //if (q->callback) { - // ((void (*)(void *, int, int, const char *))(q->callback)) (q->callback_extra, 0, 0, 0); - //} - assert (TLS->DC_working->id == want_dc_num); - tgl_do_send_code (TLS, q->extra, q->callback, q->callback_extra); - tfree_str (q->extra); - return 0; -} - -static struct query_methods send_code_methods = { - .on_answer = send_code_on_answer, - .on_error = send_code_on_error, - .type = TYPE_TO_PARAM(auth_sent_code) -}; - -//char *suser; -//extern int dc_working_num; -void tgl_do_send_code (struct tgl_state *TLS, const char *user, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int registered, const char *hash), void *callback_extra) { - vlogprintf (E_DEBUG, "sending code to dc %d\n", TLS->dc_working_num); - //suser = tstrdup (user); - clear_packet (); - tgl_do_insert_header (); - out_int (CODE_auth_send_code); - out_string (user); - out_int (0); - out_int (TG_APP_ID); - out_string (TG_APP_HASH); - out_string ("en"); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_code_methods, tstrdup (user), callback, callback_extra); -} - - -static int phone_call_on_answer (struct tgl_state *TLS, struct query *q UU) { - fetch_bool (); - if (q->callback) { - ((void (*)(struct tgl_state *TLS, void *, int))(q->callback))(TLS, q->callback_extra, 1); - } - return 0; -} - -static struct query_methods phone_call_methods = { - .on_answer = phone_call_on_answer, - .type = TYPE_TO_PARAM(bool) -}; - -void tgl_do_phone_call (struct tgl_state *TLS, const char *user, const char *hash,void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra) { - vlogprintf (E_DEBUG, "calling user\n"); - //suser = tstrdup (user); - //want_dc_num = 0; - clear_packet (); - tgl_do_insert_header (); - out_int (CODE_auth_send_call); - out_string (user); - out_string (hash); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &phone_call_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Sign in / Sign up */ -static int sign_in_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_auth_authorization); - int expires = fetch_int (); - vlogprintf (E_DEBUG, "Expires in %d\n", expires); - - struct tgl_user *U = tglf_fetch_alloc_user (TLS); - - TLS->DC_working->has_auth = 1; - - bl_do_dc_signed (TLS, TLS->DC_working->id); - - if (q->callback) { - ((void (*)(struct tgl_state *TLS, void *, int, struct tgl_user *))q->callback) (TLS, q->callback_extra, 1, U); - } - - return 0; -} - -static struct query_methods sign_in_methods = { - .on_answer = sign_in_on_answer, - .type = TYPE_TO_PARAM(auth_authorization) -}; - -int tgl_do_send_code_result (struct tgl_state *TLS, const char *user, const char *hash, const char *code, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *Self), void *callback_extra) { - clear_packet (); - out_int (CODE_auth_sign_in); - out_string (user); - out_string (hash); - out_string (code); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, 0, callback, callback_extra); - return 0; -} - -int tgl_do_send_code_result_auth (struct tgl_state *TLS, const char *user, const char *hash, const char *code, const char *first_name, const char *last_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *Self), void *callback_extra) { - clear_packet (); - out_int (CODE_auth_sign_up); - out_string (user); - out_string (hash); - out_string (code); - out_string (first_name); - out_string (last_name); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &sign_in_methods, 0, callback, callback_extra); - return 0; -} -/* }}} */ - -/* {{{ Get contacts */ -static int get_contacts_on_answer (struct tgl_state *TLS, struct query *q UU) { - int i; - - assert (fetch_int () == (int)CODE_contacts_contacts); - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - for (i = 0; i < n; i++) { - assert (fetch_int () == (int)CODE_contact); - fetch_int (); // id - fetch_int (); // mutual - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - struct tgl_user **list = talloc (sizeof (void *) * n); - for (i = 0; i < n; i++) { - list[i] = tglf_fetch_alloc_user (TLS); - } - if (q->callback) { - ((void (*)(struct tgl_state *TLS, void *, int, int, struct tgl_user **))q->callback) (TLS, q->callback_extra, 1, n, list); - } - tfree (list, sizeof (void *) * n); -/* for (i = 0; i < n; i++) { - struct tgl_user *U = tglf_fetch_alloc_user (TLS); - print_start (); - push_color (COLOR_YELLOW); - printf ("User #%d: ", tgl_get_peer_id (U->id)); - print_user_name (U->id, (tgl_peer_t *)U); - push_color (COLOR_GREEN); - printf (" ("); - printf ("%s", U->print_name); - if (U->phone) { - printf (" "); - printf ("%s", U->phone); - } - printf (") "); - pop_color (); - if (U->status.online > 0) { - printf ("online\n"); - } else { - if (U->status.online < 0) { - printf ("offline. Was online "); - print_date_full (U->status.when); - } else { - printf ("offline permanent"); - } - printf ("\n"); - } - pop_color (); - print_end (); - }*/ - return 0; -} - -static struct query_methods get_contacts_methods = { - .on_answer = get_contacts_on_answer, - .type = TYPE_TO_PARAM(contacts_contacts) -}; - - -void tgl_do_update_contact_list (struct tgl_state *TLS, void (*callback) (struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *contacts[]), void *callback_extra) { - clear_packet (); - out_int (CODE_contacts_get_contacts); - out_string (""); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &get_contacts_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Encrypt decrypted */ -static int *encr_extra; -static int *encr_ptr; -static int *encr_end; - -static char *encrypt_decrypted_message (struct tgl_secret_chat *E) { - static int msg_key[4]; - static unsigned char sha1a_buffer[20]; - static unsigned char sha1b_buffer[20]; - static unsigned char sha1c_buffer[20]; - static unsigned char sha1d_buffer[20]; - int x = *(encr_ptr); - assert (x >= 0 && !(x & 3)); - sha1 ((void *)encr_ptr, 4 + x, sha1a_buffer); - memcpy (msg_key, sha1a_buffer + 4, 16); - - static unsigned char buf[64]; - memcpy (buf, msg_key, 16); - memcpy (buf + 16, E->key, 32); - sha1 (buf, 48, sha1a_buffer); - - memcpy (buf, E->key + 8, 16); - memcpy (buf + 16, msg_key, 16); - memcpy (buf + 32, E->key + 12, 16); - sha1 (buf, 48, sha1b_buffer); - - memcpy (buf, E->key + 16, 32); - memcpy (buf + 32, msg_key, 16); - sha1 (buf, 48, sha1c_buffer); - - memcpy (buf, msg_key, 16); - memcpy (buf + 16, E->key + 24, 32); - sha1 (buf, 48, sha1d_buffer); - - static unsigned char key[32]; - memcpy (key, sha1a_buffer + 0, 8); - memcpy (key + 8, sha1b_buffer + 8, 12); - memcpy (key + 20, sha1c_buffer + 4, 12); - - static unsigned char iv[32]; - memcpy (iv, sha1a_buffer + 8, 12); - memcpy (iv + 12, sha1b_buffer + 0, 8); - memcpy (iv + 20, sha1c_buffer + 16, 4); - memcpy (iv + 24, sha1d_buffer + 0, 8); - - AES_KEY aes_key; - AES_set_encrypt_key (key, 256, &aes_key); - AES_ige_encrypt ((void *)encr_ptr, (void *)encr_ptr, 4 * (encr_end - encr_ptr), &aes_key, iv, 1); - memset (&aes_key, 0, sizeof (aes_key)); - - return (void *)msg_key; -} - -static void encr_start (void) { - encr_extra = packet_ptr; - packet_ptr += 1; // str len - packet_ptr += 2; // fingerprint - packet_ptr += 4; // msg_key - packet_ptr += 1; // len -} - - -static void encr_finish (struct tgl_secret_chat *E) { - int l = packet_ptr - (encr_extra + 8); - while (((packet_ptr - encr_extra) - 3) & 3) { - int t; - tglt_secure_random (&t, 4); - out_int (t); - } - - *encr_extra = ((packet_ptr - encr_extra) - 1) * 4 * 256 + 0xfe; - encr_extra ++; - *(long long *)encr_extra = E->key_fingerprint; - encr_extra += 2; - encr_extra[4] = l * 4; - encr_ptr = encr_extra + 4; - encr_end = packet_ptr; - memcpy (encr_extra, encrypt_decrypted_message (E), 16); -} -/* }}} */ - -void tgl_do_send_encr_chat_layer (struct tgl_state *TLS, struct tgl_secret_chat *E) { - long long t; - tglt_secure_random (&t, 8); - int action[2]; - action[0] = CODE_decrypted_message_action_notify_layer; - action[1] = TGL_ENCRYPTED_LAYER; - bl_do_send_message_action_encr (TLS, t, TLS->our_id, tgl_get_peer_type (E->id), tgl_get_peer_id (E->id), time (0), 2, action); - - struct tgl_message *M = tgl_message_get (TLS, t); - assert (M); - assert (M->action.type == tgl_message_action_notify_layer); - tgl_do_send_msg (TLS, M, 0, 0); - //print_message (M); -} - -void tgl_do_set_encr_chat_ttl (struct tgl_state *TLS, struct tgl_secret_chat *E, int ttl, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - long long t; - tglt_secure_random (&t, 8); - int action[2]; - action[0] = CODE_decrypted_message_action_set_message_t_t_l; - action[1] = ttl; - bl_do_send_message_action_encr (TLS, t, TLS->our_id, tgl_get_peer_type (E->id), tgl_get_peer_id (E->id), time (0), 2, action); - - struct tgl_message *M = tgl_message_get (TLS, t); - assert (M); - assert (M->action.type == tgl_message_action_set_message_ttl); - tgl_do_send_msg (TLS, M, callback, callback_extra); - //print_message (M); -} - -/* {{{ Seng msg (plain text) */ -static int msg_send_encr_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == CODE_messages_sent_encrypted_message); - struct tgl_message *M = q->extra; - //M->date = fetch_int (); - fetch_int (); - if (M->flags & FLAG_PENDING) { - bl_do_set_message_sent (TLS, M); - bl_do_msg_update (TLS, M->id); - } - - if (q->callback) { - ((void (*)(struct tgl_state *TLS, void *, int, struct tgl_message *))q->callback) (TLS, q->callback_extra, 1, M); - } - return 0; -} - -static int msg_send_on_answer (struct tgl_state *TLS, struct query *q UU) { - unsigned x = fetch_int (); - assert (x == CODE_messages_sent_message || x == CODE_messages_sent_message_link); - int id = fetch_int (); // id - long long y = *(long long *)q->extra; - tfree (q->extra, 8); - struct tgl_message *M = tgl_message_get (TLS, y); - if (M && M->id != id) { - bl_do_set_msg_id (TLS, M, id); - } - int date = fetch_int (); - int pts = fetch_int (); - //tglu_fetch_seq (); - //bl_do_ - int seq = fetch_int (); - if (seq == TLS->seq + 1 && !(TLS->locks & TGL_LOCK_DIFF)) { - bl_do_set_date (TLS, date); - bl_do_set_pts (TLS, pts); - bl_do_msg_seq_update (TLS, id); - } else { - if (seq > TLS->seq + 1) { - vlogprintf (E_NOTICE, "Hole in seq\n"); - tgl_do_get_difference (TLS, 0, 0, 0); - } - } - if (x == CODE_messages_sent_message_link) { - assert (skip_type_any (TYPE_TO_PARAM_1 (vector, TYPE_TO_PARAM (contacts_link))) >= 0); - } - /*if (x == CODE_messages_sent_message_link) { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - int i; - unsigned a, b; - for (i = 0; i < n; i++) { - assert (fetch_int () == (int)CODE_contacts_link); - a = fetch_int (); - assert (a == CODE_contacts_my_link_empty || a == CODE_contacts_my_link_requested || a == CODE_contacts_my_link_contact); - if (a == CODE_contacts_my_link_requested) { - fetch_bool (); - } - b = fetch_int (); - assert (b == CODE_contacts_foreign_link_unknown || b == CODE_contacts_foreign_link_requested || b == CODE_contacts_foreign_link_mutual); - if (b == CODE_contacts_foreign_link_requested) { - fetch_bool (); - } - struct tgl_user *U = tglf_fetch_alloc_user (TLS); - - U->flags &= ~(FLAG_USER_IN_CONTACT | FLAG_USER_OUT_CONTACT); - if (a == CODE_contacts_my_link_contact) { - U->flags |= FLAG_USER_IN_CONTACT; - } - U->flags &= ~(FLAG_USER_IN_CONTACT | FLAG_USER_OUT_CONTACT); - if (b == CODE_contacts_foreign_link_mutual) { - U->flags |= FLAG_USER_IN_CONTACT | FLAG_USER_OUT_CONTACT; - } - if (b == CODE_contacts_foreign_link_requested) { - U->flags |= FLAG_USER_OUT_CONTACT; - } - print_start (); - push_color (COLOR_YELLOW); - printf ("Link with user "); - print_user_name (U->id, (void *)U); - printf (" changed\n"); - pop_color (); - print_end (); - } - }*/ - if (M->flags & FLAG_PENDING) { - bl_do_set_message_sent (TLS, M); - } - if (q->callback) { - ((void (*)(struct tgl_state *,void *, int, struct tgl_message *))q->callback) (TLS, q->callback_extra, 1, M); - } - return 0; -} - -static int msg_send_on_error (struct tgl_state *TLS, struct query *q, int error_code, int error_len, char *error) { - //vlogprintf (E_WARNING, "error for query #%lld: #%d :%.*s\n", q->msg_id, error_code, error_len, error); - if (error_code == 420) { - assert (!strncmp (error, "FLOOD_WAIT_", 11)); - int wait = atoll (error + 11); - q->flags &= ~QUERY_ACK_RECEIVED; - - TLS->timer_methods->insert (q->ev, wait); - q->session_id = 0; - return 1; - } - long long x = *(long long *)q->extra; - tfree (q->extra, 8); - struct tgl_message *M = tgl_message_get (TLS, x); - if (q->callback) { - ((void (*)(struct tgl_state *,void *, int, struct tgl_message *))q->callback) (TLS, q->callback_extra, 0, M); - } - if (M) { - bl_do_delete_msg (TLS, M); - } - return 0; -} - -static struct query_methods msg_send_methods = { - .on_answer = msg_send_on_answer, - .on_error = msg_send_on_error, - .type = TYPE_TO_PARAM(messages_sent_message) -}; - -static struct query_methods msg_send_encr_methods = { - .on_answer = msg_send_encr_on_answer, - .type = TYPE_TO_PARAM(messages_sent_encrypted_message) -}; - -//int out_message_num; - -void tgl_do_send_encr_msg_action (struct tgl_state *TLS, struct tgl_message *M, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - tgl_peer_t *P = tgl_peer_get (TLS, M->to_id); - if (!P || P->encr_chat.state != sc_ok) { - vlogprintf (E_WARNING, "Unknown encrypted chat\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - - clear_packet (); - out_int (CODE_messages_send_encrypted_service); - out_int (CODE_input_encrypted_chat); - out_int (tgl_get_peer_id (M->to_id)); - out_long (P->encr_chat.access_hash); - out_long (M->id); - encr_start (); - if (P->encr_chat.layer <= 16) { - out_int (CODE_decrypted_message_service_l16); - } else { - out_int (CODE_decrypted_message_layer); - out_random (15 + 4 * (lrand48 () % 3)); - out_int (TGL_ENCRYPTED_LAYER); - out_int (2 * P->encr_chat.in_seq_no + (P->encr_chat.admin_id != TLS->our_id)); - out_int (2 * P->encr_chat.out_seq_no + (P->encr_chat.admin_id == TLS->our_id) - 2); - out_int (CODE_decrypted_message_service); - } - out_long (M->id); - if (P->encr_chat.layer < 17) { - out_random (15 + 4 * (lrand48 () % 3)); - } - - switch (M->action.type) { - case tgl_message_action_notify_layer: - out_int (CODE_decrypted_message_action_notify_layer); - out_int (M->action.layer); - break; - case tgl_message_action_set_message_ttl: - out_int (CODE_decrypted_message_action_set_message_t_t_l); - out_int (M->action.ttl); - break; - default: - assert (0); - } - encr_finish (&P->encr_chat); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_encr_methods, M, callback, callback_extra); -} - -void tgl_do_send_encr_msg (struct tgl_state *TLS, struct tgl_message *M, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - if (M->service) { - tgl_do_send_encr_msg_action (TLS, M, callback, callback_extra); - return; - } - tgl_peer_t *P = tgl_peer_get (TLS, M->to_id); - if (!P || P->encr_chat.state != sc_ok) { - vlogprintf (E_WARNING, "Unknown encrypted chat\n"); - if (callback) { - callback (TLS, callback_extra, 0, M); - } - return; - } - - clear_packet (); - out_int (CODE_messages_send_encrypted); - out_int (CODE_input_encrypted_chat); - out_int (tgl_get_peer_id (M->to_id)); - out_long (P->encr_chat.access_hash); - out_long (M->id); - encr_start (); - if (P->encr_chat.layer <= 16) { - out_int (CODE_decrypted_message_service_l16); - } else { - out_int (CODE_decrypted_message_layer); - out_random (15 + 4 * (lrand48 () % 3)); - out_int (TGL_ENCRYPTED_LAYER); - out_int (2 * P->encr_chat.in_seq_no + (P->encr_chat.admin_id != TLS->our_id)); - out_int (2 * P->encr_chat.out_seq_no + (P->encr_chat.admin_id == TLS->our_id) - 2); - out_int (CODE_decrypted_message); - } - out_long (M->id); - if (P->encr_chat.layer < 17) { - out_random (15 + 4 * (lrand48 () % 3)); - } else { - out_int (0); - } - out_cstring ((void *)M->message, M->message_len); - out_int (CODE_decrypted_message_media_empty); - encr_finish (&P->encr_chat); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_encr_methods, M, callback, callback_extra); -} - -void tgl_do_send_msg (struct tgl_state *TLS, struct tgl_message *M, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - if (tgl_get_peer_type (M->to_id) == TGL_PEER_ENCR_CHAT) { - tgl_do_send_encr_msg (TLS, M, callback, callback_extra); - return; - } - clear_packet (); - out_int (CODE_messages_send_message); - out_peer_id (TLS, M->to_id); - out_cstring (M->message, M->message_len); - out_long (M->id); - long long *x = talloc (8); - *x = M->id; - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_methods, x, callback, callback_extra); -} - -void tgl_do_send_message (struct tgl_state *TLS, tgl_peer_id_t id, const char *msg, int len, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT) { - tgl_peer_t *P = tgl_peer_get (TLS, id); - if (!P) { - vlogprintf (E_WARNING, "Unknown encrypted chat\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - if (P->encr_chat.state != sc_ok) { - vlogprintf (E_WARNING, "Chat is not yet initialized\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - } - long long t; - tglt_secure_random (&t, 8); - vlogprintf (E_DEBUG, "t = %lld, len = %d\n", t, len); - bl_do_send_message_text (TLS, t, TLS->our_id, tgl_get_peer_type (id), tgl_get_peer_id (id), time (0), len, msg); - struct tgl_message *M = tgl_message_get (TLS, t); - assert (M); - tgl_do_send_msg (TLS, M, callback, callback_extra); - //print_message (M); -} -/* }}} */ - -/* {{{ Send text file */ -void tgl_do_send_text (struct tgl_state *TLS, tgl_peer_id_t id, char *file_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - int fd = open (file_name, O_RDONLY); - if (fd < 0) { - vlogprintf (E_WARNING, "No such file '%s'\n", file_name); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - static char buf[(1 << 20) + 1]; - int x = read (fd, buf, (1 << 20) + 1); - assert (x >= 0); - if (x == (1 << 20) + 1) { - vlogprintf (E_WARNING, "Too big file '%s'\n", file_name); - close (fd); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - } else { - buf[x] = 0; - tgl_do_send_message (TLS, id, buf, x, callback, callback_extra); - //tfree_str (file_name); - close (fd); - } -} -/* }}} */ - -/* {{{ Mark read */ -void tgl_do_messages_mark_read (struct tgl_state *TLS, tgl_peer_id_t id, int max_id, int offset, void (*callback)(struct tgl_state *TLS, void *callback_extra, int), void *callback_extra); -static int mark_read_on_receive (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_messages_affected_history); - //tglu_fetch_pts (); - int pts = fetch_int (); - //tglu_fetch_seq (); - int seq = fetch_int (); // seq - - if (seq == TLS->seq + 1 && !(TLS->locks & TGL_LOCK_DIFF)) { - bl_do_set_pts (TLS, pts); - bl_do_set_seq (TLS, seq); - } else { - if (seq > TLS->seq + 1) { - vlogprintf (E_NOTICE, "Hole in seq\n"); - tgl_do_get_difference (TLS, 0, 0, 0); - } - } - - int offset = fetch_int (); // offset - int *t = q->extra; - if (offset > 0) { - tgl_do_messages_mark_read (TLS, tgl_set_peer_id (t[0], t[1]), t[2], offset, q->callback, q->callback_extra); - } else { - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback)(TLS, q->callback_extra, 1); - } - } - tfree (t, 12); - return 0; -} - -static int mark_read_encr_on_receive (struct tgl_state *TLS, struct query *q UU) { - fetch_bool (); - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback)(TLS, q->callback_extra, 1); - } - return 0; -} - -static struct query_methods mark_read_methods = { - .on_answer = mark_read_on_receive, - .type = TYPE_TO_PARAM(messages_affected_history) -}; - -static struct query_methods mark_read_encr_methods = { - .on_answer = mark_read_encr_on_receive, - .type = TYPE_TO_PARAM(bool) -}; - -void tgl_do_messages_mark_read (struct tgl_state *TLS, tgl_peer_id_t id, int max_id, int offset, void (*callback)(struct tgl_state *TLS, void *callback_extra, int), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_read_history); - out_peer_id (TLS, id); - out_int (max_id); - out_int (offset); - out_int (CODE_bool_true); - int *t = talloc (12); - t[0] = tgl_get_peer_type (id); - t[1] = tgl_get_peer_id (id); - t[2] = max_id; - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &mark_read_methods, t, callback, callback_extra); -} - -void tgl_do_messages_mark_read_encr (struct tgl_state *TLS, tgl_peer_id_t id, long long access_hash, int last_time, void (*callback)(struct tgl_state *TLS, void *callback_extra, int), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_read_encrypted_history); - out_int (CODE_input_encrypted_chat); - out_int (tgl_get_peer_id (id)); - out_long (access_hash); - out_int (last_time); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &mark_read_encr_methods, 0, callback, callback_extra); -} - -void tgl_do_mark_read (struct tgl_state *TLS, tgl_peer_id_t id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra) { - if (tgl_get_peer_type (id) == TGL_PEER_USER || tgl_get_peer_type (id) == TGL_PEER_CHAT) { - tgl_do_messages_mark_read (TLS, id, 0, 0, callback, callback_extra); - return; - } - tgl_peer_t *P = tgl_peer_get (TLS, id); - if (!P) { - vlogprintf (E_WARNING, "Unknown peer\n"); - callback (TLS, callback_extra, 0); - return; - } - assert (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT); - if (P->last) { - tgl_do_messages_mark_read_encr (TLS, id, P->encr_chat.access_hash, P->last->date, callback, callback_extra); - } else { - tgl_do_messages_mark_read_encr (TLS, id, P->encr_chat.access_hash, 0, callback, callback_extra); - } -} -/* }}} */ - -/* {{{ Get history */ -void _tgl_do_get_history (struct tgl_state *TLS, tgl_peer_id_t id, int limit, int offset, int max_id, int list_offset, int list_size, struct tgl_message *ML[], void (*callback)(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra); -static int get_history_on_answer (struct tgl_state *TLS, struct query *q UU) { - int count = -1; - int i; - int x = fetch_int (); - assert (x == (int)CODE_messages_messages_slice || x == (int)CODE_messages_messages); - if (x == (int)CODE_messages_messages_slice) { - count = fetch_int (); - //fetch_int (); - } - assert (fetch_int () == CODE_vector); - void **T = q->extra; - struct tgl_message **ML = T[0]; - int list_offset = (long)T[1]; - int list_size = (long)T[2]; - tgl_peer_id_t id = tgl_set_peer_id ((long)T[4], (long)T[3]); - int limit = (long)T[5]; - int offset = (long)T[6]; - tfree (T, sizeof (void *) * 7); - - int n = fetch_int (); - - if (list_size - list_offset < n) { - int new_list_size = 2 * list_size; - if (new_list_size - list_offset < n) { - new_list_size = n + list_offset; - } - ML = trealloc (ML, list_size * sizeof (void *), new_list_size * sizeof (void *)); - assert (ML); - list_size = new_list_size; - } - //struct tgl_message **ML = talloc (sizeof (void *) * n); - for (i = 0; i < n; i++) { - ML[i + list_offset] = tglf_fetch_alloc_message (TLS); - } - list_offset += n; - offset += n; - limit -= n; - if (count >= 0 && limit + offset >= count) { - limit = count - offset; - if (limit < 0) { limit = 0; } - } - assert (limit >= 0); - - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_chat (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - - - if (limit <= 0 || x == (int)CODE_messages_messages) { - if (q->callback) { - ((void (*)(struct tgl_state *TLS, void *, int, int, struct tgl_message **))q->callback) (TLS, q->callback_extra, 1, list_offset, ML); - } - if (list_offset > 0) { - tgl_do_messages_mark_read (TLS, id, ML[0]->id, 0, 0, 0); - } - - - tfree (ML, sizeof (void *) * list_size); - } else { - _tgl_do_get_history (TLS, id, limit, 0, ML[list_offset - 1]->id, list_offset, list_size, ML, q->callback, q->callback_extra); - } - return 0; -} - -static struct query_methods get_history_methods = { - .on_answer = get_history_on_answer, - .type = TYPE_TO_PARAM(messages_messages) -}; - -void tgl_do_get_local_history (struct tgl_state *TLS, tgl_peer_id_t id, int limit, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) { - tgl_peer_t *P = tgl_peer_get (TLS, id); - if (!P || !P->last) { - if (callback) { - callback (TLS, callback_extra, 0, 0, 0); - } - return; - } - struct tgl_message *M = P->last; - int count = 1; - assert (!M->prev); - while (count < limit && M->next) { - M = M->next; - count ++; - } - struct tgl_message **ML = talloc (sizeof (void *) * count); - M = P->last; - ML[0] = M; - count = 1; - while (count < limit && M->next) { - M = M->next; - ML[count ++] = M; - } - - if (callback) { - callback (TLS, callback_extra, 1, count, ML); - } - tfree (ML, sizeof (void *) * count); -} - -void tgl_do_get_local_history_ext (struct tgl_state *TLS, tgl_peer_id_t id, int offset, int limit, void (*callback)(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) { - tgl_peer_t *P = tgl_peer_get (TLS, id); - if (!P || !P->last) { - if (callback) { - callback (TLS, callback_extra, 0, 0, 0); - } - return; - } - struct tgl_message *M = P->last; - int count = 1; - assert (!M->prev); - while (count < limit + offset && M->next) { - M = M->next; - count ++; - } - if (count <= offset) { - if (callback) { - callback (TLS, callback_extra, 1, 0, 0); - } - return; - } - struct tgl_message **ML = talloc (sizeof (void *) * (count - offset)); - M = P->last; - ML[0] = M; - count = 1; - while (count < limit && M->next) { - M = M->next; - if (count >= offset) { - ML[count - offset] = M; - } - count ++; - } - - if (callback) { - callback (TLS, callback_extra, 1, count - offset, ML); - } - tfree (ML, sizeof (void *) * (count) - offset); -} - - - -void _tgl_do_get_history (struct tgl_state *TLS, tgl_peer_id_t id, int limit, int offset, int max_id, int list_offset, int list_size, struct tgl_message *ML[], void (*callback)(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) { - void **T = talloc (sizeof (void *) * 7); - T[0] = ML; - T[1] = (void *)(long)list_offset; - T[2] = (void *)(long)list_size; - T[3] = (void *)(long)tgl_get_peer_id (id); - T[4] = (void *)(long)tgl_get_peer_type (id); - T[5] = (void *)(long)limit; - T[6] = (void *)(long)offset; - - clear_packet (); - out_int (CODE_messages_get_history); - out_peer_id (TLS, id); - out_int (offset); - out_int (max_id); - out_int (limit); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &get_history_methods, T, callback, callback_extra); -} - -void tgl_do_get_history (struct tgl_state *TLS, tgl_peer_id_t id, int limit, int offline_mode, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) { - if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT || offline_mode) { - tgl_do_get_local_history (TLS, id, limit, callback, callback_extra); - tgl_do_mark_read (TLS, id, 0, 0); - return; - } - _tgl_do_get_history (TLS, id, limit, 0, 0, 0, 0, 0, callback, callback_extra); -} - -void tgl_do_get_history_ext (struct tgl_state *TLS, tgl_peer_id_t id, int offset, int limit, int offline_mode, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) { - if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT || offline_mode) { - tgl_do_get_local_history (TLS, id, limit, callback, callback_extra); - tgl_do_mark_read (TLS, id, 0, 0); - return; - } - _tgl_do_get_history (TLS, id, limit, offset, 0, 0, 0, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Get dialogs */ -static int get_dialogs_on_answer (struct tgl_state *TLS, struct query *q UU) { - unsigned x = fetch_int (); - assert (x == CODE_messages_dialogs || x == CODE_messages_dialogs_slice); - if (x == CODE_messages_dialogs_slice) { - fetch_int (); // total_count - } - assert (fetch_int () == CODE_vector); - int n, i; - n = fetch_int (); - int dl_size = n; - - tgl_peer_id_t *PL = talloc0 (sizeof (tgl_peer_id_t) * n); - int *UC = talloc0 (4 * n); - int *LM = talloc0 (4 * n); - for (i = 0; i < n; i++) { - assert (fetch_int () == (int)CODE_dialog); - PL[i] = tglf_fetch_peer_id (TLS); - LM[i] = fetch_int (); - UC[i] = fetch_int (); - assert (skip_type_any (TYPE_TO_PARAM (peer_notify_settings)) >= 0); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_message (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_chat (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - /*print_start (); - push_color (COLOR_YELLOW); - for (i = dl_size - 1; i >= 0; i--) { - tgl_peer_t *UC; - switch (tgl_get_peer_type (plist[i])) { - case TGL_PEER_USER: - UC = tgl_peer_get (TLS, plist[i]); - printf ("User "); - print_user_name (plist[i], UC); - printf (": %d unread\n", dlist[2 * i + 1]); - break; - case TGL_PEER_CHAT: - UC = tgl_peer_get (TLS, plist[i]); - printf ("Chat "); - print_chat_name (plist[i], UC); - printf (": %d unread\n", dlist[2 * i + 1]); - break; - } - } - pop_color (); - print_end (); - - dialog_list_got = 1;*/ - - if (q->callback) { - ((void (*)(struct tgl_state *TLS, void *, int, int, tgl_peer_id_t *, int *, int *))q->callback) (TLS, q->callback_extra, 1, dl_size, PL, LM, UC); - } - tfree (PL, sizeof (tgl_peer_id_t) * dl_size); - tfree (UC, 4 * dl_size); - tfree (LM, 4 * dl_size); - - return 0; -} - -static struct query_methods get_dialogs_methods = { - .on_answer = get_dialogs_on_answer, - .type = TYPE_TO_PARAM(messages_dialogs) -}; - - -void tgl_do_get_dialog_list (struct tgl_state *TLS, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[]), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_get_dialogs); - out_int (0); - out_int (0); - out_int (1000); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dialogs_methods, 0, callback, callback_extra); -} -/* }}} */ - -int allow_send_linux_version = 1; - -/* {{{ Send photo/video file */ -struct send_file { - int fd; - long long size; - long long offset; - int part_num; - int part_size; - long long id; - long long thumb_id; - tgl_peer_id_t to_id; - unsigned media_type; - char *file_name; - int encr; - int avatar; - unsigned char *iv; - unsigned char *init_iv; - unsigned char *key; -}; - -static void out_peer_id (struct tgl_state *TLS, tgl_peer_id_t id) { - tgl_peer_t *U; - switch (tgl_get_peer_type (id)) { - case TGL_PEER_CHAT: - out_int (CODE_input_peer_chat); - out_int (tgl_get_peer_id (id)); - break; - case TGL_PEER_USER: - U = tgl_peer_get (TLS, id); - if (U && U->user.access_hash) { - out_int (CODE_input_peer_foreign); - out_int (tgl_get_peer_id (id)); - out_long (U->user.access_hash); - } else { - out_int (CODE_input_peer_contact); - out_int (tgl_get_peer_id (id)); - } - break; - default: - assert (0); - } -} - -static void send_part (struct tgl_state *TLS, struct send_file *f, void *callback, void *callback_extra); -static int send_file_part_on_answer (struct tgl_state *TLS, struct query *q) { - assert (fetch_int () == (int)CODE_bool_true); - send_part (TLS, q->extra, q->callback, q->callback_extra); - return 0; -} - -static int send_file_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_messages_stated_message); - struct tgl_message *M = tglf_fetch_alloc_message (TLS); - assert (fetch_int () == CODE_vector); - int n, i; - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_chat (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - //tglu_fetch_pts (); - int pts = fetch_int (); - //tglu_fetch_seq (); - - int seq = fetch_int (); - if (seq == TLS->seq + 1 && !(TLS->locks & TGL_LOCK_DIFF)) { - bl_do_set_pts (TLS, pts); - bl_do_msg_seq_update (TLS, M->id); - } else { - if (seq > TLS->seq + 1) { - vlogprintf (E_NOTICE, "Hole in seq\n"); - tgl_do_get_difference (TLS, 0, 0, 0); - } - } - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_message *))q->callback)(TLS, q->callback_extra, 1, M); - } - //print_message (M); - return 0; -} - -static int send_encr_file_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_messages_sent_encrypted_file); - struct tgl_message *M = q->extra; - //M->date = fetch_int (); - fetch_int (); - int *save = in_ptr; - - assert (skip_type_any (TYPE_TO_PARAM (encrypted_file)) >= 0); - - //print_message (M); - if (M->flags & FLAG_PENDING) { - bl_do_create_message_media_encr_sent (TLS, M->id, save, in_ptr - save); - //bl_do_set_message_sent (M); - bl_do_msg_update (TLS, M->id); - } - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_message *))q->callback)(TLS, q->callback_extra, 1, M); - } - return 0; -} - -static int set_photo_on_answer (struct tgl_state *TLS, struct query *q) { - assert (skip_type_any (TYPE_TO_PARAM(photos_photo)) >= 0); - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback)(TLS, q->callback_extra, 1); - } - return 0; -} - -static struct query_methods send_file_part_methods = { - .on_answer = send_file_part_on_answer, - .type = TYPE_TO_PARAM(bool) -}; - -static struct query_methods send_file_methods = { - .on_answer = send_file_on_answer, - .type = TYPE_TO_PARAM(messages_stated_message) -}; - -static struct query_methods set_photo_methods = { - .on_answer = set_photo_on_answer, - .type = TYPE_TO_PARAM(photos_photo) -}; - -static struct query_methods send_encr_file_methods = { - .on_answer = send_encr_file_on_answer, - .type = TYPE_TO_PARAM(messages_sent_encrypted_message) -}; - -static void send_part (struct tgl_state *TLS, struct send_file *f, void *callback, void *callback_extra) { - if (f->fd >= 0) { - if (!f->part_num) { - TLS->cur_uploading_bytes += f->size; - } - clear_packet (); - if (f->size < (16 << 20)) { - out_int (CODE_upload_save_file_part); - out_long (f->id); - out_int (f->part_num ++); - } else { - out_int (CODE_upload_save_big_file_part); - out_long (f->id); - out_int (f->part_num ++); - out_int ((f->size + f->part_size - 1) / f->part_size); - } - static char buf[512 << 10]; - int x = read (f->fd, buf, f->part_size); - assert (x > 0); - f->offset += x; - TLS->cur_uploaded_bytes += x; - - if (f->encr) { - if (x & 15) { - assert (f->offset == f->size); - tglt_secure_random (buf + x, (-x) & 15); - x = (x + 15) & ~15; - } - - AES_KEY aes_key; - AES_set_encrypt_key (f->key, 256, &aes_key); - AES_ige_encrypt ((void *)buf, (void *)buf, x, &aes_key, f->iv, 1); - memset (&aes_key, 0, sizeof (aes_key)); - } - out_cstring (buf, x); - vlogprintf (E_DEBUG, "offset=%lld size=%lld\n", f->offset, f->size); - if (f->offset == f->size) { - close (f->fd); - f->fd = -1; - } else { - assert (f->part_size == x); - } - //update_prompt (); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f, callback, callback_extra); - } else { - TLS->cur_uploaded_bytes -= f->size; - TLS->cur_uploading_bytes -= f->size; - //update_prompt (); - clear_packet (); - assert (f->media_type == CODE_input_media_uploaded_photo || f->media_type == CODE_input_media_uploaded_video || f->media_type == CODE_input_media_uploaded_thumb_video || f->media_type == CODE_input_media_uploaded_audio || f->media_type == CODE_input_media_uploaded_document || f->media_type == CODE_input_media_uploaded_thumb_document); - if (f->avatar) { - assert (!f->encr); - if (f->avatar > 0) { - out_int (CODE_messages_edit_chat_photo); - out_int (f->avatar); - out_int (CODE_input_chat_uploaded_photo); - if (f->size < (16 << 20)) { - out_int (CODE_input_file); - } else { - out_int (CODE_input_file_big); - } - out_long (f->id); - out_int (f->part_num); - /*char *s = f->file_name + strlen (f->file_name); - while (s >= f->file_name && *s != '/') { s --;} - out_string (s + 1);*/ - out_string (""); - if (f->size < (16 << 20)) { - out_string (""); - } - out_int (CODE_input_photo_crop_auto); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_methods, 0, callback, callback_extra); - } else { - out_int (CODE_photos_upload_profile_photo); - if (f->size < (16 << 20)) { - out_int (CODE_input_file); - } else { - out_int (CODE_input_file_big); - } - out_long (f->id); - out_int (f->part_num); - char *s = f->file_name + strlen (f->file_name); - while (s >= f->file_name && *s != '/') { s --;} - out_string (s + 1); - if (f->size < (16 << 20)) { - out_string (""); - } - out_string ("profile photo"); - out_int (CODE_input_geo_point_empty); - out_int (CODE_input_photo_crop_auto); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &set_photo_methods, 0, callback, callback_extra); - } - } else if (!f->encr) { - out_int (CODE_messages_send_media); - out_peer_id (TLS, f->to_id); - out_int (f->media_type); - if (f->size < (16 << 20)) { - out_int (CODE_input_file); - } else { - out_int (CODE_input_file_big); - } - out_long (f->id); - out_int (f->part_num); - char *s = f->file_name + strlen (f->file_name); - while (s >= f->file_name && *s != '/') { s --;} - out_string (s + 1); - if (f->size < (16 << 20)) { - out_string (""); - } - if (f->media_type == CODE_input_media_uploaded_thumb_video || f->media_type == CODE_input_media_uploaded_thumb_document) { - out_int (CODE_input_file); - out_long (f->thumb_id); - out_int (1); - out_string ("thumb.jpg"); - out_string (""); - } - if (f->media_type == CODE_input_media_uploaded_video || f->media_type == CODE_input_media_uploaded_thumb_video) { - out_int (100); - out_int (100); - out_int (100); - out_string ("video"); - } - if (f->media_type == CODE_input_media_uploaded_document || f->media_type == CODE_input_media_uploaded_thumb_document) { - out_string (s + 1); - out_string ("text"); - } - if (f->media_type == CODE_input_media_uploaded_audio) { - out_int (60); - out_string ("audio"); - } - - long long r; - tglt_secure_random (&r, 8); - out_long (r); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_methods, 0, callback, callback_extra); - } else { - //struct tgl_message *M = talloc0 (sizeof (*M)); - - out_int (CODE_messages_send_encrypted_file); - out_int (CODE_input_encrypted_chat); - out_int (tgl_get_peer_id (f->to_id)); - tgl_peer_t *P = tgl_peer_get (TLS, f->to_id); - assert (P); - out_long (P->encr_chat.access_hash); - long long r; - tglt_secure_random (&r, 8); - out_long (r); - encr_start (); - if (P->encr_chat.layer <= 16) { - out_int (CODE_decrypted_message_service_l16); - } else { - out_int (CODE_decrypted_message_layer); - out_random (15 + 4 * (lrand48 () % 3)); - out_int (TGL_ENCRYPTED_LAYER); - out_int (2 * P->encr_chat.in_seq_no + (P->encr_chat.admin_id != TLS->our_id)); - out_int (2 * P->encr_chat.out_seq_no + (P->encr_chat.admin_id == TLS->our_id)); - out_int (CODE_decrypted_message); - } - out_long (r); - if (P->encr_chat.layer < 17) { - out_random (15 + 4 * (lrand48 () % 3)); - } else { - out_int (0); - } - out_string (""); - int *save_ptr = packet_ptr; - if (f->media_type == CODE_input_media_uploaded_photo) { - out_int (CODE_decrypted_message_media_photo); - //M->media.type = CODE_decrypted_message_media_photo; - } else if (f->media_type == CODE_input_media_uploaded_video) { - out_int (CODE_decrypted_message_media_video); - //M->media.type = CODE_decrypted_message_media_video; - } else if (f->media_type == CODE_input_media_uploaded_audio) { - out_int (CODE_decrypted_message_media_audio); - //M->media.type = CODE_decrypted_message_media_audio; - } else if (f->media_type == CODE_input_media_uploaded_document) { - out_int (CODE_decrypted_message_media_document); - //M->media.type = CODE_decrypted_message_media_document;; - } else { - assert (0); - } - if (f->media_type != CODE_input_media_uploaded_audio) { - out_cstring ((void *)thumb_file, thumb_file_size); - out_int (90); - out_int (90); - } - if (f->media_type == CODE_input_media_uploaded_video) { - out_int (0); - out_string ("video"); - } - if (f->media_type == CODE_input_media_uploaded_document) { - out_string (f->file_name); - out_string ("text"); - } - if (f->media_type == CODE_input_media_uploaded_audio) { - out_int (60); - out_string ("audio"); - } - if (f->media_type == CODE_input_media_uploaded_video || f->media_type == CODE_input_media_uploaded_photo) { - out_int (100); - out_int (100); - } - out_int (f->size); - out_cstring ((void *)f->key, 32); - out_cstring ((void *)f->init_iv, 32); - - bl_do_create_message_media_encr_pending (TLS, r, TLS->our_id, tgl_get_peer_type (f->to_id), tgl_get_peer_id (f->to_id), time (0), 0, 0, save_ptr, packet_ptr - save_ptr); - - encr_finish (&P->encr_chat); - if (f->size < (16 << 20)) { - out_int (CODE_input_encrypted_file_uploaded); - } else { - out_int (CODE_input_encrypted_file_big_uploaded); - } - out_long (f->id); - out_int (f->part_num); - if (f->size < (16 << 20)) { - out_string (""); - } - - unsigned char md5[16]; - unsigned char str[64]; - memcpy (str, f->key, 32); - memcpy (str + 32, f->init_iv, 32); - MD5 (str, 64, md5); - out_int ((*(int *)md5) ^ (*(int *)(md5 + 4))); - - tfree_secure (f->iv, 32); - struct tgl_message *M = tgl_message_get (TLS, r); - assert (M); - - //M->media.encr_photo.key = f->key; - //M->media.encr_photo.iv = f->init_iv; - //M->media.encr_photo.key_fingerprint = (*(int *)md5) ^ (*(int *)(md5 + 4)); - //M->media.encr_photo.size = f->size; - - //M->flags = FLAG_ENCRYPTED; - //M->from_id = TGL_MK_USER (TLS->our_id); - //M->to_id = f->to_id; - //M->unread = 1; - //M->message = tstrdup (""); - //M->out = 1; - //M->id = r; - //M->date = time (0); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_file_methods, M, callback, callback_extra); - } - tfree_str (f->file_name); - tfree (f, sizeof (*f)); - } -} - -/*void send_file_thumb (struct send_file *f, void *callback, void *callback_extra) { - clear_packet (); - f->thumb_id = lrand48 () * (1ll << 32) + lrand48 (); - out_int (CODE_upload_save_file_part); - out_long (f->thumb_id); - out_int (0); - out_cstring ((void *)thumb_file, thumb_file_size); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f, callback, callback_extra); -}*/ - -void _tgl_do_send_photo (struct tgl_state *TLS, enum tgl_message_media_type type, tgl_peer_id_t to_id, char *file_name, int avatar, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - int fd = open (file_name, O_RDONLY); - if (fd < 0) { - vlogprintf (E_WARNING, "No such file '%s'\n", file_name); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - struct stat buf; - fstat (fd, &buf); - long long size = buf.st_size; - if (size <= 0) { - vlogprintf (E_WARNING, "File has zero length\n"); - close (fd); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - struct send_file *f = talloc0 (sizeof (*f)); - f->fd = fd; - f->size = size; - f->offset = 0; - f->part_num = 0; - f->avatar = avatar; - int tmp = ((size + 2999) / 3000); - f->part_size = (1 << 14); - while (f->part_size < tmp) { - f->part_size *= 2; - } - - if (f->part_size > (512 << 10)) { - close (fd); - vlogprintf (E_WARNING, "Too big file. Maximal supported size is %d.\n", (512 << 10) * 1000); - tfree (f, sizeof (*f)); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - - tglt_secure_random (&f->id, 8); - f->to_id = to_id; - switch (type) { - case tgl_message_media_photo: - f->media_type = CODE_input_media_uploaded_photo; - break; - case tgl_message_media_video: - f->media_type = CODE_input_media_uploaded_video; - break; - case tgl_message_media_audio: - f->media_type = CODE_input_media_uploaded_audio; - break; - case tgl_message_media_document: - f->media_type = CODE_input_media_uploaded_document; - break; - default: - close (fd); - vlogprintf (E_WARNING, "Unknown type %d.\n", type); - tfree (f, sizeof (*f)); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - f->file_name = tstrdup (file_name); - if (tgl_get_peer_type (f->to_id) == TGL_PEER_ENCR_CHAT) { - f->encr = 1; - f->iv = talloc (32); - tglt_secure_random (f->iv, 32); - f->init_iv = talloc (32); - memcpy (f->init_iv, f->iv, 32); - f->key = talloc (32); - tglt_secure_random (f->key, 32); - } - /*if (f->media_type == CODE_input_media_uploaded_video && !f->encr) { - f->media_type = CODE_input_media_uploaded_thumb_video; - send_file_thumb (f); - } else if (f->media_type == CODE_input_media_uploaded_document && !f->encr) { - f->media_type = CODE_input_media_uploaded_thumb_document; - send_file_thumb (f); - } else { - send_part (f); - }*/ - send_part (TLS, f, callback, callback_extra); -} - -void tgl_do_send_photo (struct tgl_state *TLS, enum tgl_message_media_type type, tgl_peer_id_t to_id, char *file_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - _tgl_do_send_photo (TLS, type, to_id, file_name, 0, callback, callback_extra); -} - -void tgl_do_set_chat_photo (struct tgl_state *TLS, tgl_peer_id_t chat_id, char *file_name, void (*callback)(struct tgl_state *TLS,void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - assert (tgl_get_peer_type (chat_id) == TGL_PEER_CHAT); - _tgl_do_send_photo (TLS, tgl_message_media_photo, chat_id, file_name, tgl_get_peer_id (chat_id), callback, callback_extra); -} - -void tgl_do_set_profile_photo (struct tgl_state *TLS, char *file_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra) { - _tgl_do_send_photo (TLS, tgl_message_media_photo, TGL_MK_USER(TLS->our_id), file_name, -1, (void *)callback, callback_extra); -} -/* }}} */ - -/* {{{ Profile name */ - -int set_profile_name_on_answer (struct tgl_state *TLS, struct query *q) { - struct tgl_user *U = tglf_fetch_alloc_user (TLS); - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_user *))q->callback) (TLS, q->callback_extra, 1, U); - } - return 0; -} - -static struct query_methods set_profile_name_methods = { - .on_answer = set_profile_name_on_answer, - .type = TYPE_TO_PARAM(user) -}; - -void tgl_do_set_profile_name (struct tgl_state *TLS, char *first_name, char *last_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U), void *callback_extra) { - clear_packet (); - out_int (CODE_account_update_profile); - out_string (first_name); - out_string (last_name); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &set_profile_name_methods, 0, callback, callback_extra); -} - -void tgl_do_set_username (struct tgl_state *TLS, char *name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U), void *callback_extra) { - clear_packet (); - out_int (CODE_account_update_username); - out_string (name); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &set_profile_name_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Contacts search */ - -int contact_search_on_answer (struct tgl_state *TLS, struct query *q) { - assert (fetch_int () == CODE_contacts_found); - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - int i; - for (i = 0; i < n; i++) { - assert (fetch_int () == (int)CODE_contact_found); - fetch_int (); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - - struct tgl_user **UL = talloc (sizeof (void *) * n); - for (i = 0; i < n; i++) { - UL[i] = tglf_fetch_alloc_user (TLS); - } - - if (q->callback) { - ((void (*)(struct tgl_state *,void *, int, int, struct tgl_user **))q->callback) (TLS, q->callback_extra, 1, n, UL); - } - tfree (UL, sizeof (void *) * n); - return 0; -} - -static struct query_methods contact_search_methods = { - .on_answer = contact_search_on_answer, - .type = TYPE_TO_PARAM(contacts_found) -}; - -void tgl_do_contact_search (struct tgl_state *TLS, char *name, int limit, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int cnt, struct tgl_user *U[]), void *callback_extra) { - clear_packet (); - out_int (CODE_contacts_search); - out_string (name); - out_int (limit); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &contact_search_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Forward */ -static int fwd_msg_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_messages_stated_message); - struct tgl_message *M = tglf_fetch_alloc_message (TLS); - assert (fetch_int () == CODE_vector); - int n, i; - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_chat (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - //tglu_fetch_pts (); - int pts = fetch_int (); - - int seq = fetch_int (); - if (seq == TLS->seq + 1 && !(TLS->locks & TGL_LOCK_DIFF)) { - bl_do_set_pts (TLS, pts); - bl_do_msg_seq_update (TLS, M->id); - } else { - if (seq > TLS->seq + 1) { - vlogprintf (E_NOTICE, "Hole in seq\n"); - tgl_do_get_difference (TLS, 0, 0, 0); - } - } - //print_message (M); - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_message *))q->callback) (TLS, q->callback_extra, 1, M); - } - return 0; -} - -static struct query_methods fwd_msg_methods = { - .on_answer = fwd_msg_on_answer, - .type = TYPE_TO_PARAM(messages_stated_message) -}; - -void tgl_do_forward_message (struct tgl_state *TLS, tgl_peer_id_t id, int n, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT) { - vlogprintf (E_WARNING, "Can not forward messages from secret chat\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - clear_packet (); - out_int (CODE_messages_forward_message); - out_peer_id (TLS, id); - out_int (n); - long long r; - tglt_secure_random (&r, 8); - out_long (r); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &fwd_msg_methods, 0, callback, callback_extra); -} - -void tgl_do_send_contact (struct tgl_state *TLS, 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)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT) { - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - long long t; - tglt_secure_random (&t, 8); - vlogprintf (E_DEBUG, "t = %lld\n", t); - - clear_packet (); - out_int (CODE_messages_send_media); - out_peer_id (TLS, id); - out_int (CODE_input_media_contact); - out_cstring (phone, phone_len); - out_cstring (first_name, first_name_len); - out_cstring (last_name, last_name_len); - out_long (t); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &fwd_msg_methods, 0, callback, callback_extra); -} - -void tgl_do_forward_media (struct tgl_state *TLS, tgl_peer_id_t id, int n, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT) { - vlogprintf (E_WARNING, "Can not forward messages from secret chat\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - struct tgl_message *M = tgl_message_get (TLS, n); - if (!M) { - vlogprintf (E_WARNING, "No such message\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - if (M->flags & FLAG_ENCRYPTED) { - vlogprintf (E_WARNING, "Can not forward media from encrypted message\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - if (M->media.type != tgl_message_media_photo && M->media.type != tgl_message_media_video && M->media.type != tgl_message_media_audio && M->media.type != tgl_message_media_document) { - vlogprintf (E_WARNING, "Can only forward photo/audio/video/document\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - clear_packet (); - out_int (CODE_messages_send_media); - out_peer_id (TLS, id); - switch (M->media.type) { - case tgl_message_media_photo: - out_int (CODE_input_media_photo); - out_int (CODE_input_photo); - out_long (M->media.photo.id); - out_long (M->media.photo.access_hash); - break; - case tgl_message_media_video: - out_int (CODE_input_media_video); - out_int (CODE_input_video); - out_long (M->media.video.id); - out_long (M->media.video.access_hash); - break; - case tgl_message_media_audio: - out_int (CODE_input_media_audio); - out_int (CODE_input_audio); - out_long (M->media.audio.id); - out_long (M->media.audio.access_hash); - break; - case tgl_message_media_document: - out_int (CODE_input_media_document); - out_int (CODE_input_document); - out_long (M->media.document.id); - out_long (M->media.document.access_hash); - break; - default: - assert (0); - } - long long r; - tglt_secure_random (&r, 8); - out_long (r); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &fwd_msg_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Send location */ - -void tgl_do_send_location(struct tgl_state *TLS, tgl_peer_id_t id, double latitude, double longitude, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT) { - clear_packet (); - out_int (CODE_messages_send_encrypted); - out_int (CODE_input_encrypted_chat); - out_int (tgl_get_peer_id (id)); - tgl_peer_t *P = tgl_peer_get (TLS, id); - assert (P); - out_long (P->encr_chat.access_hash); - - long long r; - tglt_secure_random (&r, 8); - out_long (r); - encr_start (); - if (P->encr_chat.layer <= 16) { - out_int (CODE_decrypted_message_service_l16); - } else { - out_int (CODE_decrypted_message_layer); - out_random (15 + 4 * (lrand48 () % 3)); - out_int (TGL_ENCRYPTED_LAYER); - out_int (2 * P->encr_chat.in_seq_no + (P->encr_chat.admin_id != TLS->our_id)); - out_int (2 * P->encr_chat.out_seq_no + (P->encr_chat.admin_id == TLS->our_id)); - out_int (CODE_decrypted_message); - } - out_long (r); - if (P->encr_chat.layer < 17) { - out_random (15 + 4 * (lrand48 () % 3)); - } else { - out_int (0); - } - out_string (""); - int *save_ptr = packet_ptr; - out_int (CODE_decrypted_message_media_geo_point); - out_double (latitude); - out_double (longitude); - - bl_do_create_message_media_encr_pending (TLS, r, TLS->our_id, tgl_get_peer_type (id), tgl_get_peer_id (id), time (0), 0, 0, save_ptr, packet_ptr - save_ptr); - - encr_finish (&P->encr_chat); - - struct tgl_message *M = tgl_message_get (TLS, r); - assert (M); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_send_encr_methods, M, callback, callback_extra); - } else { - long long t; - tglt_secure_random (&t, 8); - vlogprintf (E_DEBUG, "t = %lld\n", t); - - clear_packet (); - out_int (CODE_messages_send_media); - out_peer_id (TLS, id); - out_int (CODE_input_media_geo_point); - out_int (CODE_input_geo_point); - out_double (latitude); - out_double (longitude); - out_long (t); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &fwd_msg_methods, 0, callback, callback_extra); - } -} -/* }}} */ - -/* {{{ Rename chat */ -static int rename_chat_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_messages_stated_message); - struct tgl_message *M = tglf_fetch_alloc_message (TLS); - assert (fetch_int () == CODE_vector); - int n, i; - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_chat (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - //tglu_fetch_pts (); - int pts = fetch_int (); - - int seq = fetch_int (); - if (seq == TLS->seq + 1 && !(TLS->locks & TGL_LOCK_DIFF)) { - bl_do_set_pts (TLS, pts); - bl_do_msg_seq_update (TLS, M->id); - } else { - if (seq > TLS->seq + 1) { - vlogprintf (E_NOTICE, "Hole in seq\n"); - tgl_do_get_difference (TLS, 0, 0, 0); - } - } - //print_message (M); - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_message *))q->callback) (TLS, q->callback_extra, 1, M); - } - return 0; -} - -static struct query_methods rename_chat_methods = { - .on_answer = rename_chat_on_answer, - .type = TYPE_TO_PARAM(messages_stated_message) -}; - -void tgl_do_rename_chat (struct tgl_state *TLS, tgl_peer_id_t id, char *name UU, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_edit_chat_title); - assert (tgl_get_peer_type (id) == TGL_PEER_CHAT); - out_int (tgl_get_peer_id (id)); - out_string (name); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &rename_chat_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Chat info */ -/*void print_chat_info (struct tgl_chat *C) { - tgl_peer_t *U = (void *)C; - print_start (); - push_color (COLOR_YELLOW); - printf ("Chat "); - print_chat_name (U->id, U); - printf (" members:\n"); - int i; - for (i = 0; i < C->user_list_size; i++) { - printf ("\t\t"); - print_user_name (TGL_MK_USER (C->user_list[i].user_id), tgl_peer_get (TLS, TGL_MK_USER (C->user_list[i].user_id))); - printf (" invited by "); - print_user_name (TGL_MK_USER (C->user_list[i].inviter_id), tgl_peer_get (TLS, TGL_MK_USER (C->user_list[i].inviter_id))); - printf (" at "); - print_date_full (C->user_list[i].date); - if (C->user_list[i].user_id == C->admin_id) { - printf (" admin"); - } - printf ("\n"); - } - pop_color (); - print_end (); -}*/ - -static int chat_info_on_answer (struct tgl_state *TLS, struct query *q UU) { - struct tgl_chat *C = tglf_fetch_alloc_chat_full (TLS); - //print_chat_info (C); - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_chat *))q->callback) (TLS, q->callback_extra, 1, C); - } - return 0; -} - -static struct query_methods chat_info_methods = { - .on_answer = chat_info_on_answer, - .type = TYPE_TO_PARAM(messages_chat_full) -}; - -void tgl_do_get_chat_info (struct tgl_state *TLS, tgl_peer_id_t id, int offline_mode, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *C), void *callback_extra) { - if (offline_mode) { - tgl_peer_t *C = tgl_peer_get (TLS, id); - if (!C) { - vlogprintf (E_WARNING, "No such chat\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - } else { - //print_chat_info (&C->chat); - if (callback) { - callback (TLS, callback_extra, 1, &C->chat); - } - } - return; - } - clear_packet (); - out_int (CODE_messages_get_full_chat); - assert (tgl_get_peer_type (id) == TGL_PEER_CHAT); - out_int (tgl_get_peer_id (id)); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &chat_info_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ User info */ - -/*void print_user_info (struct tgl_user *U) { - tgl_peer_t *C = (void *)U; - print_start (); - push_color (COLOR_YELLOW); - printf ("User "); - print_user_name (U->id, C); - printf (":\n"); - printf ("\treal name: %s %s\n", U->real_first_name, U->real_last_name); - printf ("\tphone: %s\n", U->phone); - if (U->status.online > 0) { - printf ("\tonline\n"); - } else { - printf ("\toffline (was online "); - print_date_full (U->status.when); - printf (")\n"); - } - pop_color (); - print_end (); -}*/ - -static int user_info_on_answer (struct tgl_state *TLS, struct query *q UU) { - struct tgl_user *U = tglf_fetch_alloc_user_full (TLS); - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_user *))q->callback) (TLS, q->callback_extra, 1, U); - } - return 0; -} - -static struct query_methods user_info_methods = { - .on_answer = user_info_on_answer, - .type = TYPE_TO_PARAM(user_full) -}; - -void tgl_do_get_user_info (struct tgl_state *TLS, tgl_peer_id_t id, int offline_mode, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U), void *callback_extra) { - if (offline_mode) { - tgl_peer_t *C = tgl_peer_get (TLS, id); - if (!C) { - vlogprintf (E_WARNING, "No such user\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - } else { - if (callback) { - callback (TLS, callback_extra, 1, &C->user); - } - } - return; - } - clear_packet (); - out_int (CODE_users_get_full_user); - assert (tgl_get_peer_type (id) == TGL_PEER_USER); - tgl_peer_t *U = tgl_peer_get (TLS, id); - if (U && U->user.access_hash) { - out_int (CODE_input_user_foreign); - out_int (tgl_get_peer_id (id)); - out_long (U->user.access_hash); - } else { - out_int (CODE_input_user_contact); - out_int (tgl_get_peer_id (id)); - } - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &user_info_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Get user info silently */ -/*int user_list_info_silent_on_answer (struct query *q UU) { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - int i; - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - return 0; -} - -struct query_methods user_list_info_silent_methods = { - .on_answer = user_list_info_silent_on_answer, - .type = TYPE_TO_PARAM_1(vector, TYPE_TO_PARAM(user)) -}; - -void tgl_do_get_user_list_info_silent (int num, int *list) { - clear_packet (); - out_int (CODE_users_get_users); - out_int (CODE_vector); - out_int (num); - int i; - for (i = 0; i < num; i++) { - out_int (CODE_input_user_contact); - out_int (list[i]); - //out_long (0); - } - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &user_list_info_silent_methods, 0); -}*/ -/* }}} */ - -/* {{{ Load photo/video */ -struct download { - int offset; - int size; - long long volume; - long long secret; - long long access_hash; - int local_id; - int dc; - int next; - int fd; - char *name; - long long id; - unsigned char *iv; - unsigned char *key; - int type; - int refcnt; -}; - - -static void end_load (struct tgl_state *TLS, struct download *D, void *callback, void *callback_extra) { - TLS->cur_downloading_bytes -= D->size; - TLS->cur_downloaded_bytes -= D->size; - //update_prompt (); - close (D->fd); - /*if (D->next == 1) { - logprintf ("Done: %s\n", D->name); - } else if (D->next == 2) { - static char buf[PATH_MAX]; - if (tsnprintf (buf, sizeof (buf), OPEN_BIN, D->name) >= (int) sizeof (buf)) { - logprintf ("Open image command buffer overflow\n"); - } else { - int x = system (buf); - if (x < 0) { - logprintf ("Can not open image viewer: %m\n"); - logprintf ("Image is at %s\n", D->name); - } - } - }*/ - - if (callback) { - ((void (*)(struct tgl_state *, void *, int, char *))callback) (TLS, callback_extra, 1, D->name); - } - - if (D->iv) { - tfree_secure (D->iv, 32); - } - tfree_str (D->name); - tfree (D, sizeof (*D)); -} - -static void load_next_part (struct tgl_state *TLS, struct download *D, void *callback, void *callback_extra); -static int download_on_answer (struct tgl_state *TLS, struct query *q) { - assert (fetch_int () == (int)CODE_upload_file); - unsigned x = fetch_int (); - assert (x); - struct download *D = q->extra; - if (D->fd == -1) { - D->fd = open (D->name, O_CREAT | O_WRONLY, 0640); - if (D->fd < 0) { - vlogprintf (E_ERROR, "Can not open for writing: %m\n"); - assert (D->fd >= 0); - } - } - fetch_int (); // mtime - int len = prefetch_strlen (); - assert (len >= 0); - TLS->cur_downloaded_bytes += len; - //update_prompt (); - if (D->iv) { - unsigned char *ptr = (void *)fetch_str (len); - assert (!(len & 15)); - AES_KEY aes_key; - AES_set_decrypt_key (D->key, 256, &aes_key); - AES_ige_encrypt (ptr, ptr, len, &aes_key, D->iv, 0); - memset (&aes_key, 0, sizeof (aes_key)); - if (len > D->size - D->offset) { - len = D->size - D->offset; - } - assert (write (D->fd, ptr, len) == len); - } else { - assert (write (D->fd, fetch_str (len), len) == len); - } - D->offset += len; - D->refcnt --; - if (D->offset < D->size) { - load_next_part (TLS, D, q->callback, q->callback_extra); - return 0; - } else { - if (!D->refcnt) { - end_load (TLS, D, q->callback, q->callback_extra); - } - return 0; - } -} - -static struct query_methods download_methods = { - .on_answer = download_on_answer, - .type = TYPE_TO_PARAM(upload_file) -}; - -static void load_next_part (struct tgl_state *TLS, struct download *D, void *callback, void *callback_extra) { - if (!D->offset) { - static char buf[PATH_MAX]; - int l; - if (!D->id) { - l = tsnprintf (buf, sizeof (buf), "%s/download_%lld_%d.jpg", TLS->downloads_directory, D->volume, D->local_id); - } else { - l = tsnprintf (buf, sizeof (buf), "%s/download_%lld", TLS->downloads_directory, D->id); - } - if (l >= (int) sizeof (buf)) { - vlogprintf (E_ERROR, "Download filename is too long"); - exit (1); - } - D->name = tstrdup (buf); - struct stat st; - if (stat (buf, &st) >= 0) { - D->offset = st.st_size; - if (D->offset >= D->size) { - TLS->cur_downloading_bytes += D->size; - TLS->cur_downloaded_bytes += D->offset; - vlogprintf (E_NOTICE, "Already downloaded\n"); - end_load (TLS, D, callback, callback_extra); - return; - } - } - - TLS->cur_downloading_bytes += D->size; - TLS->cur_downloaded_bytes += D->offset; - //update_prompt (); - } - D->refcnt ++; - clear_packet (); - out_int (CODE_upload_get_file); - if (!D->id) { - out_int (CODE_input_file_location); - out_long (D->volume); - out_int (D->local_id); - out_long (D->secret); - } else { - if (D->iv) { - out_int (CODE_input_encrypted_file_location); - } else { - out_int (D->type); - } - out_long (D->id); - out_long (D->access_hash); - } - out_int (D->offset); - out_int (1 << 14); - tglq_send_query (TLS, TLS->DC_list[D->dc], packet_ptr - packet_buffer, packet_buffer, &download_methods, D, callback, callback_extra); - //tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &download_methods, D); -} - -void tgl_do_load_photo_size (struct tgl_state *TLS, struct tgl_photo_size *P, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra) { - if (!P->loc.dc) { - vlogprintf (E_WARNING, "Bad video thumb\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - - assert (P); - struct download *D = talloc0 (sizeof (*D)); - D->id = 0; - D->offset = 0; - D->size = P->size; - D->volume = P->loc.volume; - D->dc = P->loc.dc; - D->local_id = P->loc.local_id; - D->secret = P->loc.secret; - D->name = 0; - D->fd = -1; - load_next_part (TLS, D, callback, callback_extra); -} - -void tgl_do_load_photo (struct tgl_state *TLS, struct tgl_photo *photo, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra) { - if (!photo->sizes_num) { - vlogprintf (E_WARNING, "No sizes\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - int max = -1; - int maxi = 0; - int i; - for (i = 0; i < photo->sizes_num; i++) { - if (photo->sizes[i].w + photo->sizes[i].h > max) { - max = photo->sizes[i].w + photo->sizes[i].h; - maxi = i; - } - } - tgl_do_load_photo_size (TLS, &photo->sizes[maxi], callback, callback_extra); -} - -void tgl_do_load_video_thumb (struct tgl_state *TLS, struct tgl_video *video, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra) { - tgl_do_load_photo_size (TLS, &video->thumb, callback, callback_extra); -} - -void tgl_do_load_document_thumb (struct tgl_state *TLS, struct tgl_document *video, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra) { - tgl_do_load_photo_size (TLS, &video->thumb, callback, callback_extra); -} - -void tgl_do_load_video (struct tgl_state *TLS, struct tgl_video *V, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra) { - assert (V); - struct download *D = talloc0 (sizeof (*D)); - D->offset = 0; - D->size = V->size; - D->id = V->id; - D->access_hash = V->access_hash; - D->dc = V->dc_id; - D->name = 0; - D->fd = -1; - D->type = CODE_input_video_file_location; - load_next_part (TLS, D, callback, callback_extra); -} - -void tgl_do_load_audio (struct tgl_state *TLS, struct tgl_audio *V, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra) { - assert (V); - struct download *D = talloc0 (sizeof (*D)); - D->offset = 0; - D->size = V->size; - D->id = V->id; - D->access_hash = V->access_hash; - D->dc = V->dc_id; - D->name = 0; - D->fd = -1; - D->type = CODE_input_audio_file_location; - load_next_part (TLS, D, callback, callback_extra); -} - -void tgl_do_load_document (struct tgl_state *TLS, struct tgl_document *V, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra) { - assert (V); - struct download *D = talloc0 (sizeof (*D)); - D->offset = 0; - D->size = V->size; - D->id = V->id; - D->access_hash = V->access_hash; - D->dc = V->dc_id; - D->name = 0; - D->fd = -1; - D->type = CODE_input_document_file_location; - load_next_part (TLS, D, callback, callback_extra); -} - -void tgl_do_load_encr_video (struct tgl_state *TLS, struct tgl_encr_video *V, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra) { - assert (V); - struct download *D = talloc0 (sizeof (*D)); - D->offset = 0; - D->size = V->size; - D->id = V->id; - D->access_hash = V->access_hash; - D->dc = V->dc_id; - D->name = 0; - D->fd = -1; - D->key = V->key; - D->iv = talloc (32); - memcpy (D->iv, V->iv, 32); - load_next_part (TLS, D, callback, callback_extra); - - unsigned char md5[16]; - unsigned char str[64]; - memcpy (str, V->key, 32); - memcpy (str + 32, V->iv, 32); - MD5 (str, 64, md5); - assert (V->key_fingerprint == ((*(int *)md5) ^ (*(int *)(md5 + 4)))); -} -/* }}} */ - -/* {{{ Export auth */ - -static int import_auth_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_auth_authorization); - fetch_int (); // expires - tglf_fetch_alloc_user (TLS); - - bl_do_dc_signed (TLS, ((struct tgl_dc *)q->extra)->id); - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback) (TLS, q->callback_extra, 1); - } - return 0; -} - -static struct query_methods import_auth_methods = { - .on_answer = import_auth_on_answer, - .on_error = fail_on_error, - .type = TYPE_TO_PARAM(auth_authorization) -}; - -static int export_auth_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_auth_exported_authorization); - bl_do_set_our_id (TLS, fetch_int ()); - int l = prefetch_strlen (); - char *s = talloc (l); - memcpy (s, fetch_str (l), l); - - clear_packet (); - tgl_do_insert_header (); - out_int (CODE_auth_import_authorization); - out_int (TLS->our_id); - out_cstring (s, l); - tglq_send_query (TLS, q->extra, packet_ptr - packet_buffer, packet_buffer, &import_auth_methods, q->extra, q->callback, q->callback_extra); - tfree (s, l); - return 0; -} - -static struct query_methods export_auth_methods = { - .on_answer = export_auth_on_answer, - .on_error = fail_on_error, - .type = TYPE_TO_PARAM(auth_exported_authorization) -}; - -void tgl_do_export_auth (struct tgl_state *TLS, int num, void (*callback) (struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra) { - clear_packet (); - out_int (CODE_auth_export_authorization); - out_int (num); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &export_auth_methods, TLS->DC_list[num], callback, callback_extra); -} -/* }}} */ - -/* {{{ Add contact */ -static int add_contact_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_contacts_imported_contacts); - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - if (n > 0) { - vlogprintf (E_DEBUG, "Added successfully"); - } else { - vlogprintf (E_DEBUG, "Not added"); - } - int i; - for (i = 0; i < n ; i++) { - assert (fetch_int () == (int)CODE_imported_contact); - fetch_int (); // uid - fetch_long (); // client_id - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - long long id = fetch_long (); - vlogprintf (E_NOTICE, "contact #%lld not added. Please retry\n", id); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - - struct tgl_user **UL = talloc (n * sizeof (void *)); - for (i = 0; i < n; i++) { - UL[i] = tglf_fetch_alloc_user (TLS); - } - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, int, struct tgl_user **))q->callback) (TLS, q->callback_extra, 1, n, UL); - } - tfree (UL, n * sizeof (void *)); - return 0; -} - -static struct query_methods add_contact_methods = { - .on_answer = add_contact_on_answer, - .type = TYPE_TO_PARAM(contacts_imported_contacts) -}; - -void tgl_do_add_contact (struct tgl_state *TLS, 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)(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_user *users[]), void *callback_extra) { - clear_packet (); - out_int (CODE_contacts_import_contacts); - out_int (CODE_vector); - out_int (1); - out_int (CODE_input_phone_contact); - long long r; - tglt_secure_random (&r, 8); - out_long (r); - out_cstring (phone, phone_len); - out_cstring (first_name, first_name_len); - out_cstring (last_name, last_name_len); - out_int (force ? CODE_bool_true : CODE_bool_false); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &add_contact_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Add contact */ -static int del_contact_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (skip_type_contacts_link (TYPE_TO_PARAM(contacts_link)) >= 0); - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback) (TLS, q->callback_extra, 1); - } - return 0; -} - -static struct query_methods del_contact_methods = { - .on_answer = del_contact_on_answer, - .type = TYPE_TO_PARAM(contacts_link) -}; - -void tgl_do_del_contact (struct tgl_state *TLS, tgl_peer_id_t id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra) { - if (tgl_get_peer_type (id) != TGL_PEER_USER) { - if (callback) { - callback (TLS, callback_extra, 0); - } - return; - } - clear_packet (); - out_int (CODE_contacts_delete_contact); - - tgl_peer_t *U = tgl_peer_get (TLS, id); - if (U && U->user.access_hash) { - out_int (CODE_input_user_foreign); - out_int (tgl_get_peer_id (id)); - out_long (U->user.access_hash); - } else { - out_int (CODE_input_user_contact); - out_int (tgl_get_peer_id (id)); - } - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &del_contact_methods, 0, callback, callback_extra); -} - /* }}} */ - -/* {{{ Msg search */ -void _tgl_do_msg_search (struct tgl_state *TLS, tgl_peer_id_t id, int from, int to, int limit, int offset, int max_id, char *s, int list_offset, int list_size, struct tgl_message **list, void (*callback)(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra); -static int msg_search_on_answer (struct tgl_state *TLS, struct query *q UU) { - int count = -1; - int i; - int x = fetch_int (); - assert (x == (int)CODE_messages_messages_slice || x == (int)CODE_messages_messages); - if (x == (int)CODE_messages_messages_slice) { - count = fetch_int (); - //fetch_int (); - } - assert (fetch_int () == CODE_vector); - void **T = q->extra; - struct tgl_message **ML = T[0]; - int list_offset = (long)T[1]; - int list_size = (long)T[2]; - tgl_peer_id_t id = tgl_set_peer_id ((long)T[4], (long)T[3]); - int limit = (long)T[5]; - int offset = (long)T[6]; - int from = (long)T[7]; - int to = (long)T[8]; - char *s = T[9]; - tfree (T, sizeof (void *) * 10); - - int n = fetch_int (); - - if (list_size - list_offset < n) { - int new_list_size = 2 * list_size; - if (new_list_size - list_offset < n) { - new_list_size = n + list_offset; - } - ML = trealloc (ML, list_size * sizeof (void *), new_list_size * sizeof (void *)); - assert (ML); - list_size = new_list_size; - } - //struct tgl_message **ML = talloc (sizeof (void *) * n); - for (i = 0; i < n; i++) { - ML[i + list_offset] = tglf_fetch_alloc_message (TLS); - } - list_offset += n; - offset += n; - limit -= n; - if (count >= 0 && limit + offset >= count) { - limit = count - offset; - if (limit < 0) { limit = 0; } - } - assert (limit >= 0); - - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_chat (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - - - if (limit <= 0 || x == (int)CODE_messages_messages) { - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, int, struct tgl_message **))q->callback) (TLS, q->callback_extra, 1, list_offset, ML); - } - - tfree_str (s); - tfree (ML, sizeof (void *) * list_size); - } else { - _tgl_do_msg_search (TLS, id, from, to, limit, 0, ML[list_offset - 1]->id, s, list_offset, list_size, ML, q->callback, q->callback_extra); - } - return 0; -} - -static struct query_methods msg_search_methods = { - .on_answer = msg_search_on_answer, - .type = TYPE_TO_PARAM(messages_messages) -}; - -void _tgl_do_msg_search (struct tgl_state *TLS, tgl_peer_id_t id, int from, int to, int limit, int offset, int max_id, char *s, int list_offset, int list_size, struct tgl_message **list, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) { - if (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT) { - vlogprintf (E_WARNING, "Can not search in secure chat\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0, 0); - } - return; - } - clear_packet (); - out_int (CODE_messages_search); - if (tgl_get_peer_type (id) == TGL_PEER_UNKNOWN) { - out_int (CODE_input_peer_empty); - } else { - out_peer_id (TLS, id); - } - void **T = talloc (sizeof (void *) * 10); - T[0] = list; - T[1] = (void *)(long)list_offset; - T[2] = (void *)(long)list_size; - T[3] = (void *)(long)tgl_get_peer_id (id); - T[4] = (void *)(long)tgl_get_peer_type (id); - T[5] = (void *)(long)limit; - T[6] = (void *)(long)offset; - T[7] = (void *)(long)from; - T[8] = (void *)(long)to; - T[9] = s; - - out_string (s); - out_int (CODE_input_messages_filter_empty); - out_int (from); - out_int (to); - out_int (offset); // offset - out_int (max_id); // max_id - out_int (limit); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &msg_search_methods, T, callback, callback_extra); -} - -void tgl_do_msg_search (struct tgl_state *TLS, tgl_peer_id_t id, int from, int to, int limit, int offset, const char *s, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra) { - _tgl_do_msg_search (TLS, id, from, to, limit, offset, 0, tstrdup (s), 0, 0, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Contacts search */ -static int contacts_search_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == CODE_contacts_found); - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - int i; - for (i = 0; i < n; i++) { - assert (fetch_int () == (int)CODE_contact_found); - fetch_int (); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - - struct tgl_user **UL = talloc (sizeof (void *) * n); - for (i = 0; i < n; i++) { - UL[i] = tglf_fetch_alloc_user (TLS); - } - /*print_start (); - push_color (COLOR_YELLOW); - for (i = 0; i < n; i++) { - struct tgl_user *U = tglf_fetch_alloc_user (TLS); - printf ("User "); - push_color (COLOR_RED); - printf ("%s %s", U->first_name, U->last_name); - pop_color (); - printf (". Phone %s\n", U->phone); - } - pop_color (); - print_end ();*/ - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, int, struct tgl_user **))q->callback) (TLS, q->callback_extra, 1, n, UL); - } - tfree (UL, sizeof (void *) * n); - return 0; -} - -static struct query_methods contacts_search_methods = { - .on_answer = contacts_search_on_answer, - .type = TYPE_TO_PARAM(contacts_found) -}; - -void tgl_do_contacts_search (struct tgl_state *TLS, int limit, const char *s, void (*callback) (struct tgl_state *, void *callback_extra, int success, int size, struct tgl_user *users[]), void *callback_extra) { - clear_packet (); - out_int (CODE_contacts_search); - out_string (s); - out_int (limit); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &contacts_search_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Encr accept */ -static int send_encr_accept_on_answer (struct tgl_state *TLS, struct query *q UU) { - struct tgl_secret_chat *E = tglf_fetch_alloc_encrypted_chat (TLS); - - /*if (E->state == sc_ok) { - print_start (); - push_color (COLOR_YELLOW); - printf ("Encrypted connection with "); - print_encr_chat_name (E->id, (void *)E); - printf (" established\n"); - pop_color (); - print_end (); - } else { - print_start (); - push_color (COLOR_YELLOW); - printf ("Encrypted connection with "); - print_encr_chat_name (E->id, (void *)E); - printf (" failed\n"); - pop_color (); - print_end (); - }*/ - - if (E->state == sc_ok) { - tgl_do_send_encr_chat_layer (TLS, E); - } - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_secret_chat *))q->callback) (TLS, q->callback_extra, E->state == sc_ok, E); - } - return 0; -} - -static int send_encr_request_on_answer (struct tgl_state *TLS, struct query *q UU) { - struct tgl_secret_chat *E = tglf_fetch_alloc_encrypted_chat (TLS); - /*if (E->state == sc_deleted) { - print_start (); - push_color (COLOR_YELLOW); - printf ("Encrypted connection with "); - print_encr_chat_name (E->id, (void *)E); - printf (" can not be established\n"); - pop_color (); - print_end (); - } else { - print_start (); - push_color (COLOR_YELLOW); - printf ("Establishing connection with "); - print_encr_chat_name (E->id, (void *)E); - printf ("\n"); - pop_color (); - print_end (); - - assert (E->state == sc_waiting); - }*/ - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_secret_chat *))q->callback) (TLS, q->callback_extra, E->state != sc_deleted, E); - } - return 0; -} - -static struct query_methods send_encr_accept_methods = { - .on_answer = send_encr_accept_on_answer, - .type = TYPE_TO_PARAM(encrypted_chat) -}; - -static struct query_methods send_encr_request_methods = { - .on_answer = send_encr_request_on_answer, - .type = TYPE_TO_PARAM(encrypted_chat) -}; - -//int encr_root; -//unsigned char *encr_prime; -//int encr_param_version; -//static BN_CTX *ctx; - -void tgl_do_send_accept_encr_chat (struct tgl_state *TLS, struct tgl_secret_chat *E, unsigned char *random, void (*callback)(struct tgl_state *TLS,void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) { - int i; - int ok = 0; - for (i = 0; i < 64; i++) { - if (E->key[i]) { - ok = 1; - break; - } - } - if (ok) { - if (callback) { - callback (TLS, callback_extra, 1, E); - } - return; - } // Already generated key for this chat - assert (E->g_key); - assert (TLS->BN_ctx); - unsigned char random_here[256]; - tglt_secure_random (random_here, 256); - for (i = 0; i < 256; i++) { - random[i] ^= random_here[i]; - } - BIGNUM *b = BN_bin2bn (random, 256, 0); - ensure_ptr (b); - BIGNUM *g_a = BN_bin2bn (E->g_key, 256, 0); - ensure_ptr (g_a); - assert (tglmp_check_g (TLS, TLS->encr_prime, g_a) >= 0); - //if (!ctx) { - // ctx = BN_CTX_new (); - // ensure_ptr (ctx); - //} - BIGNUM *p = BN_bin2bn (TLS->encr_prime, 256, 0); - ensure_ptr (p); - BIGNUM *r = BN_new (); - ensure_ptr (r); - ensure (BN_mod_exp (r, g_a, b, p, TLS->BN_ctx)); - static unsigned char kk[256]; - memset (kk, 0, sizeof (kk)); - BN_bn2bin (r, kk + (256 - BN_num_bytes (r))); - for (i = 0; i < 256; i++) { - kk[i] ^= E->nonce[i]; - } - static unsigned char sha_buffer[20]; - sha1 (kk, 256, sha_buffer); - - bl_do_encr_chat_set_key (TLS, E, kk, *(long long *)(sha_buffer + 12)); - - clear_packet (); - out_int (CODE_messages_accept_encryption); - out_int (CODE_input_encrypted_chat); - out_int (tgl_get_peer_id (E->id)); - out_long (E->access_hash); - - ensure (BN_set_word (g_a, TLS->encr_root)); - ensure (BN_mod_exp (r, g_a, b, p, TLS->BN_ctx)); - static unsigned char buf[256]; - memset (buf, 0, sizeof (buf)); - BN_bn2bin (r, buf + (256 - BN_num_bytes (r))); - out_cstring ((void *)buf, 256); - - out_long (E->key_fingerprint); - BN_clear_free (b); - BN_clear_free (g_a); - BN_clear_free (p); - BN_clear_free (r); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_accept_methods, E, callback, callback_extra); -} - -void tgl_do_create_keys_end (struct tgl_state *TLS, struct tgl_secret_chat *U) { - assert (TLS->encr_prime); - BIGNUM *g_b = BN_bin2bn (U->g_key, 256, 0); - ensure_ptr (g_b); - assert (tglmp_check_g (TLS, TLS->encr_prime, g_b) >= 0); - BIGNUM *p = BN_bin2bn (TLS->encr_prime, 256, 0); - ensure_ptr (p); - BIGNUM *r = BN_new (); - ensure_ptr (r); - BIGNUM *a = BN_bin2bn ((void *)U->key, 256, 0); - ensure_ptr (a); - ensure (BN_mod_exp (r, g_b, a, p, TLS->BN_ctx)); - - unsigned char *t = talloc (256); - memcpy (t, U->key, 256); - - memset (U->key, 0, sizeof (U->key)); - BN_bn2bin (r, (void *)(((char *)(U->key)) + (256 - BN_num_bytes (r)))); - int i; - for (i = 0; i < 64; i++) { - U->key[i] ^= *(((int *)U->nonce) + i); - } - - static unsigned char sha_buffer[20]; - sha1 ((void *)U->key, 256, sha_buffer); - long long k = *(long long *)(sha_buffer + 12); - if (k != U->key_fingerprint) { - vlogprintf (E_WARNING, "Key fingerprint mismatch (my 0x%llx 0x%llx)\n", (unsigned long long)k, (unsigned long long)U->key_fingerprint); - U->state = sc_deleted; - } - - tfree_secure (t, 256); - - BN_clear_free (p); - BN_clear_free (g_b); - BN_clear_free (r); - BN_clear_free (a); -} - -void tgl_do_send_create_encr_chat (struct tgl_state *TLS, void *x, unsigned char *random, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) { - int user_id = (long)x; - int i; - unsigned char random_here[256]; - tglt_secure_random (random_here, 256); - for (i = 0; i < 256; i++) { - random[i] ^= random_here[i]; - } - BIGNUM *a = BN_bin2bn (random, 256, 0); - ensure_ptr (a); - BIGNUM *p = BN_bin2bn (TLS->encr_prime, 256, 0); - ensure_ptr (p); - - BIGNUM *g = BN_new (); - ensure_ptr (g); - - ensure (BN_set_word (g, TLS->encr_root)); - - BIGNUM *r = BN_new (); - ensure_ptr (r); - - ensure (BN_mod_exp (r, g, a, p, TLS->BN_ctx)); - - BN_clear_free (a); - - static char g_a[256]; - memset (g_a, 0, 256); - - BN_bn2bin (r, (void *)(g_a + (256 - BN_num_bytes (r)))); - - int t = lrand48 (); - while (tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (t))) { - t = lrand48 (); - } - - bl_do_encr_chat_init (TLS, t, user_id, (void *)random, (void *)g_a); - tgl_peer_t *_E = tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (t)); - assert (_E); - struct tgl_secret_chat *E = &_E->encr_chat; - - clear_packet (); - out_int (CODE_messages_request_encryption); - tgl_peer_t *U = tgl_peer_get (TLS, TGL_MK_USER (E->user_id)); - assert (U); - if (U && U->user.access_hash) { - out_int (CODE_input_user_foreign); - out_int (E->user_id); - out_long (U->user.access_hash); - } else { - out_int (CODE_input_user_contact); - out_int (E->user_id); - } - out_int (tgl_get_peer_id (E->id)); - out_cstring (g_a, 256); - //write_secret_chat_file (); - - BN_clear_free (g); - BN_clear_free (p); - BN_clear_free (r); - - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_request_methods, E, callback, callback_extra); -} - -static int get_dh_config_on_answer (struct tgl_state *TLS, struct query *q UU) { - unsigned x = fetch_int (); - assert (x == CODE_messages_dh_config || x == CODE_messages_dh_config_not_modified); - if (x == CODE_messages_dh_config) { - int a = fetch_int (); - int l = prefetch_strlen (); - assert (l == 256); - char *s = fetch_str (l); - int v = fetch_int (); - bl_do_set_dh_params (TLS, a, (void *)s, v); - - BIGNUM *p = BN_bin2bn ((void *)s, 256, 0); - ensure_ptr (p); - assert (tglmp_check_DH_params (TLS, p, a) >= 0); - BN_free (p); - } else { - assert (TLS->encr_param_version); - } - int l = prefetch_strlen (); - assert (l == 256); - unsigned char *random = talloc (256); - memcpy (random, fetch_str (256), 256); - if (q->extra) { - void **x = q->extra; - ((void (*)(struct tgl_state *, void *, void *, void *, void *))(*x))(TLS, x[1], random, q->callback, q->callback_extra); - tfree (x, 2 * sizeof (void *)); - tfree_secure (random, 256); - } else { - tfree_secure (random, 256); - } - return 0; -} - -static struct query_methods get_dh_config_methods = { - .on_answer = get_dh_config_on_answer, - .type = TYPE_TO_PARAM(messages_dh_config) -}; - -void tgl_do_accept_encr_chat_request (struct tgl_state *TLS, struct tgl_secret_chat *E, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) { - if (E->state != sc_request) { - if (callback) { - callback (TLS, callback_extra, 0, E); - } - return; - } - assert (E->state == sc_request); - - clear_packet (); - out_int (CODE_messages_get_dh_config); - out_int (TLS->encr_param_version); - out_int (256); - void **x = talloc (2 * sizeof (void *)); - x[0] = tgl_do_send_accept_encr_chat; - x[1] = E; - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dh_config_methods, x, callback, callback_extra); -} - -void tgl_do_create_encr_chat_request (struct tgl_state *TLS, int user_id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_get_dh_config); - out_int (TLS->encr_param_version); - out_int (256); - void **x = talloc (2 * sizeof (void *)); - x[0] = tgl_do_send_create_encr_chat; - x[1] = (void *)(long)(user_id); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &get_dh_config_methods, x, callback, callback_extra); -} -/* }}} */ - -/* {{{ Get difference */ -//int unread_messages; -//int difference_got; -//int seq, pts, qts, last_date; -static int get_state_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (TLS->locks & TGL_LOCK_DIFF); - TLS->locks ^= TGL_LOCK_DIFF; - assert (fetch_int () == (int)CODE_updates_state); - bl_do_set_pts (TLS, fetch_int ()); - bl_do_set_qts (TLS, fetch_int ()); - bl_do_set_date (TLS, fetch_int ()); - bl_do_set_seq (TLS, fetch_int ()); - //unread_messages = fetch_int (); - fetch_int (); - //write_state_file (); - //difference_got = 1; - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback) (TLS, q->callback_extra, 1); - } - return 0; -} - -static int lookup_state_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_updates_state); - int pts = fetch_int (); - int qts = fetch_int (); - fetch_int (); - int seq = fetch_int (); - fetch_int (); - - if (pts > TLS->pts || qts > TLS->qts || seq > TLS->seq) { - tgl_do_get_difference (TLS, 0, 0, 0); - } - return 0; -} - - -//int get_difference_active; -static int get_difference_on_answer (struct tgl_state *TLS, struct query *q UU) { - //get_difference_active = 0; - assert (TLS->locks & TGL_LOCK_DIFF); - TLS->locks ^= TGL_LOCK_DIFF; - - unsigned x = fetch_int (); - if (x == CODE_updates_difference_empty) { - bl_do_set_date (TLS, fetch_int ()); - bl_do_set_seq (TLS, fetch_int ()); - //difference_got = 1; - - vlogprintf (E_DEBUG, "Empty difference. Seq = %d\n", TLS->seq); - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback) (TLS, q->callback_extra, 1); - } - } else if (x == CODE_updates_difference || x == CODE_updates_difference_slice) { - int n, i; - assert (fetch_int () == CODE_vector); - n = fetch_int (); - struct tgl_message **ML = talloc (n * sizeof (void *)); - int ml_pos = 0; - for (i = 0; i < n; i++) { - ML[ml_pos ++] = tglf_fetch_alloc_message (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - struct tgl_message **EL = talloc (n * sizeof (void *)); - int el_pos = 0; - for (i = 0; i < n; i++) { - EL[el_pos ++] = tglf_fetch_alloc_encrypted_message (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglu_work_update (TLS, 0, 0); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_chat (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - assert (fetch_int () == (int)CODE_updates_state); - bl_do_set_pts (TLS, fetch_int ()); - bl_do_set_qts (TLS, fetch_int ()); - bl_do_set_date (TLS, fetch_int ()); - if (x == CODE_updates_difference) { - bl_do_set_seq (TLS, fetch_int ()); - vlogprintf (E_DEBUG, "Difference end. New seq = %d\n", TLS->seq); - } else { - fetch_int (); - } - //unread_messages = fetch_int (); - fetch_int (); - //write_state_file (); - /*for (i = 0; i < ml_pos; i++) { - print_message (ML[i]); - }*/ - for (i = 0; i < ml_pos; i++) { - //TLS->callback.new_msg (ML[i]); - bl_do_msg_update (TLS, ML[i]->id); - } - for (i = 0; i < el_pos; i++) { - //TLS->callback.new_msg (EL[i]); - bl_do_msg_update (TLS, EL[i]->id); - } - tfree (ML, ml_pos * sizeof (void *)); - tfree (EL, el_pos * sizeof (void *)); - - if (x == CODE_updates_difference_slice) { - //if (q->callback) { - // ((void (*)(void *, int))q->callback) (q->callback_extra, 1); - //} - tgl_do_get_difference (TLS, 0, q->callback, q->callback_extra); - } else { - //difference_got = 1; - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback) (TLS, q->callback_extra, 1); - } - } - } else { - assert (0); - } - return 0; -} - -static struct query_methods lookup_state_methods = { - .on_answer = lookup_state_on_answer, - .type = TYPE_TO_PARAM(updates_state) -}; - -static struct query_methods get_state_methods = { - .on_answer = get_state_on_answer, - .type = TYPE_TO_PARAM(updates_state) -}; - -static struct query_methods get_difference_methods = { - .on_answer = get_difference_on_answer, - .type = TYPE_TO_PARAM(updates_difference) -}; - -void tgl_do_lookup_state (struct tgl_state *TLS) { - if (TLS->locks & TGL_LOCK_DIFF) { - return; - } - clear_packet (); - tgl_do_insert_header (); - out_int (CODE_updates_get_state); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &lookup_state_methods, 0, 0, 0); -} - -void tgl_do_get_difference (struct tgl_state *TLS, int sync_from_start, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra) { - //get_difference_active = 1; - //difference_got = 0; - if (TLS->locks & TGL_LOCK_DIFF) { - if (callback) { - callback (TLS, callback_extra, 0); - } - return; - } - TLS->locks |= TGL_LOCK_DIFF; - clear_packet (); - tgl_do_insert_header (); - if (TLS->pts > 0 || sync_from_start) { - if (TLS->pts == 0) { TLS->pts = 1; } - //if (TLS->qts == 0) { TLS->qts = 1; } - if (TLS->date == 0) { TLS->date = 1; } - out_int (CODE_updates_get_difference); - out_int (TLS->pts); - out_int (TLS->date); - out_int (TLS->qts); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &get_difference_methods, 0, callback, callback_extra); - } else { - out_int (CODE_updates_get_state); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &get_state_methods, 0, callback, callback_extra); - } -} -/* }}} */ - -/* {{{ Visualize key */ -/*char *colors[4] = {COLOR_GREY, COLOR_CYAN, COLOR_BLUE, COLOR_GREEN}; - -void tgl_do_visualize_key (tgl_peer_id_t id) { - assert (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT); - tgl_peer_t *P = tgl_peer_get (TLS, id); - assert (P); - if (P->encr_chat.state != sc_ok) { - rprintf ("Chat is not initialized yet\n"); - return; - } - unsigned char buf[20]; - SHA1 ((void *)P->encr_chat.key, 256, buf); - print_start (); - int i; - for (i = 0; i < 16; i++) { - int x = buf[i]; - int j; - for (j = 0; j < 4; j ++) { - push_color (colors[x & 3]); - push_color (COLOR_INVERSE); - printf (" "); - pop_color (); - pop_color (); - x = x >> 2; - } - if (i & 1) { printf ("\n"); } - } - print_end (); -}*/ - -void tgl_do_visualize_key (struct tgl_state *TLS, tgl_peer_id_t id, unsigned char buf[16]) { - assert (tgl_get_peer_type (id) == TGL_PEER_ENCR_CHAT); - tgl_peer_t *P = tgl_peer_get (TLS, id); - assert (P); - if (P->encr_chat.state != sc_ok) { - vlogprintf (E_WARNING, "Chat is not initialized yet\n"); - return; - } - unsigned char res[20]; - SHA1 ((void *)P->encr_chat.key, 256, res); - memcpy (buf, res, 16); -} -/* }}} */ - -/* {{{ Get suggested */ -/*int get_suggested_on_answer (struct query *q UU) { - assert (fetch_int () == CODE_contacts_suggested); - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - logprintf ("n = %d\n", n); - assert (n <= 200); - int l[400]; - int i; - for (i = 0; i < n; i++) { - assert (fetch_int () == CODE_contact_suggested); - l[2 * i] = fetch_int (); - l[2 * i + 1] = fetch_int (); - } - assert (fetch_int () == CODE_vector); - int m = fetch_int (); - assert (n == m); - print_start (); - push_color (COLOR_YELLOW); - for (i = 0; i < m; i++) { - tgl_peer_t *U = (void *)tglf_fetch_alloc_user (TLS); - assert (tgl_get_peer_id (U->id) == l[2 * i]); - print_user_name (U->id, U); - printf (" phone %s: %d mutual friends\n", U->user.phone, l[2 * i + 1]); - } - pop_color (); - print_end (); - return 0; -} - -struct query_methods get_suggested_methods = { - .on_answer = get_suggested_on_answer, - .type = TYPE_TO_PARAM(contacts_suggested) -}; - -void tgl_do_get_suggested (void) { - clear_packet (); - out_int (CODE_contacts_get_suggested); - out_int (100); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &get_suggested_methods, 0); -}*/ -/* }}} */ - -/* {{{ Add user to chat */ - -static struct query_methods add_user_to_chat_methods = { - .on_answer = fwd_msg_on_answer, - .type = TYPE_TO_PARAM(messages_stated_message) -}; - -void tgl_do_add_user_to_chat (struct tgl_state *TLS, tgl_peer_id_t chat_id, tgl_peer_id_t id, int limit, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_add_chat_user); - out_int (tgl_get_peer_id (chat_id)); - - assert (tgl_get_peer_type (id) == TGL_PEER_USER); - tgl_peer_t *U = tgl_peer_get (TLS, id); - if (U && U->user.access_hash) { - out_int (CODE_input_user_foreign); - out_int (tgl_get_peer_id (id)); - out_long (U->user.access_hash); - } else { - out_int (CODE_input_user_contact); - out_int (tgl_get_peer_id (id)); - } - out_int (limit); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &add_user_to_chat_methods, 0, callback, callback_extra); -} - -void tgl_do_del_user_from_chat (struct tgl_state *TLS, tgl_peer_id_t chat_id, tgl_peer_id_t id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_delete_chat_user); - out_int (tgl_get_peer_id (chat_id)); - - assert (tgl_get_peer_type (id) == TGL_PEER_USER); - tgl_peer_t *U = tgl_peer_get (TLS, id); - if (U && U->user.access_hash) { - out_int (CODE_input_user_foreign); - out_int (tgl_get_peer_id (id)); - out_long (U->user.access_hash); - } else { - out_int (CODE_input_user_contact); - out_int (tgl_get_peer_id (id)); - } - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &add_user_to_chat_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Create secret chat */ -//char *create_print_name (tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4); - -void tgl_do_create_secret_chat (struct tgl_state *TLS, tgl_peer_id_t id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra) { - assert (tgl_get_peer_type (id) == TGL_PEER_USER); - tgl_peer_t *U = tgl_peer_get (TLS, id); - if (!U) { - vlogprintf (E_WARNING, "Can not create chat with unknown user\n"); - return; - } - - tgl_do_create_encr_chat_request (TLS, tgl_get_peer_id (id), callback, callback_extra); -} -/* }}} */ - -/* {{{ Create group chat */ -static struct query_methods create_group_chat_methods = { - .on_answer = fwd_msg_on_answer, - .type = TYPE_TO_PARAM(messages_stated_message) -}; - -void tgl_do_create_group_chat (struct tgl_state *TLS, tgl_peer_id_t id, char *chat_topic, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - assert (tgl_get_peer_type (id) == TGL_PEER_USER); - tgl_peer_t *U = tgl_peer_get (TLS, id); - if (!U) { - vlogprintf (E_WARNING, "Can not create chat with unknown user\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - clear_packet (); - out_int (CODE_messages_create_chat); - out_int (CODE_vector); - out_int (1); // Number of users, currently we support only 1 user. - if (U && U->user.access_hash) { - out_int (CODE_input_user_foreign); - out_int (tgl_get_peer_id (id)); - out_long (U->user.access_hash); - } else { - out_int (CODE_input_user_contact); - out_int (tgl_get_peer_id (id)); - } - out_string (chat_topic); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &create_group_chat_methods, 0, callback, callback_extra); -} - -void tgl_do_create_group_chat_ex (struct tgl_state *TLS, int users_num, tgl_peer_id_t ids[], char *chat_topic, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_create_chat); - out_int (CODE_vector); - out_int (users_num); // Number of users, currently we support only 1 user. - int i; - for (i = 0; i < users_num; i++) { - tgl_peer_id_t id = ids[i]; - tgl_peer_t *U = tgl_peer_get (TLS, id); - if (!U || tgl_get_peer_type (id) != TGL_PEER_USER) { - vlogprintf (E_WARNING, "Can not create chat with unknown user\n"); - if (callback) { - callback (TLS, callback_extra, 0, 0); - } - return; - } - if (U && U->user.access_hash) { - out_int (CODE_input_user_foreign); - out_int (tgl_get_peer_id (id)); - out_long (U->user.access_hash); - } else { - out_int (CODE_input_user_contact); - out_int (tgl_get_peer_id (id)); - } - } - out_string (chat_topic); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &create_group_chat_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Delete msg */ - -static int delete_msg_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - fetch_skip (n); - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback) (TLS, q->callback_extra, 1); - } - return 0; -} - -static struct query_methods delete_msg_methods = { - .on_answer = delete_msg_on_answer, - .type = TYPE_TO_PARAM_1(vector, TYPE_TO_PARAM (bare_int)) -}; - -void tgl_do_delete_msg (struct tgl_state *TLS, long long id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_delete_messages); - out_int (CODE_vector); - out_int (1); - out_int (id); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &delete_msg_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Restore msg */ - -static int restore_msg_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - fetch_skip (n); - //logprintf ("Restored %d messages\n", n); - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback) (TLS, q->callback_extra, 1); - } - return 0; -} - -static struct query_methods restore_msg_methods = { - .on_answer = restore_msg_on_answer, - .type = TYPE_TO_PARAM_1(vector, TYPE_TO_PARAM (bare_int)) -}; - -void tgl_do_restore_msg (struct tgl_state *TLS, long long id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra) { - clear_packet (); - out_int (CODE_messages_restore_messages); - out_int (CODE_vector); - out_int (1); - out_int (id); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &restore_msg_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Export card */ - -static int export_card_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - //logprintf ("Restored %d messages\n", n); - int *r = talloc (4 * n); - fetch_ints (r, n); - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, int, int *))q->callback) (TLS, q->callback_extra, 1, n, r); - } - free (r); - return 0; -} - -static struct query_methods export_card_methods = { - .on_answer = export_card_on_answer, - .type = TYPE_TO_PARAM_1(vector, TYPE_TO_PARAM (bare_int)) -}; - -void tgl_do_export_card (struct tgl_state *TLS, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, int *card), void *callback_extra) { - clear_packet (); - out_int (CODE_contacts_export_card); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &export_card_methods, 0, callback, callback_extra); -} -/* }}} */ - -/* {{{ Import card */ - -static int import_card_on_answer (struct tgl_state *TLS, struct query *q UU) { - struct tgl_user *U = tglf_fetch_alloc_user (TLS); - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int, struct tgl_user *))q->callback) (TLS, q->callback_extra, 1, U); - } - return 0; -} - -static struct query_methods import_card_methods = { - .on_answer = import_card_on_answer, - .type = TYPE_TO_PARAM (user) -}; - -void tgl_do_import_card (struct tgl_state *TLS, int size, int *card, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U), void *callback_extra) { - clear_packet (); - out_int (CODE_contacts_import_card); - out_int (CODE_vector); - out_int (size); - out_ints (card, size); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &import_card_methods, 0, callback, callback_extra); -} -/* }}} */ - -#ifndef DISABLE_EXTF -static int ext_query_on_answer (struct tgl_state *TLS, struct query *q UU) { - if (q->callback) { - char *buf = tglf_extf_fetch (TLS, q->type); - ((void (*)(struct tgl_state *, void *, int, char *))q->callback) (TLS, q->callback_extra, 1, buf); - } - tgl_paramed_type_free (q->type); - return 0; -} - -static struct query_methods ext_query_methods = { - .on_answer = ext_query_on_answer, -}; - -void tgl_do_send_extf (struct tgl_state *TLS, char *data, int data_len, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *buf), void *callback_extra) { - clear_packet (); - - ext_query_methods.type = tglf_extf_store (TLS, data, data_len); - - if (ext_query_methods.type) { - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &ext_query_methods, 0, callback, callback_extra); - } -} -#else -void tgl_do_send_extf (struct tgl_state *TLS, char *data, int data_len, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *buf), void *callback_extra) { - if (callback) { - callback (TLS, callback_extra, 0, 0); - } -} -#endif - -static void set_flag_4 (struct tgl_state *TLS, void *_D, int success) { - struct tgl_dc *D = _D; - assert (success); - D->flags |= 4; - - TLS->timer_methods->insert (D->ev, TLS->temp_key_expire_time * 0.9); -} - -static int send_bind_temp_on_answer (struct tgl_state *TLS, struct query *q UU) { - assert (fetch_int () == (int)CODE_bool_true); - struct tgl_dc *D = q->extra; - D->flags |= 2; - tgl_do_help_get_config_dc (TLS, D, set_flag_4, D); - vlogprintf (E_DEBUG, "Bind successful in dc %d\n", D->id); - return 0; -} - -static struct query_methods send_bind_temp_methods = { - .on_answer = send_bind_temp_on_answer, - .on_error = fail_on_error, - .type = TYPE_TO_PARAM (bool) -}; - -void tgl_do_send_bind_temp_key (struct tgl_state *TLS, struct tgl_dc *D, long long nonce, int expires_at, void *data, int len, long long msg_id) { - clear_packet (); - out_int (CODE_auth_bind_temp_auth_key); - out_long (D->auth_key_id); - out_long (nonce); - out_int (expires_at); - out_cstring (data, len); - struct query *q = tglq_send_query_ex (TLS, D, packet_ptr - packet_buffer, packet_buffer, &send_bind_temp_methods, D, 0, 0, 2); - assert (q->msg_id == msg_id); -} - -static int update_status_on_answer (struct tgl_state *TLS, struct query *q UU) { - fetch_bool (); - - if (q->callback) { - ((void (*)(struct tgl_state *, void *, int))q->callback) (TLS, q->callback_extra, 1); - } - return 0; -} - -static struct query_methods update_status_methods = { - .on_answer = update_status_on_answer, - .type = TYPE_TO_PARAM(bool) -}; - -void tgl_do_update_status (struct tgl_state *TLS, int online UU, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra) { - clear_packet (); - out_int (CODE_account_update_status); - out_int (online ? CODE_bool_false : CODE_bool_true); - tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &update_status_methods, 0, callback, callback_extra); -} diff --git a/queries.h b/queries.h deleted file mode 100644 index 51c61c2..0000000 --- a/queries.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - 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 "net.h" -#ifndef __QUERIES_H__ -#define __QUERIES_H__ -#include "structures.h" -#include "auto.h" -#include "tgl-layout.h" - -#define QUERY_ACK_RECEIVED 1 -#define QUERY_FORCE_SEND 2 - -struct query; -struct query_methods { - int (*on_answer)(struct tgl_state *TLS, struct query *q); - int (*on_error)(struct tgl_state *TLS, struct query *q, int error_code, int len, char *error); - int (*on_timeout)(struct tgl_state *TLS, struct query *q); - struct paramed_type *type; -}; - -struct query { - long long msg_id; - int data_len; - int flags; - int seq_no; - long long session_id; - void *data; - struct query_methods *methods; - struct tgl_timer *ev; - struct tgl_dc *DC; - struct tgl_session *session; - struct paramed_type *type; - void *extra; - void *callback; - void *callback_extra; -}; - - -struct query *tglq_send_query (struct tgl_state *TLS, struct tgl_dc *DC, int len, void *data, struct query_methods *methods, void *extra, void *callback, void *callback_extra); -void tglq_query_ack (struct tgl_state *TLS, long long id); -void tglq_query_error (struct tgl_state *TLS, long long id); -void tglq_query_result (struct tgl_state *TLS, long long id); -void tglq_query_restart (struct tgl_state *TLS, long long id); - -//double next_timer_in (void); -//void work_timers (void); - -//extern struct query_methods help_get_config_methods; - -double get_double_time (void); - -void tgl_do_send_bind_temp_key (struct tgl_state *TLS, 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); -#endif diff --git a/scheme.tl b/scheme.tl deleted file mode 120000 index 40329f0..0000000 --- a/scheme.tl +++ /dev/null @@ -1 +0,0 @@ -scheme18.tl \ No newline at end of file diff --git a/scheme12.tl b/scheme12.tl deleted file mode 100644 index 7d37a6f..0000000 --- a/scheme12.tl +++ /dev/null @@ -1,505 +0,0 @@ -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 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 = 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 = 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 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 users:Vector = contacts.Contacts; -contacts.contactsNotModified#b74ba9d2 = contacts.Contacts; - -contacts.importedContacts#d1cd0a4c imported:Vector users:Vector = contacts.ImportedContacts; - -contacts.blocked#1c138d15 blocked:Vector users:Vector = contacts.Blocked; -contacts.blockedSlice#900802a1 count:int blocked:Vector users:Vector = contacts.Blocked; - -contacts.found#566000e results:Vector users:Vector = contacts.Found; - -contacts.suggested#5649dcc5 results:Vector users:Vector = contacts.Suggested; - -messages.dialogs#15ba6c40 dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; -messages.dialogsSlice#71e094f3 count:int dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; - -messages.messages#8c718e87 messages:Vector chats:Vector users:Vector = messages.Messages; -messages.messagesSlice#b446ae3 count:int messages:Vector chats:Vector users:Vector = messages.Messages; - -messages.messageEmpty#3f4e0648 = messages.Message; -messages.message#ff90c417 message:Message chats:Vector users:Vector = messages.Message; - -messages.statedMessages#969478bb messages:Vector chats:Vector users:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessage#d07ae726 message:Message chats:Vector users:Vector 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 = messages.Chat; - -messages.chats#8150cbd8 chats:Vector users:Vector = messages.Chats; - -messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector users:Vector = 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 pts:int = Update; -updateDeleteMessages#a92bfe26 messages:Vector pts:int = Update; -updateRestoreMessages#d15de04d messages:Vector 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 new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector state:updates.State = updates.Difference; -updates.differenceSlice#a8fb1981 new_messages:Vector new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector 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 users:Vector chats:Vector date:int seq_start:int seq:int = Updates; -updates#74ae4240 updates:Vector users:Vector chats:Vector date:int seq:int = Updates; - -photos.photos#8dca6aa5 photos:Vector users:Vector = photos.Photos; -photos.photosSlice#15051f54 count:int photos:Vector users:Vector = photos.Photos; - -photos.photo#20212ca8 photo:Photo users:Vector = 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 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 chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessageLink#a9af2881 message:Message chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessage; - -messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector = 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 users:Vector seq:int = geochats.StatedMessage; - -geochats.located#48feb267 results:Vector messages:Vector chats:Vector users:Vector = geochats.Located; - -geochats.messages#d1526db1 messages:Vector chats:Vector users:Vector = geochats.Messages; -geochats.messagesSlice#bc5863e8 count:int messages:Vector chats:Vector users:Vector = 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 = 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 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 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; - -users.getUsers#d91a548 id:Vector = Vector; -users.getFullUser#ca30a5b1 id:InputUser = UserFull; - -contacts.getStatuses#c4a353ee = Vector; -contacts.getContacts#22c6aa08 hash:string = contacts.Contacts; -contacts.importContacts#da30b32d contacts:Vector 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 = 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 = 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 = Vector; -messages.restoreMessages#395f9d7e id:Vector = Vector; -messages.receivedMessages#28abcb68 max_id:int = Vector; -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 = messages.StatedMessages; -messages.getChats#3c6aa187 id:Vector = 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 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 = 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 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; - -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; diff --git a/scheme15.tl b/scheme15.tl deleted file mode 100644 index 4e18fad..0000000 --- a/scheme15.tl +++ /dev/null @@ -1,522 +0,0 @@ -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 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 = 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 = 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 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 users:Vector = contacts.Contacts; -contacts.contactsNotModified#b74ba9d2 = contacts.Contacts; - -contacts.importedContacts#ad524315 imported:Vector retry_contacts:Vector users:Vector = contacts.ImportedContacts; - -contacts.blocked#1c138d15 blocked:Vector users:Vector = contacts.Blocked; -contacts.blockedSlice#900802a1 count:int blocked:Vector users:Vector = contacts.Blocked; - -contacts.found#0566000e results:Vector users:Vector = contacts.Found; - -contacts.suggested#5649dcc5 results:Vector users:Vector = contacts.Suggested; - -messages.dialogs#15ba6c40 dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; -messages.dialogsSlice#71e094f3 count:int dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; - -messages.messages#8c718e87 messages:Vector chats:Vector users:Vector = messages.Messages; -messages.messagesSlice#0b446ae3 count:int messages:Vector chats:Vector users:Vector = messages.Messages; - -messages.messageEmpty#3f4e0648 = messages.Message; -messages.message#ff90c417 message:Message chats:Vector users:Vector = messages.Message; - -messages.statedMessages#969478bb messages:Vector chats:Vector users:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessage#d07ae726 message:Message chats:Vector users:Vector 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 = messages.Chat; - -messages.chats#8150cbd8 chats:Vector users:Vector = messages.Chats; - -messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector users:Vector = 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 pts:int = Update; -updateDeleteMessages#a92bfe26 messages:Vector pts:int = Update; -updateRestoreMessages#d15de04d messages:Vector 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 new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector state:updates.State = updates.Difference; -updates.differenceSlice#a8fb1981 new_messages:Vector new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector 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 users:Vector chats:Vector date:int seq_start:int seq:int = Updates; -updates#74ae4240 updates:Vector users:Vector chats:Vector date:int seq:int = Updates; - -photos.photos#8dca6aa5 photos:Vector users:Vector = photos.Photos; -photos.photosSlice#15051f54 count:int photos:Vector users:Vector = photos.Photos; - -photos.photo#20212ca8 photo:Photo users:Vector = 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 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 chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessageLink#a9af2881 message:Message chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessage; - -messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector = 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 users:Vector seq:int = geochats.StatedMessage; - -geochats.located#48feb267 results:Vector messages:Vector chats:Vector users:Vector = geochats.Located; - -geochats.messages#d1526db1 messages:Vector chats:Vector users:Vector = geochats.Messages; -geochats.messagesSlice#bc5863e8 count:int messages:Vector chats:Vector users:Vector = 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 = 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 = DecryptedMessageAction; -decryptedMessageActionDeleteMessages#65614304 random_ids:Vector = DecryptedMessageAction; -decryptedMessageActionScreenshotMessages#8ac1f475 random_ids:Vector = 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 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 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; - -users.getUsers#0d91a548 id:Vector = Vector; -users.getFullUser#ca30a5b1 id:InputUser = UserFull; - -contacts.getStatuses#c4a353ee = Vector; -contacts.getContacts#22c6aa08 hash:string = contacts.Contacts; -contacts.importContacts#da30b32d contacts:Vector 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 = 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 = 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 = Vector; -messages.restoreMessages#395f9d7e id:Vector = Vector; -messages.receivedMessages#28abcb68 max_id:int = Vector; -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 = messages.StatedMessages; -messages.getChats#3c6aa187 id:Vector = 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 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 = 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 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; - -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; diff --git a/scheme16.tl b/scheme16.tl deleted file mode 100644 index b1e1f19..0000000 --- a/scheme16.tl +++ /dev/null @@ -1,504 +0,0 @@ -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 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 = 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 = 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 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 users:Vector = contacts.Contacts; -contacts.contactsNotModified#b74ba9d2 = contacts.Contacts; - -contacts.importedContacts#ad524315 imported:Vector retry_contacts:Vector users:Vector = contacts.ImportedContacts; - -contacts.blocked#1c138d15 blocked:Vector users:Vector = contacts.Blocked; -contacts.blockedSlice#900802a1 count:int blocked:Vector users:Vector = contacts.Blocked; - -contacts.found#566000e results:Vector users:Vector = contacts.Found; - -contacts.suggested#5649dcc5 results:Vector users:Vector = contacts.Suggested; - -messages.dialogs#15ba6c40 dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; -messages.dialogsSlice#71e094f3 count:int dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; - -messages.messages#8c718e87 messages:Vector chats:Vector users:Vector = messages.Messages; -messages.messagesSlice#b446ae3 count:int messages:Vector chats:Vector users:Vector = messages.Messages; - -messages.messageEmpty#3f4e0648 = messages.Message; -messages.message#ff90c417 message:Message chats:Vector users:Vector = messages.Message; - -messages.statedMessages#969478bb messages:Vector chats:Vector users:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessage#d07ae726 message:Message chats:Vector users:Vector 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 = messages.Chat; - -messages.chats#8150cbd8 chats:Vector users:Vector = messages.Chats; - -messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector users:Vector = 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 pts:int = Update; -updateDeleteMessages#a92bfe26 messages:Vector pts:int = Update; -updateRestoreMessages#d15de04d messages:Vector 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 new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector state:updates.State = updates.Difference; -updates.differenceSlice#a8fb1981 new_messages:Vector new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector 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 users:Vector chats:Vector date:int seq_start:int seq:int = Updates; -updates#74ae4240 updates:Vector users:Vector chats:Vector date:int seq:int = Updates; - -photos.photos#8dca6aa5 photos:Vector users:Vector = photos.Photos; -photos.photosSlice#15051f54 count:int photos:Vector users:Vector = photos.Photos; - -photos.photo#20212ca8 photo:Photo users:Vector = 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 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 chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessageLink#a9af2881 message:Message chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessage; - -messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector = 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 users:Vector seq:int = geochats.StatedMessage; - -geochats.located#48feb267 results:Vector messages:Vector chats:Vector users:Vector = geochats.Located; - -geochats.messages#d1526db1 messages:Vector chats:Vector users:Vector = geochats.Messages; -geochats.messagesSlice#bc5863e8 count:int messages:Vector chats:Vector users:Vector = 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 = 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 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 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; - -users.getUsers#d91a548 id:Vector = Vector; -users.getFullUser#ca30a5b1 id:InputUser = UserFull; - -contacts.getStatuses#c4a353ee = Vector; -contacts.getContacts#22c6aa08 hash:string = contacts.Contacts; -contacts.importContacts#da30b32d contacts:Vector 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 = 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; -contacts.importCard#4fe196fe export_card:Vector = User; - -messages.getMessages#4222fa74 id:Vector = 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 = Vector; -messages.restoreMessages#395f9d7e id:Vector = Vector; -messages.receivedMessages#28abcb68 max_id:int = Vector; -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 = messages.StatedMessages; -messages.getChats#3c6aa187 id:Vector = 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 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 = 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 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; - -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; diff --git a/scheme17.tl b/scheme17.tl deleted file mode 100644 index c564155..0000000 --- a/scheme17.tl +++ /dev/null @@ -1,528 +0,0 @@ -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 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 = 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 = 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 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 users:Vector = contacts.Contacts; -contacts.contactsNotModified#b74ba9d2 = contacts.Contacts; - -contacts.importedContacts#ad524315 imported:Vector retry_contacts:Vector users:Vector = contacts.ImportedContacts; - -contacts.blocked#1c138d15 blocked:Vector users:Vector = contacts.Blocked; -contacts.blockedSlice#900802a1 count:int blocked:Vector users:Vector = contacts.Blocked; - -contacts.found#566000e results:Vector users:Vector = contacts.Found; - -contacts.suggested#5649dcc5 results:Vector users:Vector = contacts.Suggested; - -messages.dialogs#15ba6c40 dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; -messages.dialogsSlice#71e094f3 count:int dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; - -messages.messages#8c718e87 messages:Vector chats:Vector users:Vector = messages.Messages; -messages.messagesSlice#b446ae3 count:int messages:Vector chats:Vector users:Vector = messages.Messages; - -messages.messageEmpty#3f4e0648 = messages.Message; -messages.message#ff90c417 message:Message chats:Vector users:Vector = messages.Message; - -messages.statedMessages#969478bb messages:Vector chats:Vector users:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessage#d07ae726 message:Message chats:Vector users:Vector 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 = messages.Chat; - -messages.chats#8150cbd8 chats:Vector users:Vector = messages.Chats; - -messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector users:Vector = 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 pts:int = Update; -updateDeleteMessages#a92bfe26 messages:Vector pts:int = Update; -updateRestoreMessages#d15de04d messages:Vector 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 new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector state:updates.State = updates.Difference; -updates.differenceSlice#a8fb1981 new_messages:Vector new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector 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 users:Vector chats:Vector date:int seq_start:int seq:int = Updates; -updates#74ae4240 updates:Vector users:Vector chats:Vector date:int seq:int = Updates; - -photos.photos#8dca6aa5 photos:Vector users:Vector = photos.Photos; -photos.photosSlice#15051f54 count:int photos:Vector users:Vector = photos.Photos; - -photos.photo#20212ca8 photo:Photo users:Vector = 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 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 chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessageLink#a9af2881 message:Message chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessage; - -messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector = 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 users:Vector seq:int = geochats.StatedMessage; - -geochats.located#48feb267 results:Vector messages:Vector chats:Vector users:Vector = geochats.Located; - -geochats.messages#d1526db1 messages:Vector chats:Vector users:Vector = geochats.Messages; -geochats.messagesSlice#bc5863e8 count:int messages:Vector chats:Vector users:Vector = 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 = 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; - -updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update; -updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update; - - -message#567699b3 flags:int id:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message; -messageForwarded#a367e716 flags:int id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message; -messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message; - - -sendMessageTypingAction#16bf744e = SendMessageAction; -sendMessageCancelAction#fd5ec8f5 = SendMessageAction; -sendMessageRecordVideoAction#a187d66f = SendMessageAction; -sendMessageUploadVideoAction#92042ff7 = SendMessageAction; -sendMessageRecordAudioAction#d52f73f7 = SendMessageAction; -sendMessageUploadAudioAction#e6ac8a6f = SendMessageAction; -sendMessageUploadPhotoAction#990a3c1a = SendMessageAction; -sendMessageUploadDocumentAction#8faee98e = SendMessageAction; -sendMessageGeoLocationAction#176f8ba1 = SendMessageAction; -sendMessageChooseContactAction#628cbc6f = SendMessageAction; - ----functions--- - -invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; - -invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector 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 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; - -users.getUsers#d91a548 id:Vector = Vector; -users.getFullUser#ca30a5b1 id:InputUser = UserFull; - -contacts.getStatuses#c4a353ee = Vector; -contacts.getContacts#22c6aa08 hash:string = contacts.Contacts; -contacts.importContacts#da30b32d contacts:Vector 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 = 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; -contacts.importCard#4fe196fe export_card:Vector = User; - -messages.getMessages#4222fa74 id:Vector = 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#eed884c6 peer:InputPeer max_id:int offset:int read_contents:Bool = messages.AffectedHistory; -messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory; -messages.deleteMessages#14f2dd0a id:Vector = Vector; -messages.restoreMessages#395f9d7e id:Vector = Vector; -messages.receivedMessages#28abcb68 max_id:int = Vector; -messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = 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 = messages.StatedMessages; -messages.getChats#3c6aa187 id:Vector = 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 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 = 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 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; - -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; - -messages.readMessageContents id:Vector = Vector; - - -invokeWithLayer17#50858a19 {X:Type} query:!X = X; - diff --git a/scheme18.tl b/scheme18.tl deleted file mode 100644 index 6b7fdd5..0000000 --- a/scheme18.tl +++ /dev/null @@ -1,535 +0,0 @@ -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#7007b451 id:int first_name:string last_name:string username:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User; -userContact#cab35e18 id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User; -userRequest#d9ccc4ef id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User; -userForeign#75cf7a8 id:int first_name:string last_name:string username:string access_hash:long photo:UserProfilePhoto status:UserStatus = User; -userDeleted#d6016d7a id:int first_name:string last_name:string username: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 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 = 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 = 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 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 users:Vector = contacts.Contacts; -contacts.contactsNotModified#b74ba9d2 = contacts.Contacts; - -contacts.importedContacts#ad524315 imported:Vector retry_contacts:Vector users:Vector = contacts.ImportedContacts; - -contacts.blocked#1c138d15 blocked:Vector users:Vector = contacts.Blocked; -contacts.blockedSlice#900802a1 count:int blocked:Vector users:Vector = contacts.Blocked; - -contacts.found#566000e results:Vector users:Vector = contacts.Found; - -contacts.suggested#5649dcc5 results:Vector users:Vector = contacts.Suggested; - -messages.dialogs#15ba6c40 dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; -messages.dialogsSlice#71e094f3 count:int dialogs:Vector messages:Vector chats:Vector users:Vector = messages.Dialogs; - -messages.messages#8c718e87 messages:Vector chats:Vector users:Vector = messages.Messages; -messages.messagesSlice#b446ae3 count:int messages:Vector chats:Vector users:Vector = messages.Messages; - -messages.messageEmpty#3f4e0648 = messages.Message; -messages.message#ff90c417 message:Message chats:Vector users:Vector = messages.Message; - -messages.statedMessages#969478bb messages:Vector chats:Vector users:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessage#d07ae726 message:Message chats:Vector users:Vector 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 = messages.Chat; - -messages.chats#8150cbd8 chats:Vector users:Vector = messages.Chats; - -messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector users:Vector = 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 pts:int = Update; -updateDeleteMessages#a92bfe26 messages:Vector pts:int = Update; -updateRestoreMessages#d15de04d messages:Vector 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; -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 new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector state:updates.State = updates.Difference; -updates.differenceSlice#a8fb1981 new_messages:Vector new_encrypted_messages:Vector other_updates:Vector chats:Vector users:Vector 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 users:Vector chats:Vector date:int seq_start:int seq:int = Updates; -updates#74ae4240 updates:Vector users:Vector chats:Vector date:int seq:int = Updates; - -photos.photos#8dca6aa5 photos:Vector users:Vector = photos.Photos; -photos.photosSlice#15051f54 count:int photos:Vector users:Vector = photos.Photos; - -photos.photo#20212ca8 photo:Photo users:Vector = 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 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 chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessages; - -messages.statedMessageLink#a9af2881 message:Message chats:Vector users:Vector links:Vector pts:int seq:int = messages.StatedMessage; - -messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector = 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 users:Vector seq:int = geochats.StatedMessage; - -geochats.located#48feb267 results:Vector messages:Vector chats:Vector users:Vector = geochats.Located; - -geochats.messages#d1526db1 messages:Vector chats:Vector users:Vector = geochats.Messages; -geochats.messagesSlice#bc5863e8 count:int messages:Vector chats:Vector users:Vector = 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 = 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; - -updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update; -updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update; - -updateUserName user_id:int first_name:string last_name:string username:string = Update; -updateServiceNotification type:string message:string media:MessageMedia popup:Bool = Update; - -message#567699b3 flags:int id:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message; -messageForwarded#a367e716 flags:int id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message; -messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message; - - -sendMessageTypingAction#16bf744e = SendMessageAction; -sendMessageCancelAction#fd5ec8f5 = SendMessageAction; -sendMessageRecordVideoAction#a187d66f = SendMessageAction; -sendMessageUploadVideoAction#92042ff7 = SendMessageAction; -sendMessageRecordAudioAction#d52f73f7 = SendMessageAction; -sendMessageUploadAudioAction#e6ac8a6f = SendMessageAction; -sendMessageUploadPhotoAction#990a3c1a = SendMessageAction; -sendMessageUploadDocumentAction#8faee98e = SendMessageAction; -sendMessageGeoLocationAction#176f8ba1 = SendMessageAction; -sendMessageChooseContactAction#628cbc6f = SendMessageAction; - ----functions--- - -invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; - -invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector 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 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; - -users.getUsers#d91a548 id:Vector = Vector; -users.getFullUser#ca30a5b1 id:InputUser = UserFull; - -contacts.getStatuses#c4a353ee = Vector; -contacts.getContacts#22c6aa08 hash:string = contacts.Contacts; -contacts.importContacts#da30b32d contacts:Vector replace:Bool = contacts.ImportedContacts; -contacts.getSuggested#cd773428 limit:int = contacts.Suggested; -contacts.deleteContact#8e953744 id:InputUser = contacts.Link; -contacts.deleteContacts#59ab389e id:Vector = 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; -contacts.importCard#4fe196fe export_card:Vector = User; - -messages.getMessages#4222fa74 id:Vector = 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#eed884c6 peer:InputPeer max_id:int offset:int read_contents:Bool = messages.AffectedHistory; -messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory; -messages.deleteMessages#14f2dd0a id:Vector = Vector; -messages.restoreMessages#395f9d7e id:Vector = Vector; -messages.receivedMessages#28abcb68 max_id:int = Vector; -messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = 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 = messages.StatedMessages; -messages.getChats#3c6aa187 id:Vector = 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 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 = 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 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; - -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; - -messages.readMessageContents id:Vector = Vector; - - -account.checkUsername username:string = Bool; -account.updateUsername username:string = User; - -contacts.search q:string limit:int = contacts.Found; - -//invokeWithLayer18 {X:Type} query:!X = X; -invokeWithLayer18#1c900537 {X:Type} query:!X = X; - diff --git a/structures.c b/structures.c deleted file mode 100644 index 632625b..0000000 --- a/structures.c +++ /dev/null @@ -1,2039 +0,0 @@ -/* - 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 -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "structures.h" -#include "mtproto-common.h" -//#include "telegram.h" -#include "tree.h" -#include -#include -#include -#include "queries.h" -#include "binlog.h" -#include "updates.h" -#include "mtproto-client.h" - -#include "tgl.h" - -#define sha1 SHA1 - -static int id_cmp (struct tgl_message *M1, struct tgl_message *M2); -#define peer_cmp(a,b) (tgl_cmp_peer_id (a->id, b->id)) -#define peer_cmp_name(a,b) (strcmp (a->print_name, b->print_name)) -DEFINE_TREE(peer,tgl_peer_t *,peer_cmp,0) -DEFINE_TREE(peer_by_name,tgl_peer_t *,peer_cmp_name,0) -DEFINE_TREE(message,struct tgl_message *,id_cmp,0) - - - - - - - -char *tgls_default_create_print_name (struct tgl_state *TLS, tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4) { - const char *d[4]; - d[0] = a1; d[1] = a2; d[2] = a3; d[3] = a4; - static char buf[10000]; - buf[0] = 0; - int i; - int p = 0; - for (i = 0; i < 4; i++) { - if (d[i] && strlen (d[i])) { - p += tsnprintf (buf + p, 9999 - p, "%s%s", p ? "_" : "", d[i]); - assert (p < 9990); - } - } - char *s = buf; - while (*s) { - if (((unsigned char)*s) <= ' ') { *s = '_'; } - if (*s == '#') { *s = '@'; } - s++; - } - s = buf; - int fl = strlen (s); - int cc = 0; - while (1) { - tgl_peer_t *P = tgl_peer_get_by_name (TLS, s); - if (!P || !tgl_cmp_peer_id (P->id, id)) { - break; - } - cc ++; - assert (cc <= 9999); - tsnprintf (s + fl, 9999 - fl, "#%d", cc); - } - return tstrdup (s); -} - -enum tgl_typing_status tglf_fetch_typing (void) { - switch (fetch_int ()) { - case CODE_send_message_typing_action: - return tgl_typing_typing; - case CODE_send_message_cancel_action: - return tgl_typing_cancel; - case CODE_send_message_record_video_action: - return tgl_typing_record_video; - case CODE_send_message_upload_video_action: - return tgl_typing_upload_video; - case CODE_send_message_record_audio_action: - return tgl_typing_record_audio; - case CODE_send_message_upload_audio_action: - return tgl_typing_upload_audio; - case CODE_send_message_upload_photo_action: - return tgl_typing_upload_photo; - case CODE_send_message_upload_document_action: - return tgl_typing_upload_document; - case CODE_send_message_geo_location_action: - return tgl_typing_geo; - case CODE_send_message_choose_contact_action: - return tgl_typing_choose_contact; - default: - assert (0); - return tgl_typing_none; - } -} - -/* {{{ Fetch */ - -int tglf_fetch_file_location (struct tgl_state *TLS, struct tgl_file_location *loc) { - int x = fetch_int (); - assert (x == CODE_file_location_unavailable || x == CODE_file_location); - - if (x == CODE_file_location_unavailable) { - loc->dc = -1; - loc->volume = fetch_long (); - loc->local_id = fetch_int (); - loc->secret = fetch_long (); - } else { - loc->dc = fetch_int (); - loc->volume = fetch_long (); - loc->local_id = fetch_int (); - loc->secret = fetch_long (); - } - return 0; -} - -int tglf_fetch_user_status (struct tgl_state *TLS, struct tgl_user_status *S, struct tgl_user *U) { - unsigned x = fetch_int (); - assert (x == CODE_user_status_empty || x == CODE_user_status_online || x == CODE_user_status_offline); - switch (x) { - case CODE_user_status_empty: - if (S->online) { - tgl_insert_status_update (TLS, U); - tgl_remove_status_expire (TLS, U); - } - S->online = 0; - S->when = 0; - break; - case CODE_user_status_online: - { - int when = fetch_int (); - if (S->online != 1) { - tgl_insert_status_update (TLS, U); - tgl_insert_status_expire (TLS, U); - S->online = 1; - } else { - if (when != S->when) { - tgl_remove_status_expire (TLS, U); - tgl_insert_status_expire (TLS, U); - } - } - } - break; - case CODE_user_status_offline: - if (S->online != -1) { - tgl_insert_status_update (TLS, U); - if (S->online == 1) { - tgl_remove_status_expire (TLS, U); - } - } - S->online = -1; - S->when = fetch_int (); - break; - default: - assert (0); - } - return 0; -} - -long long tglf_fetch_user_photo (struct tgl_state *TLS, struct tgl_user *U) { - unsigned x = fetch_int (); - assert (x == CODE_user_profile_photo || x == CODE_user_profile_photo_old || x == CODE_user_profile_photo_empty); - if (x == CODE_user_profile_photo_empty) { - bl_do_set_user_profile_photo (TLS, U, 0, 0, 0); - return 0; - } - long long photo_id = 1; - if (x == CODE_user_profile_photo) { - photo_id = fetch_long (); - } - static struct tgl_file_location big; - static struct tgl_file_location small; - assert (tglf_fetch_file_location (TLS, &small) >= 0); - assert (tglf_fetch_file_location (TLS, &big) >= 0); - - bl_do_set_user_profile_photo (TLS, U, photo_id, &big, &small); - return 0; -} - -int tglf_fetch_user (struct tgl_state *TLS, struct tgl_user *U) { - unsigned x = fetch_int (); - assert (x == CODE_user_empty || x == CODE_user_self || x == CODE_user_contact || x == CODE_user_request || x == CODE_user_foreign || x == CODE_user_deleted); - U->id = TGL_MK_USER (fetch_int ()); - if (x == CODE_user_empty) { - return 0; - } - - if (x == CODE_user_self) { - bl_do_set_our_id (TLS, tgl_get_peer_id (U->id)); - } - - int new = !(U->flags & FLAG_CREATED); - if (new) { - int l1 = prefetch_strlen (); - assert (l1 >= 0); - char *s1 = fetch_str (l1); - int l2 = prefetch_strlen (); - assert (l2 >= 0); - char *s2 = fetch_str (l2); - - int l3 = prefetch_strlen (); - char *s3 = fetch_str (l3); - - if (x == CODE_user_deleted && !(U->flags & FLAG_DELETED)) { - bl_do_user_add (TLS, tgl_get_peer_id (U->id), s1, l1, s2, l2, 0, 0, 0, 0); - bl_do_user_set_username (TLS, U, s3, l3); - bl_do_user_delete (TLS, U); - } - if (x != CODE_user_deleted) { - long long access_hash = 0; - if (x != CODE_user_self) { - access_hash = fetch_long (); - } - int phone_len = 0; - char *phone = 0; - if (x != CODE_user_foreign) { - phone_len = prefetch_strlen (); - assert (phone_len >= 0); - phone = fetch_str (phone_len); - } - bl_do_user_add (TLS, tgl_get_peer_id (U->id), s1, l1, s2, l2, access_hash, phone, phone_len, x == CODE_user_contact); - bl_do_user_set_username (TLS, U, s3, l3); - assert (tglf_fetch_user_photo (TLS, U) >= 0); - assert (tglf_fetch_user_status (TLS, &U->status, U) >= 0); - - if (x == CODE_user_self) { - fetch_bool (); - } - } - } else { - int l1 = prefetch_strlen (); - char *s1 = fetch_str (l1); - int l2 = prefetch_strlen (); - char *s2 = fetch_str (l2); - - bl_do_user_set_name (TLS, U, s1, l1, s2, l2); - - int l3 = prefetch_strlen (); - char *s3 = fetch_str (l3); - bl_do_user_set_username (TLS, U, s3, l3); - - if (x == CODE_user_deleted && !(U->flags & FLAG_DELETED)) { - bl_do_user_delete (TLS, U); - } - if (x != CODE_user_deleted) { - if (x != CODE_user_self) { - bl_do_user_set_access_hash (TLS, U, fetch_long ()); - } - if (x != CODE_user_foreign) { - int l = prefetch_strlen (); - char *s = fetch_str (l); - bl_do_user_set_phone (TLS, U, s, l); - } - assert (tglf_fetch_user_photo (TLS, U) >= 0); - - tglf_fetch_user_status (TLS, &U->status, U); - if (x == CODE_user_self) { - fetch_bool (); - } - - if (x == CODE_user_contact) { - bl_do_user_set_friend (TLS, U, 1); - } else { - bl_do_user_set_friend (TLS, U, 0); - } - } - } - return 0; -} - -void tglf_fetch_user_full (struct tgl_state *TLS, struct tgl_user *U) { - assert (fetch_int () == CODE_user_full); - tglf_fetch_alloc_user (TLS); - assert (skip_type_any (TYPE_TO_PARAM (contacts_link)) >= 0); - - int *start = in_ptr; - assert (skip_type_any (TYPE_TO_PARAM (photo)) >= 0); - bl_do_user_set_full_photo (TLS, U, start, 4 * (in_ptr - start)); - - assert (skip_type_any (TYPE_TO_PARAM (peer_notify_settings)) >= 0); - - bl_do_user_set_blocked (TLS, U, fetch_bool ()); - int l1 = prefetch_strlen (); - char *s1 = fetch_str (l1); - int l2 = prefetch_strlen (); - char *s2 = fetch_str (l2); - if (U && (U->flags & FLAG_CREATED)) { - bl_do_user_set_real_name (TLS, U, s1, l1, s2, l2); - } -} - -void tglf_fetch_encrypted_chat (struct tgl_state *TLS, struct tgl_secret_chat *U) { - unsigned x = fetch_int (); - assert (x == CODE_encrypted_chat_empty || x == CODE_encrypted_chat_waiting || x == CODE_encrypted_chat_requested || x == CODE_encrypted_chat || x == CODE_encrypted_chat_discarded); - U->id = TGL_MK_ENCR_CHAT (fetch_int ()); - if (x == CODE_encrypted_chat_empty) { - return; - } - int new = !(U->flags & FLAG_CREATED); - - if (x == CODE_encrypted_chat_discarded) { - if (new) { - vlogprintf (E_WARNING, "Unknown chat in deleted state. May be we forgot something...\n"); - return; - } - bl_do_encr_chat_delete (TLS, U); - //write_secret_chat_file (); - return; - } - - static char g_key[256]; - static char nonce[256]; - if (new) { - long long access_hash = fetch_long (); - int date = fetch_int (); - int admin_id = fetch_int (); - int user_id = fetch_int () + admin_id - TLS->our_id; - - if (x == CODE_encrypted_chat_waiting) { - vlogprintf (E_WARNING, "Unknown chat in waiting state. May be we forgot something...\n"); - return; - } - if (x == CODE_encrypted_chat_requested || x == CODE_encrypted_chat) { - memset (g_key, 0, sizeof (g_key)); - } - - fetch256 (g_key); - - if (x == CODE_encrypted_chat) { - fetch_long (); // fingerprint - } - - if (x == CODE_encrypted_chat) { - vlogprintf (E_WARNING, "Unknown chat in ok state. May be we forgot something...\n"); - return; - } - - bl_do_encr_chat_requested (TLS, U, access_hash, date, admin_id, user_id, (void *)g_key, (void *)nonce); - //write_secret_chat_file (); - } else { - bl_do_encr_chat_set_access_hash (TLS, U, fetch_long ()); - bl_do_encr_chat_set_date (TLS, U, fetch_int ()); - if (fetch_int () != U->admin_id) { - vlogprintf (E_WARNING, "Changed admin in secret chat. WTF?\n"); - return; - } - if (U->user_id != U->admin_id + fetch_int () - TLS->our_id) { - vlogprintf (E_WARNING, "Changed partner in secret chat. WTF?\n"); - return; - } - if (x == CODE_encrypted_chat_waiting) { - bl_do_encr_chat_set_state (TLS, U, sc_waiting); - //write_secret_chat_file (); - return; // We needed only access hash from here - } - - if (x == CODE_encrypted_chat_requested || x == CODE_encrypted_chat) { - memset (g_key, 0, sizeof (g_key)); - } - - fetch256 (g_key); - - if (x == CODE_encrypted_chat_requested) { - return; // Duplicate? - } - bl_do_encr_chat_accepted (TLS, U, (void *)g_key, (void *)nonce, fetch_long ()); - //write_secret_chat_file (); - } -} - -void tglf_fetch_chat (struct tgl_state *TLS, struct tgl_chat *C) { - unsigned x = fetch_int (); - assert (x == CODE_chat_empty || x == CODE_chat || x == CODE_chat_forbidden); - C->id = TGL_MK_CHAT (fetch_int ()); - if (x == CODE_chat_empty) { - return; - } - int new = !(C->flags & FLAG_CREATED); - if (new) { - int y = 0; - if (x == CODE_chat_forbidden) { - y |= FLAG_FORBIDDEN; - } - int l = prefetch_strlen (); - char *s = fetch_str (l); - - struct tgl_file_location small; - struct tgl_file_location big; - memset (&small, 0, sizeof (small)); - memset (&big, 0, sizeof (big)); - int users_num = -1; - int date = 0; - int version = -1; - - if (x == CODE_chat) { - unsigned z = fetch_int (); - if (z == CODE_chat_photo_empty) { - small.dc = -2; - big.dc = -2; - } else { - assert (z == CODE_chat_photo); - tglf_fetch_file_location (TLS, &small); - tglf_fetch_file_location (TLS, &big); - } - users_num = fetch_int (); - date = fetch_int (); - if (fetch_bool ()) { - y |= FLAG_CHAT_IN_CHAT; - } - version = fetch_int (); - } else { - small.dc = -2; - big.dc = -2; - users_num = -1; - date = fetch_int (); - version = -1; - } - - bl_do_create_chat (TLS, C, y, s, l, users_num, date, version, &big, &small); - } else { - if (x == CODE_chat_forbidden) { - bl_do_chat_forbid (TLS, C, 1); - } else { - bl_do_chat_forbid (TLS, C, 0); - } - int l = prefetch_strlen (); - char *s = fetch_str (l); - bl_do_chat_set_title (TLS, C, s, l); - - struct tgl_file_location small; - struct tgl_file_location big; - memset (&small, 0, sizeof (small)); - memset (&big, 0, sizeof (big)); - - if (x == CODE_chat) { - unsigned y = fetch_int (); - if (y == CODE_chat_photo_empty) { - small.dc = -2; - big.dc = -2; - } else { - assert (y == CODE_chat_photo); - tglf_fetch_file_location (TLS, &small); - tglf_fetch_file_location (TLS, &big); - } - bl_do_chat_set_photo (TLS, C, &big, &small); - int users_num = fetch_int (); - bl_do_chat_set_date (TLS, C, fetch_int ()); - bl_do_chat_set_set_in_chat (TLS, C, fetch_bool ()); - bl_do_chat_set_version (TLS, C, users_num, fetch_int ()); - } else { - bl_do_chat_set_date (TLS, C, fetch_int ()); - } - } -} - -void tglf_fetch_chat_full (struct tgl_state *TLS, struct tgl_chat *C) { - unsigned x = fetch_int (); - assert (x == CODE_messages_chat_full); - assert (fetch_int () == CODE_chat_full); - C->id = TGL_MK_CHAT (fetch_int ()); - x = fetch_int (); - int version = 0; - struct tgl_chat_user *users = 0; - int users_num = 0; - int admin_id = 0; - - if (x == CODE_chat_participants) { - assert (fetch_int () == tgl_get_peer_id (C->id)); - admin_id = fetch_int (); - assert (fetch_int () == CODE_vector); - users_num = fetch_int (); - users = talloc (sizeof (struct tgl_chat_user) * users_num); - int i; - for (i = 0; i < users_num; 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 (); - } - version = fetch_int (); - } else { - fetch_int (); - } - int *start = in_ptr; - assert (skip_type_any (TYPE_TO_PARAM (photo)) >= 0); - int *end = in_ptr; - assert (skip_type_any (TYPE_TO_PARAM (peer_notify_settings)) >= 0); - - int n, i; - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_chat (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - if (admin_id) { - bl_do_chat_set_admin (TLS, C, admin_id); - } - if (version > 0) { - bl_do_chat_set_participants (TLS, C, version, users_num, users); - tfree (users, sizeof (struct tgl_chat_user) * users_num); - } - bl_do_chat_set_full_photo (TLS, C, start, 4 * (end - start)); -} - -void tglf_fetch_photo_size (struct tgl_state *TLS, struct tgl_photo_size *S) { - memset (S, 0, sizeof (*S)); - unsigned x = fetch_int (); - assert (x == CODE_photo_size || x == CODE_photo_cached_size || x == CODE_photo_size_empty); - S->type = fetch_str_dup (); - if (x != CODE_photo_size_empty) { - tglf_fetch_file_location (TLS, &S->loc); - S->w = fetch_int (); - S->h = fetch_int (); - if (x == CODE_photo_size) { - S->size = fetch_int (); - } else { - S->size = prefetch_strlen (); - fetch_str (S->size); - } - } -} - -void tglf_fetch_geo (struct tgl_state *TLS, struct tgl_geo *G) { - unsigned x = fetch_int (); - if (x == CODE_geo_point) { - G->longitude = fetch_double (); - G->latitude = fetch_double (); - } else { - assert (x == CODE_geo_point_empty); - G->longitude = 0; - G->latitude = 0; - } -} - -void tglf_fetch_photo (struct tgl_state *TLS, struct tgl_photo *P) { - memset (P, 0, sizeof (*P)); - unsigned x = fetch_int (); - assert (x == CODE_photo_empty || x == CODE_photo); - P->id = fetch_long (); - if (x == CODE_photo_empty) { return; } - P->access_hash = fetch_long (); - P->user_id = fetch_int (); - P->date = fetch_int (); - P->caption = fetch_str_dup (); - tglf_fetch_geo (TLS, &P->geo); - assert (fetch_int () == CODE_vector); - P->sizes_num = fetch_int (); - P->sizes = talloc (sizeof (struct tgl_photo_size) * P->sizes_num); - int i; - for (i = 0; i < P->sizes_num; i++) { - tglf_fetch_photo_size (TLS, &P->sizes[i]); - } -} - -void tglf_fetch_video (struct tgl_state *TLS, struct tgl_video *V) { - memset (V, 0, sizeof (*V)); - unsigned x = fetch_int (); - V->id = fetch_long (); - if (x == CODE_video_empty) { return; } - V->access_hash = fetch_long (); - V->user_id = fetch_int (); - V->date = fetch_int (); - V->caption = fetch_str_dup (); - V->duration = fetch_int (); - V->mime_type = fetch_str_dup (); - V->size = fetch_int (); - tglf_fetch_photo_size (TLS, &V->thumb); - V->dc_id = fetch_int (); - V->w = fetch_int (); - V->h = fetch_int (); -} - -void tglf_fetch_audio (struct tgl_state *TLS, struct tgl_audio *V) { - memset (V, 0, sizeof (*V)); - unsigned x = fetch_int (); - V->id = fetch_long (); - if (x == CODE_audio_empty) { return; } - V->access_hash = fetch_long (); - V->user_id = fetch_int (); - V->date = fetch_int (); - V->duration = fetch_int (); - V->mime_type = fetch_str_dup (); - V->size = fetch_int (); - V->dc_id = fetch_int (); -} - -void tglf_fetch_document (struct tgl_state *TLS, struct tgl_document *V) { - memset (V, 0, sizeof (*V)); - unsigned x = fetch_int (); - V->id = fetch_long (); - if (x == CODE_document_empty) { return; } - V->access_hash = fetch_long (); - V->user_id = fetch_int (); - V->date = fetch_int (); - V->caption = fetch_str_dup (); - V->mime_type = fetch_str_dup (); - V->size = fetch_int (); - tglf_fetch_photo_size (TLS, &V->thumb); - V->dc_id = fetch_int (); -} - -void tglf_fetch_message_action (struct tgl_state *TLS, struct tgl_message_action *M) { - memset (M, 0, sizeof (*M)); - unsigned x = fetch_int (); - switch (x) { - case CODE_message_action_empty: - M->type = tgl_message_action_none; - break; - case CODE_message_action_geo_chat_create: - { - M->type = tgl_message_action_geo_chat_create; - int l = prefetch_strlen (); // title - char *s = fetch_str (l); - int l2 = prefetch_strlen (); // checkin - char *s2 = fetch_str (l2); - vlogprintf (E_ERROR, "Message action: Created geochat %.*s in address %.*s. You are in magic land now, since nobody ever tested geochats in this app\n", l, s, l2, s2); - } - break; - case CODE_message_action_geo_chat_checkin: - M->type = tgl_message_action_geo_chat_checkin; - break; - case CODE_message_action_chat_create: - M->type = tgl_message_action_chat_create; - M->title = fetch_str_dup (); - assert (fetch_int () == (int)CODE_vector); - M->user_num = fetch_int (); - M->users = talloc (M->user_num * 4); - fetch_ints (M->users, M->user_num); - break; - case CODE_message_action_chat_edit_title: - M->type = tgl_message_action_chat_edit_title; - M->new_title = fetch_str_dup (); - break; - case CODE_message_action_chat_edit_photo: - M->type = tgl_message_action_chat_edit_photo; - tglf_fetch_photo (TLS, &M->photo); - break; - case CODE_message_action_chat_delete_photo: - M->type = tgl_message_action_chat_delete_photo; - break; - case CODE_message_action_chat_add_user: - M->type = tgl_message_action_chat_add_user; - M->user = fetch_int (); - break; - case CODE_message_action_chat_delete_user: - M->type = tgl_message_action_chat_delete_user; - M->user = fetch_int (); - break; - default: - vlogprintf (E_ERROR, "type = %d\n", x); - assert (0); - } -} - -void tglf_fetch_message_short (struct tgl_state *TLS, struct tgl_message *M) { - int new = !(M->flags & FLAG_CREATED); - - if (new) { - int id = fetch_int (); - int from_id = fetch_int (); - int to_id = TLS->our_id; - int l = prefetch_strlen (); - char *s = fetch_str (l); - - int pts = fetch_int (); - - int date = fetch_int (); - //tglu_fetch_seq (); - int seq = fetch_int (); - assert (seq == TLS->seq + 1); - - bl_do_create_message_text (TLS, id, from_id, TGL_PEER_USER, to_id, date, 1, l, s); - - tgl_peer_t *P = tgl_peer_get (TLS, TGL_MK_USER (from_id)); - if (!P || !(P->flags & FLAG_CREATED)) { - tgl_do_get_difference (TLS, 0, 0, 0); - } else { - bl_do_set_pts (TLS, pts); - bl_do_set_date (TLS, date); - } - //bl_do_msg_seq_update (id); - } else { - fetch_int (); // id - fetch_int (); // from_id - int l = prefetch_strlen (); - fetch_str (l); // text - - tglu_fetch_pts (TLS); - fetch_int (); - //tglu_fetch_seq (); - int seq = fetch_int (); - assert (seq == TLS->seq + 1); - //bl_do_msg_seq_update (id); - } -} - -void tglf_fetch_message_short_chat (struct tgl_state *TLS, struct tgl_message *M) { - int new = !(M->flags & FLAG_CREATED); - - if (new) { - int id = fetch_int (); - int from_id = fetch_int (); - int to_id = fetch_int (); - int l = prefetch_strlen (); - char *s = fetch_str (l); - - int pts = fetch_int (); - int date = fetch_int (); - //tglu_fetch_seq (); - - int seq = fetch_int (); - assert (seq == TLS->seq + 1); - bl_do_create_message_text (TLS, id, from_id, TGL_PEER_CHAT, to_id, date, 1, l, s); - - tgl_peer_t *P = tgl_peer_get (TLS, TGL_MK_CHAT (to_id)); - if (!P || !(P->flags & FLAG_CREATED)) { - tgl_do_get_difference (TLS, 0, 0, 0); - } else { - P = tgl_peer_get (TLS, TGL_MK_USER (from_id)); - if (!P || !(P->flags & FLAG_CREATED)) { - tgl_do_get_difference (TLS, 0, 0, 0); - } else { - bl_do_set_pts (TLS, pts); - bl_do_set_date (TLS, date); - } - } - //bl_do_msg_seq_update (id); - } else { - fetch_int (); // id - fetch_int (); // from_id - fetch_int (); // to_id - int l = prefetch_strlen (); - fetch_str (l); // text - - tglu_fetch_pts (TLS); - fetch_int (); - //tglu_fetch_seq (); - int seq = fetch_int (); - assert (seq == TLS->seq + 1); - //bl_do_msg_seq_update (id); - } -} - - -void tglf_fetch_message_media (struct tgl_state *TLS, struct tgl_message_media *M) { - memset (M, 0, sizeof (*M)); - //M->type = fetch_int (); - int x = fetch_int (); - switch (x) { - case CODE_message_media_empty: - M->type = tgl_message_media_none; - break; - case CODE_message_media_photo: - M->type = tgl_message_media_photo; - tglf_fetch_photo (TLS, &M->photo); - break; - case CODE_message_media_video: - M->type = tgl_message_media_video; - tglf_fetch_video (TLS, &M->video); - break; - case CODE_message_media_audio: - M->type = tgl_message_media_audio; - tglf_fetch_audio (TLS, &M->audio); - break; - case CODE_message_media_document: - M->type = tgl_message_media_document; - tglf_fetch_document (TLS, &M->document); - break; - case CODE_message_media_geo: - M->type = tgl_message_media_geo; - tglf_fetch_geo (TLS, &M->geo); - break; - case CODE_message_media_contact: - M->type = tgl_message_media_contact; - M->phone = fetch_str_dup (); - M->first_name = fetch_str_dup (); - M->last_name = fetch_str_dup (); - M->user_id = fetch_int (); - break; - case CODE_message_media_unsupported: - M->type = tgl_message_media_unsupported; - M->data_size = prefetch_strlen (); - M->data = talloc (M->data_size); - memcpy (M->data, fetch_str (M->data_size), M->data_size); - break; - default: - vlogprintf (E_ERROR, "type = 0x%08x\n", M->type); - assert (0); - } -} - -void tglf_fetch_message_media_encrypted (struct tgl_state *TLS, struct tgl_message_media *M) { - memset (M, 0, sizeof (*M)); - unsigned x = fetch_int (); - int l; - switch (x) { - case CODE_decrypted_message_media_empty: - M->type = tgl_message_media_none; - //M->type = CODE_message_media_empty; - break; - case CODE_decrypted_message_media_photo: - M->type = tgl_message_media_photo_encr; - //M->type = x; - l = prefetch_strlen (); - fetch_str (l); // thumb - fetch_int (); // thumb_w - fetch_int (); // thumb_h - M->encr_photo.w = fetch_int (); - M->encr_photo.h = fetch_int (); - M->encr_photo.size = fetch_int (); - - l = prefetch_strlen (); - assert (l > 0); - M->encr_photo.key = talloc (32); - memset (M->encr_photo.key, 0, 32); - if (l <= 32) { - memcpy (M->encr_photo.key + (32 - l), fetch_str (l), l); - } else { - memcpy (M->encr_photo.key, fetch_str (l) + (l - 32), 32); - } - M->encr_photo.iv = talloc (32); - l = prefetch_strlen (); - assert (l > 0); - memset (M->encr_photo.iv, 0, 32); - if (l <= 32) { - memcpy (M->encr_photo.iv + (32 - l), fetch_str (l), l); - } else { - memcpy (M->encr_photo.iv, fetch_str (l) + (l - 32), 32); - } - break; - case CODE_decrypted_message_media_video: - case CODE_decrypted_message_media_video_l12: - //M->type = CODE_decrypted_message_media_video; - M->type = tgl_message_media_video_encr; - l = prefetch_strlen (); - fetch_str (l); // thumb - fetch_int (); // thumb_w - fetch_int (); // thumb_h - M->encr_video.duration = fetch_int (); - if (x == CODE_decrypted_message_media_video) { - M->encr_video.mime_type = fetch_str_dup (); - } - M->encr_video.w = fetch_int (); - M->encr_video.h = fetch_int (); - M->encr_video.size = fetch_int (); - - l = prefetch_strlen (); - assert (l > 0); - M->encr_video.key = talloc0 (32); - if (l <= 32) { - memcpy (M->encr_video.key + (32 - l), fetch_str (l), l); - } else { - memcpy (M->encr_video.key, fetch_str (l) + (l - 32), 32); - } - M->encr_video.iv = talloc (32); - l = prefetch_strlen (); - assert (l > 0); - memset (M->encr_video.iv, 0, 32); - if (l <= 32) { - memcpy (M->encr_video.iv + (32 - l), fetch_str (l), l); - } else { - memcpy (M->encr_video.iv, fetch_str (l) + (l - 32), 32); - } - break; - case CODE_decrypted_message_media_audio: - case CODE_decrypted_message_media_audio_l12: - //M->type = CODE_decrypted_message_media_audio; - M->type = tgl_message_media_audio_encr; - M->encr_audio.duration = fetch_int (); - if (x == CODE_decrypted_message_media_audio) { - M->encr_audio.mime_type = fetch_str_dup (); - } - M->encr_audio.size = fetch_int (); - - l = prefetch_strlen (); - assert (l > 0); - M->encr_video.key = talloc0 (32); - if (l <= 32) { - memcpy (M->encr_video.key + (32 - l), fetch_str (l), l); - } else { - memcpy (M->encr_video.key, fetch_str (l) + (l - 32), 32); - } - M->encr_video.iv = talloc0 (32); - l = prefetch_strlen (); - assert (l > 0); - if (l <= 32) { - memcpy (M->encr_video.iv + (32 - l), fetch_str (l), l); - } else { - memcpy (M->encr_video.iv, fetch_str (l) + (l - 32), 32); - } - break; - case CODE_decrypted_message_media_document: - M->type = tgl_message_media_document_encr; - l = prefetch_strlen (); - fetch_str (l); // thumb - fetch_int (); // thumb_w - fetch_int (); // thumb_h - M->encr_document.file_name = fetch_str_dup (); - M->encr_document.mime_type = fetch_str_dup (); - M->encr_video.size = fetch_int (); - - l = prefetch_strlen (); - assert (l > 0); - M->encr_video.key = talloc0 (32); - if (l <= 32) { - memcpy (M->encr_video.key + (32 - l), fetch_str (l), l); - } else { - memcpy (M->encr_video.key, fetch_str (l) + (l - 32), 32); - } - M->encr_video.iv = talloc0 (32); - l = prefetch_strlen (); - assert (l > 0); - if (l <= 32) { - memcpy (M->encr_video.iv + (32 - l), fetch_str (l), l); - } else { - memcpy (M->encr_video.iv, fetch_str (l) + (l - 32), 32); - } - break; -/* case CODE_decrypted_message_media_file: - M->type = x; - M->encr_file.filename = fetch_str_dup (); - l = prefetch_strlen (); - fetch_str (l); // thumb - l = fetch_int (); - assert (l > 0); - M->encr_file.key = talloc (l); - memcpy (M->encr_file.key, fetch_str (l), l); - - l = fetch_int (); - assert (l > 0); - M->encr_file.iv = talloc (l); - memcpy (M->encr_file.iv, fetch_str (l), l); - break; - */ - case CODE_decrypted_message_media_geo_point: - M->type = tgl_message_media_geo; - M->geo.latitude = fetch_double (); - M->geo.longitude = fetch_double (); - break; - case CODE_decrypted_message_media_contact: - M->type = tgl_message_media_contact; - M->phone = fetch_str_dup (); - M->first_name = fetch_str_dup (); - M->last_name = fetch_str_dup (); - M->user_id = fetch_int (); - break; - default: - vlogprintf (E_ERROR, "type = 0x%08x\n", x); - assert (0); - } -} - -void tglf_fetch_message_action_encrypted (struct tgl_state *TLS, struct tgl_message_action *M) { - unsigned x = fetch_int (); - switch (x) { - case CODE_decrypted_message_action_set_message_t_t_l: - M->type = tgl_message_action_set_message_ttl; - M->ttl = fetch_int (); - break; - case CODE_decrypted_message_action_read_messages: - M->type = tgl_message_action_read_messages; - { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - M->read_cnt = n; - while (n -- > 0) { - long long id = fetch_long (); - struct tgl_message *N = tgl_message_get (TLS, id); - if (N) { - N->unread = 0; - } - } - } - break; - case CODE_decrypted_message_action_delete_messages: - M->type = tgl_message_action_delete_messages; - { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - M->delete_cnt = n; - while (n -- > 0) { - fetch_long (); - } - } - break; - case CODE_decrypted_message_action_screenshot_messages: - M->type = tgl_message_action_screenshot_messages; - { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - M->screenshot_cnt = n; - while (n -- > 0) { - fetch_long (); - } - } - break; - case CODE_decrypted_message_action_notify_layer: - M->type = tgl_message_action_notify_layer; - M->layer = fetch_int (); - break; - case CODE_decrypted_message_action_flush_history: - M->type = tgl_message_action_flush_history; - break; - case CODE_decrypted_message_action_typing: - M->type = tgl_message_action_typing; - M->typing = tglf_fetch_typing (); - break; - case CODE_decrypted_message_action_resend: - M->type = tgl_message_action_resend; - M->start_seq_no = fetch_int (); - M->end_seq_no = fetch_int (); - break; - default: - vlogprintf (E_ERROR, "x = 0x%08x\n", x); - assert (0); - } -} - -tgl_peer_id_t tglf_fetch_peer_id (struct tgl_state *TLS) { - unsigned x =fetch_int (); - if (x == CODE_peer_user) { - return TGL_MK_USER (fetch_int ()); - } else { - assert (CODE_peer_chat); - return TGL_MK_CHAT (fetch_int ()); - } -} - -void tglf_fetch_message (struct tgl_state *TLS, struct tgl_message *M) { - unsigned x = fetch_int (); - assert (x == CODE_message_empty || x == CODE_message || x == CODE_message_forwarded || x == CODE_message_service); - int flags = 0; - if (x != CODE_message_empty) { - flags = fetch_int (); - } - int id = fetch_int (); - assert (M->id == id); - if (x == CODE_message_empty) { - return; - } - int fwd_from_id = 0; - int fwd_date = 0; - - if (x == CODE_message_forwarded) { - fwd_from_id = fetch_int (); - fwd_date = fetch_int (); - } - int from_id = fetch_int (); - tgl_peer_id_t to_id = tglf_fetch_peer_id (TLS); - - //fetch_bool (); // out. - - //int unread = fetch_bool (); - int date = fetch_int (); - - int unread = (flags & 1) != 0; - int new = !(M->flags & FLAG_CREATED); - - if (x == CODE_message_service) { - int *start = in_ptr; - - assert (skip_type_any (TYPE_TO_PARAM (message_action)) >= 0); - - if (new) { - if (fwd_from_id) { - bl_do_create_message_service_fwd (TLS, id, from_id, tgl_get_peer_type (to_id), tgl_get_peer_id (to_id), date, fwd_from_id, fwd_date, unread, start, (in_ptr - start)); - } else { - bl_do_create_message_service (TLS, id, from_id, tgl_get_peer_type (to_id), tgl_get_peer_id (to_id), date, unread, start, (in_ptr - start)); - } - } - } else { - int l = prefetch_strlen (); - char *s = fetch_str (l); - int *start = in_ptr; - - assert (skip_type_any (TYPE_TO_PARAM (message_media)) >= 0); - - if (new) { - if (fwd_from_id) { - bl_do_create_message_media_fwd (TLS, id, from_id, tgl_get_peer_type (to_id), tgl_get_peer_id (to_id), date, fwd_from_id, fwd_date, unread, l, s, start, in_ptr - start); - } else { - bl_do_create_message_media (TLS, id, from_id, tgl_get_peer_type (to_id), tgl_get_peer_id (to_id), date, unread, l, s, start, in_ptr - start); - } - } - } - bl_do_set_unread (TLS, M, unread); -} - -void tglf_tglf_fetch_geo_message (struct tgl_state *TLS, struct tgl_message *M) { - memset (M, 0, sizeof (*M)); - unsigned x = fetch_int (); - assert (x == CODE_geo_chat_message_empty || x == CODE_geo_chat_message || x == CODE_geo_chat_message_service); - M->to_id = TGL_MK_GEO_CHAT (fetch_int ()); - M->id = fetch_int (); - if (x == CODE_geo_chat_message_empty) { - M->flags |= 1; - return; - } - M->from_id = TGL_MK_USER (fetch_int ()); - M->date = fetch_int (); - if (x == CODE_geo_chat_message_service) { - M->service = 1; - tglf_fetch_message_action (TLS, &M->action); - } else { - M->message = fetch_str_dup (); - M->message_len = strlen (M->message); - tglf_fetch_message_media (TLS, &M->media); - } -} - -static int *decr_ptr; -static int *decr_end; - -static int decrypt_encrypted_message (struct tgl_secret_chat *E) { - int *msg_key = decr_ptr; - decr_ptr += 4; - assert (decr_ptr < decr_end); - static unsigned char sha1a_buffer[20]; - static unsigned char sha1b_buffer[20]; - static unsigned char sha1c_buffer[20]; - static unsigned char sha1d_buffer[20]; - - static unsigned char buf[64]; - memcpy (buf, msg_key, 16); - memcpy (buf + 16, E->key, 32); - sha1 (buf, 48, sha1a_buffer); - - memcpy (buf, E->key + 8, 16); - memcpy (buf + 16, msg_key, 16); - memcpy (buf + 32, E->key + 12, 16); - sha1 (buf, 48, sha1b_buffer); - - memcpy (buf, E->key + 16, 32); - memcpy (buf + 32, msg_key, 16); - sha1 (buf, 48, sha1c_buffer); - - memcpy (buf, msg_key, 16); - memcpy (buf + 16, E->key + 24, 32); - sha1 (buf, 48, sha1d_buffer); - - static unsigned char key[32]; - memcpy (key, sha1a_buffer + 0, 8); - memcpy (key + 8, sha1b_buffer + 8, 12); - memcpy (key + 20, sha1c_buffer + 4, 12); - - static unsigned char iv[32]; - memcpy (iv, sha1a_buffer + 8, 12); - memcpy (iv + 12, sha1b_buffer + 0, 8); - memcpy (iv + 20, sha1c_buffer + 16, 4); - memcpy (iv + 24, sha1d_buffer + 0, 8); - - AES_KEY aes_key; - AES_set_decrypt_key (key, 256, &aes_key); - AES_ige_encrypt ((void *)decr_ptr, (void *)decr_ptr, 4 * (decr_end - decr_ptr), &aes_key, iv, 0); - memset (&aes_key, 0, sizeof (aes_key)); - - int x = *(decr_ptr); - if (x < 0 || (x & 3)) { - return -1; - } - assert (x >= 0 && !(x & 3)); - sha1 ((void *)decr_ptr, 4 + x, sha1a_buffer); - - if (memcmp (sha1a_buffer + 4, msg_key, 16)) { - return -1; - } - return 0; -} - -void tglf_fetch_encrypted_message (struct tgl_state *TLS, struct tgl_message *M) { - unsigned x = fetch_int (); - assert (x == CODE_encrypted_message || x == CODE_encrypted_message_service); - unsigned sx = x; - int new = !(M->flags & FLAG_CREATED); - long long id = fetch_long (); - int to_id = fetch_int (); - tgl_peer_id_t chat = TGL_MK_ENCR_CHAT (to_id); - int date = fetch_int (); - - tgl_peer_t *P = tgl_peer_get (TLS, chat); - if (!P) { - vlogprintf (E_WARNING, "Encrypted message to unknown chat. Dropping\n"); - M->flags |= FLAG_MESSAGE_EMPTY; - } - - - int len = prefetch_strlen (); - assert ((len & 15) == 8); - decr_ptr = (void *)fetch_str (len); - decr_end = decr_ptr + (len / 4); - int ok = 0; - if (P) { - if (*(long long *)decr_ptr != P->encr_chat.key_fingerprint) { - vlogprintf (E_WARNING, "Encrypted message with bad fingerprint to chat %s\n", P->print_name); - P = 0; - } - decr_ptr += 2; - } - int l = 0; - char *s = 0; - int *start = 0; - int *end = 0; - x = 0; - int out_seq_no = -1; - int in_seq_no = -1; - int drop = 0; - if (P && decrypt_encrypted_message (&P->encr_chat) >= 0 && new) { - ok = 1; - int *save_in_ptr = in_ptr; - int *save_in_end = in_end; - in_ptr = decr_ptr; - int ll = fetch_int (); - in_end = in_ptr + ll; - x = fetch_int (); - if (x == CODE_decrypted_message_layer) { - ll = prefetch_strlen (); - fetch_str (ll); // random_bytes - - int layer = fetch_int (); - assert (layer >= 0); - if (P && ((P->flags) & FLAG_CREATED)) { - bl_do_encr_chat_set_layer (TLS, (void *)P, layer); - } - //x = fetch_int (); - //assert (x == CODE_decrypted_message || x == CODE_decrypted_message_service); - - - out_seq_no = fetch_int (); - in_seq_no = fetch_int (); - if (in_seq_no / 2 != P->encr_chat.in_seq_no) { - vlogprintf (E_WARNING, "Hole in seq in secret chat. in_seq_no = %d, expect_seq_no = %d\n", in_seq_no / 2, P->encr_chat.in_seq_no); - drop = 1; - } - if ((in_seq_no & 1) != 1 - (P->encr_chat.admin_id == TLS->our_id) || - (out_seq_no & 1) != (P->encr_chat.admin_id == TLS->our_id)) { - vlogprintf (E_WARNING, "Bad msg admin\n"); - drop = 1; - } - if (out_seq_no / 2 > P->encr_chat.out_seq_no) { - vlogprintf (E_WARNING, "In seq no is bigger than our's out seq no (out_seq_no = %d, our_out_seq_no = %d). Drop\n", out_seq_no / 2, P->encr_chat.out_seq_no); - drop = 1; - } - if (out_seq_no / 2 < P->encr_chat.last_in_seq_no) { - vlogprintf (E_WARNING, "Clients in_seq_no decreased (out_seq_no = %d, last_out_seq_no = %d). Drop\n", out_seq_no / 2, P->encr_chat.last_in_seq_no); - drop = 1; - } - //vlogprintf (E_WARNING, "in = %d, out = %d\n", in_seq_no, out_seq_no); - //P->encr_chat.in_seq_no = in_seq_no / 2; - x = fetch_int (); - vlogprintf (E_DEBUG - 2, "layer = %d, in = %d, out = %d\n", layer, in_seq_no, out_seq_no); - } - if (!(x == CODE_decrypted_message || x == CODE_decrypted_message_service || x == CODE_decrypted_message_l16 || x == CODE_decrypted_message_service_l16)) { - vlogprintf (E_ERROR, "Incorrect message: x = 0x%08x\n", x); - drop = 1; - } - //assert (id == fetch_long ()); - if (!drop) { - long long new_id = fetch_long (); - if (P && P->encr_chat.layer >= 17) { - assert (new_id == id); - } - if (x == CODE_decrypted_message || x == CODE_decrypted_message_service) { - if (x == CODE_decrypted_message) { - fetch_int (); // ttl - } - } else { - ll = prefetch_strlen (); - fetch_str (ll); // random_bytes - } - if (x == CODE_decrypted_message || x == CODE_decrypted_message_l16) { - l = prefetch_strlen (); - s = fetch_str (l); - start = in_ptr; - assert (skip_type_any (TYPE_TO_PARAM (decrypted_message_media)) >= 0); - end = in_ptr; - } else { - start = in_ptr; - if (skip_type_any (TYPE_TO_PARAM (decrypted_message_action)) < 0) { - vlogprintf (E_ERROR, "Can not decrypt: Skipped %ld int out of %ld. Magic = 0x%08x\n", (long)(in_ptr - start), (long)(in_end - start), *start); - drop = 1; - } - end = in_ptr; - } - } - in_ptr = save_in_ptr; - in_end = save_in_end; - } - if (sx == CODE_encrypted_message) { - if (ok) { - int *start_file = in_ptr; - assert (skip_type_any (TYPE_TO_PARAM (encrypted_file)) >= 0); - if (x == CODE_decrypted_message || x == CODE_decrypted_message_l16) { - if (!drop) { - bl_do_create_message_media_encr (TLS, id, P->encr_chat.user_id, TGL_PEER_ENCR_CHAT, to_id, date, l, s, start, end - start, start_file, in_ptr - start_file); - } - } else if (x == CODE_decrypted_message_service || x == CODE_decrypted_message_service_l16) { - if (!drop) { - bl_do_create_message_service_encr (TLS, id, P->encr_chat.user_id, TGL_PEER_ENCR_CHAT, to_id, date, start, end - start); - } - } - } else { - if (!drop) { - assert (skip_type_any (TYPE_TO_PARAM (encrypted_file)) >= 0); - M->media.type = CODE_message_media_empty; - } - } - } else { - if (ok && (x == CODE_decrypted_message_service || x == CODE_decrypted_message_service_l16)) { - if (!drop) { - bl_do_create_message_service_encr (TLS, id, P->encr_chat.user_id, TGL_PEER_ENCR_CHAT, to_id, date, start, end - start); - } - } - } - if (!drop) { - if (in_seq_no >= 0 && out_seq_no >= 0) { - bl_do_encr_chat_update_seq (TLS, (void *)P, in_seq_no / 2 + 1, out_seq_no / 2); - assert (P->encr_chat.in_seq_no == in_seq_no / 2 + 1); - } - } -} - -void tglf_fetch_encrypted_message_file (struct tgl_state *TLS, struct tgl_message_media *M) { - unsigned x = fetch_int (); - assert (x == CODE_encrypted_file || x == CODE_encrypted_file_empty); - if (x == CODE_encrypted_file_empty) { - assert (M->type != tgl_message_media_photo_encr && M->type != tgl_message_media_video_encr); - } else { - assert (M->type == tgl_message_media_document_encr || M->type == tgl_message_media_photo_encr || M->type == tgl_message_media_video_encr || M->type == tgl_message_media_audio_encr); - - M->encr_photo.id = fetch_long(); - M->encr_photo.access_hash = fetch_long(); - if (!M->encr_photo.size) { - M->encr_photo.size = fetch_int (); - } else { - fetch_int (); - } - M->encr_photo.dc_id = fetch_int(); - M->encr_photo.key_fingerprint = fetch_int(); - } -} - -static int id_cmp (struct tgl_message *M1, struct tgl_message *M2) { - if (M1->id < M2->id) { return -1; } - else if (M1->id > M2->id) { return 1; } - else { return 0; } -} - -static void increase_peer_size (struct tgl_state *TLS) { - if (TLS->peer_num == TLS->peer_size) { - int new_size = TLS->peer_size ? 2 * TLS->peer_size : 10; - int old_size = TLS->peer_size; - if (old_size) { - TLS->Peers = trealloc (TLS->Peers, old_size * sizeof (void *), new_size * sizeof (void *)); - } else { - TLS->Peers = talloc (new_size * sizeof (void *)); - } - TLS->peer_size = new_size; - } -} - -struct tgl_user *tglf_fetch_alloc_user (struct tgl_state *TLS) { - int data[2]; - prefetch_data (data, 8); - tgl_peer_t *U = tgl_peer_get (TLS, TGL_MK_USER (data[1])); - if (!U) { - TLS->users_allocated ++; - U = talloc0 (sizeof (*U)); - U->id = TGL_MK_USER (data[1]); - TLS->peer_tree = tree_insert_peer (TLS->peer_tree, U, lrand48 ()); - increase_peer_size (TLS); - TLS->Peers[TLS->peer_num ++] = U; - } - tglf_fetch_user (TLS, &U->user); - return &U->user; -} - -struct tgl_secret_chat *tglf_fetch_alloc_encrypted_chat (struct tgl_state *TLS) { - int data[2]; - prefetch_data (data, 8); - tgl_peer_t *U = tgl_peer_get (TLS, TGL_MK_ENCR_CHAT (data[1])); - if (!U) { - U = talloc0 (sizeof (*U)); - U->id = TGL_MK_ENCR_CHAT (data[1]); - TLS->encr_chats_allocated ++; - TLS->peer_tree = tree_insert_peer (TLS->peer_tree, U, lrand48 ()); - increase_peer_size (TLS); - TLS->Peers[TLS->peer_num ++] = U; - } - tglf_fetch_encrypted_chat (TLS, &U->encr_chat); - return &U->encr_chat; -} - -struct tgl_user *tglf_fetch_alloc_user_full (struct tgl_state *TLS) { - int data[3]; - prefetch_data (data, 12); - tgl_peer_t *U = tgl_peer_get (TLS, TGL_MK_USER (data[2])); - if (U) { - tglf_fetch_user_full (TLS, &U->user); - return &U->user; - } else { - TLS->users_allocated ++; - U = talloc0 (sizeof (*U)); - U->id = TGL_MK_USER (data[2]); - TLS->peer_tree = tree_insert_peer (TLS->peer_tree, U, lrand48 ()); - tglf_fetch_user_full (TLS, &U->user); - increase_peer_size (TLS); - TLS->Peers[TLS->peer_num ++] = U; - return &U->user; - } -} - -struct tgl_message *tglf_fetch_alloc_message (struct tgl_state *TLS) { - int data[3]; - prefetch_data (data, 12); - struct tgl_message *M = tgl_message_get (TLS, data[0] != (int)CODE_message_empty ? data[2] : data[1]); - - if (!M) { - M = tglm_message_alloc (TLS, data[0] != (int)CODE_message_empty ? data[2] : data[1]); - } - tglf_fetch_message (TLS, M); - return M; -} - -struct tgl_message *tglf_fetch_alloc_geo_message (struct tgl_state *TLS) { - struct tgl_message *M = talloc (sizeof (*M)); - tglf_tglf_fetch_geo_message (TLS, M); - struct tgl_message *M1 = tree_lookup_message (TLS->message_tree, M); - TLS->messages_allocated ++; - if (M1) { - tglm_message_del_use (TLS, M1); - tglm_message_del_peer (TLS, M1); - tgls_clear_message (TLS, M1); - memcpy (M1, M, sizeof (*M)); - tfree (M, sizeof (*M)); - tglm_message_add_use (TLS, M1); - tglm_message_add_peer (TLS, M1); - TLS->messages_allocated --; - return M1; - } else { - tglm_message_add_use (TLS, M); - tglm_message_add_peer (TLS, M); - TLS->message_tree = tree_insert_message (TLS->message_tree, M, lrand48 ()); - return M; - } -} - -struct tgl_message *tglf_fetch_alloc_encrypted_message (struct tgl_state *TLS) { - int data[3]; - prefetch_data (data, 12); - struct tgl_message *M = tgl_message_get (TLS, *(long long *)(data + 1)); - - if (!M) { - M = talloc0 (sizeof (*M)); - M->id = *(long long *)(data + 1); - tglm_message_insert_tree (TLS, M); - TLS->messages_allocated ++; - assert (tgl_message_get (TLS, M->id) == M); - } - tglf_fetch_encrypted_message (TLS, M); - return M; -} - -struct tgl_message *tglf_fetch_alloc_message_short (struct tgl_state *TLS) { - int data[1]; - prefetch_data (data, 4); - struct tgl_message *M = tgl_message_get (TLS, data[0]); - - if (!M) { - M = talloc0 (sizeof (*M)); - M->id = data[0]; - tglm_message_insert_tree (TLS, M); - TLS->messages_allocated ++; - } - tglf_fetch_message_short (TLS, M); - return M; -} - -struct tgl_message *tglf_fetch_alloc_message_short_chat (struct tgl_state *TLS) { - int data[1]; - prefetch_data (data, 4); - struct tgl_message *M = tgl_message_get (TLS, data[0]); - - if (!M) { - M = talloc0 (sizeof (*M)); - M->id = data[0]; - tglm_message_insert_tree (TLS, M); - TLS->messages_allocated ++; - } - tglf_fetch_message_short_chat (TLS, M); - return M; -} - -struct tgl_chat *tglf_fetch_alloc_chat (struct tgl_state *TLS) { - int data[2]; - prefetch_data (data, 8); - tgl_peer_t *U = tgl_peer_get (TLS, TGL_MK_CHAT (data[1])); - if (!U) { - TLS->chats_allocated ++; - U = talloc0 (sizeof (*U)); - U->id = TGL_MK_CHAT (data[1]); - TLS->peer_tree = tree_insert_peer (TLS->peer_tree, U, lrand48 ()); - increase_peer_size (TLS); - TLS->Peers[TLS->peer_num ++] = U; - } - tglf_fetch_chat (TLS, &U->chat); - return &U->chat; -} - -struct tgl_chat *tglf_fetch_alloc_chat_full (struct tgl_state *TLS) { - int data[3]; - prefetch_data (data, 12); - tgl_peer_t *U = tgl_peer_get (TLS, TGL_MK_CHAT (data[2])); - if (U) { - tglf_fetch_chat_full (TLS, &U->chat); - return &U->chat; - } else { - TLS->chats_allocated ++; - U = talloc0 (sizeof (*U)); - U->id = TGL_MK_CHAT (data[2]); - TLS->peer_tree = tree_insert_peer (TLS->peer_tree, U, lrand48 ()); - tglf_fetch_chat_full (TLS, &U->chat); - increase_peer_size (TLS); - TLS->Peers[TLS->peer_num ++] = U; - return &U->chat; - } -} -/* }}} */ - -void tglp_insert_encrypted_chat (struct tgl_state *TLS, tgl_peer_t *P) { - TLS->encr_chats_allocated ++; - TLS->peer_tree = tree_insert_peer (TLS->peer_tree, P, lrand48 ()); - increase_peer_size (TLS); - TLS->Peers[TLS->peer_num ++] = P; -} - -void tglp_insert_user (struct tgl_state *TLS, tgl_peer_t *P) { - TLS->users_allocated ++; - TLS->peer_tree = tree_insert_peer (TLS->peer_tree, P, lrand48 ()); - increase_peer_size (TLS); - TLS->Peers[TLS->peer_num ++] = P; -} - -void tglp_insert_chat (struct tgl_state *TLS, tgl_peer_t *P) { - TLS->chats_allocated ++; - TLS->peer_tree = tree_insert_peer (TLS->peer_tree, P, lrand48 ()); - increase_peer_size (TLS); - TLS->Peers[TLS->peer_num ++] = P; -} - -void tgl_insert_empty_user (struct tgl_state *TLS, int uid) { - tgl_peer_id_t id = TGL_MK_USER (uid); - if (tgl_peer_get (TLS, id)) { return; } - tgl_peer_t *P = talloc0 (sizeof (*P)); - P->id = id; - tglp_insert_user (TLS, P); -} - -void tgl_insert_empty_chat (struct tgl_state *TLS, int cid) { - tgl_peer_id_t id = TGL_MK_CHAT (cid); - if (tgl_peer_get (TLS, id)) { return; } - tgl_peer_t *P = talloc0 (sizeof (*P)); - P->id = id; - tglp_insert_chat (TLS, P); -} - -/* {{{ Free */ - -void tgls_free_photo_size (struct tgl_state *TLS, struct tgl_photo_size *S) { - tfree_str (S->type); - if (S->data) { - tfree (S->data, S->size); - } -} - -void tgls_free_photo (struct tgl_state *TLS, struct tgl_photo *P) { - if (P->caption) { tfree_str (P->caption); } - if (P->sizes) { - int i; - for (i = 0; i < P->sizes_num; i++) { - tgls_free_photo_size (TLS, &P->sizes[i]); - } - tfree (P->sizes, sizeof (struct tgl_photo_size) * P->sizes_num); - } -} - -void tgls_free_video (struct tgl_state *TLS, struct tgl_video *V) { - tfree_str (V->mime_type); - if (!V->access_hash) { return; } - tfree_str (V->caption); - tgls_free_photo_size (TLS, &V->thumb); -} - -void tgls_free_audio (struct tgl_state *TLS, struct tgl_audio *A) { - tfree_str (A->mime_type); -} - -void tgls_free_document (struct tgl_state *TLS, struct tgl_document *D) { - if (!D->access_hash) { return; } - if (D->mime_type) { tfree_str (D->mime_type);} - if (D->caption) {tfree_str (D->caption);} - tgls_free_photo_size (TLS, &D->thumb); -} - -void tgls_free_message_media (struct tgl_state *TLS, struct tgl_message_media *M) { - switch (M->type) { - case tgl_message_media_none: - case tgl_message_media_geo: - return; - case tgl_message_media_audio: - tgls_free_audio (TLS, &M->audio); - return; - case tgl_message_media_photo: - tgls_free_photo (TLS, &M->photo); - return; - case tgl_message_media_video: - tgls_free_video (TLS, &M->video); - return; - case tgl_message_media_contact: - tfree_str (M->phone); - tfree_str (M->first_name); - tfree_str (M->last_name); - return; - case tgl_message_media_document: - tgls_free_document (TLS, &M->document); - return; - case tgl_message_media_unsupported: - tfree (M->data, M->data_size); - return; - case tgl_message_media_photo_encr: - case tgl_message_media_video_encr: - case tgl_message_media_audio_encr: - case tgl_message_media_document_encr: - tfree_secure (M->encr_photo.key, 32); - tfree_secure (M->encr_photo.iv, 32); - return; - default: - vlogprintf (E_ERROR, "type = 0x%08x\n", M->type); - assert (0); - } -} - -void tgls_free_message_action (struct tgl_state *TLS, struct tgl_message_action *M) { - switch (M->type) { - case tgl_message_action_none: - break; - case tgl_message_action_chat_create: - tfree_str (M->title); - tfree (M->users, M->user_num * 4); - break; - case tgl_message_action_chat_edit_title: - tfree_str (M->new_title); - break; - case tgl_message_action_chat_edit_photo: - tgls_free_photo (TLS, &M->photo); - break; - case tgl_message_action_chat_delete_photo: - case tgl_message_action_chat_add_user: - case tgl_message_action_chat_delete_user: - case tgl_message_action_geo_chat_create: - case tgl_message_action_geo_chat_checkin: - case tgl_message_action_set_message_ttl: - case tgl_message_action_read_messages: - case tgl_message_action_delete_messages: - case tgl_message_action_screenshot_messages: - case tgl_message_action_flush_history: - case tgl_message_action_resend: - case tgl_message_action_notify_layer: - break; - - default: - vlogprintf (E_ERROR, "type = 0x%08x\n", M->type); - assert (0); - } -} - -void tgls_clear_message (struct tgl_state *TLS, struct tgl_message *M) { - if (!M->service) { - if (M->message) { tfree (M->message, M->message_len + 1); } - tgls_free_message_media (TLS, &M->media); - } else { - tgls_free_message_action (TLS, &M->action); - } -} - -void tgls_free_message (struct tgl_state *TLS, struct tgl_message *M) { - tgls_clear_message (TLS, M); - tfree (M, sizeof (*M)); -} - -void tgls_free_chat (struct tgl_state *TLS, struct tgl_chat *U) { - if (U->title) { tfree_str (U->title); } - if (U->print_title) { tfree_str (U->print_title); } - if (U->user_list) { - tfree (U->user_list, U->user_list_size * 12); - } - tgls_free_photo (TLS, &U->photo); - tfree (U, sizeof (*U)); -} - -void tgls_free_user (struct tgl_state *TLS, struct tgl_user *U) { - if (U->first_name) { tfree_str (U->first_name); } - if (U->last_name) { tfree_str (U->last_name); } - if (U->print_name) { tfree_str (U->print_name); } - if (U->phone) { tfree_str (U->phone); } - if (U->real_first_name) { tfree_str (U->real_first_name); } - if (U->real_last_name) { tfree_str (U->real_last_name); } - tgls_free_photo (TLS, &U->photo); - tfree (U, sizeof (*U)); -} - -void tgls_free_encr_chat (struct tgl_state *TLS, struct tgl_secret_chat *U) { - if (U->print_name) { tfree_str (U->print_name); } - if (U->g_key) { tfree (U->g_key, 256); } - if (U->nonce) { tfree (U->nonce, 256); } - tfree (U, sizeof (*U)); -} - -void tgls_free_peer (struct tgl_state *TLS, tgl_peer_t *P) { - if (tgl_get_peer_type (P->id) == TGL_PEER_USER) { - tgls_free_user (TLS, (void *)P); - } else if (tgl_get_peer_type (P->id) == TGL_PEER_CHAT) { - tgls_free_chat (TLS, (void *)P); - } else if (tgl_get_peer_type (P->id) == TGL_PEER_ENCR_CHAT) { - tgls_free_encr_chat (TLS, (void *)P); - } else { - assert (0); - } -} -/* }}} */ - -/* Messages {{{ */ - -void tglm_message_del_use (struct tgl_state *TLS, struct tgl_message *M) { - M->next_use->prev_use = M->prev_use; - M->prev_use->next_use = M->next_use; -} - -void tglm_message_add_use (struct tgl_state *TLS, struct tgl_message *M) { - M->next_use = TLS->message_list.next_use; - M->prev_use = &TLS->message_list; - M->next_use->prev_use = M; - M->prev_use->next_use = M; -} - -void tglm_message_add_peer (struct tgl_state *TLS, struct tgl_message *M) { - tgl_peer_id_t id; - if (!tgl_cmp_peer_id (M->to_id, TGL_MK_USER (TLS->our_id))) { - id = M->from_id; - } else { - id = M->to_id; - } - tgl_peer_t *P = tgl_peer_get (TLS, id); - if (!P) { - P = talloc0 (sizeof (*P)); - P->id = id; - switch (tgl_get_peer_type (id)) { - case TGL_PEER_USER: - TLS->users_allocated ++; - break; - case TGL_PEER_CHAT: - TLS->chats_allocated ++; - break; - case TGL_PEER_GEO_CHAT: - TLS->geo_chats_allocated ++; - break; - case TGL_PEER_ENCR_CHAT: - TLS->encr_chats_allocated ++; - break; - } - TLS->peer_tree = tree_insert_peer (TLS->peer_tree, P, lrand48 ()); - increase_peer_size (TLS); - TLS->Peers[TLS->peer_num ++] = P; - } - if (!P->last) { - P->last = M; - M->prev = M->next = 0; - } else { - if (tgl_get_peer_type (P->id) != TGL_PEER_ENCR_CHAT) { - struct tgl_message *N = P->last; - struct tgl_message *NP = 0; - while (N && N->id > M->id) { - NP = N; - N = N->next; - } - if (N) { assert (N->id < M->id); } - M->next = N; - M->prev = NP; - if (N) { N->prev = M; } - if (NP) { NP->next = M; } - else { P->last = M; } - } else { - struct tgl_message *N = P->last; - struct tgl_message *NP = 0; - M->next = N; - M->prev = NP; - if (N) { N->prev = M; } - if (NP) { NP->next = M; } - else { P->last = M; } - } - } -} - -void tglm_message_del_peer (struct tgl_state *TLS, struct tgl_message *M) { - tgl_peer_id_t id; - if (!tgl_cmp_peer_id (M->to_id, TGL_MK_USER (TLS->our_id))) { - id = M->from_id; - } else { - id = M->to_id; - } - tgl_peer_t *P = tgl_peer_get (TLS, id); - if (M->prev) { - M->prev->next = M->next; - } - if (M->next) { - M->next->prev = M->prev; - } - if (P && P->last == M) { - P->last = M->next; - } -} - -struct tgl_message *tglm_message_alloc (struct tgl_state *TLS, long long id) { - struct tgl_message *M = talloc0 (sizeof (*M)); - M->id = id; - tglm_message_insert_tree (TLS, M); - TLS->messages_allocated ++; - return M; -} - -void tglm_update_message_id (struct tgl_state *TLS, struct tgl_message *M, long long id) { - TLS->message_tree = tree_delete_message (TLS->message_tree, M); - M->id = id; - TLS->message_tree = tree_insert_message (TLS->message_tree, M, lrand48 ()); -} - -void tglm_message_insert_tree (struct tgl_state *TLS, struct tgl_message *M) { - assert (M->id); - TLS->message_tree = tree_insert_message (TLS->message_tree, M, lrand48 ()); -} - -void tglm_message_remove_tree (struct tgl_state *TLS, struct tgl_message *M) { - assert (M->id); - TLS->message_tree = tree_delete_message (TLS->message_tree, M); -} - -void tglm_message_insert (struct tgl_state *TLS, struct tgl_message *M) { - tglm_message_add_use (TLS, M); - tglm_message_add_peer (TLS, M); -} - -void tglm_message_insert_unsent (struct tgl_state *TLS, struct tgl_message *M) { - TLS->message_unsent_tree = tree_insert_message (TLS->message_unsent_tree, M, lrand48 ()); -} - -void tglm_message_remove_unsent (struct tgl_state *TLS, struct tgl_message *M) { - TLS->message_unsent_tree = tree_delete_message (TLS->message_unsent_tree, M); -} - -static void __send_msg (struct tgl_message *M, void *_TLS) { - struct tgl_state *TLS = _TLS; - vlogprintf (E_NOTICE, "Resending message...\n"); - //print_message (M); - - if (M->media.type != tgl_message_media_none) { - assert (M->flags & FLAG_ENCRYPTED); - bl_do_delete_msg (TLS, M); - } else { - tgl_do_send_msg (TLS, M, 0, 0); - } -} - -void tglm_send_all_unsent (struct tgl_state *TLS) { - tree_act_ex_message (TLS->message_unsent_tree, __send_msg, TLS); -} -/* }}} */ - -void tglp_peer_insert_name (struct tgl_state *TLS, tgl_peer_t *P) { - TLS->peer_by_name_tree = tree_insert_peer_by_name (TLS->peer_by_name_tree, P, lrand48 ()); -} - -void tglp_peer_delete_name (struct tgl_state *TLS, tgl_peer_t *P) { - TLS->peer_by_name_tree = tree_delete_peer_by_name (TLS->peer_by_name_tree, P); -} - -tgl_peer_t *tgl_peer_get (struct tgl_state *TLS, tgl_peer_id_t id) { - static tgl_peer_t U; - U.id = id; - return tree_lookup_peer (TLS->peer_tree, &U); -} - -struct tgl_message *tgl_message_get (struct tgl_state *TLS, long long id) { - struct tgl_message M; - M.id = id; - return tree_lookup_message (TLS->message_tree, &M); -} - -tgl_peer_t *tgl_peer_get_by_name (struct tgl_state *TLS, const char *s) { - static tgl_peer_t P; - P.print_name = (void *)s; - tgl_peer_t *R = tree_lookup_peer_by_name (TLS->peer_by_name_tree, &P); - return R; -} - -void tgl_peer_iterator_ex (struct tgl_state *TLS, void (*it)(tgl_peer_t *P, void *extra), void *extra) { - tree_act_ex_peer (TLS->peer_tree, it, extra); -} - -int tgl_complete_user_list (struct tgl_state *TLS, int index, const char *text, int len, char **R) { - index ++; - while (index < TLS->peer_num && (!TLS->Peers[index]->print_name || strncmp (TLS->Peers[index]->print_name, text, len) || tgl_get_peer_type (TLS->Peers[index]->id) != TGL_PEER_USER)) { - index ++; - } - if (index < TLS->peer_num) { - *R = strdup (TLS->Peers[index]->print_name); - assert (*R); - return index; - } else { - return -1; - } -} - -int tgl_complete_chat_list (struct tgl_state *TLS, int index, const char *text, int len, char **R) { - index ++; - while (index < TLS->peer_num && (!TLS->Peers[index]->print_name || strncmp (TLS->Peers[index]->print_name, text, len) || tgl_get_peer_type (TLS->Peers[index]->id) != TGL_PEER_CHAT)) { - index ++; - } - if (index < TLS->peer_num) { - *R = strdup (TLS->Peers[index]->print_name); - assert (*R); - return index; - } else { - return -1; - } -} - -int tgl_complete_encr_chat_list (struct tgl_state *TLS, int index, const char *text, int len, char **R) { - index ++; - while (index < TLS->peer_num && (!TLS->Peers[index]->print_name || strncmp (TLS->Peers[index]->print_name, text, len) || tgl_get_peer_type (TLS->Peers[index]->id) != TGL_PEER_ENCR_CHAT)) { - index ++; - } - if (index < TLS->peer_num) { - *R = strdup (TLS->Peers[index]->print_name); - assert (*R); - return index; - } else { - return -1; - } -} - -int tgl_complete_peer_list (struct tgl_state *TLS, int index, const char *text, int len, char **R) { - index ++; - while (index < TLS->peer_num && (!TLS->Peers[index]->print_name || strncmp (TLS->Peers[index]->print_name, text, len))) { - index ++; - } - if (index < TLS->peer_num) { - *R = strdup (TLS->Peers[index]->print_name); - assert (*R); - return index; - } else { - return -1; - } -} - -void tgls_free_peer_gw (tgl_peer_t *P, void *TLS) { - tgls_free_peer (TLS, P); -} - -void tgls_free_message_gw (struct tgl_message *M, void *TLS) { - tgls_free_message (TLS, M); -} - -void tgl_free_all (struct tgl_state *TLS) { - tree_act_ex_peer (TLS->peer_tree, tgls_free_peer_gw, TLS); - TLS->peer_tree = tree_clear_peer (TLS->peer_tree); - TLS->peer_by_name_tree = tree_clear_peer_by_name (TLS->peer_by_name_tree); - tree_act_ex_message (TLS->message_tree, tgls_free_message_gw, TLS); - TLS->message_tree = tree_clear_message (TLS->message_tree); - tree_act_ex_message (TLS->message_unsent_tree, tgls_free_message_gw, TLS); - TLS->message_unsent_tree = tree_clear_message (TLS->message_unsent_tree); - - if (TLS->encr_prime) { tfree (TLS->encr_prime, 256); } - - - if (TLS->binlog_name) { tfree_str (TLS->binlog_name); } - if (TLS->auth_file) { tfree_str (TLS->auth_file); } - if (TLS->downloads_directory) { tfree_str (TLS->downloads_directory); } - - int i; - for (i = 0; i < TLS->rsa_key_num; i++) { - tfree_str (TLS->rsa_key_list[i]); - } - - for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i]) { - tgls_free_dc (TLS, TLS->DC_list[i]); - } - BN_CTX_free (TLS->BN_ctx); - tgls_free_pubkey (TLS); -} - -int tgl_print_stat (struct tgl_state *TLS, char *s, int len) { - return tsnprintf (s, len, - "users_allocated\t%d\n" - "chats_allocated\t%d\n" - "encr_chats_allocated\t%d\n" - "peer_num\t%d\n" - "messages_allocated\t%d\n", - TLS->users_allocated, - TLS->chats_allocated, - TLS->encr_chats_allocated, - TLS->peer_num, - TLS->messages_allocated - ); -} diff --git a/structures.h b/structures.h deleted file mode 100644 index b7855bb..0000000 --- a/structures.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - 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 __STRUCTURES_H__ -#define __STRUCTURES_H__ - -#include -#include "tgl-layout.h" -#include "tgl-fetch.h" -#include "tgl.h" - -char *tgls_default_create_print_name (struct tgl_state *TLS, tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4); - - -void tgls_free_user (struct tgl_state *TLS, struct tgl_user *U); -void tgls_free_chat (struct tgl_state *TLS, struct tgl_chat *U); -void tgls_free_photo (struct tgl_state *TLS, struct tgl_photo *P); -void tgls_free_message (struct tgl_state *TLS, struct tgl_message *M); -void tgls_clear_message (struct tgl_state *TLS, struct tgl_message *M); - -struct tgl_message *tglm_message_alloc (struct tgl_state *TLS, long long id); -void tglm_message_insert_tree (struct tgl_state *TLS, struct tgl_message *M); -void tglm_update_message_id (struct tgl_state *TLS, struct tgl_message *M, long long id); -void tglm_message_insert (struct tgl_state *TLS, struct tgl_message *M); -void tglm_message_insert_unsent (struct tgl_state *TLS, struct tgl_message *M); -void tglm_message_remove_unsent (struct tgl_state *TLS, struct tgl_message *M); -void tglm_send_all_unsent (struct tgl_state *TLS); -void tglm_message_remove_tree (struct tgl_state *TLS, struct tgl_message *M); -void tglm_message_add_peer (struct tgl_state *TLS, struct tgl_message *M); -void tglm_message_del_peer (struct tgl_state *TLS, struct tgl_message *M); -void tglm_message_del_use (struct tgl_state *TLS, struct tgl_message *M); -void tglm_message_add_use (struct tgl_state *TLS, struct tgl_message *M); - -void tglp_peer_insert_name (struct tgl_state *TLS, tgl_peer_t *P); -void tglp_peer_delete_name (struct tgl_state *TLS, tgl_peer_t *P); -void tglp_insert_encrypted_chat (struct tgl_state *TLS, tgl_peer_t *P); -void tglp_insert_user (struct tgl_state *TLS, tgl_peer_t *P); -void tglp_insert_chat (struct tgl_state *TLS, tgl_peer_t *P); -enum tgl_typing_status tglf_fetch_typing (void); - -#endif diff --git a/tgl b/tgl new file mode 160000 index 0000000..6a59fd3 --- /dev/null +++ b/tgl @@ -0,0 +1 @@ +Subproject commit 6a59fd311c1246aba4f6fb2c9a28e40e7abb3f2e diff --git a/tgl-fetch.h b/tgl-fetch.h deleted file mode 100644 index 428f32e..0000000 --- a/tgl-fetch.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - 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__ -#include "tgl.h" - -int tglf_fetch_file_location (struct tgl_state *TLS, struct tgl_file_location *loc); -int tglf_fetch_user_status (struct tgl_state *TLS, struct tgl_user_status *S, struct tgl_user *U); -int tglf_fetch_user (struct tgl_state *TLS, struct tgl_user *U); -struct tgl_user *tglf_fetch_alloc_user (struct tgl_state *TLS); -struct tgl_user *tglf_fetch_alloc_user_full (struct tgl_state *TLS); -struct tgl_chat *tglf_fetch_alloc_chat (struct tgl_state *TLS); -struct tgl_chat *tglf_fetch_alloc_chat_full (struct tgl_state *TLS); -struct tgl_secret_chat *tglf_fetch_alloc_encrypted_chat (struct tgl_state *TLS); -struct tgl_message *tglf_fetch_alloc_message (struct tgl_state *TLS); -struct tgl_message *tglf_fetch_alloc_geo_message (struct tgl_state *TLS); -struct tgl_message *tglf_fetch_alloc_message_short (struct tgl_state *TLS); -struct tgl_message *tglf_fetch_alloc_message_short_chat (struct tgl_state *TLS); -struct tgl_message *tglf_fetch_alloc_encrypted_message (struct tgl_state *TLS); -void tglf_fetch_encrypted_message_file (struct tgl_state *TLS, struct tgl_message_media *M); -tgl_peer_id_t tglf_fetch_peer_id (struct tgl_state *TLS); - -void tglf_fetch_message_media (struct tgl_state *TLS, struct tgl_message_media *M); -void tglf_fetch_message_media_encrypted (struct tgl_state *TLS, struct tgl_message_media *M); -void tglf_fetch_message_action (struct tgl_state *TLS, struct tgl_message_action *M); -void tglf_fetch_message_action_encrypted (struct tgl_state *TLS, struct tgl_message_action *M); -void tglf_fetch_photo (struct tgl_state *TLS, struct tgl_photo *P); - -void tglf_fetch_chat (struct tgl_state *TLS, struct tgl_chat *C); -void tglf_fetch_chat_full (struct tgl_state *TLS, struct tgl_chat *C); - -void tglf_fetch_audio (struct tgl_state *TLS, struct tgl_audio *V); -void tglf_fetch_video (struct tgl_state *TLS, struct tgl_video *V); -void tglf_fetch_document (struct tgl_state *TLS, struct tgl_document *V); -void tglf_fetch_message (struct tgl_state *TLS, struct tgl_message *M); -void tglf_fetch_geo_message (struct tgl_state *TLS, struct tgl_message *M); -#endif diff --git a/tgl-inner.h b/tgl-inner.h deleted file mode 100644 index acb3855..0000000 --- a/tgl-inner.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - 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 (TLS->verbosity >= verbosity_level) { \ - TLS->callback.logprintf (__VA_ARGS__); \ - } \ - } while (0) - -#endif diff --git a/tgl-layout.h b/tgl-layout.h deleted file mode 100644 index 50177ef..0000000 --- a/tgl-layout.h +++ /dev/null @@ -1,447 +0,0 @@ -/* - 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 tgl_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 tgl_timer *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_resend, - tgl_message_action_notify_layer, - tgl_message_action_typing -}; - -enum tgl_typing_status { - tgl_typing_none, - tgl_typing_typing, - tgl_typing_cancel, - tgl_typing_record_video, - tgl_typing_upload_video, - tgl_typing_record_audio, - tgl_typing_upload_audio, - tgl_typing_upload_photo, - tgl_typing_upload_document, - tgl_typing_geo, - tgl_typing_choose_contact -}; - -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_timer *ev; -}; - -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; - char *username; -}; - -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; - int in_seq_no; - int out_seq_no; - int last_in_seq_no; - 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; - enum tgl_typing_status typing; - struct { - int start_seq_no; - int end_seq_no; - }; - }; -}; - -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 diff --git a/tgl-timers.c b/tgl-timers.c deleted file mode 100644 index b78581a..0000000 --- a/tgl-timers.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - 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 "config.h" -#ifdef EVENT_V2 -#include -#include -#include -#else -#include -#include "event-old.h" -#endif - -#include "tgl.h" -#include - -static void timer_alarm (evutil_socket_t fd, short what, void *arg) { - void **p = arg; - ((void (*)(struct tgl_state *, void *))p[1]) (p[0], p[2]); -} - -struct tgl_timer *tgl_timer_alloc (struct tgl_state *TLS, void (*cb)(struct tgl_state *TLS, void *arg), void *arg) { - void **p = malloc (sizeof (void *) * 3); - p[0] = TLS; - p[1] = cb; - p[2] = arg; - return (void *)evtimer_new (TLS->ev_base, timer_alarm, p); -} - -void tgl_timer_insert (struct tgl_timer *t, double p) { - if (p < 0) { p = 0; } - double e = p - (int)p; - if (e < 0) { e = 0; } - struct timeval pv = { (int)p, (int)(e * 1e6)}; - event_add ((void *)t, &pv); -} - -void tgl_timer_delete (struct tgl_timer *t) { - event_del ((void *)t); -} - -void tgl_timer_free (struct tgl_timer *t) { - void *arg = event_get_callback_arg ((void *)t); - free (arg); - event_free ((void *)t); -} - -struct tgl_timer_methods tgl_libevent_timers = { - .alloc = tgl_timer_alloc, - .insert = tgl_timer_insert, - .delete = tgl_timer_delete, - .free = tgl_timer_free -}; diff --git a/tgl-timers.h b/tgl-timers.h deleted file mode 100644 index 052dd56..0000000 --- a/tgl-timers.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - 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 __TGL_TIMERS_H__ -#define __TGL_TIMERS_H__ - -#include "tgl.h" -extern struct tgl_timer_methods tgl_libevent_timers; - -#endif diff --git a/tgl.c b/tgl.c deleted file mode 100644 index c6a1d77..0000000 --- a/tgl.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - 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" - -#include - -struct tgl_state tgl_state; - - -void tgl_set_binlog_mode (struct tgl_state *TLS, int mode) { - TLS->binlog_enabled = mode; -} - -void tgl_set_binlog_path (struct tgl_state *TLS, const char *path) { - TLS->binlog_name = tstrdup (path); -} - -void tgl_set_auth_file_path (struct tgl_state *TLS, const char *path) { - TLS->auth_file = tstrdup (path); -} - -void tgl_set_download_directory (struct tgl_state *TLS, const char *path) { - TLS->downloads_directory = tstrdup (path); -} - -void tgl_set_callback (struct tgl_state *TLS, struct tgl_update_callback *cb) { - TLS->callback = *cb; -} - -void tgl_set_rsa_key (struct tgl_state *TLS, const char *key) { - assert (TLS->rsa_key_num < TGL_MAX_RSA_KEYS_NUM); - TLS->rsa_key_list[TLS->rsa_key_num ++] = tstrdup (key); -} - -void tgl_init (struct tgl_state *TLS) { - assert (TLS->timer_methods); - assert (TLS->net_methods); - if (!TLS->callback.create_print_name) { - TLS->callback.create_print_name = tgls_default_create_print_name; - } - if (!TLS->temp_key_expire_time) { - TLS->temp_key_expire_time = 100000; - } - - TLS->message_list.next_use = &TLS->message_list; - TLS->message_list.prev_use = &TLS->message_list; - - tglmp_on_start (TLS); -} - -int tgl_authorized_dc (struct tgl_state *TLS, struct tgl_dc *DC) { - assert (DC); - return (DC->flags & 4) != 0;//DC->auth_key_id; -} - -int tgl_signed_dc (struct tgl_state *TLS, struct tgl_dc *DC) { - assert (DC); - return DC->has_auth; -} - diff --git a/tgl.h b/tgl.h deleted file mode 100644 index 33e19b5..0000000 --- a/tgl.h +++ /dev/null @@ -1,395 +0,0 @@ -/* - 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 -#include -#include - -#define TGL_MAX_DC_NUM 100 -#define TG_SERVER_1 "173.240.5.1" -#define TG_SERVER_2 "149.154.167.51" -#define TG_SERVER_3 "174.140.142.6" -#define TG_SERVER_4 "149.154.167.91" -#define TG_SERVER_5 "149.154.171.5" -#define TG_SERVER_DEFAULT 4 - -#define TG_SERVER_TEST_1 "173.240.5.253" -#define TG_SERVER_TEST_2 "149.154.167.40" -#define TG_SERVER_TEST_3 "174.140.142.5" -#define TG_SERVER_TEST_DEFAULT 2 - -// JUST RANDOM STRING -#define TGL_BUILD "2590" -#define TGL_VERSION "1.1.0" - -#define TGL_ENCRYPTED_LAYER 17 - -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 -#define TGL_UPDATE_USERNAME (1 << 15) - -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_state; - -struct tgl_update_callback { - void (*new_msg)(struct tgl_state *TLS, struct tgl_message *M); - void (*marked_read)(struct tgl_state *TLS, int num, struct tgl_message *list[]); - void (*logprintf)(const char *format, ...) __attribute__ ((format (printf, 1, 2))); - void (*type_notification)(struct tgl_state *TLS, struct tgl_user *U, enum tgl_typing_status status); - void (*type_in_chat_notification)(struct tgl_state *TLS, struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status); - void (*type_in_secret_chat_notification)(struct tgl_state *TLS, struct tgl_secret_chat *E); - void (*status_notification)(struct tgl_state *TLS, struct tgl_user *U); - void (*user_registered)(struct tgl_state *TLS, struct tgl_user *U); - void (*user_activated)(struct tgl_state *TLS, struct tgl_user *U); - void (*new_authorization)(struct tgl_state *TLS, const char *device, const char *location); - void (*chat_update)(struct tgl_state *TLS, struct tgl_chat *C, unsigned flags); - void (*user_update)(struct tgl_state *TLS, struct tgl_user *C, unsigned flags); - void (*secret_chat_update)(struct tgl_state *TLS, struct tgl_secret_chat *C, unsigned flags); - void (*msg_receive)(struct tgl_state *TLS, struct tgl_message *M); - void (*our_id)(struct tgl_state *TLS, int id); - void (*notification)(struct tgl_state *TLS, char *type, char *message); - void (*user_status_update)(struct tgl_state *TLS, struct tgl_user *U); - char *(*create_print_name) (struct tgl_state *TLS, 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) (struct tgl_state *TLS, const char *host, int port, struct tgl_session *session, struct tgl_dc *dc, struct mtproto_methods *methods); -}; - -struct mtproto_methods { - int (*ready) (struct tgl_state *TLS, struct connection *c); - int (*close) (struct tgl_state *TLS, struct connection *c); - int (*execute) (struct tgl_state *TLS, struct connection *c, int op, int len); -}; - -struct tgl_timer; - -struct tgl_timer_methods { - struct tgl_timer *(*alloc) (struct tgl_state *TLS, void (*cb)(struct tgl_state *TLS, void *arg), void *arg); - void (*insert) (struct tgl_timer *t, double timeout); - void (*delete) (struct tgl_timer *t); - void (*free) (struct tgl_timer *t); -}; - -#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 - -#pragma pack(push,4) -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; - void *ev_base; - - char *rsa_key_list[TGL_MAX_RSA_KEYS_NUM]; - int rsa_key_num; - struct bignum_ctx *BN_ctx; - - struct tgl_allocator allocator; - - struct tree_peer *peer_tree; - struct tree_peer_by_name *peer_by_name_tree; - struct tree_message *message_tree; - struct tree_message *message_unsent_tree; - - int users_allocated; - int chats_allocated; - int messages_allocated; - int peer_num; - int peer_size; - int encr_chats_allocated; - int geo_chats_allocated; - - tgl_peer_t **Peers; - struct tgl_message message_list; - - int binlog_fd; - - struct tgl_timer_methods *timer_methods; - - void *pubKey; - - struct tree_query *queries_tree; - - char *base_path; - - struct tree_user *online_updates; - - struct tgl_timer *online_updates_timer; -}; -#pragma pack(pop) -//extern struct tgl_state tgl_state; - -void tgl_reopen_binlog_for_writing (struct tgl_state *TLS); -void tgl_replay_log (struct tgl_state *TLS); - -int tgl_print_stat (struct tgl_state *TLS, char *s, int len); -tgl_peer_t *tgl_peer_get (struct tgl_state *TLS, tgl_peer_id_t id); -tgl_peer_t *tgl_peer_get_by_name (struct tgl_state *TLS, const char *s); - -struct tgl_message *tgl_message_get (struct tgl_state *TLS, long long id); -void tgl_peer_iterator_ex (struct tgl_state *TLS, void (*it)(tgl_peer_t *P, void *extra), void *extra); - -int tgl_complete_user_list (struct tgl_state *TLS, int index, const char *text, int len, char **R); -int tgl_complete_chat_list (struct tgl_state *TLS, int index, const char *text, int len, char **R); -int tgl_complete_encr_chat_list (struct tgl_state *TLS, int index, const char *text, int len, char **R); -int tgl_complete_peer_list (struct tgl_state *TLS, 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 (struct tgl_state *TLS, int mode); -void tgl_set_binlog_path (struct tgl_state *TLS, const char *path); -void tgl_set_auth_file_path (struct tgl_state *TLS, const char *path); -void tgl_set_download_directory (struct tgl_state *TLS, const char *path); -void tgl_set_callback (struct tgl_state *TLS, struct tgl_update_callback *cb); -void tgl_set_rsa_key (struct tgl_state *TLS, 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 (struct tgl_state *TLS) { - TLS->verbosity ++; -} - -static inline void tgl_set_verbosity (struct tgl_state *TLS, int val) { - TLS->verbosity = val; -} - -static inline void tgl_enable_pfs (struct tgl_state *TLS) { - TLS->enable_pfs = 1; -} - -static inline void tgl_set_test_mode (struct tgl_state *TLS) { - TLS->test_mode ++; -} - -static inline void tgl_set_net_methods (struct tgl_state *TLS, struct tgl_net_methods *methods) { - TLS->net_methods = methods; -} - -static inline void tgl_set_timer_methods (struct tgl_state *TLS, struct tgl_timer_methods *methods) { - TLS->timer_methods = methods; -} - -static inline void tgl_set_ev_base (struct tgl_state *TLS, void *ev_base) { - TLS->ev_base = ev_base; -} - -//struct pollfd; -//int tgl_connections_make_poll_array (struct tgl_state *TLS, struct pollfd *fds, int max); -//void tgl_connections_poll_result (struct tgl_state *TLS, struct pollfd *fds, int max); - -void tgl_do_help_get_config (struct tgl_state *TLS, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -void tgl_do_send_code (struct tgl_state *TLS, const char *user, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int registered, const char *hash), void *callback_extra); -void tgl_do_phone_call (struct tgl_state *TLS, const char *user, const char *hash, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -int tgl_do_send_code_result (struct tgl_state *TLS, const char *user, const char *hash, const char *code, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *Self), void *callback_extra) ; -int tgl_do_send_code_result_auth (struct tgl_state *TLS, const char *user, const char *hash, const char *code, const char *first_name, const char *last_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *Self), void *callback_extra); -void tgl_do_update_contact_list (struct tgl_state *TLS, void (*callback) (struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *contacts[]), void *callback_extra); -void tgl_do_send_message (struct tgl_state *TLS, tgl_peer_id_t id, const char *msg, int len, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_send_msg (struct tgl_state *TLS, struct tgl_message *M, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_send_text (struct tgl_state *TLS, tgl_peer_id_t id, char *file, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_mark_read (struct tgl_state *TLS, tgl_peer_id_t id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -void tgl_do_get_history (struct tgl_state *TLS, tgl_peer_id_t id, int limit, int offline_mode, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra); -void tgl_do_get_history_ext (struct tgl_state *TLS, tgl_peer_id_t id, int offset, int limit, int offline_mode, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra); -void tgl_do_get_dialog_list (struct tgl_state *TLS, void (*callback)(struct tgl_state *TLS, 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 (struct tgl_state *TLS, enum tgl_message_media_type type, tgl_peer_id_t to_id, char *file_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_set_chat_photo (struct tgl_state *TLS, tgl_peer_id_t chat_id, char *file_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_set_profile_photo (struct tgl_state *TLS, char *file_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -void tgl_do_set_profile_name (struct tgl_state *TLS, char *first_name, char *last_name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U), void *callback_extra); -void tgl_do_set_username (struct tgl_state *TLS, char *name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U), void *callback_extra); -void tgl_do_forward_message (struct tgl_state *TLS, tgl_peer_id_t id, int n, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_rename_chat (struct tgl_state *TLS, tgl_peer_id_t id, char *name, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_get_chat_info (struct tgl_state *TLS, tgl_peer_id_t id, int offline_mode, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *C), void *callback_extra); -void tgl_do_get_user_info (struct tgl_state *TLS, tgl_peer_id_t id, int offline_mode, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U), void *callback_extra); -void tgl_do_load_photo (struct tgl_state *TLS, struct tgl_photo *photo, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra); -void tgl_do_load_video_thumb (struct tgl_state *TLS, struct tgl_video *video, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra); -void tgl_do_load_audio (struct tgl_state *TLS, struct tgl_audio *V, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra); -void tgl_do_load_video (struct tgl_state *TLS, struct tgl_video *V, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra); -void tgl_do_load_document (struct tgl_state *TLS, struct tgl_document *V, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra); -void tgl_do_load_document_thumb (struct tgl_state *TLS, struct tgl_document *video, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra); -void tgl_do_load_encr_video (struct tgl_state *TLS, struct tgl_encr_video *V, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *filename), void *callback_extra); -void tgl_do_export_auth (struct tgl_state *TLS, int num, void (*callback) (struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -void tgl_do_add_contact (struct tgl_state *TLS, 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)(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[]), void *callback_extra); -void tgl_do_msg_search (struct tgl_state *TLS, tgl_peer_id_t id, int from, int to, int limit, int offset, const char *s, void (*callback)(struct tgl_state *TLS, 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) (struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[]), void *callback_extra); -void tgl_do_create_encr_chat_request (struct tgl_state *TLS, int user_id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra); -void tgl_do_create_secret_chat (struct tgl_state *TLS, tgl_peer_id_t id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra); -void tgl_do_accept_encr_chat_request (struct tgl_state *TLS, struct tgl_secret_chat *E, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E), void *callback_extra); -void tgl_do_get_difference (struct tgl_state *TLS, int sync_from_start, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -void tgl_do_lookup_state (struct tgl_state *TLS); -void tgl_do_add_user_to_chat (struct tgl_state *TLS, tgl_peer_id_t chat_id, tgl_peer_id_t id, int limit, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_del_user_from_chat (struct tgl_state *TLS, tgl_peer_id_t chat_id, tgl_peer_id_t id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_create_group_chat (struct tgl_state *TLS, tgl_peer_id_t id, char *chat_topic, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_create_group_chat_ex (struct tgl_state *TLS, int users_num, tgl_peer_id_t ids[], char *chat_topic, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_delete_msg (struct tgl_state *TLS, long long id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -void tgl_do_restore_msg (struct tgl_state *TLS, long long id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -void tgl_do_update_status (struct tgl_state *TLS, int online, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -void tgl_do_help_get_config_dc (struct tgl_state *TLS, struct tgl_dc *D, void (*callback)(struct tgl_state *TLS, void *, int), void *callback_extra); -void tgl_do_export_card (struct tgl_state *TLS, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int size, int *card), void *callback_extra); -void tgl_do_import_card (struct tgl_state *TLS, int size, int *card, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U), void *callback_extra); -void tgl_do_send_contact (struct tgl_state *TLS, 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)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_forward_media (struct tgl_state *TLS, tgl_peer_id_t id, int n, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_del_contact (struct tgl_state *TLS, tgl_peer_id_t id, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success), void *callback_extra); -void tgl_do_set_encr_chat_ttl (struct tgl_state *TLS, struct tgl_secret_chat *E, int ttl, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_send_location (struct tgl_state *TLS, tgl_peer_id_t id, double latitude, double longitude, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra); -void tgl_do_contact_search (struct tgl_state *TLS, char *name, int limit, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, int cnt, struct tgl_user *U[]), void *callback_extra); - - -void tgl_do_visualize_key (struct tgl_state *TLS, tgl_peer_id_t id, unsigned char buf[16]); - -void tgl_do_send_ping (struct tgl_state *TLS, struct connection *c); - -void tgl_do_send_extf (struct tgl_state *TLS, char *data, int data_len, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, char *data), void *callback_extra); - -int tgl_authorized_dc (struct tgl_state *TLS, struct tgl_dc *DC); -int tgl_signed_dc (struct tgl_state *TLS, struct tgl_dc *DC); - -//void tgl_do_get_suggested (void); - -void tgl_do_create_keys_end (struct tgl_state *TLS, struct tgl_secret_chat *U); -void tgl_do_send_encr_chat_layer (struct tgl_state *TLS, struct tgl_secret_chat *E); - -void tgl_init (struct tgl_state *TLS); -void tgl_dc_authorize (struct tgl_state *TLS, struct tgl_dc *DC); - -void tgl_dc_iterator (struct tgl_state *TLS, void (*iterator)(struct tgl_dc *DC)); -void tgl_dc_iterator_ex (struct tgl_state *TLS, void (*iterator)(struct tgl_dc *DC, void *extra), void *extra); - -double tglt_get_double_time (void); - -void tgl_insert_empty_user (struct tgl_state *TLS, int id); -void tgl_insert_empty_chat (struct tgl_state *TLS, int id); - -int tglf_extf_autocomplete (struct tgl_state *TLS, const char *text, int text_len, int index, char **R, char *data, int data_len); -struct paramed_type *tglf_extf_store (struct tgl_state *TLS, const char *data, int data_len); -char *tglf_extf_fetch (struct tgl_state *TLS, struct paramed_type *T); - -void tgl_free_all (struct tgl_state *TLS); - -static inline struct tgl_state *tgl_state_alloc (void) { - struct tgl_state *TLS = malloc (sizeof (*TLS)); - if (!TLS) { return NULL; } - memset (TLS, 0, sizeof (*TLS)); - return TLS; -} - -#endif diff --git a/tools.c b/tools.c deleted file mode 100644 index 9447858..0000000 --- a/tools.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - 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 -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#include "interface.h" -#include "tools.h" - -#ifdef __MACH__ -#include -#include -#endif - -#ifdef __MACH__ -#define CLOCK_REALTIME 0 -#define CLOCK_MONOTONIC 1 -#endif - -#define RES_PRE 8 -#define RES_AFTER 8 -#define MAX_BLOCKS 1000000 -static void *blocks[MAX_BLOCKS]; -static void *free_blocks[MAX_BLOCKS]; -static int used_blocks; -static int free_blocks_cnt; - -static long long total_allocated_bytes; - -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); -} - -//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); - va_end (ap); - assert (r <= len && "tsnprintf buffer overflow"); - return r; -} - -int tgl_asprintf (char **res, const char *format, ...) { - va_list ap; - va_start (ap, format); - int r = vasprintf (res, format, ap); - assert (r >= 0); - va_end (ap); - void *rs = talloc (strlen (*res) + 1); - memcpy (rs, *res, strlen (*res) + 1); - free (*res); - *res = rs; - return r; -} - -void tgl_free_debug (void *ptr, int size __attribute__ ((unused))) { - total_allocated_bytes -= size; - ptr -= RES_PRE; - if (size != (int)((*(int *)ptr) ^ 0xbedabeda)) { - logprintf ("size = %d, ptr = %d\n", size, (*(int *)ptr) ^ 0xbedabeda); - } - assert (*(int *)ptr == (int)((size) ^ 0xbedabeda)); - assert (*(int *)(ptr + RES_PRE + size) == (int)((size) ^ 0x7bed7bed)); - assert (*(int *)(ptr + 4) == size); - int block_num = *(int *)(ptr + 4 + RES_PRE + size); - if (block_num >= used_blocks) { - logprintf ("block_num = %d, used = %d\n", block_num, used_blocks); - } - assert (block_num < used_blocks); - if (block_num < used_blocks - 1) { - void *p = blocks[used_blocks - 1]; - int s = (*(int *)p) ^ 0xbedabeda; - *(int *)(p + 4 + RES_PRE + s) = block_num; - blocks[block_num] = p; - } - blocks[--used_blocks] = 0; - memset (ptr, 0, size + RES_PRE + RES_AFTER); - *(int *)ptr = size + 12; - free_blocks[free_blocks_cnt ++] = ptr; -} - -void tgl_free_release (void *ptr, int size) { - free (ptr); -} - - - -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; -} - -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; -} - -void *tgl_alloc_debug (size_t size) { - total_allocated_bytes += size; - void *p = malloc (size + RES_PRE + RES_AFTER); - ensure_ptr (p); - *(int *)p = size ^ 0xbedabeda; - *(int *)(p + 4) = 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; -} - -void *tgl_alloc_release (size_t size) { - void *p = malloc (size); - ensure_ptr (p); - return p; -} - -void *tgl_alloc0 (size_t size) { - void *p = talloc (size); - memset (p, 0, size); - return p; -} - -char *tgl_strdup (const char *s) { - int l = strlen (s); - char *p = talloc (l + 1); - memcpy (p, s, l + 1); - return p; -} - -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; -} - - -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); - strm.avail_in = ilen; - strm.next_in = input; - strm.avail_out = olen ; - strm.next_out = output; - 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; -} - -void tgl_check_debug (void) { - int i; - for (i = 0; i < used_blocks; i++) { - void *ptr = blocks[i]; - int size = (*(int *)ptr) ^ 0xbedabeda; - 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]; - int l = *(int *)ptr; - int j = 0; - for (j = 0; j < l; j++) { - if (*(char *)(ptr + 4 + j)) { - hexdump (ptr + 8, ptr + 8 + l + ((-l) & 3)); - logprintf ("Used freed memory size = %d. ptr = %p\n", l + 4 - RES_PRE - RES_AFTER, ptr); - assert (0); - } - } - } - //logprintf ("ok. Used_blocks = %d. Free blocks = %d\n", used_blocks, free_blocks_cnt); -} - -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); - } - assert (*(int *)ptr == (int)((size) ^ 0xbedabeda)); - assert (*(int *)(ptr + RES_PRE + size) == (int)((size) ^ 0x7bed7bed)); - assert (*(int *)(ptr + 4) == size); - int block_num = *(int *)(ptr + 4 + RES_PRE + size); - if (block_num >= used_blocks) { - logprintf ("block_num = %d, used = %d\n", block_num, used_blocks); - } - 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; diff --git a/tools.h b/tools.h deleted file mode 100644 index cf20027..0000000 --- a/tools.h +++ /dev/null @@ -1,119 +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 . - - Copyright Vitaly Valtman 2013 -*/ - -#ifndef __TOOLS_H__ -#define __TOOLS_H__ -#include -#include -#include -#include "tgl.h" - -#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 - - -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"); } -} - - -#endif diff --git a/updates.c b/updates.c deleted file mode 100644 index d01bfdc..0000000 --- a/updates.c +++ /dev/null @@ -1,594 +0,0 @@ -/* - 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 "tree.h" - -#include - -void tglu_fetch_pts (struct tgl_state *TLS) { - int p = fetch_int (); - if (p <= TLS->pts) { return; } - bl_do_set_pts (TLS, p); -} - -void tglu_fetch_qts (struct tgl_state *TLS) { - int p = fetch_int (); - if (p <= TLS->qts) { return; } - bl_do_set_qts (TLS, p); -} - -void tglu_fetch_date (struct tgl_state *TLS) { - int p = fetch_int (); - if (p > TLS->date) { - //TLS->date = p; - bl_do_set_date (TLS, TLS->date); - } -} - -static void fetch_dc_option (struct tgl_state *TLS) { - 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 (TLS, id, l1, name, l2, ip, port); -} - -void tglu_work_update (struct tgl_state *TLS, 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 (TLS); - assert (M); - tglu_fetch_pts (TLS); - bl_do_msg_update (TLS, 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 (TLS, new); - if (M) { - bl_do_set_msg_id (TLS, 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 (TLS, id); - if (M) { - bl_do_set_unread (TLS, M, 0); - } - } - tglu_fetch_pts (TLS); - } - break; - case CODE_update_user_typing: - { - //vlogprintf (E_ERROR, "user typing\n"); - tgl_peer_id_t id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, id); - enum tgl_typing_status status = tglf_fetch_typing (); - - if (TLS->callback.type_notification && U) { - TLS->callback.type_notification (TLS, (void *)U, status); - } - } - break; - case CODE_update_chat_user_typing: - { - //vlogprintf (E_ERROR, "chat typing\n"); - 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 (TLS, chat_id); - tgl_peer_t *U = tgl_peer_get (TLS, id); - enum tgl_typing_status status = tglf_fetch_typing (); - - if (U && C) { - if (TLS->callback.type_in_chat_notification) { - TLS->callback.type_in_chat_notification (TLS, (void *)U, (void *)C, status); - } - } - } - break; - case CODE_update_user_status: - { - tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *U = tgl_peer_get (TLS, user_id); - if (U) { - tglf_fetch_user_status (TLS, &U->user.status, &U->user); - - if (TLS->callback.status_notification) { - TLS->callback.status_notification (TLS, (void *)U); - } - } else { - assert (skip_type_any (TYPE_TO_PARAM (user_status)) >= 0); - } - } - break; - case CODE_update_user_name: - { - tgl_peer_id_t user_id = TGL_MK_USER (fetch_int ()); - tgl_peer_t *UC = tgl_peer_get (TLS, 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 (TLS, U, f, l1, l, l2); - int l3 = prefetch_strlen (); - f = fetch_str (l3); - bl_do_user_set_username (TLS, U, f, l3); - } else { - fetch_skip_str (); - 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 (TLS, user_id); - tglu_fetch_date (TLS); - 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 (TLS, &small); - tglf_fetch_file_location (TLS, &big); - } - bl_do_set_user_profile_photo (TLS, 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 (TLS, &t); - tglf_fetch_file_location (TLS, &t); - } - } - fetch_bool (); - } - break; - case CODE_update_restore_messages: - { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - fetch_skip (n); - tglu_fetch_pts (TLS); - } - break; - case CODE_update_delete_messages: - { - assert (fetch_int () == CODE_vector); - int n = fetch_int (); - fetch_skip (n); - tglu_fetch_pts (TLS); - } - 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 (TLS, chat_id); - if (C && (C->flags & FLAG_CREATED)) { - if (x == CODE_chat_participants) { - bl_do_chat_set_admin (TLS, &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 (TLS, &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 (TLS, user_id); - fetch_int (); // date - if (TLS->callback.user_registered && U) { - TLS->callback.user_registered (TLS, (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 (TLS, 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 (TLS, user_id); - - if (TLS->callback.user_activated && U) { - TLS->callback.user_activated (TLS, (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 (TLS->callback.new_authorization) { - TLS->callback.new_authorization (TLS, 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 (TLS); - assert (M); - bl_do_msg_update (TLS, M->id); - } - break; - case CODE_update_new_encrypted_message: - { - struct tgl_message *M = tglf_fetch_alloc_encrypted_message (TLS); - assert (M); - tglu_fetch_qts (TLS); - bl_do_msg_update (TLS, M->id); - } - break; - case CODE_update_encryption: - { - struct tgl_secret_chat *E = tglf_fetch_alloc_encrypted_chat (TLS); - vlogprintf (E_DEBUG, "Secret chat state = %d\n", E->state); - if (E->state == sc_ok) { - tgl_do_send_encr_chat_layer (TLS, 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 (TLS, id); - - if (P) { - if (TLS->callback.type_in_secret_chat_notification) { - TLS->callback.type_in_secret_chat_notification (TLS, (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 (TLS, 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 (TLS, 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 (TLS, chat_id); - if (C && (C->flags & FLAG_CREATED)) { - bl_do_chat_add_user (TLS, &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 (TLS, chat_id); - if (C && (C->flags & FLAG_CREATED)) { - bl_do_chat_del_user (TLS, &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 (TLS); - } - } - break; - case CODE_update_user_blocked: - { - int id = fetch_int (); - int blocked = fetch_bool (); - tgl_peer_t *P = tgl_peer_get (TLS, TGL_MK_USER (id)); - if (P && (P->flags & FLAG_CREATED)) { - bl_do_user_set_blocked (TLS, &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; - case CODE_update_service_notification: - { - int l1 = prefetch_strlen (); - char *type = fetch_str (l1); - int l2 = prefetch_strlen (); - char *message = fetch_str (l2); - skip_type_message_media (TYPE_TO_PARAM(message_media)); - fetch_bool (); - vlogprintf (E_ERROR, "Notification %.*s: %.*s\n", l1, type, l2, message); - if (TLS->callback.notification) { - char *t = tstrndup (type, l1); - char *m = tstrndup (message, l2); - TLS->callback.notification (TLS, t, m); - tfree_str (t); - tfree_str (m); - } - } - break; - default: - vlogprintf (E_ERROR, "Unknown update type %08x\n", op); - ; - } -} - -void tglu_work_update_short (struct tgl_state *TLS, 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 (TLS, c, msg_id); - tglu_fetch_date (TLS); - - assert (save_end == in_ptr); -} - -static int do_skip_seq (struct tgl_state *TLS, int seq) { - if (TLS->seq) { - if (seq <= TLS->seq) { - vlogprintf (E_NOTICE, "Duplicate message with seq=%d\n", seq); - return -1; - } - if (seq > TLS->seq + 1) { - vlogprintf (E_NOTICE, "Hole in seq (seq = %d, cur_seq = %d)\n", seq, TLS->seq); - //vlogprintf (E_NOTICE, "lock_diff = %s\n", (TLS->locks & TGL_LOCK_DIFF) ? "true" : "false"); - tgl_do_get_difference (TLS, 0, 0, 0); - return -1; - } - if (TLS->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 tgl_state *TLS, struct connection *c, long long msg_id) { - int *save = in_ptr; - assert (!skip_type_any (TYPE_TO_PARAM (updates))); - if (do_skip_seq (TLS, *(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 (TLS, c, msg_id); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_user (TLS); - } - assert (fetch_int () == CODE_vector); - n = fetch_int (); - for (i = 0; i < n; i++) { - tglf_fetch_alloc_chat (TLS); - } - bl_do_set_date (TLS, fetch_int ()); - //bl_do_set_seq (fetch_int ()); - int seq = fetch_int (); - assert (seq == TLS->seq + 1); - bl_do_set_seq (TLS, seq); - assert (save_end == in_ptr); -} - -void tglu_work_update_short_message (struct tgl_state *TLS, struct connection *c, long long msg_id) { - int *save = in_ptr; - assert (!skip_type_any (TYPE_TO_PARAM (updates))); - if (do_skip_seq (TLS, *(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 (TLS); - assert (M); - - assert (save_end == in_ptr); - if (!(TLS->locks & TGL_LOCK_DIFF)) { - bl_do_msg_seq_update (TLS, M->id); - } -} - -void tglu_work_update_short_chat_message (struct tgl_state *TLS, struct connection *c, long long msg_id) { - int *save = in_ptr; - assert (!skip_type_any (TYPE_TO_PARAM (updates))); - if (do_skip_seq (TLS, *(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 (TLS); - assert (M); - assert (save_end == in_ptr); - - if (!(TLS->locks & TGL_LOCK_DIFF)) { - bl_do_msg_seq_update (TLS, M->id); - } -} - -void tglu_work_updates_to_long (struct tgl_state *TLS, 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 (TLS, 0, 0, 0); -} - -#define user_cmp(a,b) (tgl_get_peer_id ((a)->id) - tgl_get_peer_id ((b)->id)) -DEFINE_TREE(user, struct tgl_user *,user_cmp,0) - -static void notify_status (struct tgl_user *U, void *ex) { - struct tgl_state *TLS = ex; - if (TLS->callback.user_status_update) { - TLS->callback.user_status_update (TLS, U); - } -} - -static void status_notify (struct tgl_state *TLS, void *arg) { - tree_act_ex_user (TLS->online_updates, notify_status, TLS); - tree_clear_user (TLS->online_updates); - TLS->online_updates = NULL; - TLS->timer_methods->free (TLS->online_updates_timer); - TLS->online_updates_timer = NULL; -} - -void tgl_insert_status_update (struct tgl_state *TLS, struct tgl_user *U) { - if (!tree_lookup_user (TLS->online_updates, U)) { - TLS->online_updates = tree_insert_user (TLS->online_updates, U, lrand48 ()); - } - if (!TLS->online_updates_timer) { - TLS->online_updates_timer = TLS->timer_methods->alloc (TLS, status_notify, 0); - TLS->timer_methods->insert (TLS->online_updates_timer, 0); - } -} - -static void user_expire (struct tgl_state *TLS, void *arg) { - struct tgl_user *U = arg; - TLS->timer_methods->free (U->status.ev); - U->status.ev = 0; - U->status.online = -1; - U->status.when = tglt_get_double_time (); - tgl_insert_status_update (TLS, U); -} - -void tgl_insert_status_expire (struct tgl_state *TLS, struct tgl_user *U) { - assert (!U->status.ev); - U->status.ev = TLS->timer_methods->alloc (TLS, user_expire, U); - TLS->timer_methods->insert (U->status.ev, U->status.when - tglt_get_double_time ()); -} - -void tgl_remove_status_expire (struct tgl_state *TLS, struct tgl_user *U) { - TLS->timer_methods->free (U->status.ev); - U->status.ev = 0; -} diff --git a/updates.h b/updates.h deleted file mode 100644 index c586888..0000000 --- a/updates.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - 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 tgl_state *TLS, struct connection *c, long long msg_id); -void tglu_work_updates_to_long (struct tgl_state *TLS, struct connection *c, long long msg_id); -void tglu_work_update_short_chat_message (struct tgl_state *TLS, struct connection *c, long long msg_id); -void tglu_work_update_short_message (struct tgl_state *TLS, struct connection *c, long long msg_id); -void tglu_work_update_short (struct tgl_state *TLS, struct connection *c, long long msg_id); -void tglu_work_updates (struct tgl_state *TLS, struct connection *c, long long msg_id); - -void tglu_fetch_pts (struct tgl_state *TLS); -void tglu_fetch_qts (struct tgl_state *TLS); -void tglu_fetch_seq (struct tgl_state *TLS); -void tglu_fetch_date (struct tgl_state *TLS); - -void tgl_insert_status_update (struct tgl_state *TLS, struct tgl_user *U); -void tgl_insert_status_expire (struct tgl_state *TLS, struct tgl_user *U); -void tgl_remove_status_expire (struct tgl_state *TLS, struct tgl_user *U); -#endif