diff --git a/.gitignore b/.gitignore index cc731f5..edd64af 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ bin/ objs/ dep/ auto/ +libs/ diff --git a/Makefile.in b/Makefile.in index 4e3bec7..1a63c79 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4,7 +4,7 @@ CFLAGS=@CFLAGS@ LDFLAGS=@LDFLAGS@ CPPFLAGS=@CPPFLAGS@ DEFS=@DEFS@ -COMPILE_FLAGS=${CFLAGS} ${CPPFLAGS} ${DEFS} -Wall -Wextra -Werror -Wno-deprecated-declarations -fno-strict-aliasing -fno-omit-frame-pointer -ggdb -Wno-unused-parameter +COMPILE_FLAGS=${CFLAGS} ${CPPFLAGS} ${DEFS} -Wall -Wextra -Werror -Wno-deprecated-declarations -fno-strict-aliasing -fno-omit-frame-pointer -ggdb -Wno-unused-parameter -fPIC EXTRA_LIBS=@LIBS@ @EXTRA_LIBS@ LOCAL_LDFLAGS=-rdynamic -ggdb -levent ${EXTRA_LIBS} @@ -14,16 +14,19 @@ DEP=${srcdir}/dep AUTO=${srcdir}/auto EXE=${srcdir}/bin OBJ=${srcdir}/objs -DIR_LIST=${DEP} ${AUTO} ${EXE} ${OBJ} ${DEP}/auto ${OBJ}/auto +LIB=${srcdir}/libs +DIR_LIST=${DEP} ${AUTO} ${EXE} ${OBJ} ${LIB} ${DEP}/auto ${OBJ}/auto EXE_LIST=${EXE}/generate ${EXE}/tlc ${EXE}/telegram-cli +LIB_LIST=${LIB}/libtgl.a -TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/net.o ${OBJ}/mtproto-common.o ${OBJ}/mtproto-client.o ${OBJ}/queries.o ${OBJ}/structures.o ${OBJ}/binlog.o ${OBJ}/lua-tg.o ${OBJ}/auto/auto.o ${OBJ}/tgl.o ${OBJ}/updates.o +TG_OBJECTS=${OBJ}/main.o ${OBJ}/loop.o ${OBJ}/interface.o ${OBJ}/lua-tg.o +TGL_OBJECTS=${OBJ}/net.o ${OBJ}/mtproto-common.o ${OBJ}/mtproto-client.o ${OBJ}/queries.o ${OBJ}/structures.o ${OBJ}/binlog.o ${OBJ}/auto/auto.o ${OBJ}/tgl.o ${OBJ}/updates.o TLC_OBJECTS=${OBJ}/tlc.o ${OBJ}/tl-parser.o ${OBJ}/crc32.o GENERATE_OBJECTS=${OBJ}/generate.o COMMON_OBJECTS=${OBJ}/tools.o -OBJ_LIST=${TG_OBJECTS} ${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} -OBJ_C=${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} +OBJ_LIST=${TG_OBJECTS} ${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS} +OBJ_C=${TLC_OBJECTS} ${GENERATE_OBJECTS} ${COMMON_OBJECTS} ${TGL_OBJECTS} DEPENDENCE=$(subst ${OBJ}/,${DEP}/,$(patsubst %.o,%.d,${OBJ_LIST})) DEPENDENCE_LIST=${DEPENDENCE} @@ -35,7 +38,7 @@ CC=@CC@ .SUFFIXES: .c .h .o -all: ${EXE_LIST} ${DIR_LIST} +all: ${EXE_LIST} ${DIR_LIST} ${LIB_LIST} create_dirs_and_headers: ${DIR_LIST} ${AUTO}/auto.c ${AUTO}/auto-header.h ${AUTO}/constants.h create_dirs: ${DIR_LIST} @@ -53,8 +56,11 @@ ${OBJ_C}: ${OBJ}/%.o: %.c | create_dirs ${EXE}/tlc: ${TLC_OBJECTS} ${COMMON_OBJECTS} ${CC} ${TLC_OBJECTS} ${COMMON_OBJECTS} ${LINK_FLAGS} -o $@ -${EXE}/telegram-cli: ${TG_OBJECTS} ${COMMON_OBJECTS} - ${CC} ${TG_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 $@ diff --git a/binlog.c b/binlog.c index a9228d1..75aeaa9 100644 --- a/binlog.c +++ b/binlog.c @@ -198,6 +198,9 @@ static int fetch_comb_binlog_user_add (void *extra) { #ifdef USE_LUA lua_user_update (U); #endif + if (tgl_state.callback.new_user) { + tgl_state.callback.new_user (U); + } return 0; } @@ -210,6 +213,9 @@ static int fetch_comb_binlog_user_delete (void *extra) { #ifdef USE_LUA lua_user_update (&U->user); #endif + if (tgl_state.callback.delete_user) { + tgl_state.callback.delete_user ((void *)U); + } return 0; } @@ -237,6 +243,10 @@ static int fetch_comb_binlog_user_set_phone (void *extra) { #ifdef USE_LUA lua_user_update (&U->user); #endif + + if (tgl_state.callback.update_user_info) { + tgl_state.callback.update_user_info ((void *)U); + } return 0; } @@ -254,6 +264,9 @@ static int fetch_comb_binlog_user_set_friend (void *extra) { #ifdef USE_LUA lua_user_update (&U->user); #endif + if (tgl_state.callback.update_user_info) { + tgl_state.callback.update_user_info ((void *)U); + } return 0; } @@ -269,6 +282,9 @@ static int fetch_comb_binlog_user_set_full_photo (void *extra) { #ifdef USE_LUA lua_user_update (&U->user); #endif + if (tgl_state.callback.update_user_info) { + tgl_state.callback.update_user_info ((void *)U); + } return 0; } @@ -282,6 +298,9 @@ static int fetch_comb_binlog_user_set_blocked (void *extra) { #ifdef USE_LUA lua_user_update (&U->user); #endif + if (tgl_state.callback.update_user_info) { + tgl_state.callback.update_user_info ((void *)U); + } return 0; } @@ -298,6 +317,9 @@ static int fetch_comb_binlog_user_set_real_name (void *extra) { #ifdef USE_LUA lua_user_update (&U->user); #endif + if (tgl_state.callback.update_user_info) { + tgl_state.callback.update_user_info ((void *)U); + } return 0; } @@ -320,6 +342,9 @@ static int fetch_comb_binlog_user_set_name (void *extra) { #ifdef USE_LUA lua_user_update (&U->user); #endif + if (tgl_state.callback.update_user_info) { + tgl_state.callback.update_user_info ((void *)U); + } return 0; } @@ -344,6 +369,9 @@ static int fetch_comb_binlog_user_set_photo (void *extra) { #ifdef USE_LUA lua_user_update (&U->user); #endif + if (tgl_state.callback.update_user_info) { + tgl_state.callback.update_user_info ((void *)U); + } return 0; } @@ -367,6 +395,9 @@ static int fetch_comb_binlog_encr_chat_delete (void *extra) { #ifdef USE_LUA lua_secret_chat_update (U); #endif + if (tgl_state.callback.secret_chat_deleted) { + tgl_state.callback.secret_chat_deleted (U); + } return 0; } @@ -407,6 +438,9 @@ static int fetch_comb_binlog_encr_chat_requested (void *extra) { #ifdef USE_LUA lua_secret_chat_update (U); #endif + if (tgl_state.callback.secret_chat_request) { + tgl_state.callback.secret_chat_request (U); + } return 0; } @@ -470,6 +504,9 @@ static int fetch_comb_binlog_encr_chat_accepted (void *extra) { #ifdef USE_LUA lua_secret_chat_update (U); #endif + if (tgl_state.callback.secret_chat_accepted) { + tgl_state.callback.secret_chat_accepted (U); + } return 0; } @@ -507,6 +544,9 @@ static int fetch_comb_binlog_encr_chat_init (void *extra) { #ifdef USE_LUA lua_secret_chat_update (U); #endif + if (tgl_state.callback.secret_chat_created) { + tgl_state.callback.secret_chat_created ((void *)P); + } return 0; } @@ -536,6 +576,9 @@ static int fetch_comb_binlog_chat_create (void *extra) { #ifdef USE_LUA lua_chat_update (C); #endif + if (tgl_state.callback.chat_created) { + tgl_state.callback.chat_created (C); + } return 0; } @@ -548,6 +591,9 @@ static int fetch_comb_binlog_chat_change_flags (void *extra) { #ifdef USE_LUA lua_chat_update (&C->chat); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update ((void *)C); + } return 0; } @@ -567,6 +613,9 @@ static int fetch_comb_binlog_chat_set_title (void *extra) { #ifdef USE_LUA lua_chat_update (&C->chat); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update ((void *)C); + } return 0; } @@ -579,6 +628,9 @@ static int fetch_comb_binlog_chat_set_photo (void *extra) { #ifdef USE_LUA lua_chat_update (&C->chat); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update ((void *)C); + } return 0; } @@ -590,6 +642,9 @@ static int fetch_comb_binlog_chat_set_date (void *extra) { #ifdef USE_LUA lua_chat_update (&C->chat); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update ((void *)C); + } return 0; } @@ -602,6 +657,9 @@ static int fetch_comb_binlog_chat_set_version (void *extra) { #ifdef USE_LUA lua_chat_update (&C->chat); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update ((void *)C); + } return 0; } @@ -613,6 +671,9 @@ static int fetch_comb_binlog_chat_set_admin (void *extra) { #ifdef USE_LUA lua_chat_update (&C->chat); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update ((void *)C); + } return 0; } @@ -628,6 +689,9 @@ static int fetch_comb_binlog_chat_set_participants (void *extra) { #ifdef USE_LUA lua_chat_update (&C->chat); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update ((void *)C); + } return 0; } @@ -644,6 +708,9 @@ static int fetch_comb_binlog_chat_set_full_photo (void *extra) { #ifdef USE_LUA lua_chat_update (&C->chat); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update ((void *)C); + } return 0; } @@ -674,6 +741,9 @@ static int fetch_comb_binlog_chat_add_participant (void *extra) { #ifdef USE_LUA lua_chat_update (C); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update (C); + } return 0; } @@ -704,6 +774,9 @@ static int fetch_comb_binlog_chat_del_participant (void *extra) { #ifdef USE_LUA lua_chat_update (C); #endif + if (tgl_state.callback.chat_update) { + tgl_state.callback.chat_update (C); + } return 0; } @@ -734,9 +807,9 @@ static int fetch_comb_binlog_create_message_text (void *extra) { M->message_len = l; if (t == TGL_PEER_ENCR_CHAT) { - M->media.type = CODE_decrypted_message_media_empty; + M->media.type = tgl_message_media_none; } else { - M->media.type = CODE_message_media_empty; + M->media.type = tgl_message_media_none; } M->unread = 1; @@ -777,9 +850,9 @@ static int fetch_comb_binlog_send_message_text (void *extra) { M->message_len = l; if (t == TGL_PEER_ENCR_CHAT) { - M->media.type = CODE_decrypted_message_media_empty; + M->media.type = tgl_message_media_none; } else { - M->media.type = CODE_message_media_empty; + M->media.type = tgl_message_media_none; } M->unread = 1; @@ -812,7 +885,7 @@ static int fetch_comb_binlog_send_message_action_encr (void *extra) { M->to_id = tgl_set_peer_id (t, fetch_int ()); M->date = fetch_int (); - M->media.type = CODE_decrypted_message_media_empty; + M->media.type = tgl_message_media_none; tglf_fetch_message_action_encrypted (&M->action); M->unread = 1; @@ -859,9 +932,9 @@ static int fetch_comb_binlog_create_message_text_fwd (void *extra) { M->message_len = l; if (t == TGL_PEER_ENCR_CHAT) { - M->media.type = CODE_decrypted_message_media_empty; + M->media.type = tgl_message_media_none; } else { - M->media.type = CODE_message_media_empty; + M->media.type = tgl_message_media_none; } M->unread = 1; diff --git a/interface.c b/interface.c index c78581b..a819b3d 100644 --- a/interface.c +++ b/interface.c @@ -42,7 +42,7 @@ #include "interface.h" #include "telegram.h" -#include "auto/constants.h" +//#include "auto/constants.h" //#include "tools.h" //#include "structures.h" @@ -145,6 +145,7 @@ tgl_peer_id_t next_token_user (void) { } char c = s[l]; + s[l] = 0; tgl_peer_t *P = tgl_peer_get_by_name (s); s[l] = c; @@ -169,6 +170,7 @@ tgl_peer_id_t next_token_chat (void) { } char c = s[l]; + s[l] = 0; tgl_peer_t *P = tgl_peer_get_by_name (s); s[l] = c; @@ -185,6 +187,7 @@ tgl_peer_id_t next_token_encr_chat (void) { if (!s) { return TGL_PEER_NOT_FOUND; } char c = s[l]; + s[l] = 0; tgl_peer_t *P = tgl_peer_get_by_name (s); s[l] = c; @@ -216,6 +219,7 @@ tgl_peer_id_t next_token_peer (void) { } char c = s[l]; + s[l] = 0; tgl_peer_t *P = tgl_peer_get_by_name (s); s[l] = c; @@ -545,6 +549,7 @@ void print_user_list_gw (void *extra, int success, int num, struct tgl_user *UL[ int i; for (i = num - 1; i >= 0; i--) { print_user_name (UL[i]->id, (void *)UL[i]); + printf ("\n"); } print_end (); } @@ -571,7 +576,10 @@ void open_filename_gw (void *extra, int success, char *name) { } void print_chat_info_gw (void *extra, int success, struct tgl_chat *C) { - if (!success) { return; } + if (!success) { + vlogprintf (E_NOTICE, "Failed to get chat info\n"); + return; + } print_start (); tgl_peer_t *U = (void *)C; @@ -711,8 +719,14 @@ void type_in_chat_notification_upd (struct tgl_user *U, struct tgl_chat *C) { } +void print_message_gw (struct tgl_message *M) { + print_start (); + print_message (M); + print_end (); +} + struct tgl_update_callback upd_cb = { - .new_msg = print_message, + .new_msg = print_message_gw, .marked_read = mark_read_upd, .logprintf = logprintf, .type_notification = type_notification_upd, @@ -722,9 +736,11 @@ struct tgl_update_callback upd_cb = { .user_registered = 0, .user_activated = 0, .new_authorization = 0, + .secret_chat_created = 0, .secret_chat_request = 0, .secret_chat_established = 0, - .secret_chat_deleted = 0 + .secret_chat_deleted = 0, + .secret_chat_accepted = 0 }; @@ -831,7 +847,7 @@ void interpreter (char *line UU) { printf ("Empty file name\n"); RET; } - tgl_do_send_photo (CODE_input_media_uploaded_photo, id, strndup (s, t), print_msg_gw, 0); + tgl_do_send_photo (tgl_message_media_photo, id, strndup (s, t), print_msg_gw, 0); } else if (IS_WORD("send_video")) { GET_PEER; int t; @@ -840,7 +856,7 @@ void interpreter (char *line UU) { printf ("Empty file name\n"); RET; } - tgl_do_send_photo (CODE_input_media_uploaded_video, id, strndup (s, t), print_msg_gw, 0); + tgl_do_send_photo (tgl_message_media_video, id, strndup (s, t), print_msg_gw, 0); } else if (IS_WORD ("send_text")) { GET_PEER; int t; @@ -865,9 +881,9 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_photo) { + if (M && !M->service && M->media.type == tgl_message_media_photo) { tgl_do_load_photo (&M->media.photo, print_filename_gw, 0); - } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_photo) { + } else if (M && !M->service && M->media.type == tgl_message_media_photo_encr) { tgl_do_load_encr_video (&M->media.encr_video, print_filename_gw, 0); // this is not a bug. } else { printf ("Bad msg id\n"); @@ -880,9 +896,9 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_photo) { + if (M && !M->service && M->media.type == tgl_message_media_photo) { tgl_do_load_photo (&M->media.photo, open_filename_gw, 0); - } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_photo) { + } else if (M && !M->service && M->media.type == tgl_message_media_photo_encr) { tgl_do_load_encr_video (&M->media.encr_video, open_filename_gw, 0); // this is not a bug. } else { printf ("Bad msg id\n"); @@ -895,7 +911,7 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_video) { + if (M && !M->service && M->media.type == tgl_message_media_video) { tgl_do_load_video_thumb (&M->media.video, print_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -908,7 +924,7 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_video) { + if (M && !M->service && M->media.type == tgl_message_media_video) { tgl_do_load_video_thumb (&M->media.video, open_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -921,9 +937,9 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_video) { + if (M && !M->service && M->media.type == tgl_message_media_video) { tgl_do_load_video (&M->media.video, print_filename_gw, 0); - } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_video) { + } else if (M && !M->service && M->media.type == tgl_message_media_video_encr) { tgl_do_load_encr_video (&M->media.encr_video, print_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -936,9 +952,9 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_video) { + if (M && !M->service && M->media.type == tgl_message_media_video) { tgl_do_load_video (&M->media.video, open_filename_gw, 0); - } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_video) { + } else if (M && !M->service && M->media.type == tgl_message_media_video_encr) { tgl_do_load_encr_video (&M->media.encr_video, open_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -1136,7 +1152,7 @@ void interpreter (char *line UU) { printf ("Empty file name\n"); RET; } - tgl_do_send_photo (CODE_input_media_uploaded_audio, id, strndup (s, t), print_msg_gw, 0); + tgl_do_send_photo (tgl_message_media_audio, id, strndup (s, t), print_msg_gw, 0); } else if (IS_WORD("send_document")) { GET_PEER; int t; @@ -1145,7 +1161,7 @@ void interpreter (char *line UU) { printf ("Empty file name\n"); RET; } - tgl_do_send_photo (CODE_input_media_uploaded_document, id, strndup (s, t), print_msg_gw, 0); + tgl_do_send_photo (tgl_message_media_document, id, strndup (s, t), print_msg_gw, 0); } else if (IS_WORD ("load_audio")) { long long num = next_token_int (); if (num == NOT_FOUND) { @@ -1153,9 +1169,9 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_audio) { + if (M && !M->service && M->media.type == tgl_message_media_audio) { tgl_do_load_audio (&M->media.video, print_filename_gw, 0); - } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_audio) { + } else if (M && !M->service && M->media.type == tgl_message_media_audio_encr) { tgl_do_load_encr_video (&M->media.encr_video, print_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -1168,9 +1184,9 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_audio) { + if (M && !M->service && M->media.type == tgl_message_media_audio) { tgl_do_load_audio (&M->media.video, open_filename_gw, 0); - } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_audio) { + } else if (M && !M->service && M->media.type == tgl_message_media_audio_encr) { tgl_do_load_encr_video (&M->media.encr_video, open_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -1183,7 +1199,7 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == (int)CODE_message_media_document) { + if (M && !M->service && M->media.type == (int)tgl_message_media_document) { tgl_do_load_document_thumb (&M->media.document, print_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -1196,7 +1212,7 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == (int)CODE_message_media_document) { + if (M && !M->service && M->media.type == (int)tgl_message_media_document) { tgl_do_load_document_thumb (&M->media.document, open_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -1209,9 +1225,9 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_document) { + if (M && !M->service && M->media.type == tgl_message_media_document) { tgl_do_load_document (&M->media.document, print_filename_gw, 0); - } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_document) { + } else if (M && !M->service && M->media.type == tgl_message_media_document_encr) { tgl_do_load_encr_video (&M->media.encr_video, print_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -1224,9 +1240,9 @@ void interpreter (char *line UU) { RET; } struct tgl_message *M = tgl_message_get (num); - if (M && !M->service && M->media.type == CODE_message_media_document) { + if (M && !M->service && M->media.type == tgl_message_media_document) { tgl_do_load_document (&M->media.document, open_filename_gw, 0); - } else if (M && !M->service && M->media.type == CODE_decrypted_message_media_document) { + } else if (M && !M->service && M->media.type == tgl_message_media_document_encr) { tgl_do_load_encr_video (&M->media.encr_video, open_filename_gw, 0); } else { printf ("Bad msg id\n"); @@ -1387,65 +1403,80 @@ void pop_color (void) { void print_media (struct tgl_message_media *M) { assert (M); switch (M->type) { - case CODE_message_media_empty: - case CODE_decrypted_message_media_empty: + case tgl_message_media_none: return; - case CODE_message_media_photo: + case tgl_message_media_photo: if (M->photo.caption && strlen (M->photo.caption)) { printf ("[photo %s]", M->photo.caption); } else { printf ("[photo]"); } return; - case CODE_message_media_video: + case tgl_message_media_video: if (M->video.mime_type) { printf ("[video: type %s]", M->video.mime_type); } else { printf ("[video]"); } return; - case CODE_message_media_audio: + case tgl_message_media_audio: if (M->audio.mime_type) { printf ("[audio: type %s]", M->audio.mime_type); } else { printf ("[audio]"); } return; - case CODE_message_media_document: + case tgl_message_media_document: if (M->document.mime_type && M->document.caption) { printf ("[document %s: type %s]", M->document.caption, M->document.mime_type); } else { printf ("[document]"); } return; - case CODE_decrypted_message_media_photo: - printf ("[photo]"); + case tgl_message_media_photo_encr: + printf ("[photo]"); + if (M->photo.caption && strlen (M->photo.caption)) { + printf ("[photo %s]", M->photo.caption); + } else { + printf ("[photo]"); + } return; - case CODE_decrypted_message_media_video: - case CODE_decrypted_message_media_video_l12: - printf ("[video]"); + case tgl_message_media_video_encr: + if (M->encr_video.mime_type) { + printf ("[video: type %s]", M->encr_video.mime_type); + } else { + printf ("[video]"); + } return; - case CODE_decrypted_message_media_audio: - case CODE_decrypted_message_media_audio_l12: - printf ("[audio]"); + case tgl_message_media_audio_encr: + if (M->encr_audio.mime_type) { + printf ("[audio: type %s]", M->encr_audio.mime_type); + } else { + printf ("[audio]"); + } return; - case CODE_decrypted_message_media_document: - printf ("[document]"); + case tgl_message_media_document_encr: + if (M->encr_document.mime_type && M->encr_document.file_name) { + printf ("[document %s: type %s]", M->encr_document.file_name, M->encr_document.mime_type); + } else { + printf ("[document]"); + } return; - case CODE_message_media_geo: + case tgl_message_media_geo: printf ("[geo] https://maps.google.com/?q=%.6lf,%.6lf", M->geo.latitude, M->geo.longitude); return; - case CODE_message_media_contact: + case tgl_message_media_contact: printf ("[contact] "); push_color (COLOR_RED); printf ("%s %s ", M->first_name, M->last_name); pop_color (); printf ("%s", M->phone); return; - case CODE_message_media_unsupported: + case tgl_message_media_unsupported: printf ("[unsupported]"); return; default: + printf ("x = %d\n", M->type); assert (0); } } @@ -1542,7 +1573,7 @@ void print_date_full (long t) { void print_service_message (struct tgl_message *M) { assert (M); - print_start (); + //print_start (); push_color (COLOR_GREY); push_color (COLOR_MAGENTA); @@ -1562,61 +1593,61 @@ void print_service_message (struct tgl_message *M) { print_user_name (M->from_id, tgl_peer_get (M->from_id)); switch (M->action.type) { - case CODE_message_action_empty: + case tgl_message_action_none: printf ("\n"); break; - case CODE_message_action_geo_chat_create: + case tgl_message_action_geo_chat_create: printf ("Created geo chat\n"); break; - case CODE_message_action_geo_chat_checkin: + case tgl_message_action_geo_chat_checkin: printf ("Checkin in geochat\n"); break; - case CODE_message_action_chat_create: + case tgl_message_action_chat_create: printf (" created chat %s. %d users\n", M->action.title, M->action.user_num); break; - case CODE_message_action_chat_edit_title: + case tgl_message_action_chat_edit_title: printf (" changed title to %s\n", M->action.new_title); break; - case CODE_message_action_chat_edit_photo: + case tgl_message_action_chat_edit_photo: printf (" changed photo\n"); break; - case CODE_message_action_chat_delete_photo: + case tgl_message_action_chat_delete_photo: printf (" deleted photo\n"); break; - case CODE_message_action_chat_add_user: + case tgl_message_action_chat_add_user: printf (" added user "); print_user_name (tgl_set_peer_id (TGL_PEER_USER, M->action.user), tgl_peer_get (tgl_set_peer_id (TGL_PEER_USER, M->action.user))); printf ("\n"); break; - case CODE_message_action_chat_delete_user: + case tgl_message_action_chat_delete_user: printf (" deleted user "); print_user_name (tgl_set_peer_id (TGL_PEER_USER, M->action.user), tgl_peer_get (tgl_set_peer_id (TGL_PEER_USER, M->action.user))); printf ("\n"); break; - case CODE_decrypted_message_action_set_message_t_t_l: + case tgl_message_action_set_message_ttl: printf (" set ttl to %d seconds. Unsupported yet\n", M->action.ttl); break; - case CODE_decrypted_message_action_read_messages: + case tgl_message_action_read_messages: printf (" %d messages marked read\n", M->action.read_cnt); break; - case CODE_decrypted_message_action_delete_messages: + case tgl_message_action_delete_messages: printf (" %d messages deleted\n", M->action.delete_cnt); break; - case CODE_decrypted_message_action_screenshot_messages: + case tgl_message_action_screenshot_messages: printf (" %d messages screenshoted\n", M->action.screenshot_cnt); break; - case CODE_decrypted_message_action_flush_history: + case tgl_message_action_flush_history: printf (" cleared history\n"); break; - case CODE_decrypted_message_action_notify_layer: + case tgl_message_action_notify_layer: printf (" updated layer to %d\n", M->action.layer); break; default: assert (0); } pop_color (); - print_end (); + //print_end (); } tgl_peer_id_t last_from_id; @@ -1640,7 +1671,7 @@ void print_message (struct tgl_message *M) { last_from_id = M->from_id; last_to_id = M->to_id; - print_start (); + //print_start (); if (tgl_get_peer_type (M->to_id) == TGL_PEER_USER) { if (M->out) { push_color (COLOR_GREEN); @@ -1743,13 +1774,13 @@ void print_message (struct tgl_message *M) { if (M->message && strlen (M->message)) { printf ("%s", M->message); } - if (M->media.type != CODE_message_media_empty) { + if (M->media.type != tgl_message_media_none) { print_media (&M->media); } pop_color (); assert (!color_stack_pos); printf ("\n"); - print_end(); + //print_end(); } void play_sound (void) { diff --git a/net.c b/net.c index a7b349e..054d990 100644 --- a/net.c +++ b/net.c @@ -236,7 +236,7 @@ static void try_write (struct connection *c); static void conn_try_read (evutil_socket_t fd, short what, void *arg) { struct connection *c = arg; - vlogprintf (2, "Try read. Fd = %d\n", c->fd); + 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) { diff --git a/queries.c b/queries.c index da220f6..63aeb6b 100644 --- a/queries.c +++ b/queries.c @@ -757,7 +757,7 @@ void tgl_do_send_encr_chat_layer (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[0] = tgl_message_action_notify_layer; action[1] = 15; bl_do_send_message_action_encr (t, tgl_state.our_id, tgl_get_peer_type (E->id), tgl_get_peer_id (E->id), time (0), 2, action); @@ -886,7 +886,7 @@ void tgl_do_send_encr_msg_action (struct tgl_message *M, void (*callback)(void * out_cstring ((void *)buf, 16); switch (M->action.type) { - case CODE_decrypted_message_action_notify_layer: + case tgl_message_action_notify_layer: out_int (M->action.type); out_int (M->action.layer); break; @@ -1081,6 +1081,9 @@ static int get_history_on_answer (struct query *q UU) { 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) { + fetch_int (); + } assert (fetch_int () == CODE_vector); int n = fetch_int (); struct tgl_message **ML = talloc (sizeof (void *) * n); @@ -1555,7 +1558,7 @@ static void send_part (struct send_file *f, void *callback, void *callback_extra tglq_send_query (tgl_state.DC_working, packet_ptr - packet_buffer, packet_buffer, &send_file_part_methods, f, callback, callback_extra); }*/ -void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { +void tgl_do_send_photo (enum tgl_message_media_type type, tgl_peer_id_t to_id, char *file_name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { int fd = open (file_name, O_RDONLY); if (fd < 0) { vlogprintf (E_WARNING, "No such file '%s'\n", file_name); @@ -1592,7 +1595,26 @@ void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name, void (*c f->id = lrand48 () * (1ll << 32) + lrand48 (); f->to_id = to_id; - f->media_type = type; + 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)); + callback (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; @@ -1728,7 +1750,7 @@ static int chat_info_on_answer (struct query *q UU) { struct tgl_chat *C = tglf_fetch_alloc_chat_full (); //print_chat_info (C); if (q->callback) { - ((void (*)(void *, int, struct tgl_chat *))q->callback) (q->callback_extra, 0, C); + ((void (*)(void *, int, struct tgl_chat *))q->callback) (q->callback_extra, 1, C); } return 0; } @@ -1783,7 +1805,7 @@ void tgl_do_get_chat_info (tgl_peer_id_t id, int offline_mode, void (*callback)( static int user_info_on_answer (struct query *q UU) { struct tgl_user *U = tglf_fetch_alloc_user_full (); if (q->callback) { - ((void (*)(void *, int, struct tgl_user *))q->callback) (q->callback_extra, 0, U); + ((void (*)(void *, int, struct tgl_user *))q->callback) (q->callback_extra, 1, U); } return 0; } diff --git a/structures.c b/structures.c index 5ee0222..1bd37b6 100644 --- a/structures.c +++ b/structures.c @@ -580,12 +580,13 @@ void tglf_fetch_document (struct tgl_document *V) { void tglf_fetch_message_action (struct tgl_message_action *M) { memset (M, 0, sizeof (*M)); unsigned x = fetch_int (); - M->type = x; 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 @@ -594,8 +595,10 @@ void tglf_fetch_message_action (struct tgl_message_action *M) { } 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 (); @@ -603,17 +606,22 @@ void tglf_fetch_message_action (struct tgl_message_action *M) { 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 (&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: @@ -681,32 +689,41 @@ void tglf_fetch_message_short_chat (struct tgl_message *M) { void tglf_fetch_message_media (struct tgl_message_media *M) { memset (M, 0, sizeof (*M)); - M->type = fetch_int (); - switch (M->type) { + //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 (&M->photo); break; case CODE_message_media_video: + M->type = tgl_message_media_video; tglf_fetch_video (&M->video); break; case CODE_message_media_audio: + M->type = tgl_message_media_audio; tglf_fetch_audio (&M->audio); break; case CODE_message_media_document: + M->type = tgl_message_media_document; tglf_fetch_document (&M->document); break; case CODE_message_media_geo: + M->type = tgl_message_media_geo; tglf_fetch_geo (&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); @@ -723,10 +740,12 @@ void tglf_fetch_message_media_encrypted (struct tgl_message_media *M) { int l; switch (x) { case CODE_decrypted_message_media_empty: - M->type = CODE_message_media_empty; + M->type = tgl_message_media_none; + //M->type = CODE_message_media_empty; break; case CODE_decrypted_message_media_photo: - M->type = x; + M->type = tgl_message_media_photo_encr; + //M->type = x; l = prefetch_strlen (); fetch_str (l); // thumb fetch_int (); // thumb_w @@ -756,7 +775,8 @@ void tglf_fetch_message_media_encrypted (struct tgl_message_media *M) { break; case CODE_decrypted_message_media_video: case CODE_decrypted_message_media_video_l12: - M->type = CODE_decrypted_message_media_video; + //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 @@ -789,7 +809,8 @@ void tglf_fetch_message_media_encrypted (struct tgl_message_media *M) { break; case CODE_decrypted_message_media_audio: case CODE_decrypted_message_media_audio_l12: - M->type = CODE_decrypted_message_media_audio; + //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 (); @@ -814,7 +835,7 @@ void tglf_fetch_message_media_encrypted (struct tgl_message_media *M) { } break; case CODE_decrypted_message_media_document: - M->type = x; + M->type = tgl_message_media_document_encr; l = prefetch_strlen (); fetch_str (l); // thumb fetch_int (); // thumb_w @@ -857,12 +878,12 @@ void tglf_fetch_message_media_encrypted (struct tgl_message_media *M) { break; */ case CODE_decrypted_message_media_geo_point: + M->type = tgl_message_media_geo; M->geo.longitude = fetch_double (); M->geo.latitude = fetch_double (); - M->type = CODE_message_media_geo; break; case CODE_decrypted_message_media_contact: - M->type = 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 (); @@ -878,11 +899,11 @@ void tglf_fetch_message_action_encrypted (struct tgl_message_action *M) { unsigned x = fetch_int (); switch (x) { case CODE_decrypted_message_action_set_message_t_t_l: - M->type = x; + M->type = tgl_message_action_set_message_ttl; M->ttl = fetch_int (); break; case CODE_decrypted_message_action_read_messages: - M->type = x; + M->type = tgl_message_action_read_messages; { assert (fetch_int () == CODE_vector); int n = fetch_int (); @@ -897,7 +918,7 @@ void tglf_fetch_message_action_encrypted (struct tgl_message_action *M) { } break; case CODE_decrypted_message_action_delete_messages: - M->type = x; + M->type = tgl_message_action_delete_messages; { assert (fetch_int () == CODE_vector); int n = fetch_int (); @@ -908,7 +929,7 @@ void tglf_fetch_message_action_encrypted (struct tgl_message_action *M) { } break; case CODE_decrypted_message_action_screenshot_messages: - M->type = x; + M->type = tgl_message_action_screenshot_messages; { assert (fetch_int () == CODE_vector); int n = fetch_int (); @@ -919,11 +940,11 @@ void tglf_fetch_message_action_encrypted (struct tgl_message_action *M) { } break; case CODE_decrypted_message_action_notify_layer: - M->type = x; + M->type = tgl_message_action_notify_layer; M->layer = fetch_int (); break; case CODE_decrypted_message_action_flush_history: - M->type = x; + M->type = tgl_message_action_flush_history; break; default: vlogprintf (E_ERROR, "x = 0x%08x\n", x); @@ -1168,9 +1189,9 @@ void tglf_fetch_encrypted_message_file (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 != CODE_decrypted_message_media_photo && M->type != CODE_decrypted_message_media_video); + assert (M->type != tgl_message_media_photo_encr && M->type != tgl_message_media_video_encr); } else { - assert (M->type == CODE_decrypted_message_media_document || M->type == CODE_decrypted_message_media_photo || M->type == CODE_decrypted_message_media_video || M->type == CODE_decrypted_message_media_audio); + 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(); @@ -1421,36 +1442,34 @@ void tgls_free_document (struct tgl_document *D) { void tgls_free_message_media (struct tgl_message_media *M) { switch (M->type) { - case CODE_message_media_empty: - case CODE_message_media_geo: - case CODE_message_media_audio: + case tgl_message_media_none: + case tgl_message_media_geo: + case tgl_message_media_audio: return; - case CODE_message_media_photo: + case tgl_message_media_photo: tgls_free_photo (&M->photo); return; - case CODE_message_media_video: + case tgl_message_media_video: tgls_free_video (&M->video); return; - case CODE_message_media_contact: + case tgl_message_media_contact: tfree_str (M->phone); tfree_str (M->first_name); tfree_str (M->last_name); return; - case CODE_message_media_document: + case tgl_message_media_document: tgls_free_document (&M->document); return; - case CODE_message_media_unsupported: + case tgl_message_media_unsupported: tfree (M->data, M->data_size); return; - case CODE_decrypted_message_media_photo: - case CODE_decrypted_message_media_video: - case CODE_decrypted_message_media_audio: - case CODE_decrypted_message_media_document: + 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; - case 0: - break; default: vlogprintf (E_ERROR, "type = 0x%08x\n", M->type); assert (0); @@ -1459,25 +1478,23 @@ void tgls_free_message_media (struct tgl_message_media *M) { void tgls_free_message_action (struct tgl_message_action *M) { switch (M->type) { - case CODE_message_action_empty: + case tgl_message_action_none: break; - case CODE_message_action_chat_create: + case tgl_message_action_chat_create: tfree_str (M->title); tfree (M->users, M->user_num * 4); break; - case CODE_message_action_chat_edit_title: + case tgl_message_action_chat_edit_title: tfree_str (M->new_title); break; - case CODE_message_action_chat_edit_photo: + case tgl_message_action_chat_edit_photo: tgls_free_photo (&M->photo); break; - case CODE_message_action_chat_delete_photo: + case tgl_message_action_chat_delete_photo: break; - case CODE_message_action_chat_add_user: + case tgl_message_action_chat_add_user: break; - case CODE_message_action_chat_delete_user: - break; - case 0: + case tgl_message_action_chat_delete_user: break; default: assert (0); diff --git a/tgl-layout.h b/tgl-layout.h index 71bf3c0..cf15aae 100644 --- a/tgl-layout.h +++ b/tgl-layout.h @@ -22,6 +22,39 @@ typedef struct { int type; int id; } tgl_peer_id_t; +enum tgl_message_media_type { + tgl_message_media_none, + tgl_message_media_photo, + tgl_message_media_video, + tgl_message_media_audio, + tgl_message_media_document, + tgl_message_media_geo, + tgl_message_media_contact, + tgl_message_media_unsupported, + tgl_message_media_photo_encr, + tgl_message_media_video_encr, + tgl_message_media_audio_encr, + tgl_message_media_document_encr, +}; + +enum tgl_message_action_type { + tgl_message_action_none, + tgl_message_action_geo_chat_create, + tgl_message_action_geo_chat_checkin, + tgl_message_action_chat_create, + tgl_message_action_chat_edit_title, + tgl_message_action_chat_edit_photo, + tgl_message_action_chat_delete_photo, + tgl_message_action_chat_add_user, + tgl_message_action_chat_delete_user, + tgl_message_action_set_message_ttl, + tgl_message_action_read_messages, + tgl_message_action_delete_messages, + tgl_message_action_screenshot_messages, + tgl_message_action_flush_history, + tgl_message_action_notify_layer +}; + struct tgl_file_location { int dc; long long volume; @@ -251,7 +284,7 @@ struct tgl_document { }; struct tgl_message_action { - unsigned type; + enum tgl_message_action_type type; union { struct { char *title; @@ -270,7 +303,7 @@ struct tgl_message_action { }; struct tgl_message_media { - unsigned type; + enum tgl_message_media_type type; union { struct tgl_photo photo; struct tgl_video video; diff --git a/tgl.h b/tgl.h index f9fe339..6a66ec4 100644 --- a/tgl.h +++ b/tgl.h @@ -25,9 +25,20 @@ struct tgl_update_callback { void (*user_registered)(struct tgl_user *U); void (*user_activated)(struct tgl_user *U); void (*new_authorization)(const char *device, const char *location); + void (*secret_chat_created)(struct tgl_secret_chat *E); void (*secret_chat_request)(struct tgl_secret_chat *E); void (*secret_chat_established)(struct tgl_secret_chat *E); void (*secret_chat_deleted)(struct tgl_secret_chat *E); + void (*secret_chat_accepted)(struct tgl_secret_chat *E); + void (*new_user)(struct tgl_user *U); + void (*delete_user)(struct tgl_user *U); + void (*update_user_info)(struct tgl_user *U); + //void (*secret_chat_delete)(struct tgl_secret_chat *U); + //void (*secret_chat_requested)(struct tgl_secret_chat *U); + //void (*secret_chat_accepted)(struct tgl_secret_chat *U); + //void (*secret_chat_created)(struct tgl_secret_chat *U); + void (*chat_created)(struct tgl_chat *C); + void (*chat_update)(struct tgl_chat *C); }; struct tgl_net_methods { @@ -109,7 +120,7 @@ int tgl_complete_peer_list (int index, const char *text, int len, char **R); #define TGL_MK_CHAT(id) tgl_set_peer_id (TGL_PEER_CHAT,id) #define TGL_MK_GEO_CHAT(id) tgl_set_peer_id (TGL_PEER_GEO_CHAT,id) #define TGL_MK_ENCR_CHAT(id) tgl_set_peer_id (TGL_PEER_ENCR_CHAT,id) - + void tgl_set_binlog_mode (int mode); void tgl_set_binlog_path (const char *path); void tgl_set_auth_file_path (const char *path); @@ -165,7 +176,7 @@ void tgl_do_send_text (tgl_peer_id_t id, char *file, void (*callback)(void *call void tgl_do_mark_read (tgl_peer_id_t id, void (*callback)(void *callback_extra, int success), void *callback_extra); void tgl_do_get_history (tgl_peer_id_t id, int limit, int offline_mode, void (*callback)(void *callback_extra, int success, int size, struct tgl_message *list[]), void *callback_extra); void tgl_do_get_dialog_list (void (*callback)(void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[]), void *callback_extra); -void tgl_do_send_photo (int type, tgl_peer_id_t to_id, char *file_name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra); +void tgl_do_send_photo (enum tgl_message_media_type type, tgl_peer_id_t to_id, char *file_name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra); void tgl_do_forward_message (tgl_peer_id_t id, int n, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra); void tgl_do_rename_chat (tgl_peer_id_t id, char *name, void (*callback)(void *callback_extra, int success, struct tgl_message *M), void *callback_extra); void tgl_do_get_chat_info (tgl_peer_id_t id, int offline_mode, void (*callback)(void *callback_extra, int success, struct tgl_chat *C), void *callback_extra);