From 4118547208147858a18cdf3cca91ce3510cd2fa5 Mon Sep 17 00:00:00 2001 From: vvaltman Date: Mon, 12 Jan 2015 00:52:40 +0300 Subject: [PATCH] updated to latest version of tgl --- CHANGELOG | 2 + interface.c | 234 ++++++++++++++++++-------- interface.h | 2 +- loop.c | 465 +++++++++++++++------------------------------------- loop.h | 3 +- lua-tg.c | 77 +++------ lua-tg.h | 2 +- main.c | 5 +- telegram.h | 4 +- tgl | 2 +- 10 files changed, 328 insertions(+), 468 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7726801..0da030c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +1.2.0 +* layer 22 support 1.0.6 * layer 18 support 1.0.5 diff --git a/interface.c b/interface.c index a719c45..8676c1d 100644 --- a/interface.c +++ b/interface.c @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this telegram-cli. If not, see . - Copyright Vitaly Valtman 2013-2014 + Copyright Vitaly Valtman 2013-2015 */ #ifdef HAVE_CONFIG_H @@ -77,6 +77,12 @@ #define ALLOW_MULT 1 char *default_prompt = "> "; +extern int read_one_string; +extern char one_string[]; +extern int one_string_len; +extern char *one_string_prompt; +extern int one_string_flags; + int disable_auto_accept; int msg_num_mode; int disable_colors; @@ -105,6 +111,7 @@ extern int sfd; extern int use_ids; extern struct tgl_state *TLS; +int readline_deactivated; int is_same_word (const char *s, size_t l, const char *word) { return s && word && strlen (word) == l && !memcmp (s, word, l); @@ -507,6 +514,7 @@ void set_prompt (const char *s) { void update_prompt (void) { if (readline_disabled) { return; } + if (read_one_string) { return; } print_start (); set_prompt (get_default_prompt ()); if (readline_active) { @@ -635,25 +643,31 @@ void do_dialog_list (int arg_num, struct arg args[], struct in_ev *ev) { void do_send_photo (int arg_num, struct arg args[], struct in_ev *ev) { assert (arg_num == 2); if (ev) { ev->refcnt ++; } - tgl_do_send_photo (TLS, tgl_message_media_photo, args[0].P->id, args[1].str, print_msg_success_gw, ev); + tgl_do_send_document (TLS, -1, args[0].P->id, args[1].str, print_msg_success_gw, ev); +} + +void do_send_file (int arg_num, struct arg args[], struct in_ev *ev) { + assert (arg_num == 2); + if (ev) { ev->refcnt ++; } + tgl_do_send_document (TLS, -2, args[0].P->id, args[1].str, print_msg_success_gw, ev); } void do_send_audio (int arg_num, struct arg args[], struct in_ev *ev) { assert (arg_num == 2); if (ev) { ev->refcnt ++; } - tgl_do_send_photo (TLS, tgl_message_media_audio, args[0].P->id, args[1].str, print_msg_success_gw, ev); + tgl_do_send_document (TLS, FLAG_DOCUMENT_AUDIO, args[0].P->id, args[1].str, print_msg_success_gw, ev); } void do_send_video (int arg_num, struct arg args[], struct in_ev *ev) { assert (arg_num == 2); if (ev) { ev->refcnt ++; } - tgl_do_send_photo (TLS, tgl_message_media_video, args[0].P->id, args[1].str, print_msg_success_gw, ev); + tgl_do_send_document (TLS, FLAG_DOCUMENT_VIDEO, args[0].P->id, args[1].str, print_msg_success_gw, ev); } void do_send_document (int arg_num, struct arg args[], struct in_ev *ev) { assert (arg_num == 2); if (ev) { ev->refcnt ++; } - tgl_do_send_photo (TLS, tgl_message_media_document, args[0].P->id, args[1].str, print_msg_success_gw, ev); + tgl_do_send_document (TLS, 0, args[0].P->id, args[1].str, print_msg_success_gw, ev); } void do_send_text (int arg_num, struct arg args[], struct in_ev *ev) { @@ -714,22 +728,25 @@ void do_rename_chat (int arg_num, struct arg args[], struct in_ev *ev) { void do_ ## act ## _ ## tp (int arg_num, struct arg args[], struct in_ev *ev) { \ assert (arg_num == 1);\ struct tgl_message *M = tgl_message_get (TLS, args[0].num);\ - if (M && !M->service && M->media.type == tgl_message_media_ ## tp) {\ - if (ev) { ev->refcnt ++; } \ - tgl_do_load_ ## tp (TLS, &M->media.tp, actf, ev); \ - } else if (M && !M->service && M->media.type == tgl_message_media_ ## tp ## _encr) { \ - if (ev) { ev->refcnt ++; } \ - tgl_do_load_encr_video (TLS, &M->media.encr_video, actf, ev); \ - } \ + if (M && !M->service) {\ + if (M->media.type == tgl_message_media_photo) { \ + tgl_do_load_photo (TLS, &M->media.photo, actf, ev);\ + } else if (M->media.type == tgl_message_media_document) {\ + tgl_do_load_document (TLS, &M->media.document, actf, ev);\ + } else if (M->media.type == tgl_message_media_photo_encr || M->media.type == tgl_message_media_document_encr) {\ + tgl_do_load_encr_document (TLS, &M->media.encr_document, actf, ev); \ + }\ + }\ } #define DO_LOAD_PHOTO_THUMB(tp,act,actf) \ void do_ ## act ## _ ## tp ## _thumb (int arg_num, struct arg args[], struct in_ev *ev) { \ assert (arg_num == 1);\ struct tgl_message *M = tgl_message_get (TLS, args[0].num);\ - if (M && !M->service && M->media.type == tgl_message_media_ ## tp) { \ - if (ev) { ev->refcnt ++; } \ - tgl_do_load_ ## tp ## _thumb (TLS, &M->media.tp, actf, ev); \ + if (M && !M->service) {\ + if (M->media.type == tgl_message_media_document) {\ + tgl_do_load_document_thumb (TLS, &M->media.document, actf, ev);\ + }\ }\ } @@ -737,14 +754,18 @@ DO_LOAD_PHOTO(photo, load, print_filename_gw) DO_LOAD_PHOTO(video, load, print_filename_gw) DO_LOAD_PHOTO(audio, load, print_filename_gw) DO_LOAD_PHOTO(document, load, print_filename_gw) +DO_LOAD_PHOTO(file, load, print_filename_gw) DO_LOAD_PHOTO_THUMB(video, load, print_filename_gw) DO_LOAD_PHOTO_THUMB(document, load, print_filename_gw) +DO_LOAD_PHOTO_THUMB(file, load, print_filename_gw) DO_LOAD_PHOTO(photo, open, open_filename_gw) DO_LOAD_PHOTO(video, open, open_filename_gw) DO_LOAD_PHOTO(audio, open, open_filename_gw) DO_LOAD_PHOTO(document, open, open_filename_gw) +DO_LOAD_PHOTO(file, open, open_filename_gw) DO_LOAD_PHOTO_THUMB(video, open, open_filename_gw) DO_LOAD_PHOTO_THUMB(document, open, open_filename_gw) +DO_LOAD_PHOTO_THUMB(file, open, open_filename_gw) void do_add_contact (int arg_num, struct arg args[], struct in_ev *ev) { assert (arg_num == 3); @@ -1069,6 +1090,12 @@ void do_broadcast (int arg_num, struct arg args[], struct in_ev *ev) { tgl_do_send_broadcast (TLS, arg_num - 1, ids, args[arg_num - 1].str, strlen (args[arg_num - 1].str), print_msg_list_success_gw, ev); } +void do_set_password (int arg_num, struct arg args[], struct in_ev *ev) { + assert (arg_num == 1); + if (ev) { ev->refcnt ++; } + tgl_do_set_password (TLS, args[0].str ? args[0].str : "empty", print_success_gw, ev); +} + extern char *default_username; extern char *config_filename; extern char *prefix; @@ -1133,6 +1160,8 @@ struct command commands[] = { {"load_audio", {ca_number, ca_none}, do_load_audio, "load_audio \tDownloads file to downloads dirs. Prints file name after download end"}, {"load_document", {ca_number, ca_none}, do_load_document, "load_document \tDownloads file to downloads dirs. Prints file name after download end"}, {"load_document_thumb", {ca_number, ca_none}, do_load_document_thumb, "load_document_thumb \tDownloads file to downloads dirs. Prints file name after download end"}, + {"load_file", {ca_number, ca_none}, do_load_file, "load_file \tDownloads file to downloads dirs. Prints file name after download end"}, + {"load_file_thumb", {ca_number, ca_none}, do_load_file_thumb, "load_file_thumb \tDownloads file to downloads dirs. Prints file name after download end"}, {"load_photo", {ca_number, ca_none}, do_load_photo, "load_photo \tDownloads file to downloads dirs. Prints file name after download end"}, {"load_video", {ca_number, ca_none}, do_load_video, "load_video \tDownloads file to downloads dirs. Prints file name after download end"}, {"load_video_thumb", {ca_number, ca_none}, do_load_video_thumb, "load_video_thumb \tDownloads file to downloads dirs. Prints file name after download end"}, @@ -1149,6 +1178,7 @@ struct command commands[] = { {"send_audio", {ca_peer, ca_file_name_end, ca_none}, do_send_audio, "send_audio \tSends audio to peer"}, {"send_contact", {ca_peer, ca_string, ca_string, ca_string, ca_none}, do_send_contact, "send_contact \tSends contact (not necessary telegram user)"}, {"send_document", {ca_peer, ca_file_name_end, ca_none}, do_send_document, "send_document \tSends document to peer"}, + {"send_file", {ca_peer, ca_file_name_end, ca_none}, do_send_file, "send_file \tSends document to peer"}, {"send_location", {ca_peer, ca_double, ca_double, ca_none}, do_send_location, "send_location \tSends geo location"}, {"send_photo", {ca_peer, ca_file_name_end, ca_none}, do_send_photo, "send_photo \tSends photo to peer"}, {"send_text", {ca_peer, ca_file_name_end, ca_none}, do_send_text, "send_text \tSends contents of text file as plain text message"}, @@ -1156,6 +1186,7 @@ struct command commands[] = { {"send_typing_abort", {ca_peer, ca_none}, do_send_typing_abort, "send_typing \tSends typing notification abort"}, {"send_video", {ca_peer, ca_file_name_end, ca_none}, do_send_video, "send_video \tSends video to peer"}, {"set", {ca_string, ca_number, ca_none}, do_set, "set \tSets value of param. Currently available: log_level, debug_verbosity, alarm, msg_num"}, + {"set_password", {ca_string | ca_optional, ca_none}, do_set_password, "set_password \tSets password"}, {"set_profile_name", {ca_string, ca_string, ca_none}, do_set_profile_name, "set_profile_name \tSets profile name."}, {"set_profile_photo", {ca_file_name_end, ca_none}, do_set_profile_photo, "set_profile_photo \tSets profile photo. Photo will be cropped to square"}, {"set_ttl", {ca_secret_chat, ca_number, ca_none}, do_set_ttl, "set_ttl \tSets secret chat ttl. Client itself ignores ttl"}, @@ -1168,6 +1199,8 @@ struct command commands[] = { {"view_audio", {ca_number, ca_none}, do_open_audio, "view_audio \tDownloads file to downloads dirs. Then tries to open it with system default action"}, {"view_document", {ca_number, ca_none}, do_open_document, "view_document \tDownloads file to downloads dirs. Then tries to open it with system default action"}, {"view_document_thumb", {ca_number, ca_none}, do_open_document_thumb, "view_document_thumb \tDownloads file to downloads dirs. Then tries to open it with system default action"}, + {"view_file", {ca_number, ca_none}, do_open_file, "view_file \tDownloads file to downloads dirs. Then tries to open it with system default action"}, + {"view_file_thumb", {ca_number, ca_none}, do_open_file_thumb, "view_file_thumb \tDownloads file to downloads dirs. Then tries to open it with system default action"}, {"view_photo", {ca_number, ca_none}, do_open_photo, "view_photo \tDownloads file to downloads dirs. Then tries to open it with system default action"}, {"view_video", {ca_number, ca_none}, do_open_video, "view_video \tDownloads file to downloads dirs. Then tries to open it with system default action"}, {"view_video_thumb", {ca_number, ca_none}, do_open_video_thumb, "view_video_thumb \tDownloads file to downloads dirs. Then tries to open it with system default action"}, @@ -2093,10 +2126,17 @@ void user_status_upd (struct tgl_state *TLS, struct tgl_user *U) { mprint_end (ev); } +void on_login (struct tgl_state *TLS); +void on_started (struct tgl_state *TLS); +void do_get_string (struct tgl_state *TLS, const char *prompt, int flags, void (*cb)(struct tgl_state *, char *, void *), void *arg); + struct tgl_update_callback upd_cb = { .new_msg = print_message_gw, .marked_read = mark_read_upd, .logprintf = logprintf, + .get_string = do_get_string, + .logged_in = on_login, + .started = on_started, .type_notification = type_notification_upd, .type_in_chat_notification = type_in_chat_notification_upd, .type_in_secret_chat_notification = 0, @@ -2378,13 +2418,14 @@ int readline_active; int saved_point; char *saved_line; int prompt_was; -void print_start (void) { - if (in_readline) { return; } - if (readline_disabled) { return; } - assert (!prompt_was); - if (readline_active) { + + +void deactivate_readline (void) { + if (read_one_string) { + printf ("\033[2K\r"); + fflush (stdout); + } else { saved_point = rl_point; -#ifdef READLINE_GNU saved_line = malloc (rl_end + 1); assert (saved_line); saved_line[rl_end] = 0; @@ -2392,16 +2433,34 @@ void print_start (void) { rl_save_prompt(); rl_replace_line("", 0); -#else - assert (rl_end >= 0); - saved_line = malloc (rl_end + 1); - assert (saved_line); - memcpy (saved_line, rl_line_buffer, rl_end + 1); - rl_line_buffer[0] = 0; - set_prompt (""); -#endif rl_redisplay(); } +} + + +void reactivate_readline (void) { + if (read_one_string) { + printf ("%s ", one_string_prompt); + if (!(one_string_flags & 1)) { + printf ("%.*s", one_string_len, one_string); + } + fflush (stdout); + } else { + set_prompt (get_default_prompt ()); + rl_replace_line(saved_line, 0); + rl_point = saved_point; + rl_redisplay(); + free (saved_line); + } +} + +void print_start (void) { + if (in_readline) { return; } + if (readline_disabled) { return; } + assert (!prompt_was); + if (readline_active) { + deactivate_readline (); + } prompt_was = 1; } @@ -2413,15 +2472,7 @@ void print_end (void) { } assert (prompt_was); if (readline_active) { - set_prompt (get_default_prompt ()); -#if READLINE_GNU - rl_replace_line(saved_line, 0); -#else - memcpy (rl_line_buffer, saved_line, rl_end + 1); // not safe, but I hope this would work. -#endif - rl_point = saved_point; - rl_redisplay(); - free (saved_line); + reactivate_readline (); } prompt_was = 0; } @@ -2489,50 +2540,89 @@ void print_media (struct in_ev *ev, struct tgl_message_media *M) { mprintf (ev, "[photo]"); } return; - case tgl_message_media_video: - if (M->video.mime_type) { - mprintf (ev, "[video: type %s]", M->video.mime_type); - } else { - mprintf (ev, "[video]"); - } - return; - case tgl_message_media_audio: - if (M->audio.mime_type) { - mprintf (ev, "[audio: type %s]", M->audio.mime_type); - } else { - mprintf (ev, "[audio]"); - } - return; case tgl_message_media_document: - if (M->document.mime_type && M->document.caption) { - mprintf (ev, "[document %s: type %s]", M->document.caption, M->document.mime_type); + mprintf (ev, "["); + if (M->document.flags & FLAG_DOCUMENT_IMAGE) { + mprintf (ev, "image"); + } else if (M->document.flags & FLAG_DOCUMENT_AUDIO) { + mprintf (ev, "audio"); + } else if (M->document.flags & FLAG_DOCUMENT_VIDEO) { + mprintf (ev, "video"); + } else if (M->document.flags & FLAG_DOCUMENT_STICKER) { + mprintf (ev, "sticker"); } else { - mprintf (ev, "[document]"); + mprintf (ev, "document"); } + + if (M->document.caption && strlen (M->document.caption)) { + mprintf (ev, " %s:", M->document.caption); + } else { + mprintf (ev, ":"); + } + + if (M->document.mime_type) { + mprintf (ev, " type=%s", M->document.mime_type); + } + + if (M->document.w && M->document.h) { + mprintf (ev, " size=%dx%d", M->document.w, M->document.h); + } + + if (M->document.duration) { + mprintf (ev, " duration=%d", M->document.duration); + } + + mprintf (ev, " size="); + if (M->document.size < (1 << 10)) { + mprintf (ev, "%dB", M->document.size); + } else if (M->document.size < (1 << 20)) { + mprintf (ev, "%dKiB", M->document.size >> 10); + } else if (M->document.size < (1 << 30)) { + mprintf (ev, "%dMiB", M->document.size >> 20); + } else { + mprintf (ev, "%dGiB", M->document.size >> 30); + } + + mprintf (ev, "]"); + return; case tgl_message_media_photo_encr: mprintf (ev, "[photo]"); return; - case tgl_message_media_video_encr: - if (M->encr_video.mime_type) { - mprintf (ev, "[video: type %s]", M->encr_video.mime_type); - } else { - mprintf (ev, "[video]"); - } - return; - case tgl_message_media_audio_encr: - if (M->encr_audio.mime_type) { - mprintf (ev, "[audio: type %s]", M->encr_audio.mime_type); - } else { - mprintf (ev, "[audio]"); - } - return; case tgl_message_media_document_encr: - if (M->encr_document.mime_type && M->encr_document.file_name) { - mprintf (ev, "[document %s: type %s]", M->encr_document.file_name, M->encr_document.mime_type); + mprintf (ev, "["); + if (M->encr_document.flags & FLAG_DOCUMENT_IMAGE) { + mprintf (ev, "[image"); + } else if (M->encr_document.flags & FLAG_DOCUMENT_AUDIO) { + mprintf (ev, "[audio"); + } else if (M->encr_document.flags & FLAG_DOCUMENT_VIDEO) { + mprintf (ev, "[video"); + } else if (M->encr_document.flags & FLAG_DOCUMENT_STICKER) { + mprintf (ev, "[sticker"); } else { - mprintf (ev, "[document]"); + mprintf (ev, "[document"); } + + if (M->encr_document.caption) { + mprintf (ev, "%s:", M->encr_document.caption); + } else { + mprintf (ev, ":"); + } + + if (M->encr_document.mime_type) { + mprintf (ev, "type %s", M->encr_document.mime_type); + } + + if (M->encr_document.w && M->encr_document.h) { + mprintf (ev, " size %d:%d", M->encr_document.w, M->encr_document.h); + } + + if (M->encr_document.duration) { + mprintf (ev, " duration %d", M->encr_document.duration); + } + + mprintf (ev, "]"); + return; case tgl_message_media_geo: mprintf (ev, "[geo] https://maps.google.com/?q=%.6lf,%.6lf", M->geo.latitude, M->geo.longitude); diff --git a/interface.h b/interface.h index cc9c64c..1585090 100644 --- a/interface.h +++ b/interface.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this telegram-cli. If not, see . - Copyright Vitaly Valtman 2013-2014 + Copyright Vitaly Valtman 2013-2015 */ #ifndef __INTERFACE_H__ #define __INTERFACE_H__ diff --git a/loop.c b/loop.c index c2b6348..2fbd8e0 100644 --- a/loop.c +++ b/loop.c @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this telegram-cli. If not, see . - Copyright Vitaly Valtman 2013-2014 + Copyright Vitaly Valtman 2013-2015 */ #ifdef HAVE_CONFIG_H @@ -98,90 +98,113 @@ extern volatile int sigterm_cnt; extern char *start_command; extern struct tgl_state *TLS; -static void stdin_read_callback_all (int arg, short what, struct event *self) { - if (!readline_disabled) { - if (((long)arg) & 1) { - rl_callback_read_char (); - } else { - char *line = 0; - size_t len = 0; - assert (getline (&line, &len, stdin) >= 0); - got_it (line, strlen (line)); - } - } else { - while (1) { - if (line_buffer_pos == line_buffer_size) { - line_buffer = realloc (line_buffer, line_buffer_size * 2 + 100); - assert (line_buffer); - line_buffer_size = line_buffer_size * 2 + 100; - assert (line_buffer); - } - int r = read (0, line_buffer + line_buffer_pos, line_buffer_size - line_buffer_pos); - //logprintf ("r = %d, size = %d, pos = %d, what = 0x%x, fd = %d\n", r, line_buffer_size, line_buffer_pos, (int)what, fd); - if (r < 0) { - perror ("read"); - delete_stdin_event = 1; - break; - } - if (r == 0) { - //struct event *ev = event_base_get_running_event (TLS->ev_base); - //event_del (ev); - //event_del (self); - - delete_stdin_event = 1; - break; - } - line_buffer_pos += r; +struct event *term_ev = 0; +int read_one_string; +#define MAX_ONE_STRING_LEN 511 +char one_string[MAX_ONE_STRING_LEN + 1]; +int one_string_len; +void (*on_string_cb)(struct tgl_state *TLS, char *str, void *arg); +void *string_cb_arg; +char *one_string_prompt; +int one_string_flags; - while (1) { - int p = 0; - while (p < line_buffer_pos && line_buffer[p] != '\n') { p ++; } - if (p < line_buffer_pos) { - if (((long)arg) & 1) { - line_buffer[p] = 0; - interpreter (line_buffer); - } else { - got_it (line_buffer, p + 1); - } - memmove (line_buffer, line_buffer + p + 1, line_buffer_pos - p - 1); - line_buffer_pos -= (p + 1); - } else { - break; - } +void deactivate_readline (void); +void reactivate_readline (void); + +static void one_string_read_end (void) { + printf ("\n"); + fflush (stdout); + + read_one_string = 0; + free (one_string_prompt); + one_string_prompt = NULL; + reactivate_readline (); + on_string_cb (TLS, one_string, string_cb_arg); +} + +void do_get_string (struct tgl_state *TLS, const char *prompt, int flags, void (*cb)(struct tgl_state *, char *, void *), void *arg) { + deactivate_readline (); + printf ("%s ", prompt); + fflush (stdout); + one_string_prompt = strdup (prompt); + one_string_flags = flags; + read_one_string = 1; + on_string_cb = cb; + string_cb_arg = arg; + one_string_len = 0; +} + +static void stdin_read_callback (evutil_socket_t fd, short what, void *arg) { + if (!readline_disabled && !read_one_string) { + rl_callback_read_char (); + return; + } + if (read_one_string) { + char c; + int r = read (0, &c, 1); + if (r <= 0) { + perror ("read"); + delete_stdin_event = 1; + return; + } + if (c == '\n' || c == '\r') { + one_string[one_string_len] = 0; + one_string_read_end (); + return; + } + if (one_string_len < MAX_ONE_STRING_LEN) { + one_string[one_string_len ++] = c; + if (!(one_string_flags & 1)) { + printf ("%c", c); + fflush (stdout); } + } + return; + } + + if (line_buffer_pos == line_buffer_size) { + line_buffer = realloc (line_buffer, line_buffer_size * 2 + 100); + assert (line_buffer); + line_buffer_size = line_buffer_size * 2 + 100; + assert (line_buffer); + } + int r = read (0, line_buffer + line_buffer_pos, line_buffer_size - line_buffer_pos); + if (r <= 0) { + perror ("read"); + delete_stdin_event = 1; + return; + } + line_buffer_pos += r; + + while (1) { + int p = 0; + while (p < line_buffer_pos && line_buffer[p] != '\n') { p ++; } + if (p < line_buffer_pos) { + line_buffer[p] = 0; + interpreter (line_buffer); + memmove (line_buffer, line_buffer + p + 1, line_buffer_pos - p - 1); + line_buffer_pos -= (p + 1); + } else { break; } } } -static void stdin_read_callback_char (evutil_socket_t fd, short what, void *arg) { - stdin_read_callback_all (1, what, arg); -} -static void stdin_read_callback_line (evutil_socket_t fd, short what, void *arg) { - stdin_read_callback_all (2, what, arg); -} - -struct event *term_ev = 0; -void net_loop (int flags, int (*is_end)(void)) { +void net_loop (void) { delete_stdin_event = 0; if (verbosity >= E_DEBUG) { logprintf ("Starting netloop\n"); } - if (flags & 3) { - if (flags & 1) { - term_ev = event_new (TLS->ev_base, 0, EV_READ | EV_PERSIST, stdin_read_callback_char, 0); - } else { - term_ev = event_new (TLS->ev_base, 0, EV_READ | EV_PERSIST, stdin_read_callback_line, 0); - } - event_add (term_ev, 0); - } + term_ev = event_new (TLS->ev_base, 0, EV_READ | EV_PERSIST, stdin_read_callback, 0); + event_add (term_ev, 0); + int last_get_state = time (0); - while (!is_end || !is_end ()) { - + while (1) { event_base_loop (TLS->ev_base, EVLOOP_ONCE); if (term_ev && delete_stdin_event) { + logprintf ("delete stdin\n"); event_free (term_ev); term_ev = 0; } @@ -189,6 +212,7 @@ void net_loop (int flags, int (*is_end)(void)) { #ifdef USE_LUA lua_do_all (); #endif + if (safe_quit && !TLS->active_queries) { printf ("All done. Exit\n"); do_halt (0); @@ -200,8 +224,10 @@ void net_loop (int flags, int (*is_end)(void)) { tgl_do_lookup_state (TLS); last_get_state = time (0); } + write_state_file (); update_prompt (); + if (unknown_user_list_pos) { int i; for (i = 0; i < unknown_user_list_pos; i++) { @@ -221,38 +247,6 @@ void net_loop (int flags, int (*is_end)(void)) { } } -char **_s; -size_t *_l; -int got_it_ok; - -void got_it (char *line, int len) { - assert (len > 0); - line[-- len] = 0; // delete end of line - *_s = line; - *_l = len; - got_it_ok = 1; -} - -int is_got_it (void) { - return got_it_ok; -} - -int net_getline (char **s, size_t *l) { - fflush (stdout); -// rl_already_prompted = 1; - got_it_ok = 0; - _s = s; - _l = l; -// rl_callback_handler_install (0, got_it); - net_loop (2, is_got_it); - return 0; -} - -int main_loop (void) { - net_loop (1, 0); - return 0; -} - struct tgl_dc *cur_a_dc; int is_authorized (void) { return tgl_authorized_dc (TLS, cur_a_dc); @@ -268,77 +262,6 @@ int all_authorized (void) { return 1; } -int config_got; - -int got_config (void) { - return config_got; -} - -void on_get_config (void *extra, int success) { - if (!success) { - logprintf ("Can not get config.\n"); - do_halt (1); - } - config_got = 1; - -} - -int should_register; -char *hash; -void sign_in_callback (struct tgl_state *TLSR, void *extra, int success, int registered, const char *mhash) { - assert (TLSR == TLS); - if (!success) { - logprintf ("Can not send code\n"); - do_halt (1); - } - should_register = !registered; - hash = strdup (mhash); - assert (hash); -} - - -int signed_in_ok; - -void sign_in_result (struct tgl_state *TLSR, void *extra, int success, struct tgl_user *U) { - assert (TLSR == TLS); - if (!success) { - logprintf ("Can not login\n"); - do_halt (1); - } - signed_in_ok = 1; -} - -int signed_in (void) { - return signed_in_ok; -} - -int sent_code (void) { - return hash != 0; -} - -int dc_signed_in (void) { - return tgl_signed_dc (TLS, cur_a_dc); -} - -void export_auth_callback (struct tgl_state *TLSR, void *DC, int success) { - assert (TLSR == TLS); - if (!success) { - logprintf ("Can not export auth\n"); - do_halt (1); - } -} - -int d_got_ok; -void get_difference_callback (struct tgl_state *TLSR, void *extra, int success) { - assert (TLSR == TLS); - assert (success); - d_got_ok = 1; -} - -int dgot (void) { - return d_got_ok; -} - int zero[512]; @@ -641,11 +564,6 @@ void read_secret_chat_file (void) { close (secret_chat_fd); } -void dlist_cb (struct tgl_state *TLSR, void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[]) { - assert (TLSR == TLS); - d_got_ok = 1; -} - static void read_incoming (struct bufferevent *bev, void *_arg) { vlogprintf (E_WARNING, "Read from incoming connection\n"); struct in_ev *ev = _arg; @@ -713,10 +631,42 @@ static void accept_incoming (evutil_socket_t efd, short what, void *arg) { } char *get_downloads_directory (void); +void on_login (struct tgl_state *TLS) { + write_auth_file (); +} + +void on_started (struct tgl_state *TLS); +void dlist_cb (struct tgl_state *TLSR, void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[]) { + on_started (TLS); +} + +void on_started (struct tgl_state *TLS) { + if (wait_dialog_list) { + wait_dialog_list = 0; + tgl_do_get_dialog_list (TLS, dlist_cb, 0); + } + #ifdef USE_LUA + lua_diff_end (); + #endif + + if (start_command) { + safe_quit = 1; + while (*start_command) { + char *start = start_command; + while (*start_command && *start_command != '\n') { + start_command ++; + } + if (*start_command) { + *start_command = 0; + start_command ++; + } + interpreter_ex (start, 0); + } + } +} + int loop (void) { - //on_start (); tgl_set_callback (TLS, &upd_cb); - //TLS->temp_key_expire_time = 60; struct event_base *ev = event_base_new (); tgl_set_ev_base (TLS, ev); tgl_set_net_methods (TLS, &tgl_conn_methods); @@ -724,6 +674,7 @@ int loop (void) { assert (TLS->timer_methods); tgl_set_download_directory (TLS, get_downloads_directory ()); tgl_register_app_id (TLS, TELEGRAM_CLI_APP_ID, TELEGRAM_CLI_APP_HASH); + tgl_set_app_version (TLS, "Telegram-cli " TELEGRAM_CLI_VERSION); tgl_init (TLS); if (binlog_enabled) { @@ -765,159 +716,9 @@ int loop (void) { bl_do_reset_authorization (TLS); } - net_loop (0, all_authorized); - - int i; - for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i] && !tgl_authorized_dc (TLS, TLS->DC_list[i])) { - assert (0); - } - - if (!tgl_signed_dc (TLS, TLS->DC_working)) { - if (disable_output) { - fprintf (stderr, "Can not login without output\n"); - do_halt (1); - } - if (!default_username) { - size_t size = 0; - char *user = 0; - - if (!user) { - printf ("Telephone number (with '+' sign): "); - if (net_getline (&user, &size) == -1) { - perror ("getline()"); - do_halt (1); - } - set_default_username (user); - } - } - tgl_do_send_code (TLS, default_username, sign_in_callback, 0); - net_loop (0, sent_code); - - if (verbosity >= E_DEBUG) { - logprintf ("%s\n", should_register ? "phone not registered" : "phone registered"); - } - if (!should_register) { - char *code = 0; - size_t size = 0; - printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); - while (1) { - if (net_getline (&code, &size) == -1) { - perror ("getline()"); - do_halt (1); - } - if (!strcmp (code, "call")) { - printf ("You typed \"call\", switching to phone system.\n"); - tgl_do_phone_call (TLS, default_username, hash, 0, 0); - printf ("Calling you! Code: "); - continue; - } - if (tgl_do_send_code_result (TLS, default_username, hash, code, sign_in_result, 0) >= 0) { - break; - } - printf ("Invalid code. Try again: "); - free (code); - } - } else { - printf ("User is not registered. Do you want to register? [Y/n] "); - char *code; - size_t size; - if (net_getline (&code, &size) == -1) { - perror ("getline()"); - do_halt (1); - } - if (!*code || *code == 'y' || *code == 'Y') { - printf ("Ok, starting registartion.\n"); - } else { - printf ("Then try again\n"); - do_halt (1); - } - char *first_name; - printf ("First name: "); - if (net_getline (&first_name, &size) == -1) { - perror ("getline()"); - do_halt (1); - } - char *last_name; - printf ("Last name: "); - if (net_getline (&last_name, &size) == -1) { - perror ("getline()"); - do_halt (1); - } - printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); - while (1) { - if (net_getline (&code, &size) == -1) { - perror ("getline()"); - do_halt (1); - } - if (!strcmp (code, "call")) { - printf ("You typed \"call\", switching to phone system.\n"); - tgl_do_phone_call (TLS, default_username, hash, 0, 0); - printf ("Calling you! Code: "); - continue; - } - if (tgl_do_send_code_result_auth (TLS, default_username, hash, code, first_name, last_name, sign_in_result, 0) >= 0) { - break; - } - printf ("Invalid code. Try again: "); - free (code); - } - } - - net_loop (0, signed_in); - //bl_do_dc_signed (TLS->DC_working); - } - - for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i] && !tgl_signed_dc (TLS, TLS->DC_list[i])) { - tgl_do_export_auth (TLS, i, export_auth_callback, (void*)(long)TLS->DC_list[i]); - cur_a_dc = TLS->DC_list[i]; - net_loop (0, dc_signed_in); - assert (tgl_signed_dc (TLS, TLS->DC_list[i])); - } - write_auth_file (); - - fflush (stdout); - fflush (stderr); - - //read_state_file (); - //read_secret_chat_file (); - set_interface_callbacks (); - - tglm_send_all_unsent (TLS); - tgl_do_get_difference (TLS, sync_from_start, get_difference_callback, 0); - net_loop (0, dgot); - assert (!(TLS->locks & TGL_LOCK_DIFF)); - TLS->started = 1; - if (wait_dialog_list) { - d_got_ok = 0; - tgl_do_get_dialog_list (TLS, dlist_cb, 0); - net_loop (0, dgot); - } - #ifdef USE_LUA - lua_diff_end (); - #endif - - if (start_command) { - safe_quit = 1; - while (*start_command) { - char *start = start_command; - while (*start_command && *start_command != '\n') { - start_command ++; - } - if (*start_command) { - *start_command = 0; - start_command ++; - } - interpreter_ex (start, 0); - } - } - - /*tgl_do_get_dialog_list (get_dialogs_callback, 0); - if (wait_dialog_list) { - dialog_list_got = 0; - net_loop (0, dlgot); - }*/ - - return main_loop (); + tgl_login (TLS); + net_loop (); + return 0; } diff --git a/loop.h b/loop.h index e580118..d0b9bad 100644 --- a/loop.h +++ b/loop.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this telegram-cli. If not, see . - Copyright Vitaly Valtman 2013-2014 + Copyright Vitaly Valtman 2013-2015 */ #ifndef __LOOP_H__ #define __LOOP_H__ @@ -23,7 +23,6 @@ int loop (void); void do_halt (int error); -void net_loop (int flags, int (*end)(void)); void write_auth_file (void); void write_state_file (void); void write_secret_chat_file (void); diff --git a/lua-tg.c b/lua-tg.c index 68ba69a..9efa0b8 100644 --- a/lua-tg.c +++ b/lua-tg.c @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this telegram-cli. If not, see . - Copyright Vitaly Valtman 2013-2014 + Copyright Vitaly Valtman 2013-2015 */ #ifdef HAVE_CONFIG_H @@ -248,7 +248,7 @@ void push_media (struct tgl_message_media *M) { lua_newtable (luaState); lua_add_string_field ("type", "photo"); break; - case tgl_message_media_video: + /*case tgl_message_media_video: case tgl_message_media_video_encr: lua_newtable (luaState); lua_add_string_field ("type", "video"); @@ -257,7 +257,7 @@ void push_media (struct tgl_message_media *M) { case tgl_message_media_audio_encr: lua_newtable (luaState); lua_add_string_field ("type", "audio"); - break; + break;*/ case tgl_message_media_document: case tgl_message_media_document_encr: lua_newtable (luaState); @@ -491,6 +491,7 @@ enum lua_query_type { lq_create_group_chat, lq_send_audio, lq_send_document, + lq_send_file, lq_load_audio, lq_load_document, lq_load_document_thumb, @@ -883,22 +884,27 @@ void lua_do_all (void) { p += 3; break; case lq_send_photo: - tgl_do_send_photo (TLS, tgl_message_media_photo, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_msg_cb, lua_ptr[p]); + tgl_do_send_document (TLS, -1, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_msg_cb, lua_ptr[p]); free (lua_ptr[p + 2]); p += 3; break; case lq_send_video: - tgl_do_send_photo (TLS, tgl_message_media_video, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_msg_cb, lua_ptr[p]); + tgl_do_send_document (TLS, FLAG_DOCUMENT_VIDEO, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_msg_cb, lua_ptr[p]); free (lua_ptr[p + 2]); p += 3; break; case lq_send_audio: - tgl_do_send_photo (TLS, tgl_message_media_audio, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_msg_cb, lua_ptr[p]); + tgl_do_send_document (TLS, FLAG_DOCUMENT_AUDIO, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_msg_cb, lua_ptr[p]); free (lua_ptr[p + 2]); p += 3; break; case lq_send_document: - tgl_do_send_photo (TLS, tgl_message_media_document, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_msg_cb, lua_ptr[p]); + tgl_do_send_document (TLS, 0, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_msg_cb, lua_ptr[p]); + free (lua_ptr[p + 2]); + p += 3; + break; + case lq_send_file: + tgl_do_send_document (TLS, -2, ((tgl_peer_t *)lua_ptr[p + 1])->id, lua_ptr[p + 2], lua_msg_cb, lua_ptr[p]); free (lua_ptr[p + 2]); p += 3; break; @@ -913,66 +919,24 @@ void lua_do_all (void) { p += 3; break; case lq_load_photo: + case lq_load_video: + case lq_load_audio: + case lq_load_document: M = lua_ptr[p + 1]; - if (!M || (M->media.type != tgl_message_media_photo && M->media.type != tgl_message_media_photo_encr)) { + if (!M || (M->media.type != tgl_message_media_photo && M->media.type != tgl_message_media_photo_encr && M->media.type != tgl_message_media_document && M->media.type != tgl_message_media_document_encr)) { lua_file_cb (TLS, lua_ptr[p], 0, 0); } else { if (M->media.type == tgl_message_media_photo) { tgl_do_load_photo (TLS, &M->media.photo, lua_file_cb, lua_ptr[p]); + } else if (M->media.type == tgl_message_media_document) { + tgl_do_load_document (TLS, &M->media.document, lua_file_cb, lua_ptr[p]); } else { - tgl_do_load_encr_video (TLS, &M->media.encr_video, lua_file_cb, lua_ptr[p]); - } - } - p += 2; - break; - case lq_load_video: - M = lua_ptr[p + 1]; - if (!M || (M->media.type != tgl_message_media_video && M->media.type != tgl_message_media_video_encr)) { - lua_file_cb (TLS, lua_ptr[p], 0, 0); - } else { - if (M->media.type == tgl_message_media_video) { - tgl_do_load_video (TLS, &M->media.video, lua_file_cb, lua_ptr[p]); - } else { - tgl_do_load_encr_video (TLS, &M->media.encr_video, lua_file_cb, lua_ptr[p]); + tgl_do_load_encr_document (TLS, &M->media.encr_document, lua_file_cb, lua_ptr[p]); } } p += 2; break; case lq_load_video_thumb: - M = lua_ptr[p + 1]; - if (!M || (M->media.type != tgl_message_media_video)) { - lua_file_cb (TLS, lua_ptr[p], 0, 0); - } else { - tgl_do_load_video_thumb (TLS, &M->media.video, lua_file_cb, lua_ptr[p]); - } - p += 2; - break; - case lq_load_audio: - M = lua_ptr[p + 1]; - if (!M || (M->media.type != tgl_message_media_audio && M->media.type != tgl_message_media_audio_encr)) { - lua_file_cb (TLS, lua_ptr[p], 0, 0); - } else { - if (M->media.type == tgl_message_media_audio) { - tgl_do_load_audio (TLS, &M->media.audio, lua_file_cb, lua_ptr[p]); - } else { - tgl_do_load_encr_video (TLS, &M->media.encr_video, lua_file_cb, lua_ptr[p]); - } - } - p += 2; - break; - case lq_load_document: - M = lua_ptr[p + 1]; - if (!M || (M->media.type != tgl_message_media_document && M->media.type != tgl_message_media_document_encr)) { - lua_file_cb (TLS, lua_ptr[p], 0, 0); - } else { - if (M->media.type == tgl_message_media_document) { - tgl_do_load_document (TLS, &M->media.document, lua_file_cb, lua_ptr[p]); - } else { - tgl_do_load_encr_video (TLS, &M->media.encr_video, lua_file_cb, lua_ptr[p]); - } - } - p += 2; - break; case lq_load_document_thumb: M = lua_ptr[p + 1]; if (!M || (M->media.type != tgl_message_media_document)) { @@ -1171,6 +1135,7 @@ struct lua_function functions[] = { {"send_video", lq_send_video, { lfp_peer, lfp_string, lfp_none }}, {"send_audio", lq_send_audio, { lfp_peer, lfp_string, lfp_none }}, {"send_document", lq_send_document, { lfp_peer, lfp_string, lfp_none }}, + {"send_file", lq_send_file, { lfp_peer, lfp_string, lfp_none }}, {"send_text", lq_send_text, { lfp_peer, lfp_string, lfp_none }}, {"chat_set_photo", lq_chat_set_photo, { lfp_chat, lfp_string, lfp_none }}, {"load_photo", lq_load_photo, { lfp_msg, lfp_none }}, diff --git a/lua-tg.h b/lua-tg.h index 2db43b8..d7bfc02 100644 --- a/lua-tg.h +++ b/lua-tg.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this telegram-cli. If not, see . - Copyright Vitaly Valtman 2013-2014 + Copyright Vitaly Valtman 2013-2015 */ #ifndef __LUA_TG_H__ #define __LUA_TG_H__ diff --git a/main.c b/main.c index 9a4a098..474f242 100644 --- a/main.c +++ b/main.c @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this telegram-cli. If not, see . - Copyright Vitaly Valtman 2013-2014 + Copyright Vitaly Valtman 2013-2015 */ #ifdef HAVE_CONFIG_H @@ -839,10 +839,11 @@ int main (int argc, char **argv) { if (!disable_output) { printf ( - "Telegram-cli version " TGL_VERSION ", Copyright (C) 2013-2014 Vitaly Valtman\n" + "Telegram-cli version " TELEGRAM_CLI_VERSION ", Copyright (C) 2013-2015 Vitaly Valtman\n" "Telegram-cli comes with ABSOLUTELY NO WARRANTY; for details type `show_license'.\n" "This is free software, and you are welcome to redistribute it\n" "under certain conditions; type `show_license' for details.\n" + "Telegram-cli uses libtgl version " TGL_VERSION "\n" ); } running_for_first_time (); diff --git a/telegram.h b/telegram.h index 49b16a4..e8a5432 100644 --- a/telegram.h +++ b/telegram.h @@ -14,9 +14,11 @@ You should have received a copy of the GNU General Public License along with this telegram-cli. If not, see . - Copyright Vitaly Valtman 2013-2014 + Copyright Vitaly Valtman 2013-2015 */ #ifndef PROG_NAME #define PROG_NAME "telegram-cli" #endif + +#define TELEGRAM_CLI_VERSION "1.2.0" diff --git a/tgl b/tgl index 0205b66..24ed7ee 160000 --- a/tgl +++ b/tgl @@ -1 +1 @@ -Subproject commit 0205b668d3abcf35a348556776d1180439d115d9 +Subproject commit 24ed7ee1fa0520dc4e69e845a84281e034b4c482