2013-10-23 10:26:17 -04:00
/*
2014-08-21 18:02:43 -04:00
This file is part of telegram - cli .
2013-10-23 10:26:17 -04:00
2014-08-21 18:02:43 -04:00
Telegram - cli is free software : you can redistribute it and / or modify
2013-10-23 10:26:17 -04:00
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 .
2014-08-21 18:02:43 -04:00
Telegram - cli is distributed in the hope that it will be useful ,
2013-10-23 10:26:17 -04:00
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
2014-08-21 18:02:43 -04:00
along with this telegram - cli . If not , see < http : //www.gnu.org/licenses/>.
2013-10-23 10:26:17 -04:00
2014-08-21 18:02:43 -04:00
Copyright Vitaly Valtman 2013 - 2014
2013-10-23 10:26:17 -04:00
*/
2014-01-13 08:05:25 -05:00
# ifdef HAVE_CONFIG_H
2013-11-09 17:47:19 -05:00
# include "config.h"
2014-01-13 08:05:25 -05:00
# endif
2013-10-03 08:38:25 -04:00
# define _GNU_SOURCE
2013-11-09 17:47:19 -05:00
2013-10-03 08:38:25 -04:00
# include <assert.h>
# include <stdio.h>
2013-10-11 16:52:20 -04:00
# include <stdarg.h>
2013-10-03 08:38:25 -04:00
# include <stdlib.h>
# include <string.h>
2013-10-18 14:00:19 -04:00
2013-11-09 17:47:19 -05:00
# ifdef READLINE_GNU
2013-10-18 14:00:19 -04:00
# include <readline/readline.h>
# include <readline/history.h>
2013-11-09 17:47:19 -05:00
# else
2013-11-11 06:34:45 -05:00
# include <readline/readline.h>
# include <readline/history.h>
2013-11-09 17:47:19 -05:00
# endif
2013-10-18 14:00:19 -04:00
2013-10-03 08:38:25 -04:00
# include "include.h"
2014-08-13 11:55:16 -04:00
//#include "queries.h"
2013-10-13 06:18:08 -04:00
# include "interface.h"
# include "telegram.h"
2014-09-07 15:12:39 -04:00
# ifdef EVENT_V2
2014-08-21 16:35:27 -04:00
# include <event2/event.h>
2014-09-07 15:12:39 -04:00
# else
# include <event.h>
# include "event-old.h"
# endif
2014-08-18 12:39:04 -04:00
//#include "auto/constants.h"
2014-08-14 18:16:01 -04:00
//#include "tools.h"
2014-08-13 11:55:16 -04:00
//#include "structures.h"
2013-10-18 12:00:47 -04:00
2014-08-21 11:38:51 -04:00
# ifdef USE_LUA
# include "lua-tg.h"
# endif
2014-08-13 11:55:16 -04:00
//#include "mtproto-common.h"
2013-11-25 12:16:34 -05:00
2014-08-13 08:56:55 -04:00
# include "tgl.h"
2014-08-31 10:18:19 -04:00
# include "loop.h"
2014-08-13 08:56:55 -04:00
2014-08-14 18:16:01 -04:00
# ifndef PATH_MAX
# define PATH_MAX 4096
# endif
# ifdef __APPLE__
# define OPEN_BIN "open %s"
# else
# define OPEN_BIN "xdg-open %s"
# endif
2014-01-24 10:05:41 -05:00
# define ALLOW_MULT 1
2013-10-24 11:44:54 -04:00
char * default_prompt = " > " ;
2014-08-26 12:06:30 -04:00
int disable_auto_accept ;
2013-10-25 15:50:10 -04:00
int msg_num_mode ;
2014-08-24 20:11:41 -04:00
int disable_colors ;
2014-02-27 03:48:05 -05:00
int alert_sound ;
2014-08-21 11:38:51 -04:00
extern int binlog_read ;
2013-10-03 08:38:25 -04:00
2013-12-21 06:53:32 -05:00
int safe_quit ;
2013-10-29 20:08:30 -04:00
int in_readline ;
2013-11-11 06:34:45 -05:00
int readline_active ;
2013-10-29 20:08:30 -04:00
2013-11-15 11:14:25 -05:00
int log_level ;
2013-10-29 20:08:30 -04:00
char * line_ptr ;
2013-12-06 12:14:41 -05:00
int in_chat_mode ;
2014-08-13 11:55:16 -04:00
tgl_peer_id_t chat_mode_id ;
2014-08-26 14:26:00 -04:00
extern int readline_disabled ;
2013-11-09 17:47:19 -05:00
2014-09-09 13:05:36 -04:00
extern int disable_output ;
2013-10-29 20:08:30 -04:00
int is_same_word ( const char * s , size_t l , const char * word ) {
return s & & word & & strlen ( word ) = = l & & ! memcmp ( s , word , l ) ;
}
2014-08-12 21:22:15 -04:00
char * end_string_token ( int * l ) {
while ( * line_ptr = = ' ' ) { line_ptr + + ; }
if ( ! * line_ptr ) {
* l = 0 ;
return 0 ;
}
char * s = line_ptr ;
while ( * line_ptr ) { line_ptr + + ; }
while ( * line_ptr = = ' ' | | ! * line_ptr ) { line_ptr - - ; }
line_ptr + + ;
* l = line_ptr - s ;
return s ;
}
2014-08-13 11:55:16 -04:00
2013-10-29 20:08:30 -04:00
char * next_token ( int * l ) {
while ( * line_ptr = = ' ' ) { line_ptr + + ; }
if ( ! * line_ptr ) {
* l = 0 ;
return 0 ;
}
int neg = 0 ;
char * s = line_ptr ;
2013-11-06 17:16:46 -05:00
int in_str = 0 ;
while ( * line_ptr & & ( * line_ptr ! = ' ' | | neg | | in_str ) ) {
2013-10-29 20:08:30 -04:00
line_ptr + + ;
}
* l = line_ptr - s ;
return s ;
}
# define NOT_FOUND (int)0x80000000
2014-08-13 11:55:16 -04:00
tgl_peer_id_t TGL_PEER_NOT_FOUND = { . id = NOT_FOUND } ;
2013-10-31 19:18:34 -04:00
2013-11-04 18:15:24 -05:00
long long next_token_int ( void ) {
2013-10-29 20:08:30 -04:00
int l ;
char * s = next_token ( & l ) ;
if ( ! s ) { return NOT_FOUND ; }
char * r ;
2013-11-04 18:15:24 -05:00
long long x = strtoll ( s , & r , 10 ) ;
2013-10-29 20:08:30 -04:00
if ( r = = s + l ) {
return x ;
} else {
return NOT_FOUND ;
}
}
2014-08-13 11:55:16 -04:00
tgl_peer_id_t next_token_user ( void ) {
2013-10-29 20:08:30 -04:00
int l ;
char * s = next_token ( & l ) ;
2014-08-13 11:55:16 -04:00
if ( ! s ) { return TGL_PEER_NOT_FOUND ; }
2013-10-29 20:08:30 -04:00
2013-10-31 19:18:34 -04:00
if ( l > = 6 & & ! memcmp ( s , " user# " , 5 ) ) {
s + = 5 ;
l - = 5 ;
int r = atoi ( s ) ;
2014-08-13 11:55:16 -04:00
if ( r > = 0 ) { return tgl_set_peer_id ( TGL_PEER_USER , r ) ; }
else { return TGL_PEER_NOT_FOUND ; }
2013-10-29 20:08:30 -04:00
}
2014-09-03 11:54:50 -04:00
if ( l > = 8 & & ! memcmp ( s , " user#id " , 7 ) ) {
s + = 7 ;
l - = 7 ;
int r = atoi ( s ) ;
if ( r > = 0 ) { return tgl_set_peer_id ( TGL_PEER_USER , r ) ; }
else { return TGL_PEER_NOT_FOUND ; }
}
2013-10-31 19:18:34 -04:00
2014-08-13 08:56:55 -04:00
char c = s [ l ] ;
2014-08-18 12:39:04 -04:00
s [ l ] = 0 ;
2014-08-13 11:55:16 -04:00
tgl_peer_t * P = tgl_peer_get_by_name ( s ) ;
2014-08-13 08:56:55 -04:00
s [ l ] = c ;
2014-08-13 11:55:16 -04:00
if ( P & & tgl_get_peer_type ( P - > id ) = = TGL_PEER_USER ) {
2014-08-13 08:56:55 -04:00
return P - > id ;
2013-10-29 20:08:30 -04:00
} else {
2014-08-13 11:55:16 -04:00
return TGL_PEER_NOT_FOUND ;
2013-10-29 20:08:30 -04:00
}
}
2014-08-13 11:55:16 -04:00
tgl_peer_id_t next_token_chat ( void ) {
2013-10-29 20:08:30 -04:00
int l ;
char * s = next_token ( & l ) ;
2014-08-13 11:55:16 -04:00
if ( ! s ) { return TGL_PEER_NOT_FOUND ; }
2013-10-31 19:18:34 -04:00
if ( l > = 6 & & ! memcmp ( s , " chat# " , 5 ) ) {
s + = 5 ;
l - = 5 ;
int r = atoi ( s ) ;
2014-08-13 11:55:16 -04:00
if ( r > = 0 ) { return tgl_set_peer_id ( TGL_PEER_CHAT , r ) ; }
else { return TGL_PEER_NOT_FOUND ; }
2013-10-29 20:08:30 -04:00
}
2014-09-03 11:54:50 -04:00
if ( l > = 8 & & ! memcmp ( s , " chat#id " , 7 ) ) {
s + = 7 ;
l - = 7 ;
int r = atoi ( s ) ;
if ( r > = 0 ) { return tgl_set_peer_id ( TGL_PEER_CHAT , r ) ; }
else { return TGL_PEER_NOT_FOUND ; }
}
2013-10-31 19:18:34 -04:00
2014-08-13 08:56:55 -04:00
char c = s [ l ] ;
2014-08-18 12:39:04 -04:00
s [ l ] = 0 ;
2014-08-13 11:55:16 -04:00
tgl_peer_t * P = tgl_peer_get_by_name ( s ) ;
2014-08-13 08:56:55 -04:00
s [ l ] = c ;
2014-08-13 11:55:16 -04:00
if ( P & & tgl_get_peer_type ( P - > id ) = = TGL_PEER_CHAT ) {
2014-08-13 08:56:55 -04:00
return P - > id ;
2013-10-29 20:08:30 -04:00
} else {
2014-08-13 11:55:16 -04:00
return TGL_PEER_NOT_FOUND ;
2013-10-29 20:08:30 -04:00
}
}
2014-08-13 11:55:16 -04:00
tgl_peer_id_t next_token_encr_chat ( void ) {
2013-11-04 18:15:24 -05:00
int l ;
char * s = next_token ( & l ) ;
2014-08-13 11:55:16 -04:00
if ( ! s ) { return TGL_PEER_NOT_FOUND ; }
2013-11-04 18:15:24 -05:00
2014-08-13 08:56:55 -04:00
char c = s [ l ] ;
2014-08-18 12:39:04 -04:00
s [ l ] = 0 ;
2014-08-13 11:55:16 -04:00
tgl_peer_t * P = tgl_peer_get_by_name ( s ) ;
2014-08-13 08:56:55 -04:00
s [ l ] = c ;
2014-08-13 11:55:16 -04:00
if ( P & & tgl_get_peer_type ( P - > id ) = = TGL_PEER_ENCR_CHAT ) {
2014-08-13 08:56:55 -04:00
return P - > id ;
2013-11-04 18:15:24 -05:00
} else {
2014-08-13 11:55:16 -04:00
return TGL_PEER_NOT_FOUND ;
2013-11-04 18:15:24 -05:00
}
}
2014-08-13 11:55:16 -04:00
tgl_peer_id_t next_token_peer ( void ) {
2013-10-29 20:08:30 -04:00
int l ;
char * s = next_token ( & l ) ;
2014-08-13 11:55:16 -04:00
if ( ! s ) { return TGL_PEER_NOT_FOUND ; }
2013-10-31 19:18:34 -04:00
if ( l > = 6 & & ! memcmp ( s , " user# " , 5 ) ) {
s + = 5 ;
l - = 5 ;
int r = atoi ( s ) ;
2014-08-13 11:55:16 -04:00
if ( r > = 0 ) { return tgl_set_peer_id ( TGL_PEER_USER , r ) ; }
else { return TGL_PEER_NOT_FOUND ; }
2013-10-31 19:18:34 -04:00
}
if ( l > = 6 & & ! memcmp ( s , " chat# " , 5 ) ) {
s + = 5 ;
l - = 5 ;
int r = atoi ( s ) ;
2014-08-13 11:55:16 -04:00
if ( r > = 0 ) { return tgl_set_peer_id ( TGL_PEER_CHAT , r ) ; }
else { return TGL_PEER_NOT_FOUND ; }
2013-10-29 20:08:30 -04:00
}
2014-08-13 08:56:55 -04:00
char c = s [ l ] ;
2014-08-18 12:39:04 -04:00
s [ l ] = 0 ;
2014-08-13 11:55:16 -04:00
tgl_peer_t * P = tgl_peer_get_by_name ( s ) ;
2014-08-13 08:56:55 -04:00
s [ l ] = c ;
if ( P ) {
return P - > id ;
2013-10-29 20:08:30 -04:00
} else {
2014-08-13 11:55:16 -04:00
return TGL_PEER_NOT_FOUND ;
2013-10-29 20:08:30 -04:00
}
}
2013-10-28 18:33:13 -04:00
2013-10-03 08:38:25 -04:00
char * get_default_prompt ( void ) {
2013-12-06 12:14:41 -05:00
static char buf [ 1000 ] ;
int l = 0 ;
if ( in_chat_mode ) {
2014-08-13 11:55:16 -04:00
tgl_peer_t * U = tgl_peer_get ( chat_mode_id ) ;
2013-12-06 12:14:41 -05:00
assert ( U & & U - > print_name ) ;
2014-08-14 18:16:01 -04:00
l + = snprintf ( buf + l , 999 - l , COLOR_RED " %.*s " COLOR_NORMAL , 100 , U - > print_name ) ;
2013-12-06 12:14:41 -05:00
}
2014-08-13 11:55:16 -04:00
if ( tgl_state . unread_messages | | tgl_state . cur_uploading_bytes | | tgl_state . cur_downloading_bytes ) {
2014-08-14 18:16:01 -04:00
l + = snprintf ( buf + l , 999 - l , COLOR_RED " [ " ) ;
2013-10-28 18:33:13 -04:00
int ok = 0 ;
2014-08-13 11:55:16 -04:00
if ( tgl_state . unread_messages ) {
2014-08-14 18:16:01 -04:00
l + = snprintf ( buf + l , 999 - l , " %d unread " , tgl_state . unread_messages ) ;
2013-10-28 18:33:13 -04:00
ok = 1 ;
}
2014-08-13 11:55:16 -04:00
if ( tgl_state . cur_uploading_bytes ) {
2013-10-28 18:33:13 -04:00
if ( ok ) { * ( buf + l ) = ' ' ; l + + ; }
ok = 1 ;
2014-08-14 18:16:01 -04:00
l + = snprintf ( buf + l , 999 - l , " %lld%%Up " , 100 * tgl_state . cur_uploaded_bytes / tgl_state . cur_uploading_bytes ) ;
2013-10-28 18:33:13 -04:00
}
2014-08-13 11:55:16 -04:00
if ( tgl_state . cur_downloading_bytes ) {
2013-10-28 18:33:13 -04:00
if ( ok ) { * ( buf + l ) = ' ' ; l + + ; }
ok = 1 ;
2014-08-14 18:16:01 -04:00
l + = snprintf ( buf + l , 999 - l , " %lld%%Down " , 100 * tgl_state . cur_downloaded_bytes / tgl_state . cur_downloading_bytes ) ;
2013-10-28 18:33:13 -04:00
}
2014-08-14 18:16:01 -04:00
l + = snprintf ( buf + l , 999 - l , " ] " COLOR_NORMAL ) ;
2014-08-21 16:35:27 -04:00
l + = snprintf ( buf + l , 999 - l , " %s " , default_prompt ) ;
2013-10-24 11:44:54 -04:00
return buf ;
2013-12-06 12:14:41 -05:00
}
2014-08-14 18:16:01 -04:00
l + = snprintf ( buf + l , 999 - l , " %s " , default_prompt ) ;
2013-12-06 12:14:41 -05:00
return buf ;
2013-10-03 08:38:25 -04:00
}
char * complete_none ( const char * text UU , int state UU ) {
return 0 ;
}
2013-11-09 17:47:19 -05:00
void set_prompt ( const char * s ) {
2014-08-26 14:26:00 -04:00
if ( readline_disabled ) { return ; }
2013-11-09 17:47:19 -05:00
rl_set_prompt ( s ) ;
}
2013-10-28 18:33:13 -04:00
void update_prompt ( void ) {
2014-08-26 14:26:00 -04:00
if ( readline_disabled ) { return ; }
2013-10-28 18:33:13 -04:00
print_start ( ) ;
2013-11-09 17:47:19 -05:00
set_prompt ( get_default_prompt ( ) ) ;
2013-11-11 06:34:45 -05:00
if ( readline_active ) {
rl_redisplay ( ) ;
}
2013-10-28 18:33:13 -04:00
print_end ( ) ;
}
2013-11-30 13:52:13 -05:00
char * modifiers [ ] = {
" [offline] " ,
0
} ;
2013-12-06 12:14:41 -05:00
char * in_chat_commands [ ] = {
" /exit " ,
" /quit " ,
2013-12-19 17:50:31 -05:00
" /history " ,
" /read " ,
2013-12-06 12:14:41 -05:00
0
} ;
2014-08-25 12:17:17 -04:00
enum command_argument {
ca_none ,
ca_user ,
ca_chat ,
ca_secret_chat ,
ca_peer ,
ca_file_name ,
ca_file_name_end ,
ca_period ,
ca_number ,
ca_string_end ,
ca_string ,
ca_modifier ,
2014-09-10 07:52:42 -04:00
ca_command ,
ca_extf
2013-10-03 08:38:25 -04:00
} ;
2013-10-03 12:09:06 -04:00
2014-08-25 12:17:17 -04:00
struct command {
char * name ;
enum command_argument args [ 10 ] ;
} ;
struct command commands [ ] = {
{ " help " , { ca_none } } ,
{ " contact_list " , { ca_none } } ,
{ " stats " , { ca_none } } ,
{ " history " , { ca_peer , ca_none , ca_number , ca_number } } ,
{ " dialog_list " , { ca_none } } ,
{ " send_photo " , { ca_peer , ca_file_name_end } } ,
{ " send_video " , { ca_peer , ca_file_name_end } } ,
{ " send_audio " , { ca_peer , ca_file_name_end } } ,
{ " send_document " , { ca_peer , ca_file_name_end } } ,
{ " send_text " , { ca_peer , ca_file_name_end } } ,
{ " chat_info " , { ca_chat , ca_none } } ,
{ " user_info " , { ca_user , ca_none } } ,
{ " fwd " , { ca_peer , ca_number , ca_none } } ,
2014-09-07 11:17:35 -04:00
{ " fwd_media " , { ca_peer , ca_number , ca_none } } ,
2014-08-25 12:17:17 -04:00
{ " msg " , { ca_peer , ca_string_end } } ,
{ " rename_chat " , { ca_peer , ca_string_end } } ,
{ " load_photo " , { ca_number , ca_none } } ,
{ " view_photo " , { ca_number , ca_none } } ,
{ " load_video_thumb " , { ca_number , ca_none } } ,
{ " view_video_thumb " , { ca_number , ca_none } } ,
{ " load_video " , { ca_number , ca_none } } ,
{ " view_video " , { ca_number , ca_none } } ,
{ " load_audio " , { ca_number , ca_none } } ,
{ " view_audio " , { ca_number , ca_none } } ,
{ " load_document " , { ca_number , ca_none } } ,
{ " view_document " , { ca_number , ca_none } } ,
{ " load_document_thumb " , { ca_number , ca_none } } ,
{ " view_document_thumb " , { ca_number , ca_none } } ,
{ " add_contact " , { ca_string , ca_string , ca_string , ca_none } } ,
2014-09-10 10:13:52 -04:00
{ " del_contact " , { ca_user , ca_none } } ,
2014-08-25 12:17:17 -04:00
{ " rename_contact " , { ca_user , ca_string , ca_string , ca_none } } ,
{ " show_license " , { ca_none } } ,
{ " search " , { ca_peer , ca_string_end } } ,
{ " mark_read " , { ca_peer , ca_none } } ,
{ " visualize_key " , { ca_secret_chat , ca_none } } ,
{ " create_secret_chat " , { ca_user , ca_none } } ,
{ " global_search " , { ca_string_end } } ,
2014-09-02 06:27:23 -04:00
{ " chat_add_user " , { ca_chat , ca_user , ca_none } } ,
{ " chat_del_user " , { ca_chat , ca_user , ca_none } } ,
2014-08-25 12:17:17 -04:00
{ " status_online " , { ca_none } } ,
{ " status_offline " , { ca_none } } ,
{ " quit " , { ca_none } } ,
{ " safe_quit " , { ca_none } } ,
{ " set " , { ca_string , ca_string , ca_none } } ,
{ " chat_with_peer " , { ca_peer , ca_none } } ,
{ " delete_msg " , { ca_number , ca_none } } ,
{ " restore_msg " , { ca_number , ca_none } } ,
2014-09-02 06:22:26 -04:00
{ " create_group_chat " , { ca_user , ca_string_end } } ,
2014-08-25 12:17:17 -04:00
{ " chat_set_photo " , { ca_chat , ca_file_name_end } } ,
{ " set_profile_photo " , { ca_file_name_end } } ,
2014-08-27 11:40:21 -04:00
{ " accept_secret_chat " , { ca_secret_chat , ca_none } } ,
2014-08-29 11:46:04 -04:00
{ " export_card " , { ca_none } } ,
{ " import_card " , { ca_string , ca_none } } ,
2014-09-02 07:20:18 -04:00
{ " send_contact " , { ca_peer , ca_string , ca_string , ca_string } } ,
2014-08-25 12:17:17 -04:00
{ 0 , { ca_none } }
} ;
2013-11-30 13:52:13 -05:00
2014-08-25 12:17:17 -04:00
enum command_argument get_complete_mode ( void ) {
2013-10-29 20:08:30 -04:00
line_ptr = rl_line_buffer ;
2013-10-03 08:38:25 -04:00
int l = 0 ;
2013-10-29 20:08:30 -04:00
char * r = next_token ( & l ) ;
2014-08-25 12:17:17 -04:00
if ( ! r ) { return ca_command ; }
2014-09-10 07:52:42 -04:00
if ( * r = = ' ( ' ) { return ca_extf ; }
2013-10-29 20:08:30 -04:00
while ( r & & r [ 0 ] = = ' [ ' & & r [ l - 1 ] = = ' ] ' ) {
r = next_token ( & l ) ;
2014-08-25 12:17:17 -04:00
if ( ! r ) { return ca_command ; }
2013-10-29 20:08:30 -04:00
}
2013-11-30 13:52:13 -05:00
if ( * r = = ' [ ' & & ! r [ l ] ) {
2014-08-25 12:17:17 -04:00
return ca_modifier ;
2013-11-30 13:52:13 -05:00
}
2013-10-29 20:08:30 -04:00
2014-08-25 12:17:17 -04:00
if ( ! * line_ptr ) { return ca_command ; }
struct command * command = commands ;
2013-10-03 08:38:25 -04:00
int n = 0 ;
2014-08-25 12:17:17 -04:00
struct tgl_command ;
while ( command - > name ) {
if ( is_same_word ( r , l , command - > name ) ) {
2013-10-03 08:38:25 -04:00
break ;
}
n + + ;
command + + ;
}
2014-08-25 12:17:17 -04:00
enum command_argument * flags = command - > args ;
2013-10-03 08:38:25 -04:00
while ( 1 ) {
2013-10-29 20:08:30 -04:00
if ( ! next_token ( & l ) | | ! * line_ptr ) {
2014-08-25 12:17:17 -04:00
return * flags ;
}
if ( * flags = = ca_none ) {
return ca_none ;
}
if ( * flags = = ca_string_end ) {
return ca_string_end ;
}
if ( * flags = = ca_file_name_end ) {
return ca_file_name_end ;
}
flags + + ;
if ( * flags = = ca_period ) {
flags - - ;
2013-10-29 20:08:30 -04:00
}
2013-10-03 08:38:25 -04:00
}
}
int complete_string_list ( char * * list , int index , const char * text , int len , char * * R ) {
index + + ;
2013-10-03 12:09:06 -04:00
while ( list [ index ] & & strncmp ( list [ index ] , text , len ) ) {
2013-10-03 08:38:25 -04:00
index + + ;
}
2013-10-03 12:09:06 -04:00
if ( list [ index ] ) {
2014-01-10 09:37:56 -05:00
* R = strdup ( list [ index ] ) ;
2013-10-03 08:38:25 -04:00
return index ;
} else {
* R = 0 ;
return - 1 ;
}
}
2014-08-25 12:17:17 -04:00
int complete_command_list ( int index , const char * text , int len , char * * R ) {
index + + ;
while ( commands [ index ] . name & & strncmp ( commands [ index ] . name , text , len ) ) {
index + + ;
}
if ( commands [ index ] . name ) {
* R = strdup ( commands [ index ] . name ) ;
return index ;
} else {
* R = 0 ;
return - 1 ;
}
}
2013-10-03 08:38:25 -04:00
char * command_generator ( const char * text , int state ) {
2014-08-25 12:17:17 -04:00
static int len , index ;
static enum command_argument mode ;
2013-12-06 12:14:41 -05:00
if ( in_chat_mode ) {
char * R = 0 ;
index = complete_string_list ( in_chat_commands , index , text , rl_point , & R ) ;
return R ;
}
2013-10-03 12:09:06 -04:00
2013-10-28 17:56:17 -04:00
char c = 0 ;
2013-10-03 08:38:25 -04:00
if ( ! state ) {
len = strlen ( text ) ;
index = - 1 ;
2013-10-28 17:56:17 -04:00
c = rl_line_buffer [ rl_point ] ;
rl_line_buffer [ rl_point ] = 0 ;
2013-10-03 08:38:25 -04:00
mode = get_complete_mode ( ) ;
} else {
if ( index = = - 1 ) { return 0 ; }
}
2014-08-25 12:17:17 -04:00
if ( mode = = ca_none | | mode = = ca_string | | mode = = ca_string_end | | mode = = ca_number ) {
2013-10-28 17:57:22 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
return 0 ;
}
2013-10-03 08:38:25 -04:00
char * R = 0 ;
2014-08-25 12:17:17 -04:00
switch ( mode ) {
case ca_command :
index = complete_command_list ( index , text , len , & R ) ;
2013-10-28 17:56:17 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
2013-10-03 08:38:25 -04:00
return R ;
2014-08-25 12:17:17 -04:00
case ca_user :
2014-08-13 11:55:16 -04:00
index = tgl_complete_user_list ( index , text , len , & R ) ;
2013-10-28 17:56:17 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
2013-10-03 08:38:25 -04:00
return R ;
2014-08-25 12:17:17 -04:00
case ca_peer :
2014-08-13 11:55:16 -04:00
index = tgl_complete_peer_list ( index , text , len , & R ) ;
2013-10-28 17:56:17 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
2013-10-03 08:38:25 -04:00
return R ;
2014-08-25 12:17:17 -04:00
case ca_file_name :
case ca_file_name_end :
R = rl_filename_completion_function ( text , state ) ;
2013-10-28 17:56:17 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
return R ;
2014-08-25 12:17:17 -04:00
case ca_chat :
2014-08-13 11:55:16 -04:00
index = tgl_complete_chat_list ( index , text , len , & R ) ;
2013-10-28 17:56:17 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
2013-10-23 06:24:59 -04:00
return R ;
2014-08-25 12:17:17 -04:00
case ca_secret_chat :
2014-08-13 11:55:16 -04:00
index = tgl_complete_encr_chat_list ( index , text , len , & R ) ;
2013-11-04 18:15:24 -05:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
return R ;
2014-08-25 12:17:17 -04:00
case ca_modifier :
2013-11-30 13:52:13 -05:00
index = complete_string_list ( modifiers , index , text , len , & R ) ;
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
return R ;
2014-09-10 07:52:42 -04:00
case ca_extf :
index = tglf_extf_autocomplete ( text , len , index , & R , rl_line_buffer , rl_point ) ;
return R ;
2013-10-03 08:38:25 -04:00
default :
2013-10-28 17:56:17 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
2013-10-03 08:38:25 -04:00
return 0 ;
}
}
char * * complete_text ( char * text , int start UU , int end UU ) {
return ( char * * ) rl_completion_matches ( text , command_generator ) ;
}
2013-11-25 12:16:34 -05:00
int offline_mode ;
int count = 1 ;
void work_modifier ( const char * s , int l ) {
if ( is_same_word ( s , l , " [offline] " ) ) {
offline_mode = 1 ;
}
# ifdef ALLOW_MULT
if ( sscanf ( s , " [x%d] " , & count ) > = 1 ) {
}
# endif
2013-10-29 20:08:30 -04:00
}
2014-08-14 18:16:01 -04:00
void print_msg_list_gw ( void * extra , int success , int num , struct tgl_message * ML [ ] ) {
if ( ! success ) { return ; }
print_start ( ) ;
int i ;
for ( i = num - 1 ; i > = 0 ; i - - ) {
print_message ( ML [ i ] ) ;
}
print_end ( ) ;
}
void print_msg_gw ( void * extra , int success , struct tgl_message * M ) {
if ( ! success ) { return ; }
print_start ( ) ;
print_message ( M ) ;
print_end ( ) ;
}
void print_user_list_gw ( void * extra , int success , int num , struct tgl_user * UL [ ] ) {
if ( ! success ) { return ; }
print_start ( ) ;
int i ;
for ( i = num - 1 ; i > = 0 ; i - - ) {
print_user_name ( UL [ i ] - > id , ( void * ) UL [ i ] ) ;
2014-08-18 12:39:04 -04:00
printf ( " \n " ) ;
2014-08-14 18:16:01 -04:00
}
print_end ( ) ;
}
2014-08-29 11:46:04 -04:00
void print_user_gw ( void * extra , int success , struct tgl_user * U ) {
if ( ! success ) { return ; }
print_start ( ) ;
print_user_name ( U - > id , ( void * ) U ) ;
printf ( " \n " ) ;
print_end ( ) ;
}
2014-08-14 18:16:01 -04:00
void print_filename_gw ( void * extra , int success , char * name ) {
if ( ! success ) { return ; }
print_start ( ) ;
printf ( " Saved to %s \n " , name ) ;
print_end ( ) ;
}
void open_filename_gw ( void * extra , int success , char * name ) {
if ( ! success ) { return ; }
static char buf [ PATH_MAX ] ;
if ( snprintf ( buf , sizeof ( buf ) , OPEN_BIN , 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 " , name ) ;
}
}
}
void print_chat_info_gw ( void * extra , int success , struct tgl_chat * C ) {
2014-08-18 12:39:04 -04:00
if ( ! success ) {
vlogprintf ( E_NOTICE , " Failed to get chat info \n " ) ;
return ;
}
2014-08-14 18:16:01 -04:00
print_start ( ) ;
tgl_peer_t * U = ( void * ) C ;
push_color ( COLOR_YELLOW ) ;
printf ( " Chat " ) ;
print_chat_name ( U - > id , U ) ;
2014-09-03 12:32:56 -04:00
printf ( " (id %d) members: \n " , tgl_get_peer_id ( U - > id ) ) ;
2014-08-14 18:16:01 -04:00
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 ( 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 ( 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 ( ) ;
}
void print_user_info_gw ( void * extra , int success , struct tgl_user * U ) {
if ( ! success ) { return ; }
tgl_peer_t * C = ( void * ) U ;
print_start ( ) ;
push_color ( COLOR_YELLOW ) ;
printf ( " User " ) ;
print_user_name ( U - > id , C ) ;
2014-08-24 12:49:06 -04:00
printf ( " (#%d): \n " , tgl_get_peer_id ( U - > id ) ) ;
2014-08-14 18:16:01 -04:00
printf ( " \t real name: %s %s \n " , U - > real_first_name , U - > real_last_name ) ;
printf ( " \t phone: %s \n " , U - > phone ) ;
if ( U - > status . online > 0 ) {
printf ( " \t online \n " ) ;
} else {
printf ( " \t offline (was online " ) ;
print_date_full ( U - > status . when ) ;
printf ( " ) \n " ) ;
}
pop_color ( ) ;
print_end ( ) ;
}
void print_secret_chat_gw ( void * extra , int success , struct tgl_secret_chat * E ) {
if ( ! success ) { return ; }
print_start ( ) ;
push_color ( COLOR_YELLOW ) ;
printf ( " Encrypted chat " ) ;
print_encr_chat_name ( E - > id , ( void * ) E ) ;
printf ( " is now in wait state \n " ) ;
pop_color ( ) ;
print_end ( ) ;
}
2013-12-06 12:14:41 -05:00
2014-08-14 18:16:01 -04:00
void print_dialog_list_gw ( void * extra , int success , int size , tgl_peer_id_t peers [ ] , int last_msg_id [ ] , int unread_count [ ] ) {
if ( ! success ) { return ; }
print_start ( ) ;
push_color ( COLOR_YELLOW ) ;
int i ;
for ( i = size - 1 ; i > = 0 ; i - - ) {
tgl_peer_t * UC ;
switch ( tgl_get_peer_type ( peers [ i ] ) ) {
case TGL_PEER_USER :
UC = tgl_peer_get ( peers [ i ] ) ;
printf ( " User " ) ;
print_user_name ( peers [ i ] , UC ) ;
printf ( " : %d unread \n " , unread_count [ i ] ) ;
break ;
case TGL_PEER_CHAT :
UC = tgl_peer_get ( peers [ i ] ) ;
printf ( " Chat " ) ;
print_chat_name ( peers [ i ] , UC ) ;
printf ( " : %d unread \n " , unread_count [ i ] ) ;
break ;
}
}
pop_color ( ) ;
print_end ( ) ;
}
2013-12-06 12:14:41 -05:00
void interpreter_chat_mode ( char * line ) {
2014-02-22 20:06:57 -05:00
if ( line = = NULL | | /* EOF received */
! strncmp ( line , " /exit " , 5 ) | | ! strncmp ( line , " /quit " , 5 ) ) {
2013-12-06 12:14:41 -05:00
in_chat_mode = 0 ;
update_prompt ( ) ;
return ;
}
2013-12-19 17:50:31 -05:00
if ( ! strncmp ( line , " /history " , 8 ) ) {
int limit = 40 ;
2014-01-10 07:37:07 -05:00
sscanf ( line , " /history %99d " , & limit ) ;
2013-12-19 17:50:31 -05:00
if ( limit < 0 | | limit > 1000 ) { limit = 40 ; }
2014-08-14 18:16:01 -04:00
tgl_do_get_history ( chat_mode_id , limit , offline_mode , print_msg_list_gw , 0 ) ;
2013-12-19 17:50:31 -05:00
return ;
}
if ( ! strncmp ( line , " /read " , 5 ) ) {
2014-08-14 18:16:01 -04:00
tgl_do_mark_read ( chat_mode_id , 0 , 0 ) ;
2013-12-19 17:50:31 -05:00
return ;
}
2014-08-20 12:41:56 -04:00
if ( strlen ( line ) > 0 ) {
2014-08-20 12:36:45 -04:00
tgl_do_send_message ( chat_mode_id , line , strlen ( line ) , 0 , 0 ) ;
2014-02-12 18:52:25 -05:00
}
2013-12-06 12:14:41 -05:00
}
2014-08-21 16:35:27 -04:00
# define MAX_UNREAD_MESSAGE_COUNT 10000
struct tgl_message * unread_message_list [ MAX_UNREAD_MESSAGE_COUNT ] ;
int unread_message_count ;
struct event * unread_message_event ;
void print_read_list ( int num , struct tgl_message * list [ ] ) {
int i ;
print_start ( ) ;
for ( i = 0 ; i < num ; i + + ) if ( list [ i ] ) {
tgl_peer_id_t to_id ;
if ( tgl_get_peer_type ( list [ i ] - > to_id ) = = TGL_PEER_USER & & tgl_get_peer_id ( list [ i ] - > to_id ) = = tgl_state . our_id ) {
to_id = list [ i ] - > from_id ;
} else {
to_id = list [ i ] - > to_id ;
}
int j ;
int c1 = 0 ;
int c2 = 0 ;
for ( j = i ; j < num ; j + + ) if ( list [ j ] ) {
tgl_peer_id_t end_id ;
if ( tgl_get_peer_type ( list [ j ] - > to_id ) = = TGL_PEER_USER & & tgl_get_peer_id ( list [ j ] - > to_id ) = = tgl_state . our_id ) {
end_id = list [ j ] - > from_id ;
} else {
end_id = list [ j ] - > to_id ;
}
if ( ! tgl_cmp_peer_id ( to_id , end_id ) ) {
if ( list [ j ] - > out ) {
c1 + + ;
} else {
c2 + + ;
}
list [ j ] = 0 ;
}
}
assert ( c1 + c2 > 0 ) ;
push_color ( COLOR_YELLOW ) ;
switch ( tgl_get_peer_type ( to_id ) ) {
case TGL_PEER_USER :
printf ( " User " ) ;
print_user_name ( to_id , tgl_peer_get ( to_id ) ) ;
break ;
case TGL_PEER_CHAT :
printf ( " Chat " ) ;
print_chat_name ( to_id , tgl_peer_get ( to_id ) ) ;
break ;
case TGL_PEER_ENCR_CHAT :
printf ( " Secret chat " ) ;
2014-08-27 12:59:42 -04:00
print_encr_chat_name ( to_id , tgl_peer_get ( to_id ) ) ;
2014-08-21 16:35:27 -04:00
break ;
default :
assert ( 0 ) ;
}
printf ( " marked read %d outbox and %d inbox messages \n " , c1 , c2 ) ;
pop_color ( ) ;
}
print_end ( ) ;
}
void unread_message_alarm ( evutil_socket_t fd , short what , void * arg ) {
print_read_list ( unread_message_count , unread_message_list ) ;
unread_message_count = 0 ;
event_free ( unread_message_event ) ;
unread_message_event = 0 ;
}
2014-08-14 18:16:01 -04:00
void mark_read_upd ( int num , struct tgl_message * list [ ] ) {
2014-08-21 11:38:51 -04:00
if ( ! binlog_read ) { return ; }
2014-08-14 18:16:01 -04:00
if ( log_level < 1 ) { return ; }
2014-08-21 11:38:51 -04:00
2014-08-21 16:35:27 -04:00
if ( unread_message_count + num < = MAX_UNREAD_MESSAGE_COUNT ) {
memcpy ( unread_message_list + unread_message_count , list , num * sizeof ( void * ) ) ;
unread_message_count + = num ;
if ( ! unread_message_event ) {
unread_message_event = evtimer_new ( tgl_state . ev_base , unread_message_alarm , 0 ) ;
static struct timeval ptimeout = { 1 , 0 } ;
event_add ( unread_message_event , & ptimeout ) ;
}
} else {
print_read_list ( unread_message_count , unread_message_list ) ;
print_read_list ( num , list ) ;
unread_message_count = 0 ;
if ( unread_message_event ) {
event_free ( unread_message_event ) ;
unread_message_event = 0 ;
}
}
/*
tgl_peer_id_t to_id = list [ 0 ] - > to_id ;
2014-08-21 11:38:51 -04:00
int ok = 1 ;
int i ;
for ( i = 1 ; i < num ; i + + ) {
if ( tgl_cmp_peer_id ( to_id , list [ i ] - > to_id ) ) {
ok = 0 ;
}
}
2014-08-14 18:16:01 -04:00
print_start ( ) ;
push_color ( COLOR_YELLOW ) ;
2014-08-21 11:38:51 -04:00
if ( ! ok ) {
printf ( " %d messages mark read \n " , num ) ;
} else {
printf ( " %d messages mark read in " , num ) ;
switch ( tgl_get_peer_type ( to_id ) ) {
case TGL_PEER_USER :
printf ( " user " ) ;
print_user_name ( to_id , tgl_peer_get ( to_id ) ) ;
break ;
case TGL_PEER_CHAT :
printf ( " chat " ) ;
print_chat_name ( to_id , tgl_peer_get ( to_id ) ) ;
break ;
case TGL_PEER_ENCR_CHAT :
printf ( " secret chat " ) ;
print_chat_name ( to_id , tgl_peer_get ( to_id ) ) ;
break ;
}
printf ( " \n " ) ;
}
2014-08-14 18:16:01 -04:00
pop_color ( ) ;
2014-08-21 16:35:27 -04:00
print_end ( ) ; */
2014-08-14 18:16:01 -04:00
}
void type_notification_upd ( struct tgl_user * U ) {
2014-09-09 13:05:36 -04:00
if ( log_level < 2 | | disable_output ) { return ; }
2014-08-14 18:16:01 -04:00
print_start ( ) ;
push_color ( COLOR_YELLOW ) ;
printf ( " User " ) ;
print_user_name ( U - > id , ( void * ) U ) ;
printf ( " is typing \n " ) ;
pop_color ( ) ;
print_end ( ) ;
}
void type_in_chat_notification_upd ( struct tgl_user * U , struct tgl_chat * C ) {
2014-09-09 13:05:36 -04:00
if ( log_level < 2 | | disable_output ) { return ; }
2014-08-14 18:16:01 -04:00
print_start ( ) ;
push_color ( COLOR_YELLOW ) ;
printf ( " User " ) ;
print_user_name ( U - > id , ( void * ) U ) ;
printf ( " is typing in chat " ) ;
print_chat_name ( C - > id , ( void * ) C ) ;
printf ( " \n " ) ;
pop_color ( ) ;
print_end ( ) ;
}
2014-08-18 12:39:04 -04:00
void print_message_gw ( struct tgl_message * M ) {
2014-08-21 11:38:51 -04:00
# ifdef USE_LUA
lua_new_msg ( M ) ;
# endif
2014-09-09 13:05:36 -04:00
if ( disable_output ) { return ; }
2014-08-21 11:38:51 -04:00
if ( ! binlog_read ) { return ; }
2014-08-18 12:39:04 -04:00
print_start ( ) ;
print_message ( M ) ;
print_end ( ) ;
}
2014-08-21 11:38:51 -04:00
void our_id_gw ( int id ) {
# ifdef USE_LUA
lua_our_id ( id ) ;
# endif
}
void print_peer_updates ( int flags ) {
if ( flags & TGL_UPDATE_PHONE ) {
printf ( " phone " ) ;
}
if ( flags & TGL_UPDATE_CONTACT ) {
printf ( " contact " ) ;
}
if ( flags & TGL_UPDATE_PHOTO ) {
printf ( " photo " ) ;
}
if ( flags & TGL_UPDATE_BLOCKED ) {
printf ( " blocked " ) ;
}
if ( flags & TGL_UPDATE_REAL_NAME ) {
printf ( " name " ) ;
}
if ( flags & TGL_UPDATE_NAME ) {
printf ( " contact_name " ) ;
}
if ( flags & TGL_UPDATE_REQUESTED ) {
printf ( " status " ) ;
}
if ( flags & TGL_UPDATE_WORKING ) {
printf ( " status " ) ;
}
if ( flags & TGL_UPDATE_FLAGS ) {
printf ( " flags " ) ;
}
if ( flags & TGL_UPDATE_TITLE ) {
printf ( " title " ) ;
}
if ( flags & TGL_UPDATE_ADMIN ) {
printf ( " admin " ) ;
}
if ( flags & TGL_UPDATE_MEMBERS ) {
printf ( " members " ) ;
}
if ( flags & TGL_UPDATE_ACCESS_HASH ) {
printf ( " access_hash " ) ;
}
}
void user_update_gw ( struct tgl_user * U , unsigned flags ) {
# ifdef USE_LUA
lua_user_update ( U , flags ) ;
# endif
2014-09-09 13:05:36 -04:00
if ( disable_output ) { return ; }
2014-08-21 11:38:51 -04:00
if ( ! binlog_read ) { return ; }
if ( ! ( flags & TGL_UPDATE_CREATED ) ) {
print_start ( ) ;
push_color ( COLOR_YELLOW ) ;
printf ( " User " ) ;
print_user_name ( U - > id , ( void * ) U ) ;
if ( ! ( flags & TGL_UPDATE_DELETED ) ) {
printf ( " updated " ) ;
print_peer_updates ( flags ) ;
} else {
printf ( " deleted " ) ;
}
printf ( " \n " ) ;
pop_color ( ) ;
print_end ( ) ;
}
}
void chat_update_gw ( struct tgl_chat * U , unsigned flags ) {
# ifdef USE_LUA
lua_chat_update ( U , flags ) ;
# endif
2014-09-09 13:05:36 -04:00
if ( disable_output ) { return ; }
2014-08-21 11:38:51 -04:00
if ( ! binlog_read ) { return ; }
if ( ! ( flags & TGL_UPDATE_CREATED ) ) {
print_start ( ) ;
push_color ( COLOR_YELLOW ) ;
printf ( " Chat " ) ;
print_chat_name ( U - > id , ( void * ) U ) ;
if ( ! ( flags & TGL_UPDATE_DELETED ) ) {
printf ( " updated " ) ;
print_peer_updates ( flags ) ;
} else {
printf ( " deleted " ) ;
}
printf ( " \n " ) ;
pop_color ( ) ;
print_end ( ) ;
}
}
void secret_chat_update_gw ( struct tgl_secret_chat * U , unsigned flags ) {
# ifdef USE_LUA
lua_secret_chat_update ( U , flags ) ;
# endif
2014-09-09 13:05:36 -04:00
if ( disable_output ) { return ; }
2014-08-21 11:38:51 -04:00
if ( ! binlog_read ) { return ; }
2014-08-31 10:18:19 -04:00
if ( ( flags & TGL_UPDATE_WORKING ) | | ( flags & TGL_UPDATE_DELETED ) ) {
write_secret_chat_file ( ) ;
}
2014-08-26 12:06:30 -04:00
if ( ( flags & TGL_UPDATE_REQUESTED ) & & ! disable_auto_accept ) {
tgl_do_accept_encr_chat_request ( U , 0 , 0 ) ;
}
2014-08-21 11:38:51 -04:00
if ( ! ( flags & TGL_UPDATE_CREATED ) ) {
print_start ( ) ;
push_color ( COLOR_YELLOW ) ;
printf ( " Secret chat " ) ;
print_encr_chat_name ( U - > id , ( void * ) U ) ;
if ( ! ( flags & TGL_UPDATE_DELETED ) ) {
printf ( " updated " ) ;
print_peer_updates ( flags ) ;
} else {
printf ( " deleted " ) ;
}
printf ( " \n " ) ;
pop_color ( ) ;
print_end ( ) ;
}
}
2014-08-29 11:46:04 -04:00
void print_card_gw ( void * extra , int success , int size , int * card ) {
assert ( success ) ;
print_start ( ) ;
printf ( " Card: " ) ;
int i ;
for ( i = 0 ; i < size ; i + + ) {
printf ( " %08x%c " , card [ i ] , i = = size - 1 ? ' \n ' : ' : ' ) ;
}
print_end ( ) ;
}
2014-09-10 07:52:42 -04:00
void callback_extf ( void * extra , int success , char * buf ) {
print_start ( ) ;
printf ( " %s \n " , buf ) ;
print_end ( ) ;
}
2014-08-14 18:16:01 -04:00
struct tgl_update_callback upd_cb = {
2014-08-18 12:39:04 -04:00
. new_msg = print_message_gw ,
2014-08-14 18:16:01 -04:00
. marked_read = mark_read_upd ,
. logprintf = logprintf ,
. type_notification = type_notification_upd ,
. type_in_chat_notification = type_in_chat_notification_upd ,
. type_in_secret_chat_notification = 0 ,
. status_notification = 0 ,
. user_registered = 0 ,
. user_activated = 0 ,
. new_authorization = 0 ,
2014-08-21 11:38:51 -04:00
. user_update = user_update_gw ,
. chat_update = chat_update_gw ,
. secret_chat_update = secret_chat_update_gw ,
. msg_receive = print_message_gw ,
. our_id = our_id_gw
2014-08-14 18:16:01 -04:00
} ;
2013-10-03 08:38:25 -04:00
void interpreter ( char * line UU ) {
2013-10-29 20:08:30 -04:00
assert ( ! in_readline ) ;
in_readline = 1 ;
2013-12-06 12:14:41 -05:00
if ( in_chat_mode ) {
interpreter_chat_mode ( line ) ;
in_readline = 0 ;
return ;
}
line_ptr = line ;
2013-11-25 12:16:34 -05:00
offline_mode = 0 ;
count = 1 ;
2013-10-29 20:08:30 -04:00
if ( ! line ) {
in_readline = 0 ;
return ;
}
2013-10-13 06:18:08 -04:00
if ( line & & * line ) {
add_history ( line ) ;
}
2013-10-29 20:08:30 -04:00
int l ;
char * command ;
while ( 1 ) {
command = next_token ( & l ) ;
2013-11-01 07:27:08 -04:00
if ( ! command ) { in_readline = 0 ; return ; }
2013-10-29 20:08:30 -04:00
if ( * command = = ' [ ' & & command [ l - 1 ] = = ' ] ' ) {
2013-11-25 12:16:34 -05:00
work_modifier ( command , l ) ;
2013-10-29 20:08:30 -04:00
} else {
break ;
}
}
2013-11-25 12:16:34 -05:00
int _ ;
char * save = line_ptr ;
int ll = l ;
char * cs = command ;
for ( _ = 0 ; _ < count ; _ + + ) {
line_ptr = save ;
l = ll ;
command = cs ;
2013-10-29 20:08:30 -04:00
# define IS_WORD(s) is_same_word (command, l, (s))
# define RET in_readline = 0; return;
2013-10-31 19:18:34 -04:00
2014-08-13 11:55:16 -04:00
tgl_peer_id_t id ;
2013-10-31 19:18:34 -04:00
# define GET_PEER \
id = next_token_peer ( ) ; \
2014-08-13 11:55:16 -04:00
if ( ! tgl_cmp_peer_id ( id , TGL_PEER_NOT_FOUND ) ) { \
2013-12-06 11:40:52 -05:00
printf ( " Bad user/chat id \n " ) ; \
2013-10-31 19:18:34 -04:00
RET ; \
}
# define GET_PEER_USER \
id = next_token_user ( ) ; \
2014-08-13 11:55:16 -04:00
if ( ! tgl_cmp_peer_id ( id , TGL_PEER_NOT_FOUND ) ) { \
2013-10-31 19:18:34 -04:00
printf ( " Bad user id \n " ) ; \
RET ; \
}
# define GET_PEER_CHAT \
id = next_token_chat ( ) ; \
2014-08-13 11:55:16 -04:00
if ( ! tgl_cmp_peer_id ( id , TGL_PEER_NOT_FOUND ) ) { \
2013-11-04 18:15:24 -05:00
printf ( " Bad chat id \n " ) ; \
RET ; \
}
# define GET_PEER_ENCR_CHAT \
id = next_token_encr_chat ( ) ; \
2014-08-13 11:55:16 -04:00
if ( ! tgl_cmp_peer_id ( id , TGL_PEER_NOT_FOUND ) ) { \
2013-11-04 18:15:24 -05:00
printf ( " Bad encr_chat id \n " ) ; \
2013-10-31 19:18:34 -04:00
RET ; \
}
2014-09-10 07:52:42 -04:00
if ( command & & * command = = ' ( ' ) {
tgl_do_send_extf ( line , strlen ( line ) , callback_extf , 0 ) ;
} else if ( IS_WORD ( " contact_list " ) ) {
2014-08-14 18:16:01 -04:00
tgl_do_update_contact_list ( print_user_list_gw , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " dialog_list " ) ) {
2014-08-14 18:16:01 -04:00
tgl_do_get_dialog_list ( print_dialog_list_gw , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " stats " ) ) {
2013-10-13 06:18:08 -04:00
static char stat_buf [ 1 < < 15 ] ;
2014-08-13 08:56:55 -04:00
tgl_print_stat ( stat_buf , ( 1 < < 15 ) - 1 ) ;
2013-10-13 06:18:08 -04:00
printf ( " %s \n " , stat_buf ) ;
2014-08-26 14:26:00 -04:00
fflush ( stdout ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " msg " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER ;
2013-10-29 20:08:30 -04:00
int t ;
char * s = next_token ( & t ) ;
if ( ! s ) {
printf ( " Empty message \n " ) ;
RET ;
}
2014-08-20 12:36:45 -04:00
tgl_do_send_message ( id , s , strlen ( s ) , 0 , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " rename_chat " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER_CHAT ;
2013-10-29 20:08:30 -04:00
int t ;
char * s = next_token ( & t ) ;
if ( ! s ) {
printf ( " Empty new name \n " ) ;
RET ;
}
2014-08-20 12:36:45 -04:00
tgl_do_rename_chat ( id , s , 0 , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " send_photo " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER ;
2013-10-29 20:08:30 -04:00
int t ;
2014-08-12 21:22:15 -04:00
char * s = end_string_token ( & t ) ;
2013-10-29 20:08:30 -04:00
if ( ! s ) {
printf ( " Empty file name \n " ) ;
RET ;
}
2014-08-20 12:36:45 -04:00
tgl_do_send_photo ( tgl_message_media_photo , id , strndup ( s , t ) , 0 , 0 ) ;
2014-08-25 12:17:17 -04:00
} else if ( IS_WORD ( " chat_set_photo " ) ) {
GET_PEER_CHAT ;
int t ;
char * s = end_string_token ( & t ) ;
if ( ! s ) {
printf ( " Empty file name \n " ) ;
RET ;
}
tgl_do_set_chat_photo ( id , strndup ( s , t ) , 0 , 0 ) ;
} else if ( IS_WORD ( " set_profile_photo " ) ) {
int t ;
char * s = end_string_token ( & t ) ;
if ( ! s ) {
printf ( " Empty file name \n " ) ;
RET ;
}
tgl_do_set_profile_photo ( strndup ( s , t ) , 0 , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " send_video " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER ;
2013-10-29 20:08:30 -04:00
int t ;
2014-08-12 21:22:15 -04:00
char * s = end_string_token ( & t ) ;
2013-10-29 20:08:30 -04:00
if ( ! s ) {
printf ( " Empty file name \n " ) ;
RET ;
}
2014-08-20 12:36:45 -04:00
tgl_do_send_photo ( tgl_message_media_video , id , strndup ( s , t ) , 0 , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " send_text " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER ;
2013-10-29 20:08:30 -04:00
int t ;
char * s = next_token ( & t ) ;
if ( ! s ) {
printf ( " Empty file name \n " ) ;
RET ;
}
2014-08-20 12:36:45 -04:00
tgl_do_send_text ( id , strndup ( s , t ) , 0 , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " fwd " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER ;
2013-10-29 20:08:30 -04:00
int num = next_token_int ( ) ;
if ( num = = NOT_FOUND | | num < = 0 ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-20 12:36:45 -04:00
tgl_do_forward_message ( id , num , 0 , 0 ) ;
2014-09-07 11:17:35 -04:00
} else if ( IS_WORD ( " fwd_media " ) ) {
GET_PEER ;
int num = next_token_int ( ) ;
if ( num = = NOT_FOUND | | num < = 0 ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
tgl_do_forward_media ( id , num , 0 , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " load_photo " ) ) {
2013-11-04 18:15:24 -05:00
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
2013-10-29 20:08:30 -04:00
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_photo ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_photo ( & M - > media . photo , print_filename_gw , 0 ) ;
2014-08-18 12:39:04 -04:00
} else if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_photo_encr ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_encr_video ( & M - > media . encr_video , print_filename_gw , 0 ) ; // this is not a bug.
2013-10-29 20:08:30 -04:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " view_photo " ) ) {
2013-11-04 18:15:24 -05:00
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
2013-10-29 20:08:30 -04:00
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_photo ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_photo ( & M - > media . photo , open_filename_gw , 0 ) ;
2014-08-18 12:39:04 -04:00
} else if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_photo_encr ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_encr_video ( & M - > media . encr_video , open_filename_gw , 0 ) ; // this is not a bug.
2013-10-29 20:08:30 -04:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " load_video_thumb " ) ) {
2013-11-04 18:15:24 -05:00
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
2013-10-29 20:08:30 -04:00
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_video ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_video_thumb ( & M - > media . video , print_filename_gw , 0 ) ;
2013-10-29 20:08:30 -04:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " view_video_thumb " ) ) {
2013-11-04 18:15:24 -05:00
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
2013-10-29 20:08:30 -04:00
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_video ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_video_thumb ( & M - > media . video , open_filename_gw , 0 ) ;
2013-10-29 20:08:30 -04:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " load_video " ) ) {
2013-11-04 18:15:24 -05:00
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
2013-10-29 20:08:30 -04:00
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_video ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_video ( & M - > media . video , print_filename_gw , 0 ) ;
2014-08-18 12:39:04 -04:00
} else if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_video_encr ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_encr_video ( & M - > media . encr_video , print_filename_gw , 0 ) ;
2013-10-29 20:08:30 -04:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " view_video " ) ) {
2013-11-04 18:15:24 -05:00
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
2013-10-29 20:08:30 -04:00
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_video ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_video ( & M - > media . video , open_filename_gw , 0 ) ;
2014-08-18 12:39:04 -04:00
} else if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_video_encr ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_encr_video ( & M - > media . encr_video , open_filename_gw , 0 ) ;
2013-10-29 20:08:30 -04:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " chat_info " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER_CHAT ;
2014-08-14 18:16:01 -04:00
tgl_do_get_chat_info ( id , offline_mode , print_chat_info_gw , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " user_info " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER_USER ;
2014-08-14 18:16:01 -04:00
tgl_do_get_user_info ( id , offline_mode , print_user_info_gw , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " history " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER ;
2013-10-29 20:08:30 -04:00
int limit = next_token_int ( ) ;
2014-08-14 18:16:01 -04:00
tgl_do_get_history ( id , limit > 0 ? limit : 40 , offline_mode , print_msg_list_gw , 0 ) ;
2013-11-06 19:08:16 -05:00
} else if ( IS_WORD ( " chat_add_user " ) ) {
GET_PEER_CHAT ;
2014-08-13 11:55:16 -04:00
tgl_peer_id_t chat_id = id ;
2013-11-06 19:08:16 -05:00
GET_PEER_USER ;
2014-08-20 12:36:45 -04:00
tgl_do_add_user_to_chat ( chat_id , id , 100 , 0 , 0 ) ;
2013-11-06 19:08:16 -05:00
} else if ( IS_WORD ( " chat_del_user " ) ) {
GET_PEER_CHAT ;
2014-08-13 11:55:16 -04:00
tgl_peer_id_t chat_id = id ;
2013-11-06 19:08:16 -05:00
GET_PEER_USER ;
2014-08-20 12:36:45 -04:00
tgl_do_del_user_from_chat ( chat_id , id , 0 , 0 ) ;
2013-10-30 06:10:16 -04:00
} else if ( IS_WORD ( " add_contact " ) ) {
int phone_len , first_name_len , last_name_len ;
char * phone , * first_name , * last_name ;
phone = next_token ( & phone_len ) ;
if ( ! phone ) {
printf ( " No phone number found \n " ) ;
RET ;
}
first_name = next_token ( & first_name_len ) ;
if ( ! first_name_len ) {
printf ( " No first name found \n " ) ;
RET ;
}
last_name = next_token ( & last_name_len ) ;
if ( ! last_name_len ) {
printf ( " No last name found \n " ) ;
RET ;
}
2014-08-14 18:16:01 -04:00
tgl_do_add_contact ( phone , phone_len , first_name , first_name_len , last_name , last_name_len , 0 , print_user_list_gw , 0 ) ;
2014-09-10 10:13:52 -04:00
} else if ( IS_WORD ( " del_contact " ) ) {
GET_PEER_USER ;
tgl_do_del_contact ( id , 0 , 0 ) ;
2014-09-02 07:20:18 -04:00
} else if ( IS_WORD ( " send_contact " ) ) {
GET_PEER ;
int phone_len , first_name_len , last_name_len ;
char * phone , * first_name , * last_name ;
phone = next_token ( & phone_len ) ;
if ( ! phone ) {
printf ( " No phone number found \n " ) ;
RET ;
}
first_name = next_token ( & first_name_len ) ;
if ( ! first_name_len ) {
printf ( " No first name found \n " ) ;
RET ;
}
last_name = next_token ( & last_name_len ) ;
if ( ! last_name_len ) {
printf ( " No last name found \n " ) ;
RET ;
}
tgl_do_send_contact ( id , phone , phone_len , first_name , first_name_len , last_name , last_name_len , print_msg_gw , 0 ) ;
2013-10-30 06:10:16 -04:00
} else if ( IS_WORD ( " rename_contact " ) ) {
2013-10-31 19:18:34 -04:00
GET_PEER_USER ;
2014-08-13 11:55:16 -04:00
tgl_peer_t * U = tgl_peer_get ( id ) ;
2013-10-30 06:10:16 -04:00
if ( ! U ) {
printf ( " No such user \n " ) ;
RET ;
}
if ( ! U - > user . phone | | ! strlen ( U - > user . phone ) ) {
printf ( " User has no phone. Can not rename \n " ) ;
RET ;
}
int phone_len , first_name_len , last_name_len ;
char * phone , * first_name , * last_name ;
phone_len = strlen ( U - > user . phone ) ;
phone = U - > user . phone ;
first_name = next_token ( & first_name_len ) ;
if ( ! first_name_len ) {
printf ( " No first name found \n " ) ;
RET ;
}
last_name = next_token ( & last_name_len ) ;
if ( ! last_name_len ) {
printf ( " No last name found \n " ) ;
RET ;
}
2014-08-14 18:16:01 -04:00
tgl_do_add_contact ( phone , phone_len , first_name , first_name_len , last_name , last_name_len , 1 , print_user_list_gw , 0 ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " help " ) ) {
2013-10-28 15:14:34 -04:00
//print_start ();
2013-10-24 14:22:11 -04:00
push_color ( COLOR_YELLOW ) ;
printf (
" help - prints this help \n "
" msg <peer> Text - sends message to this peer \n "
" contact_list - prints info about users in your contact list \n "
" stats - just for debugging \n "
2014-01-30 11:46:09 -05:00
" history <peer> [limit] - prints history (and marks it as read). Default limit = 40 \n "
2013-10-24 14:22:11 -04:00
" dialog_list - prints info about your dialogs \n "
" send_photo <peer> <photo-file-name> - sends photo to peer \n "
" send_video <peer> <video-file-name> - sends video to peer \n "
" send_text <peer> <text-file-name> - sends text file as plain messages \n "
" chat_info <chat> - prints info about chat \n "
2013-10-25 13:29:02 -04:00
" user_info <user> - prints info about user \n "
2013-10-28 15:14:34 -04:00
" fwd <user> <msg-seqno> - forward message to user. You can see message numbers starting client with -N \n "
2014-02-21 06:23:37 -05:00
" rename_chat <chat> <new-name> \n "
2014-02-08 11:44:10 -05:00
" load_photo/load_video/load_video_thumb <msg-seqno> - loads photo/video to download dir. You can see message numbers starting client with -N \n "
" view_photo/view_video/view_video_thumb <msg-seqno> - loads photo/video to download dir and starts system default viewer. You can see message numbers starting client with -N \n "
2013-10-28 15:14:34 -04:00
" show_license - prints contents of GPLv2 \n "
2013-11-04 12:34:27 -05:00
" search <peer> pattern - searches pattern in messages with peer \n "
2013-11-06 18:18:35 -05:00
" global_search pattern - searches pattern in all messages \n "
2013-11-04 12:34:27 -05:00
" mark_read <peer> - mark read all received messages with peer \n "
2013-11-06 18:18:35 -05:00
" add_contact <phone-number> <first-name> <last-name> - tries to add contact to contact-list by phone \n "
" create_secret_chat <user> - creates secret chat with this user \n "
2014-02-25 15:09:59 -05:00
" create_group_chat <user> <chat-topic> - creates group chat with this user, add more users with chat_add_user <user> \n "
2013-11-06 18:18:35 -05:00
" rename_contact <user> <first-name> <last-name> - tries to rename contact. If you have another device it will be a fight \n "
" suggested_contacts - print info about contacts, you have max common friends \n "
" visualize_key <secret_chat> - prints visualization of encryption key. You should compare it to your partner's one \n "
2013-11-15 11:14:25 -05:00
" set <param> <param-value>. Possible <param> values are: \n "
" \t debug_verbosity - just as it sounds. Debug verbosity \n "
" \t log_level - level of logging of new events. Lower is less verbose: \n "
" \t \t Level 1: prints info about read messages \n "
" \t \t Level 2: prints line, when somebody is typing in chat \n "
" \t \t Level 3: prints line, when somebody changes online status \n "
" \t msg_num - enables/disables numeration of messages \n "
2014-02-27 03:48:05 -05:00
" \t alert - enables/disables alert sound notifications \n "
2013-12-06 12:16:17 -05:00
" chat_with_peer <peer> - starts chat with this peer. Every command after is message to this peer. Type /exit or /quit to end this mode \n "
2013-10-24 14:22:11 -04:00
) ;
pop_color ( ) ;
2013-10-29 20:08:30 -04:00
} else if ( IS_WORD ( " show_license " ) ) {
2013-10-25 05:28:29 -04:00
char * b =
# include "LICENSE.h"
;
printf ( " %s " , b ) ;
2013-11-01 11:02:28 -04:00
} else if ( IS_WORD ( " search " ) ) {
GET_PEER ;
int from = 0 ;
int to = 0 ;
int limit = 40 ;
int t ;
char * s = next_token ( & t ) ;
if ( ! s ) {
printf ( " Empty message \n " ) ;
RET ;
}
2014-08-14 18:16:01 -04:00
tgl_do_msg_search ( id , from , to , limit , s , print_msg_list_gw , 0 ) ;
2013-11-06 18:12:40 -05:00
} else if ( IS_WORD ( " global_search " ) ) {
int from = 0 ;
int to = 0 ;
int limit = 40 ;
int t ;
char * s = next_token ( & t ) ;
if ( ! s ) {
printf ( " Empty message \n " ) ;
RET ;
}
2014-08-14 18:16:01 -04:00
tgl_do_msg_search ( TGL_PEER_NOT_FOUND , from , to , limit , s , print_msg_list_gw , 0 ) ;
2013-11-04 12:34:27 -05:00
} else if ( IS_WORD ( " mark_read " ) ) {
GET_PEER ;
2014-08-14 18:16:01 -04:00
tgl_do_mark_read ( id , 0 , 0 ) ;
2013-11-04 18:15:24 -05:00
} else if ( IS_WORD ( " visualize_key " ) ) {
2014-08-14 18:16:01 -04:00
static char * colors [ 4 ] = { COLOR_GREY , COLOR_CYAN , COLOR_BLUE , COLOR_GREEN } ;
2013-11-04 18:15:24 -05:00
GET_PEER_ENCR_CHAT ;
2014-08-14 18:16:01 -04:00
static unsigned char buf [ 16 ] ;
memset ( buf , 0 , sizeof ( buf ) ) ;
tgl_do_visualize_key ( id , 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 ) ;
2014-08-26 17:03:50 -04:00
if ( ! disable_colors ) {
printf ( " " ) ;
} else {
switch ( x & 3 ) {
case 0 :
printf ( " " ) ;
break ;
case 1 :
printf ( " -- " ) ;
break ;
case 2 :
printf ( " == " ) ;
break ;
case 3 :
printf ( " || " ) ;
break ;
}
}
2014-08-14 18:16:01 -04:00
pop_color ( ) ;
pop_color ( ) ;
x = x > > 2 ;
}
if ( i & 1 ) { printf ( " \n " ) ; }
}
print_end ( ) ;
2013-11-05 17:24:26 -05:00
} else if ( IS_WORD ( " create_secret_chat " ) ) {
GET_PEER ;
2014-08-14 18:16:01 -04:00
tgl_do_create_secret_chat ( id , print_secret_chat_gw , 0 ) ;
2014-02-25 15:09:59 -05:00
} else if ( IS_WORD ( " create_group_chat " ) ) {
2014-09-04 12:48:04 -04:00
GET_PEER_USER ;
2014-02-25 15:09:59 -05:00
int t ;
char * s = next_token ( & t ) ;
if ( ! s ) {
printf ( " Empty chat topic \n " ) ;
RET ;
}
2014-08-20 12:36:45 -04:00
tgl_do_create_group_chat ( id , s , 0 , 0 ) ;
2014-08-14 18:16:01 -04:00
//} else if (IS_WORD ("suggested_contacts")) {
// tgl_do_get_suggested ();
2013-11-09 04:51:07 -05:00
} else if ( IS_WORD ( " status_online " ) ) {
2014-08-14 18:16:01 -04:00
tgl_do_update_status ( 1 , 0 , 0 ) ;
2013-11-09 04:51:07 -05:00
} else if ( IS_WORD ( " status_offline " ) ) {
2014-08-14 18:16:01 -04:00
tgl_do_update_status ( 0 , 0 , 0 ) ;
2013-11-09 04:51:07 -05:00
} else if ( IS_WORD ( " contacts_search " ) ) {
int t ;
char * s = next_token ( & t ) ;
if ( ! s ) {
printf ( " Empty search query \n " ) ;
RET ;
}
2014-08-14 18:16:01 -04:00
tgl_do_contacts_search ( 100 , s , print_user_list_gw , 0 ) ;
2013-11-15 05:37:14 -05:00
} else if ( IS_WORD ( " send_audio " ) ) {
GET_PEER ;
int t ;
2014-08-12 21:22:15 -04:00
char * s = end_string_token ( & t ) ;
2013-11-15 05:37:14 -05:00
if ( ! s ) {
printf ( " Empty file name \n " ) ;
RET ;
}
2014-08-20 12:36:45 -04:00
tgl_do_send_photo ( tgl_message_media_audio , id , strndup ( s , t ) , 0 , 0 ) ;
2013-11-15 05:37:14 -05:00
} else if ( IS_WORD ( " send_document " ) ) {
GET_PEER ;
int t ;
2014-08-12 21:22:15 -04:00
char * s = end_string_token ( & t ) ;
2013-11-15 05:37:14 -05:00
if ( ! s ) {
printf ( " Empty file name \n " ) ;
RET ;
}
2014-08-20 12:36:45 -04:00
tgl_do_send_photo ( tgl_message_media_document , id , strndup ( s , t ) , 0 , 0 ) ;
2013-11-15 05:37:14 -05:00
} else if ( IS_WORD ( " load_audio " ) ) {
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_audio ) {
2014-08-26 12:06:30 -04:00
tgl_do_load_audio ( & M - > media . audio , print_filename_gw , 0 ) ;
2014-08-18 12:39:04 -04:00
} else if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_audio_encr ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_encr_video ( & M - > media . encr_video , print_filename_gw , 0 ) ;
2013-11-15 05:37:14 -05:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " view_audio " ) ) {
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_audio ) {
2014-08-26 12:06:30 -04:00
tgl_do_load_audio ( & M - > media . audio , open_filename_gw , 0 ) ;
2014-08-18 12:39:04 -04:00
} else if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_audio_encr ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_encr_video ( & M - > media . encr_video , open_filename_gw , 0 ) ;
2013-11-15 05:37:14 -05:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " load_document_thumb " ) ) {
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = ( int ) tgl_message_media_document ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_document_thumb ( & M - > media . document , print_filename_gw , 0 ) ;
2013-11-15 05:37:14 -05:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " view_document_thumb " ) ) {
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = ( int ) tgl_message_media_document ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_document_thumb ( & M - > media . document , open_filename_gw , 0 ) ;
2013-11-15 05:37:14 -05:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " load_document " ) ) {
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_document ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_document ( & M - > media . document , print_filename_gw , 0 ) ;
2014-08-18 12:39:04 -04:00
} else if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_document_encr ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_encr_video ( & M - > media . encr_video , print_filename_gw , 0 ) ;
2013-11-15 05:37:14 -05:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
} else if ( IS_WORD ( " view_document " ) ) {
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-13 11:55:16 -04:00
struct tgl_message * M = tgl_message_get ( num ) ;
2014-08-18 12:39:04 -04:00
if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_document ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_document ( & M - > media . document , open_filename_gw , 0 ) ;
2014-08-18 12:39:04 -04:00
} else if ( M & & ! M - > service & & M - > media . type = = tgl_message_media_document_encr ) {
2014-08-14 18:16:01 -04:00
tgl_do_load_encr_video ( & M - > media . encr_video , open_filename_gw , 0 ) ;
2013-11-15 05:37:14 -05:00
} else {
printf ( " Bad msg id \n " ) ;
RET ;
}
2013-11-15 11:14:25 -05:00
} else if ( IS_WORD ( " set " ) ) {
command = next_token ( & l ) ;
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
if ( IS_WORD ( " debug_verbosity " ) ) {
2014-08-13 11:55:16 -04:00
tgl_set_verbosity ( num ) ;
2013-11-15 11:14:25 -05:00
} else if ( IS_WORD ( " log_level " ) ) {
log_level = num ;
} else if ( IS_WORD ( " msg_num " ) ) {
msg_num_mode = num ;
2014-02-27 03:48:05 -05:00
} else if ( IS_WORD ( " alert " ) ) {
alert_sound = num ;
2013-11-15 11:14:25 -05:00
}
2013-12-06 12:14:41 -05:00
} else if ( IS_WORD ( " chat_with_peer " ) ) {
GET_PEER ;
in_chat_mode = 1 ;
chat_mode_id = id ;
2014-01-24 10:05:41 -05:00
} else if ( IS_WORD ( " delete_msg " ) ) {
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-14 18:16:01 -04:00
tgl_do_delete_msg ( num , 0 , 0 ) ;
2014-01-24 10:05:41 -05:00
} else if ( IS_WORD ( " restore_msg " ) ) {
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-14 18:16:01 -04:00
tgl_do_restore_msg ( num , 0 , 0 ) ;
2014-01-24 10:05:41 -05:00
} else if ( IS_WORD ( " delete_restore_msg " ) ) {
long long num = next_token_int ( ) ;
if ( num = = NOT_FOUND ) {
printf ( " Bad msg id \n " ) ;
RET ;
}
2014-08-14 18:16:01 -04:00
tgl_do_delete_msg ( num , 0 , 0 ) ;
tgl_do_restore_msg ( num , 0 , 0 ) ;
2014-08-29 11:46:04 -04:00
} else if ( IS_WORD ( " export_card " ) ) {
tgl_do_export_card ( print_card_gw , 0 ) ;
} else if ( IS_WORD ( " import_card " ) ) {
int l ;
char * s = next_token ( & l ) ;
if ( l > 0 ) {
int i ;
static int p [ 10 ] ;
int pp = 0 ;
int cur = 0 ;
int ok = 1 ;
for ( i = 0 ; i < l ; i + + ) {
if ( s [ i ] > = ' 0 ' & & s [ i ] < = ' 9 ' ) {
cur = cur * 16 + s [ i ] - ' 0 ' ;
} else if ( s [ i ] > = ' a ' & & s [ i ] < = ' f ' ) {
cur = cur * 16 + s [ i ] - ' a ' + 10 ;
} else if ( s [ i ] = = ' : ' ) {
if ( pp > = 9 ) {
ok = 0 ;
break ;
}
p [ pp + + ] = cur ;
cur = 0 ;
}
}
if ( ok ) {
p [ pp + + ] = cur ;
tgl_do_import_card ( pp , p , print_user_gw , 0 ) ;
}
}
2013-11-09 13:23:11 -05:00
} else if ( IS_WORD ( " quit " ) ) {
exit ( 0 ) ;
2014-08-27 11:40:21 -04:00
} else if ( IS_WORD ( " accept_secret_chat " ) ) {
GET_PEER_ENCR_CHAT ;
tgl_peer_t * E = tgl_peer_get ( id ) ;
assert ( E ) ;
tgl_do_accept_encr_chat_request ( & E - > encr_chat , 0 , 0 ) ;
2013-12-21 06:53:32 -05:00
} else if ( IS_WORD ( " safe_quit " ) ) {
safe_quit = 1 ;
2013-10-11 16:52:20 -04:00
}
2013-11-25 12:16:34 -05:00
}
2013-10-29 20:08:30 -04:00
# undef IS_WORD
# undef RET
2013-11-15 07:59:06 -05:00
update_prompt ( ) ;
2013-10-29 20:08:30 -04:00
in_readline = 0 ;
2013-10-11 16:52:20 -04:00
}
2013-10-13 06:18:08 -04:00
int readline_active ;
2013-10-11 16:52:20 -04:00
void rprintf ( const char * format , . . . ) {
2013-11-06 17:16:46 -05:00
print_start ( ) ;
2013-10-13 06:18:08 -04:00
va_list ap ;
va_start ( ap , format ) ;
vfprintf ( stdout , format , ap ) ;
va_end ( ap ) ;
2013-11-06 17:16:46 -05:00
print_end ( ) ;
2013-10-13 06:18:08 -04:00
}
2013-10-18 15:30:24 -04:00
int saved_point ;
char * saved_line ;
int prompt_was ;
void print_start ( void ) {
2013-10-29 20:08:30 -04:00
if ( in_readline ) { return ; }
2014-08-26 14:26:00 -04:00
if ( readline_disabled ) { return ; }
2013-10-18 15:30:24 -04:00
assert ( ! prompt_was ) ;
if ( readline_active ) {
saved_point = rl_point ;
2013-11-09 17:47:19 -05:00
# ifdef READLINE_GNU
2014-08-14 18:16:01 -04:00
saved_line = malloc ( rl_end + 1 ) ;
2014-01-10 09:37:56 -05:00
saved_line [ rl_end ] = 0 ;
memcpy ( saved_line , rl_line_buffer , rl_end ) ;
2013-10-18 15:30:24 -04:00
rl_save_prompt ( ) ;
rl_replace_line ( " " , 0 ) ;
2013-11-09 17:47:19 -05:00
# else
assert ( rl_end > = 0 ) ;
2014-08-14 18:16:01 -04:00
saved_line = malloc ( rl_end + 1 ) ;
2013-11-09 17:47:19 -05:00
memcpy ( saved_line , rl_line_buffer , rl_end + 1 ) ;
rl_line_buffer [ 0 ] = 0 ;
set_prompt ( " " ) ;
# endif
2013-10-18 15:30:24 -04:00
rl_redisplay ( ) ;
}
prompt_was = 1 ;
}
2013-11-09 17:47:19 -05:00
2013-10-18 15:30:24 -04:00
void print_end ( void ) {
2013-10-29 20:08:30 -04:00
if ( in_readline ) { return ; }
2014-08-26 14:26:00 -04:00
if ( readline_disabled ) {
fflush ( stdout ) ;
return ;
}
2013-10-18 15:30:24 -04:00
assert ( prompt_was ) ;
if ( readline_active ) {
2013-11-09 17:47:19 -05:00
set_prompt ( get_default_prompt ( ) ) ;
# if READLINE_GNU
2013-10-18 15:30:24 -04:00
rl_replace_line ( saved_line , 0 ) ;
2013-11-09 17:47:19 -05:00
# else
memcpy ( rl_line_buffer , saved_line , rl_end + 1 ) ; // not safe, but I hope this would work.
# endif
2013-10-18 15:30:24 -04:00
rl_point = saved_point ;
rl_redisplay ( ) ;
2014-08-14 18:16:01 -04:00
free ( saved_line ) ;
2013-10-18 15:30:24 -04:00
}
prompt_was = 0 ;
}
2014-08-20 21:56:53 -04:00
/*void hexdump (int *in_ptr, int *in_end) {
2013-11-09 17:47:19 -05:00
print_start ( ) ;
2013-10-13 06:18:08 -04:00
int * ptr = in_ptr ;
2013-11-09 17:47:19 -05:00
while ( ptr < in_end ) { printf ( " %08x " , * ( ptr + + ) ) ; }
printf ( " \n " ) ;
print_end ( ) ;
2014-08-20 21:56:53 -04:00
} */
2013-10-13 06:18:08 -04:00
void logprintf ( const char * format , . . . ) {
2013-11-21 14:35:49 -05:00
int x = 0 ;
if ( ! prompt_was ) {
x = 1 ;
print_start ( ) ;
}
2014-08-26 14:26:00 -04:00
if ( ! disable_colors ) {
printf ( COLOR_GREY ) ;
}
printf ( " *** " ) ;
2013-10-11 16:52:20 -04:00
va_list ap ;
va_start ( ap , format ) ;
vfprintf ( stdout , format , ap ) ;
va_end ( ap ) ;
2014-08-26 14:26:00 -04:00
if ( ! disable_colors ) {
printf ( COLOR_NORMAL ) ;
}
2013-11-21 14:35:49 -05:00
if ( x ) {
print_end ( ) ;
}
2013-10-03 08:38:25 -04:00
}
2013-10-16 15:19:39 -04:00
2013-10-18 15:30:24 -04:00
int color_stack_pos ;
const char * color_stack [ 10 ] ;
void push_color ( const char * color ) {
2014-08-24 20:11:41 -04:00
if ( disable_colors ) { return ; }
2013-10-18 15:30:24 -04:00
assert ( color_stack_pos < 10 ) ;
color_stack [ color_stack_pos + + ] = color ;
printf ( " %s " , color ) ;
}
void pop_color ( void ) {
2014-08-24 20:11:41 -04:00
if ( disable_colors ) { return ; }
2013-10-18 15:30:24 -04:00
assert ( color_stack_pos > 0 ) ;
color_stack_pos - - ;
if ( color_stack_pos > = 1 ) {
2013-10-21 14:24:31 -04:00
printf ( " %s " , color_stack [ color_stack_pos - 1 ] ) ;
2013-10-18 15:30:24 -04:00
} else {
printf ( " %s " , COLOR_NORMAL ) ;
}
}
2014-08-13 11:55:16 -04:00
void print_media ( struct tgl_message_media * M ) {
2013-12-19 17:50:31 -05:00
assert ( M ) ;
2013-10-18 15:30:24 -04:00
switch ( M - > type ) {
2014-08-18 12:39:04 -04:00
case tgl_message_media_none :
2013-10-18 15:30:24 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_photo :
2013-10-21 14:24:31 -04:00
if ( M - > photo . caption & & strlen ( M - > photo . caption ) ) {
printf ( " [photo %s] " , M - > photo . caption ) ;
} else {
printf ( " [photo] " ) ;
}
2013-10-18 15:30:24 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_video :
2014-08-12 21:22:15 -04:00
if ( M - > video . mime_type ) {
printf ( " [video: type %s] " , M - > video . mime_type ) ;
} else {
printf ( " [video] " ) ;
}
2013-10-18 15:30:24 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_audio :
2014-08-12 21:22:15 -04:00
if ( M - > audio . mime_type ) {
printf ( " [audio: type %s] " , M - > audio . mime_type ) ;
} else {
printf ( " [audio] " ) ;
}
2013-11-15 05:37:14 -05:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_document :
2013-11-15 05:37:14 -05:00
if ( M - > document . mime_type & & M - > document . caption ) {
printf ( " [document %s: type %s] " , M - > document . caption , M - > document . mime_type ) ;
} else {
printf ( " [document] " ) ;
}
return ;
2014-08-18 12:39:04 -04:00
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] " ) ;
}
2013-11-04 12:34:27 -05:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_video_encr :
if ( M - > encr_video . mime_type ) {
printf ( " [video: type %s] " , M - > encr_video . mime_type ) ;
} else {
printf ( " [video] " ) ;
}
2013-11-04 12:34:27 -05:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_audio_encr :
if ( M - > encr_audio . mime_type ) {
printf ( " [audio: type %s] " , M - > encr_audio . mime_type ) ;
} else {
printf ( " [audio] " ) ;
}
2013-11-15 05:37:14 -05:00
return ;
2014-08-18 12:39:04 -04:00
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] " ) ;
}
2013-11-15 05:37:14 -05:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_geo :
2013-10-23 14:23:33 -04:00
printf ( " [geo] https://maps.google.com/?q=%.6lf,%.6lf " , M - > geo . latitude , M - > geo . longitude ) ;
2013-10-18 15:30:24 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_contact :
2013-10-18 15:30:24 -04:00
printf ( " [contact] " ) ;
push_color ( COLOR_RED ) ;
printf ( " %s %s " , M - > first_name , M - > last_name ) ;
pop_color ( ) ;
printf ( " %s " , M - > phone ) ;
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_unsupported :
2013-10-18 15:30:24 -04:00
printf ( " [unsupported] " ) ;
return ;
default :
2014-08-18 12:39:04 -04:00
printf ( " x = %d \n " , M - > type ) ;
2013-10-18 15:30:24 -04:00
assert ( 0 ) ;
}
}
2013-10-23 06:24:59 -04:00
int unknown_user_list_pos ;
int unknown_user_list [ 1000 ] ;
2014-08-13 11:55:16 -04:00
void print_user_name ( tgl_peer_id_t id , tgl_peer_t * U ) {
assert ( tgl_get_peer_type ( id ) = = TGL_PEER_USER ) ;
2013-10-18 15:30:24 -04:00
push_color ( COLOR_RED ) ;
if ( ! U ) {
2014-08-13 11:55:16 -04:00
printf ( " user#%d " , tgl_get_peer_id ( id ) ) ;
2013-10-23 06:24:59 -04:00
int i ;
2013-10-31 19:18:34 -04:00
int ok = 1 ;
2013-10-23 06:24:59 -04:00
for ( i = 0 ; i < unknown_user_list_pos ; i + + ) {
2014-08-13 11:55:16 -04:00
if ( unknown_user_list [ i ] = = tgl_get_peer_id ( id ) ) {
2013-10-31 19:18:34 -04:00
ok = 0 ;
2013-10-23 06:24:59 -04:00
break ;
}
}
2013-10-31 19:18:34 -04:00
if ( ok ) {
2013-10-23 06:24:59 -04:00
assert ( unknown_user_list_pos < 1000 ) ;
2014-08-13 11:55:16 -04:00
unknown_user_list [ unknown_user_list_pos + + ] = tgl_get_peer_id ( id ) ;
2013-10-23 06:24:59 -04:00
}
2013-10-18 15:30:24 -04:00
} else {
2013-10-24 03:38:32 -04:00
if ( U - > flags & ( FLAG_USER_SELF | FLAG_USER_CONTACT ) ) {
2013-10-23 06:24:59 -04:00
push_color ( COLOR_REDB ) ;
}
2013-11-21 14:35:49 -05:00
if ( ( U - > flags & FLAG_DELETED ) ) {
2014-08-13 11:55:16 -04:00
printf ( " deleted user#%d " , tgl_get_peer_id ( id ) ) ;
2013-11-21 14:35:49 -05:00
} else if ( ! ( U - > flags & FLAG_CREATED ) ) {
2014-08-13 11:55:16 -04:00
printf ( " empty user#%d " , tgl_get_peer_id ( id ) ) ;
2013-11-06 18:12:40 -05:00
} else if ( ! U - > user . first_name | | ! strlen ( U - > user . first_name ) ) {
2013-10-23 06:24:59 -04:00
printf ( " %s " , U - > user . last_name ) ;
2013-11-06 18:12:40 -05:00
} else if ( ! U - > user . last_name | | ! strlen ( U - > user . last_name ) ) {
2013-10-23 06:24:59 -04:00
printf ( " %s " , U - > user . first_name ) ;
} else {
printf ( " %s %s " , U - > user . first_name , U - > user . last_name ) ;
}
2013-10-24 03:38:32 -04:00
if ( U - > flags & ( FLAG_USER_SELF | FLAG_USER_CONTACT ) ) {
2013-10-23 06:24:59 -04:00
pop_color ( ) ;
}
2013-10-18 15:30:24 -04:00
}
pop_color ( ) ;
}
2014-08-13 11:55:16 -04:00
void print_chat_name ( tgl_peer_id_t id , tgl_peer_t * C ) {
assert ( tgl_get_peer_type ( id ) = = TGL_PEER_CHAT ) ;
2013-10-18 15:30:24 -04:00
push_color ( COLOR_MAGENTA ) ;
if ( ! C ) {
2014-08-13 11:55:16 -04:00
printf ( " chat#%d " , tgl_get_peer_id ( id ) ) ;
2013-10-18 15:30:24 -04:00
} else {
printf ( " %s " , C - > chat . title ) ;
}
pop_color ( ) ;
}
2014-08-13 11:55:16 -04:00
void print_encr_chat_name ( tgl_peer_id_t id , tgl_peer_t * C ) {
assert ( tgl_get_peer_type ( id ) = = TGL_PEER_ENCR_CHAT ) ;
2013-11-02 13:01:22 -04:00
push_color ( COLOR_MAGENTA ) ;
if ( ! C ) {
2014-08-13 11:55:16 -04:00
printf ( " encr_chat#%d " , tgl_get_peer_id ( id ) ) ;
2013-11-02 13:01:22 -04:00
} else {
printf ( " %s " , C - > print_name ) ;
}
pop_color ( ) ;
}
2014-08-13 11:55:16 -04:00
void print_encr_chat_name_full ( tgl_peer_id_t id , tgl_peer_t * C ) {
assert ( tgl_get_peer_type ( id ) = = TGL_PEER_ENCR_CHAT ) ;
2013-11-02 13:01:22 -04:00
push_color ( COLOR_MAGENTA ) ;
if ( ! C ) {
2014-08-13 11:55:16 -04:00
printf ( " encr_chat#%d " , tgl_get_peer_id ( id ) ) ;
2013-11-02 13:01:22 -04:00
} else {
printf ( " %s " , C - > print_name ) ;
}
pop_color ( ) ;
}
2013-10-18 15:30:24 -04:00
static char * monthes [ ] = { " Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " , " Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec " } ;
void print_date ( long t ) {
2014-02-18 13:06:00 -05:00
struct tm * tm = localtime ( ( void * ) & t ) ;
2013-10-18 15:30:24 -04:00
if ( time ( 0 ) - t < 12 * 60 * 60 ) {
printf ( " [%02d:%02d] " , tm - > tm_hour , tm - > tm_min ) ;
} else {
printf ( " [%02d %s] " , tm - > tm_mday , monthes [ tm - > tm_mon ] ) ;
}
}
2013-10-24 03:38:32 -04:00
void print_date_full ( long t ) {
2014-02-18 13:06:00 -05:00
struct tm * tm = localtime ( ( void * ) & t ) ;
2013-10-24 03:38:32 -04:00
printf ( " [%04d/%02d/%02d %02d:%02d:%02d] " , tm - > tm_year + 1900 , tm - > tm_mon + 1 , tm - > tm_mday , tm - > tm_hour , tm - > tm_min , tm - > tm_sec ) ;
}
2014-08-13 11:55:16 -04:00
void print_service_message ( struct tgl_message * M ) {
2013-12-19 17:50:31 -05:00
assert ( M ) ;
2014-08-18 12:39:04 -04:00
//print_start ();
2013-10-21 15:27:29 -04:00
push_color ( COLOR_GREY ) ;
2013-10-24 18:21:52 -04:00
push_color ( COLOR_MAGENTA ) ;
2013-10-27 19:24:03 -04:00
if ( msg_num_mode ) {
2013-11-02 06:14:30 -04:00
printf ( " %lld " , M - > id ) ;
2013-10-27 19:24:03 -04:00
}
2013-10-21 15:27:29 -04:00
print_date ( M - > date ) ;
2013-10-24 18:21:52 -04:00
pop_color ( ) ;
2013-10-21 15:27:29 -04:00
printf ( " " ) ;
2014-08-13 11:55:16 -04:00
if ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_CHAT ) {
print_chat_name ( M - > to_id , tgl_peer_get ( M - > to_id ) ) ;
2013-11-15 05:37:14 -05:00
} else {
2014-08-13 11:55:16 -04:00
assert ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_ENCR_CHAT ) ;
print_encr_chat_name ( M - > to_id , tgl_peer_get ( M - > to_id ) ) ;
2013-11-15 05:37:14 -05:00
}
2013-10-21 15:27:29 -04:00
printf ( " " ) ;
2014-08-13 11:55:16 -04:00
print_user_name ( M - > from_id , tgl_peer_get ( M - > from_id ) ) ;
2013-10-21 15:27:29 -04:00
switch ( M - > action . type ) {
2014-08-18 12:39:04 -04:00
case tgl_message_action_none :
2013-10-21 15:27:29 -04:00
printf ( " \n " ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_geo_chat_create :
2013-11-22 18:26:35 -05:00
printf ( " Created geo chat \n " ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_geo_chat_checkin :
2013-11-22 18:26:35 -05:00
printf ( " Checkin in geochat \n " ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_create :
2013-10-21 15:27:29 -04:00
printf ( " created chat %s. %d users \n " , M - > action . title , M - > action . user_num ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_edit_title :
2013-10-21 15:27:29 -04:00
printf ( " changed title to %s \n " ,
M - > action . new_title ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_edit_photo :
2013-10-21 15:27:29 -04:00
printf ( " changed photo \n " ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_delete_photo :
2013-10-21 15:27:29 -04:00
printf ( " deleted photo \n " ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_add_user :
2013-10-21 15:27:29 -04:00
printf ( " added user " ) ;
2014-08-13 11:55:16 -04:00
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 ) ) ) ;
2013-10-21 15:27:29 -04:00
printf ( " \n " ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_delete_user :
2013-10-21 15:27:29 -04:00
printf ( " deleted user " ) ;
2014-08-13 11:55:16 -04:00
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 ) ) ) ;
2013-10-21 15:27:29 -04:00
printf ( " \n " ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_set_message_ttl :
2013-11-15 05:37:14 -05:00
printf ( " set ttl to %d seconds. Unsupported yet \n " , M - > action . ttl ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_read_messages :
2014-08-12 21:22:15 -04:00
printf ( " %d messages marked read \n " , M - > action . read_cnt ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_delete_messages :
2014-08-12 21:22:15 -04:00
printf ( " %d messages deleted \n " , M - > action . delete_cnt ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_screenshot_messages :
2014-08-12 21:22:15 -04:00
printf ( " %d messages screenshoted \n " , M - > action . screenshot_cnt ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_flush_history :
2014-08-12 21:22:15 -04:00
printf ( " cleared history \n " ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_notify_layer :
2014-08-12 21:22:15 -04:00
printf ( " updated layer to %d \n " , M - > action . layer ) ;
break ;
2013-10-21 15:27:29 -04:00
default :
assert ( 0 ) ;
}
pop_color ( ) ;
2014-08-18 12:39:04 -04:00
//print_end ();
2013-10-21 15:27:29 -04:00
}
2014-08-13 11:55:16 -04:00
tgl_peer_id_t last_from_id ;
tgl_peer_id_t last_to_id ;
2013-10-31 19:18:34 -04:00
2014-08-13 11:55:16 -04:00
void print_message ( struct tgl_message * M ) {
2013-12-19 17:50:31 -05:00
assert ( M ) ;
2013-11-21 14:35:49 -05:00
if ( M - > flags & ( FLAG_MESSAGE_EMPTY | FLAG_DELETED ) ) {
2013-11-04 12:34:27 -05:00
return ;
}
2013-12-19 17:50:31 -05:00
if ( ! ( M - > flags & FLAG_CREATED ) ) { return ; }
2013-10-18 12:00:47 -04:00
if ( M - > service ) {
2013-10-21 15:27:29 -04:00
print_service_message ( M ) ;
2013-10-18 12:00:47 -04:00
return ;
}
2014-08-13 11:55:16 -04:00
if ( ! tgl_get_peer_type ( M - > to_id ) ) {
2013-12-18 10:21:49 -05:00
logprintf ( " Bad msg \n " ) ;
return ;
}
2013-10-18 15:30:24 -04:00
2013-10-31 19:18:34 -04:00
last_from_id = M - > from_id ;
last_to_id = M - > to_id ;
2013-10-18 15:30:24 -04:00
2014-08-18 12:39:04 -04:00
//print_start ();
2014-08-13 11:55:16 -04:00
if ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_USER ) {
2013-10-18 12:00:47 -04:00
if ( M - > out ) {
2013-10-18 15:30:24 -04:00
push_color ( COLOR_GREEN ) ;
2013-10-25 15:50:10 -04:00
if ( msg_num_mode ) {
2013-11-02 06:14:30 -04:00
printf ( " %lld " , M - > id ) ;
2013-10-25 15:50:10 -04:00
}
2013-10-18 15:30:24 -04:00
print_date ( M - > date ) ;
pop_color ( ) ;
printf ( " " ) ;
2014-08-13 11:55:16 -04:00
print_user_name ( M - > to_id , tgl_peer_get ( M - > to_id ) ) ;
2013-10-18 15:30:24 -04:00
push_color ( COLOR_GREEN ) ;
2013-10-21 14:24:31 -04:00
if ( M - > unread ) {
printf ( " <<< " ) ;
} else {
printf ( " ««« " ) ;
}
2013-10-16 15:19:39 -04:00
} else {
2013-10-18 15:30:24 -04:00
push_color ( COLOR_BLUE ) ;
2013-10-25 15:50:10 -04:00
if ( msg_num_mode ) {
2013-11-02 06:14:30 -04:00
printf ( " %lld " , M - > id ) ;
2013-10-25 15:50:10 -04:00
}
2013-10-18 15:30:24 -04:00
print_date ( M - > date ) ;
pop_color ( ) ;
printf ( " " ) ;
2014-08-13 11:55:16 -04:00
print_user_name ( M - > from_id , tgl_peer_get ( M - > from_id ) ) ;
2013-10-18 15:30:24 -04:00
push_color ( COLOR_BLUE ) ;
2013-10-21 14:24:31 -04:00
if ( M - > unread ) {
printf ( " >>> " ) ;
} else {
printf ( " »»» " ) ;
}
2014-02-27 03:48:05 -05:00
if ( alert_sound ) {
play_sound ( ) ;
}
2013-10-18 12:00:47 -04:00
}
2014-08-13 11:55:16 -04:00
} else if ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_ENCR_CHAT ) {
tgl_peer_t * P = tgl_peer_get ( M - > to_id ) ;
2013-11-04 12:34:27 -05:00
assert ( P ) ;
if ( M - > out ) {
push_color ( COLOR_GREEN ) ;
if ( msg_num_mode ) {
printf ( " %lld " , M - > id ) ;
}
print_date ( M - > date ) ;
printf ( " " ) ;
push_color ( COLOR_CYAN ) ;
printf ( " %s " , P - > print_name ) ;
pop_color ( ) ;
if ( M - > unread ) {
printf ( " <<< " ) ;
} else {
printf ( " ««« " ) ;
}
} else {
push_color ( COLOR_BLUE ) ;
if ( msg_num_mode ) {
printf ( " %lld " , M - > id ) ;
}
print_date ( M - > date ) ;
push_color ( COLOR_CYAN ) ;
printf ( " %s " , P - > print_name ) ;
pop_color ( ) ;
if ( M - > unread ) {
printf ( " >>> " ) ;
} else {
printf ( " »»» " ) ;
}
2014-02-27 03:48:05 -05:00
if ( alert_sound ) {
play_sound ( ) ;
}
2013-11-04 12:34:27 -05:00
}
2013-10-18 12:00:47 -04:00
} else {
2014-08-13 11:55:16 -04:00
assert ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_CHAT ) ;
2013-10-18 15:30:24 -04:00
push_color ( COLOR_MAGENTA ) ;
2013-10-25 15:50:10 -04:00
if ( msg_num_mode ) {
2013-11-02 06:14:30 -04:00
printf ( " %lld " , M - > id ) ;
2013-10-25 15:50:10 -04:00
}
2013-10-18 15:30:24 -04:00
print_date ( M - > date ) ;
pop_color ( ) ;
printf ( " " ) ;
2014-08-13 11:55:16 -04:00
print_chat_name ( M - > to_id , tgl_peer_get ( M - > to_id ) ) ;
2013-10-18 15:30:24 -04:00
printf ( " " ) ;
2014-08-13 11:55:16 -04:00
print_user_name ( M - > from_id , tgl_peer_get ( M - > from_id ) ) ;
if ( ( tgl_get_peer_type ( M - > from_id ) = = TGL_PEER_USER ) & & ( tgl_get_peer_id ( M - > from_id ) = = tgl_state . our_id ) ) {
2013-10-18 15:30:24 -04:00
push_color ( COLOR_GREEN ) ;
} else {
push_color ( COLOR_BLUE ) ;
2013-10-16 15:19:39 -04:00
}
2013-10-21 14:24:31 -04:00
if ( M - > unread ) {
printf ( " >>> " ) ;
} else {
printf ( " »»» " ) ;
}
2013-10-18 15:30:24 -04:00
}
2014-08-13 11:55:16 -04:00
if ( tgl_get_peer_type ( M - > fwd_from_id ) = = TGL_PEER_USER ) {
2013-10-24 18:21:52 -04:00
printf ( " [fwd from " ) ;
2014-08-13 11:55:16 -04:00
print_user_name ( M - > fwd_from_id , tgl_peer_get ( M - > fwd_from_id ) ) ;
2013-10-24 18:21:52 -04:00
printf ( " ] " ) ;
}
2013-10-18 15:30:24 -04:00
if ( M - > message & & strlen ( M - > message ) ) {
printf ( " %s " , M - > message ) ;
}
2014-08-18 12:39:04 -04:00
if ( M - > media . type ! = tgl_message_media_none ) {
2013-10-18 15:30:24 -04:00
print_media ( & M - > media ) ;
2013-10-16 15:19:39 -04:00
}
2013-10-18 15:30:24 -04:00
pop_color ( ) ;
assert ( ! color_stack_pos ) ;
printf ( " \n " ) ;
2014-08-18 12:39:04 -04:00
//print_end();
2013-10-16 15:19:39 -04:00
}
2013-11-09 17:47:19 -05:00
2014-02-27 03:48:05 -05:00
void play_sound ( void ) {
printf ( " \a " ) ;
}
2013-11-09 17:47:19 -05:00
void set_interface_callbacks ( void ) {
2014-08-26 14:26:00 -04:00
if ( readline_disabled ) { return ; }
2013-11-09 17:47:19 -05:00
readline_active = 1 ;
rl_callback_handler_install ( get_default_prompt ( ) , interpreter ) ;
2014-08-25 12:17:17 -04:00
//rl_attempted_completion_function = (void *) complete_text;
rl_completion_entry_function = command_generator ;
2013-11-09 17:47:19 -05:00
}