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
2015-01-11 16:52:40 -05:00
Copyright Vitaly Valtman 2013 - 2015
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
2015-05-23 21:28:38 -04:00
# ifdef USE_PYTHON
# include "python-tg.h"
# endif
# ifndef _GNU_SOURCE
# define _GNU_SOURCE
# endif
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
2014-09-22 18:23:40 -04:00
# include <unistd.h>
2013-10-18 14:00:19 -04:00
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-20 18:22:35 -04:00
# include <event2/bufferevent.h>
# include <event2/buffer.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
2015-05-02 07:49:21 -04:00
2014-08-13 11:55:16 -04:00
//#include "mtproto-common.h"
2013-11-25 12:16:34 -05:00
2014-11-12 09:38:44 -05:00
# include <tgl/tgl.h>
2015-09-25 11:28:23 -04:00
# include <tgl/tgl-queries.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
2015-05-11 07:20:34 -04:00
# ifdef USE_JSON
2015-05-11 10:14:58 -04:00
# include <jansson.h>
2015-05-11 07:20:34 -04:00
# include "json-tg.h"
# endif
2015-06-17 09:48:44 -04:00
# include "tgl/mtproto-common.h"
# include "auto/auto-store.h"
# include "auto/auto-fetch-ds.h"
# include "auto/auto-types.h"
# include "auto/auto-free-ds.h"
2015-10-02 05:32:16 -04:00
# include <errno.h>
2014-01-24 10:05:41 -05:00
# define ALLOW_MULT 1
2013-10-24 11:44:54 -04:00
char * default_prompt = " > " ;
2015-01-11 16:52:40 -05:00
extern int read_one_string ;
extern char one_string [ ] ;
extern int one_string_len ;
extern char * one_string_prompt ;
extern int one_string_flags ;
2015-05-11 07:20:34 -04:00
extern int enable_json ;
2014-08-26 12:06:30 -04:00
int disable_auto_accept ;
2013-10-25 15:50:10 -04:00
int msg_num_mode ;
2015-09-30 13:41:29 -04:00
int permanent_msg_id_mode ;
int permanent_peer_id_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 ;
2014-09-20 18:22:35 -04:00
struct in_ev * notify_ev ;
2014-09-22 18:23:40 -04:00
extern int usfd ;
extern int sfd ;
2014-10-11 20:27:34 -04:00
extern int use_ids ;
2014-09-22 18:23:40 -04:00
2014-12-21 19:50:28 -05:00
extern int daemonize ;
2014-10-24 13:43:08 -04:00
extern struct tgl_state * TLS ;
2015-01-11 16:52:40 -05:00
int readline_deactivated ;
2014-10-24 13:43:08 -04:00
2015-06-17 09:48:44 -04:00
void fail_interface ( struct tgl_state * TLS , struct in_ev * ev , int error_code , const char * format , . . . ) __attribute__ ( ( format ( printf , 4 , 5 ) ) ) ;
2014-12-21 19:50:28 -05:00
void event_incoming ( struct bufferevent * bev , short what , void * _arg ) ;
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-09-17 17:03:20 -04:00
static void skip_wspc ( void ) {
while ( * line_ptr & & ( ( unsigned char ) * line_ptr ) < = ' ' ) {
line_ptr + + ;
2014-08-12 21:22:15 -04:00
}
}
2014-08-13 11:55:16 -04:00
2014-09-17 17:03:20 -04:00
static char * cur_token ;
static int cur_token_len ;
static int cur_token_end_str ;
static int cur_token_quoted ;
2014-09-20 18:22:35 -04:00
# define SOCKET_ANSWER_MAX_SIZE (1 << 25)
static char socket_answer [ SOCKET_ANSWER_MAX_SIZE + 1 ] ;
static int socket_answer_pos = - 1 ;
void socket_answer_start ( void ) {
socket_answer_pos = 0 ;
}
static void socket_answer_add_printf ( const char * format , . . . ) __attribute__ ( ( format ( printf , 1 , 2 ) ) ) ;
void socket_answer_add_printf ( const char * format , . . . ) {
if ( socket_answer_pos < 0 ) { return ; }
va_list ap ;
va_start ( ap , format ) ;
socket_answer_pos + = vsnprintf ( socket_answer + socket_answer_pos , SOCKET_ANSWER_MAX_SIZE - socket_answer_pos , format , ap ) ;
va_end ( ap ) ;
if ( socket_answer_pos > SOCKET_ANSWER_MAX_SIZE ) { socket_answer_pos = - 1 ; }
}
void socket_answer_end ( struct in_ev * ev ) {
2015-06-01 05:07:44 -04:00
if ( ev - > bev ) {
2014-09-20 18:22:35 -04:00
static char s [ 100 ] ;
sprintf ( s , " ANSWER %d \n " , socket_answer_pos ) ;
bufferevent_write ( ev - > bev , s , strlen ( s ) ) ;
bufferevent_write ( ev - > bev , socket_answer , socket_answer_pos ) ;
bufferevent_write ( ev - > bev , " \n " , 1 ) ;
}
socket_answer_pos = - 1 ;
}
# define mprintf(ev,...) \
if ( ev ) { socket_answer_add_printf ( __VA_ARGS__ ) ; } \
else { printf ( __VA_ARGS__ ) ; }
# define mprint_start(ev,...) \
if ( ! ev ) { print_start ( __VA_ARGS__ ) ; } \
else { socket_answer_start ( ) ; }
# define mprint_end(ev,...) \
if ( ! ev ) { print_end ( __VA_ARGS__ ) ; } \
else { socket_answer_end ( ev ) ; }
# define mpush_color(ev,...) \
if ( ! ev ) { push_color ( __VA_ARGS__ ) ; }
# define mpop_color(ev,...) \
if ( ! ev ) { pop_color ( __VA_ARGS__ ) ; }
2014-09-17 17:03:20 -04:00
static void unescape_token ( char * start , char * end ) {
static char cur_token_buff [ ( 1 < < 20 ) + 1 ] ;
cur_token_len = 0 ;
cur_token = cur_token_buff ;
while ( start < end ) {
assert ( cur_token_len < ( 1 < < 20 ) ) ;
switch ( * start ) {
case ' \\ ' :
start + + ;
switch ( * start ) {
case ' n ' :
cur_token [ cur_token_len + + ] = ' \n ' ;
break ;
case ' r ' :
cur_token [ cur_token_len + + ] = ' \r ' ;
break ;
case ' t ' :
cur_token [ cur_token_len + + ] = ' \t ' ;
break ;
case ' b ' :
cur_token [ cur_token_len + + ] = ' \b ' ;
break ;
case ' a ' :
cur_token [ cur_token_len + + ] = ' \a ' ;
break ;
default :
cur_token [ cur_token_len + + ] = * start ;
break ;
}
break ;
default :
cur_token [ cur_token_len + + ] = * start ; ;
break ;
}
start + + ;
}
cur_token [ cur_token_len ] = 0 ;
}
int force_end_mode ;
static void next_token ( void ) {
skip_wspc ( ) ;
cur_token_end_str = 0 ;
cur_token_quoted = 0 ;
if ( ! * line_ptr ) {
cur_token_len = 0 ;
cur_token_end_str = 1 ;
return ;
}
char c = * line_ptr ;
char * start = line_ptr ;
if ( c = = ' " ' | | c = = ' \' ' ) {
cur_token_quoted = 1 ;
line_ptr + + ;
int esc = 0 ;
while ( * line_ptr & & ( esc | | * line_ptr ! = c ) ) {
if ( * line_ptr = = ' \\ ' ) {
esc = 1 - esc ;
} else {
esc = 0 ;
}
line_ptr + + ;
}
if ( ! * line_ptr ) {
cur_token_len = - 2 ;
} else {
unescape_token ( start + 1 , line_ptr ) ;
line_ptr + + ;
}
} else {
while ( * line_ptr & & ( ( unsigned char ) * line_ptr ) > ' ' ) {
line_ptr + + ;
}
cur_token = start ;
cur_token_len = line_ptr - start ;
cur_token_end_str = ( ! force_end_mode ) & & ( * line_ptr = = 0 ) ;
2013-10-29 20:08:30 -04:00
}
2014-09-17 17:03:20 -04:00
}
void next_token_end ( void ) {
skip_wspc ( ) ;
if ( * line_ptr & & * line_ptr ! = ' " ' & & * line_ptr ! = ' \' ' ) {
cur_token_quoted = 0 ;
cur_token = line_ptr ;
while ( * line_ptr ) { line_ptr + + ; }
cur_token_len = line_ptr - cur_token ;
while ( ( ( unsigned char ) cur_token [ cur_token_len - 1 ] ) < = ' ' & & cur_token_len > = 0 ) {
cur_token_len - - ;
}
assert ( cur_token_len > 0 ) ;
cur_token_end_str = ! force_end_mode ;
return ;
} else {
if ( * line_ptr ) {
next_token ( ) ;
skip_wspc ( ) ;
if ( * line_ptr ) {
cur_token_len = - 1 ;
}
} else {
next_token ( ) ;
}
2013-10-29 20:08:30 -04:00
}
}
2015-06-17 05:05:57 -04:00
void next_token_end_ac ( void ) {
skip_wspc ( ) ;
if ( * line_ptr & & * line_ptr ! = ' " ' & & * line_ptr ! = ' \' ' ) {
cur_token_quoted = 0 ;
cur_token = line_ptr ;
while ( * line_ptr ) { line_ptr + + ; }
cur_token_len = line_ptr - cur_token ;
assert ( cur_token_len > 0 ) ;
cur_token_end_str = ! force_end_mode ;
return ;
} else {
if ( * line_ptr ) {
next_token ( ) ;
skip_wspc ( ) ;
if ( * line_ptr ) {
cur_token_len = - 1 ;
}
} else {
next_token ( ) ;
}
}
}
2013-10-29 20:08:30 -04:00
# define NOT_FOUND (int)0x80000000
2015-09-30 12:49:50 -04:00
tgl_peer_id_t TGL_PEER_NOT_FOUND = { . peer_id = NOT_FOUND } ;
2013-10-31 19:18:34 -04:00
2014-09-17 17:03:20 -04:00
long long cur_token_int ( void ) {
if ( cur_token_len < = 0 ) {
2013-10-29 20:08:30 -04:00
return NOT_FOUND ;
2014-09-17 17:03:20 -04:00
} else {
char c = cur_token [ cur_token_len ] ;
cur_token [ cur_token_len ] = 0 ;
char * end = 0 ;
long long x = strtoll ( cur_token , & end , 0 ) ;
cur_token [ cur_token_len ] = c ;
if ( end ! = cur_token + cur_token_len ) {
return NOT_FOUND ;
} else {
return x ;
}
2013-10-29 20:08:30 -04:00
}
}
2015-09-30 12:49:50 -04:00
int hex2int ( char c ) {
if ( c > = ' 0 ' & & c < = ' 9 ' ) { return c - ' 0 ' ; }
if ( c > = ' a ' & & c < = ' f ' ) { return c - ' a ' + 10 ; }
assert ( 0 ) ;
return 0 ;
}
2015-10-01 07:11:31 -04:00
char * print_permanent_msg_id ( tgl_message_id_t id ) {
static char buf [ 2 * sizeof ( tgl_message_id_t ) + 1 ] ;
unsigned char * s = ( void * ) & id ;
int i ;
for ( i = 0 ; i < ( int ) sizeof ( tgl_message_id_t ) ; i + + ) {
sprintf ( buf + 2 * i , " %02x " , ( unsigned ) s [ i ] ) ;
}
return buf ;
}
char * print_permanent_peer_id ( tgl_peer_id_t id ) {
static char buf [ 2 * sizeof ( tgl_peer_id_t ) + 2 ] ;
buf [ 0 ] = ' $ ' ;
unsigned char * s = ( void * ) & id ;
int i ;
for ( i = 0 ; i < ( int ) sizeof ( tgl_peer_id_t ) ; i + + ) {
sprintf ( buf + 1 + 2 * i , " %02x " , ( unsigned ) s [ i ] ) ;
}
return buf ;
}
tgl_message_id_t parse_input_msg_id ( const char * s , int l ) {
if ( ! s | | l < = 0 ) {
2015-09-30 12:49:50 -04:00
tgl_message_id_t id ;
memset ( & id , 0 , sizeof ( id ) ) ;
id . peer_type = 0 ;
return id ;
} else {
tgl_message_id_t id ;
memset ( & id , 0 , sizeof ( id ) ) ;
2015-10-01 07:11:31 -04:00
if ( l = = 2 * sizeof ( tgl_message_id_t ) ) {
2015-09-30 12:49:50 -04:00
int i ;
for ( i = 0 ; i < ( int ) sizeof ( tgl_message_id_t ) ; i + + ) {
if (
2015-10-01 07:11:31 -04:00
( s [ i ] < ' 0 ' | | s [ i ] > ' 9 ' ) & &
( s [ i ] < ' a ' | | s [ i ] > ' f ' )
2015-09-30 12:49:50 -04:00
) {
id . peer_type = 0 ;
return id ;
}
}
unsigned char * d = ( void * ) & id ;
for ( i = 0 ; i < ( int ) sizeof ( tgl_message_id_t ) ; i + + ) {
2015-10-01 07:11:31 -04:00
d [ i ] = hex2int ( s [ 2 * i ] ) * 16 + hex2int ( s [ 2 * i + 1 ] ) ;
2015-09-30 12:49:50 -04:00
}
return id ;
} else {
2015-10-01 07:11:31 -04:00
char * sc = tstrndup ( s , l ) ;
2015-09-30 12:49:50 -04:00
char * end = 0 ;
2015-10-01 07:11:31 -04:00
long long x = strtoll ( sc , & end , 0 ) ;
tfree_str ( sc ) ;
if ( end ! = sc + l ) {
2015-09-30 12:49:50 -04:00
id . peer_type = 0 ;
} else {
id . peer_type = TGL_PEER_TEMP_ID ;
id . id = x ;
}
return id ;
}
}
}
2015-10-01 07:11:31 -04:00
tgl_message_id_t cur_token_msg_id ( void ) {
return parse_input_msg_id ( cur_token , cur_token_len ) ;
}
2014-10-03 05:35:02 -04:00
double cur_token_double ( void ) {
if ( cur_token_len < = 0 ) {
return NOT_FOUND ;
} else {
char c = cur_token [ cur_token_len ] ;
cur_token [ cur_token_len ] = 0 ;
char * end = 0 ;
double x = strtod ( cur_token , & end ) ;
cur_token [ cur_token_len ] = c ;
if ( end ! = cur_token + cur_token_len ) {
return NOT_FOUND ;
} else {
return x ;
}
}
}
2015-10-01 07:11:31 -04:00
tgl_peer_id_t parse_input_peer_id ( const char * s , int l , int mask ) {
if ( ! s | | l < = 0 ) { return TGL_PEER_NOT_FOUND ; }
2014-09-17 17:03:20 -04:00
2015-09-30 13:41:29 -04:00
if ( * s = = ' $ ' ) {
s + + ;
l - - ;
if ( l ! = 2 * sizeof ( tgl_peer_id_t ) ) {
return TGL_PEER_NOT_FOUND ;
}
2013-10-29 20:08:30 -04:00
2015-09-30 13:41:29 -04:00
tgl_peer_id_t res ;
unsigned char * r = ( void * ) & res ;
int i ;
for ( i = 0 ; i < l ; i + + ) {
if ( ( s [ i ] < ' 0 ' | | s [ i ] > ' 9 ' ) & &
( s [ i ] < ' a ' | | s [ i ] > ' f ' ) ) {
return TGL_PEER_NOT_FOUND ;
}
}
for ( i = 0 ; i < ( int ) sizeof ( tgl_peer_id_t ) ; i + + ) {
r [ i ] = hex2int ( s [ 2 * i ] ) * 16 + hex2int ( s [ 2 * i + 1 ] ) ;
}
2013-10-31 19:18:34 -04:00
2015-09-30 13:41:29 -04:00
if ( mask & & tgl_get_peer_type ( res ) ! = mask ) {
return TGL_PEER_NOT_FOUND ;
}
return res ;
2013-10-29 20:08:30 -04:00
}
2015-09-30 13:41:29 -04:00
const char * ss [ ] = { " user#id " , " user# " , " chat#id " , " chat# " , " secret_chat#id " , " secret_chat# " , " channel#id " , " channel# " } ;
int tt [ ] = { TGL_PEER_USER , TGL_PEER_USER , TGL_PEER_CHAT , TGL_PEER_CHAT , TGL_PEER_ENCR_CHAT , TGL_PEER_ENCR_CHAT , TGL_PEER_CHANNEL , TGL_PEER_CHANNEL } ;
2014-09-17 17:03:20 -04:00
2015-10-01 07:11:31 -04:00
char * sc = tstrndup ( s , l ) ;
2015-09-30 13:41:29 -04:00
int i ;
for ( i = 0 ; i < 8 ; i + + ) if ( ! mask | | mask = = tt [ i ] ) {
int x = strlen ( ss [ i ] ) ;
if ( l > x & & ! memcmp ( s , ss [ i ] , x ) ) {
2015-10-01 07:11:31 -04:00
int r = atoi ( sc + x ) ;
tfree_str ( sc ) ;
2015-09-30 13:41:29 -04:00
if ( r < 0 ) { return TGL_PEER_NOT_FOUND ; }
tgl_peer_t * P = tgl_peer_get ( TLS , tgl_set_peer_id ( tt [ i ] , r ) ) ;
if ( ! P ) { return TGL_PEER_NOT_FOUND ; }
return P - > id ;
}
2014-09-03 11:54:50 -04:00
}
2013-10-31 19:18:34 -04:00
2015-10-01 07:11:31 -04:00
tgl_peer_t * P = tgl_peer_get_by_name ( TLS , sc ) ;
tfree_str ( sc ) ;
2014-08-13 08:56:55 -04:00
2015-09-30 13:41:29 -04:00
if ( P & & ( ! mask | | tgl_get_peer_type ( P - > id ) = = mask ) ) {
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
}
}
2015-09-30 13:41:29 -04:00
tgl_peer_id_t cur_token_user ( void ) {
2015-10-01 07:11:31 -04:00
return parse_input_peer_id ( cur_token , cur_token_len , TGL_PEER_USER ) ;
2015-09-30 13:41:29 -04:00
}
tgl_peer_id_t cur_token_chat ( void ) {
2015-10-01 07:11:31 -04:00
return parse_input_peer_id ( cur_token , cur_token_len , TGL_PEER_CHAT ) ;
2015-09-30 13:41:29 -04:00
}
2014-09-17 17:03:20 -04:00
tgl_peer_id_t cur_token_encr_chat ( void ) {
2015-10-01 07:11:31 -04:00
return parse_input_peer_id ( cur_token , cur_token_len , TGL_PEER_ENCR_CHAT ) ;
2015-09-30 13:41:29 -04:00
}
2013-11-04 18:15:24 -05:00
2015-09-30 13:41:29 -04:00
tgl_peer_id_t cur_token_channel ( void ) {
2015-10-01 07:11:31 -04:00
return parse_input_peer_id ( cur_token , cur_token_len , TGL_PEER_CHANNEL ) ;
2013-11-04 18:15:24 -05:00
}
2014-09-17 17:03:20 -04:00
tgl_peer_id_t cur_token_peer ( void ) {
2015-10-01 07:11:31 -04:00
return parse_input_peer_id ( cur_token , cur_token_len , 0 ) ;
2013-10-29 20:08:30 -04:00
}
2015-10-01 07:11:31 -04:00
/*
2014-09-17 17:03:20 -04:00
static tgl_peer_t * mk_peer ( tgl_peer_id_t id ) {
if ( tgl_get_peer_type ( id ) = = NOT_FOUND ) { return 0 ; }
2014-10-24 13:43:08 -04:00
tgl_peer_t * P = tgl_peer_get ( TLS , id ) ;
2014-10-01 06:34:55 -04:00
if ( ! P ) {
if ( tgl_get_peer_type ( id ) = = TGL_PEER_USER ) {
2014-10-24 13:43:08 -04:00
tgl_insert_empty_user ( TLS , tgl_get_peer_id ( id ) ) ;
2014-10-01 06:34:55 -04:00
}
if ( tgl_get_peer_type ( id ) = = TGL_PEER_CHAT ) {
2014-10-24 13:43:08 -04:00
tgl_insert_empty_chat ( TLS , tgl_get_peer_id ( id ) ) ;
2014-10-01 06:34:55 -04:00
}
2014-10-24 13:43:08 -04:00
P = tgl_peer_get ( TLS , id ) ;
2014-10-01 06:34:55 -04:00
}
2014-09-17 17:03:20 -04:00
return P ;
2015-10-01 07:11:31 -04:00
} */
2014-09-17 17:03:20 -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-10-24 13:43:08 -04:00
tgl_peer_t * U = tgl_peer_get ( TLS , 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-10-24 13:43:08 -04:00
if ( TLS - > unread_messages | | TLS - > cur_uploading_bytes | | TLS - > 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-10-24 13:43:08 -04:00
if ( TLS - > unread_messages ) {
l + = snprintf ( buf + l , 999 - l , " %d unread " , TLS - > unread_messages ) ;
2013-10-28 18:33:13 -04:00
ok = 1 ;
}
2014-10-24 13:43:08 -04:00
if ( TLS - > cur_uploading_bytes ) {
2013-10-28 18:33:13 -04:00
if ( ok ) { * ( buf + l ) = ' ' ; l + + ; }
ok = 1 ;
2014-10-24 13:43:08 -04:00
l + = snprintf ( buf + l , 999 - l , " %lld%%Up " , 100 * TLS - > cur_uploaded_bytes / TLS - > cur_uploading_bytes ) ;
2013-10-28 18:33:13 -04:00
}
2014-10-24 13:43:08 -04:00
if ( TLS - > cur_downloading_bytes ) {
2013-10-28 18:33:13 -04:00
if ( ok ) { * ( buf + l ) = ' ' ; l + + ; }
ok = 1 ;
2014-10-24 13:43:08 -04:00
l + = snprintf ( buf + l , 999 - l , " %lld%%Down " , 100 * TLS - > cur_downloaded_bytes / TLS - > 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
}
2014-11-12 09:38:44 -05:00
char * complete_none ( const char * text , int state ) {
2013-10-03 08:38:25 -04:00
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 ) {
2015-06-29 22:52:17 -04:00
if ( readline_disabled ) {
fflush ( stdout ) ;
return ;
}
2015-01-11 16:52:40 -05:00
if ( read_one_string ) { 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] " ,
2015-05-14 08:48:20 -04:00
" [enable_preview] " ,
" [disable_preview] " ,
" [reply= " ,
2013-11-30 13:52:13 -05:00
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 ,
2015-10-01 07:11:31 -04:00
ca_channel ,
2014-08-25 12:17:17 -04:00
ca_peer ,
ca_file_name ,
ca_file_name_end ,
ca_period ,
ca_number ,
2014-10-03 05:35:02 -04:00
ca_double ,
2014-08-25 12:17:17 -04:00
ca_string_end ,
2015-06-17 05:05:57 -04:00
ca_msg_string_end ,
2014-08-25 12:17:17 -04:00
ca_string ,
ca_modifier ,
2014-09-10 07:52:42 -04:00
ca_command ,
2014-09-17 17:03:20 -04:00
ca_extf ,
2015-09-30 12:49:50 -04:00
ca_msg_id ,
2014-09-17 17:03:20 -04:00
ca_optional = 256
} ;
struct arg {
int flags ;
2015-10-01 07:11:31 -04:00
union {
//tgl_peer_t *P;
//struct tgl_message *M;
2014-09-17 17:03:20 -04:00
char * str ;
long long num ;
2014-10-03 05:35:02 -04:00
double dval ;
2015-09-30 12:49:50 -04:00
tgl_message_id_t msg_id ;
2015-10-01 07:11:31 -04:00
tgl_peer_id_t peer_id ;
2014-09-17 17:03:20 -04:00
} ;
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 ] ;
2015-05-06 07:39:45 -04:00
void ( * fun ) ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) ;
2014-09-18 09:10:42 -04:00
char * desc ;
2015-05-06 07:39:45 -04:00
void * arg ;
2014-08-25 12:17:17 -04:00
} ;
2014-09-17 17:03:20 -04:00
int offline_mode ;
2015-05-14 08:48:20 -04:00
int reply_id ;
int disable_msg_preview ;
2014-10-24 13:43:08 -04:00
void print_user_list_gw ( struct tgl_state * TLS , void * extra , int success , int num , struct tgl_user * UL [ ] ) ;
void print_msg_list_gw ( struct tgl_state * TLS , void * extra , int success , int num , struct tgl_message * ML [ ] ) ;
2015-09-25 13:01:51 -04:00
void print_msg_list_history_gw ( struct tgl_state * TLS , void * extra , int success , int num , struct tgl_message * ML [ ] ) ;
2014-11-28 08:16:51 -05:00
void print_msg_list_success_gw ( struct tgl_state * TLS , void * extra , int success , int num , struct tgl_message * ML [ ] ) ;
2015-09-30 12:49:50 -04:00
void print_dialog_list_gw ( struct tgl_state * TLS , void * extra , int success , int size , tgl_peer_id_t peers [ ] , tgl_message_id_t * last_msg_id [ ] , int unread_count [ ] ) ;
2014-10-24 13:43:08 -04:00
void print_chat_info_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_chat * C ) ;
2015-10-01 07:11:31 -04:00
void print_channel_info_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_channel * C ) ;
2014-10-24 13:43:08 -04:00
void print_user_info_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_user * C ) ;
2015-05-14 08:48:20 -04:00
void print_filename_gw ( struct tgl_state * TLS , void * extra , int success , const char * name ) ;
2015-05-01 13:19:12 -04:00
void print_string_gw ( struct tgl_state * TLS , void * extra , int success , const char * name ) ;
2015-05-14 08:48:20 -04:00
void open_filename_gw ( struct tgl_state * TLS , void * extra , int success , const char * name ) ;
2014-10-24 13:43:08 -04:00
void print_secret_chat_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_secret_chat * E ) ;
void print_card_gw ( struct tgl_state * TLS , void * extra , int success , int size , int * card ) ;
void print_user_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_user * U ) ;
2015-09-30 12:49:50 -04:00
void print_peer_gw ( struct tgl_state * TLS , void * extra , int success , tgl_peer_t * U ) ;
2014-10-24 13:43:08 -04:00
void print_msg_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_message * M ) ;
void print_msg_success_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_message * M ) ;
void print_encr_chat_success_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_secret_chat * E ) ; ;
void print_success_gw ( struct tgl_state * TLS , void * extra , int success ) ;
2014-09-17 17:03:20 -04:00
2014-09-18 09:10:42 -04:00
struct command commands [ ] ;
2015-05-14 08:48:20 -04:00
/* {{{ client methods */
2015-05-06 07:39:45 -04:00
void do_help ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2015-10-01 07:11:31 -04:00
assert ( arg_num < = 1 ) ;
2014-09-20 18:22:35 -04:00
if ( ev ) { mprint_start ( ev ) ; }
2015-10-01 07:11:31 -04:00
int total = 0 ;
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_YELLOW ) ;
2014-09-18 09:10:42 -04:00
struct command * cmd = commands ;
while ( cmd - > name ) {
2015-10-01 07:11:31 -04:00
if ( ! arg_num | | ! strcmp ( args [ 0 ] . str , cmd - > name ) ) {
mprintf ( ev , " %s \n " , cmd - > desc ) ;
total + + ;
}
2014-09-18 09:10:42 -04:00
cmd + + ;
}
2015-10-01 07:11:31 -04:00
if ( ! total ) {
assert ( arg_num = = 1 ) ;
mprintf ( ev , " Unknown command '%s' \n " , args [ 0 ] . str ) ;
}
2014-09-20 18:22:35 -04:00
mpop_color ( ev ) ;
if ( ev ) { mprint_end ( ev ) ; }
if ( ! ev ) {
fflush ( stdout ) ;
}
2014-09-17 17:03:20 -04:00
}
2015-05-06 07:39:45 -04:00
void do_stats ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-17 17:03:20 -04:00
assert ( ! arg_num ) ;
static char stat_buf [ 1 < < 15 ] ;
2014-10-24 13:43:08 -04:00
tgl_print_stat ( TLS , stat_buf , ( 1 < < 15 ) - 1 ) ;
2014-09-20 18:22:35 -04:00
if ( ev ) { mprint_start ( ev ) ; }
mprintf ( ev , " %s \n " , stat_buf ) ;
if ( ev ) { mprint_end ( ev ) ; }
if ( ! ev ) {
fflush ( stdout ) ;
}
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_show_license ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( ! arg_num ) ;
static char * b =
# include "LICENSE.h"
;
if ( ev ) { mprint_start ( ev ) ; }
mprintf ( ev , " %s " , b ) ;
if ( ev ) { mprint_end ( ev ) ; }
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_quit ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
if ( daemonize ) {
event_incoming ( ev - > bev , BEV_EVENT_EOF , ev ) ;
}
do_halt ( 0 ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_safe_quit ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
if ( daemonize ) {
event_incoming ( ev - > bev , BEV_EVENT_EOF , ev ) ;
}
safe_quit = 1 ;
2015-01-11 16:52:40 -05:00
}
2015-05-14 08:48:20 -04:00
void do_set ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
int num = args [ 1 ] . num ;
if ( ! strcmp ( args [ 0 ] . str , " debug_verbosity " ) ) {
tgl_set_verbosity ( TLS , num ) ;
} else if ( ! strcmp ( args [ 0 ] . str , " log_level " ) ) {
log_level = num ;
} else if ( ! strcmp ( args [ 0 ] . str , " msg_num " ) ) {
msg_num_mode = num ;
} else if ( ! strcmp ( args [ 0 ] . str , " alert " ) ) {
alert_sound = num ;
}
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_chat_with_peer ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
if ( ! ev ) {
in_chat_mode = 1 ;
2015-10-01 07:11:31 -04:00
chat_mode_id = args [ 0 ] . peer_id ;
2015-05-14 08:48:20 -04:00
}
}
void do_main_session ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
if ( notify_ev & & ! - - notify_ev - > refcnt ) {
free ( notify_ev ) ;
}
notify_ev = ev ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
/* }}} */
2014-09-17 17:03:20 -04:00
2015-05-14 08:48:20 -04:00
# define ARG2STR_DEF(n,def) args[n].str ? args[n].str : def, args[n].str ? strlen (args[n].str) : strlen (def)
# define ARG2STR(n) args[n].str, args[n].str ? strlen (args[n].str) : 0
/* {{{ WORK WITH ACCOUNT */
void do_set_password ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-05-14 08:48:20 -04:00
tgl_do_set_password ( TLS , ARG2STR_DEF ( 0 , " empty " ) , print_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
/* }}} */
2014-09-17 17:03:20 -04:00
2015-05-14 08:48:20 -04:00
/* {{{ SENDING MESSAGES */
void do_msg ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-05-28 07:57:38 -04:00
vlogprintf ( E_DEBUG , " reply_id=%d, disable=%d \n " , reply_id , disable_msg_preview ) ;
2015-10-01 07:11:31 -04:00
tgl_do_send_message ( TLS , args [ 0 ] . peer_id , ARG2STR ( 1 ) , TGL_SEND_MSG_FLAG_REPLY ( reply_id ) | disable_msg_preview , NULL , print_msg_success_gw , ev ) ;
2015-06-17 09:48:44 -04:00
}
2015-09-25 11:28:23 -04:00
void do_post ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
if ( ev ) { ev - > refcnt + + ; }
vlogprintf ( E_DEBUG , " reply_id=%d, disable=%d \n " , reply_id , disable_msg_preview ) ;
2015-10-01 07:11:31 -04:00
tgl_do_send_message ( TLS , args [ 0 ] . peer_id , ARG2STR ( 1 ) , TGL_SEND_MSG_FLAG_REPLY ( reply_id ) | disable_msg_preview | TGLMF_POST_AS_CHANNEL , NULL , print_msg_success_gw , ev ) ;
2015-09-25 11:28:23 -04:00
}
2015-06-17 09:48:44 -04:00
void do_msg_kbd ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 3 ) ;
if ( ev ) { ev - > refcnt + + ; }
clear_packet ( ) ;
if ( tglf_store_type ( TLS , ARG2STR ( 1 ) , TYPE_TO_PARAM ( reply_markup ) ) < 0 ) {
fail_interface ( TLS , ev , ENOSYS , " can not parse reply markup " ) ;
return ;
}
in_ptr = packet_buffer ;
in_end = packet_ptr ;
struct tl_ds_reply_markup * DS_RM = fetch_ds_type_reply_markup ( TYPE_TO_PARAM ( reply_markup ) ) ;
assert ( DS_RM ) ;
2015-10-01 07:11:31 -04:00
tgl_do_send_message ( TLS , args [ 0 ] . peer_id , ARG2STR ( 2 ) , TGL_SEND_MSG_FLAG_REPLY ( reply_id ) | disable_msg_preview , DS_RM , print_msg_success_gw , ev ) ;
2015-06-17 09:48:44 -04:00
free_ds_type_reply_markup ( DS_RM , TYPE_TO_PARAM ( reply_markup ) ) ;
2015-04-27 10:52:19 -04:00
}
2015-05-14 08:48:20 -04:00
void do_reply ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
2015-04-27 10:52:19 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-09-30 12:49:50 -04:00
tgl_do_reply_message ( TLS , & args [ 0 ] . msg_id , ARG2STR ( 1 ) , disable_msg_preview , print_msg_success_gw , ev ) ;
2015-04-27 10:52:19 -04:00
}
2015-05-14 08:48:20 -04:00
void do_send_text ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
2015-04-27 10:52:19 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_send_text ( TLS , args [ 0 ] . peer_id , args [ 1 ] . str , TGL_SEND_MSG_FLAG_REPLY ( reply_id ) | disable_msg_preview , print_msg_success_gw , ev ) ;
2015-04-27 10:52:19 -04:00
}
2015-09-25 13:01:51 -04:00
void do_post_text ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_send_text ( TLS , args [ 0 ] . peer_id , args [ 1 ] . str , TGL_SEND_MSG_FLAG_REPLY ( reply_id ) | disable_msg_preview | TGLMF_POST_AS_CHANNEL , print_msg_success_gw , ev ) ;
2015-09-25 13:01:51 -04:00
}
2015-05-14 08:48:20 -04:00
void do_reply_text ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
2015-04-27 10:52:19 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-09-30 12:49:50 -04:00
tgl_do_reply_text ( TLS , & args [ 0 ] . msg_id , args [ 1 ] . str , disable_msg_preview , print_msg_success_gw , ev ) ;
2015-04-27 10:52:19 -04:00
}
2015-05-14 08:48:20 -04:00
static void _do_send_file ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev , unsigned long long flags ) {
2015-05-05 05:48:58 -04:00
assert ( arg_num > = 2 ) ;
2015-04-27 10:52:19 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_send_document ( TLS , args [ 0 ] . peer_id , args [ 1 ] . str , arg_num = = 2 ? NULL : args [ 2 ] . str , arg_num = = 2 ? 0 : strlen ( args [ 2 ] . str ) , flags | TGL_SEND_MSG_FLAG_REPLY ( reply_id ) , print_msg_success_gw , ev ) ;
2015-04-27 10:52:19 -04:00
}
2015-05-14 08:48:20 -04:00
void do_send_photo ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_PHOTO ) ;
}
void do_send_file ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_AUTO ) ;
}
void do_send_audio ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_AUDIO ) ;
}
void do_send_video ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_VIDEO ) ;
}
void do_send_document ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , 0 ) ;
}
2015-09-25 13:01:51 -04:00
void do_post_photo ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_PHOTO | TGLMF_POST_AS_CHANNEL ) ;
}
void do_post_file ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_AUTO | TGLMF_POST_AS_CHANNEL ) ;
}
void do_post_audio ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_AUDIO | TGLMF_POST_AS_CHANNEL ) ;
}
void do_post_video ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_VIDEO | TGLMF_POST_AS_CHANNEL ) ;
}
void do_post_document ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_send_file ( command , arg_num , args , ev , TGLMF_POST_AS_CHANNEL ) ;
}
2015-05-14 08:48:20 -04:00
void _do_reply_file ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev , unsigned long long flags ) {
2015-05-05 05:48:58 -04:00
assert ( arg_num > = 2 ) ;
2015-04-27 10:52:19 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-09-30 12:49:50 -04:00
tgl_do_reply_document ( TLS , & args [ 0 ] . msg_id , args [ 1 ] . str , arg_num = = 2 ? NULL : args [ 2 ] . str , arg_num = = 2 ? 0 : strlen ( args [ 2 ] . str ) , flags , print_msg_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_reply_photo ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_reply_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_PHOTO ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_reply_file ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_reply_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_AUTO ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_reply_audio ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_reply_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_AUDIO ) ;
}
void do_reply_video ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_reply_file ( command , arg_num , args , ev , TGL_SEND_MSG_FLAG_DOCUMENT_VIDEO ) ;
}
void do_reply_document ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
_do_reply_file ( command , arg_num , args , ev , 0 ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-06 07:39:45 -04:00
void do_fwd ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2015-04-24 09:19:13 -04:00
assert ( arg_num > = 2 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-04-24 09:19:13 -04:00
assert ( arg_num < = 1000 ) ;
2015-09-30 12:49:50 -04:00
//if (arg_num == 2) {
// tgl_do_forward_message (TLS, args[0].P->id, &args[1].msg_id, 0, print_msg_success_gw, ev);
//} else {
static tgl_message_id_t * list [ 1000 ] ;
2015-04-24 09:19:13 -04:00
int i ;
for ( i = 0 ; i < arg_num - 1 ; i + + ) {
2015-09-30 12:49:50 -04:00
list [ i ] = & args [ i + 1 ] . msg_id ;
2015-04-24 09:19:13 -04:00
}
2015-10-01 07:11:31 -04:00
tgl_do_forward_messages ( TLS , args [ 0 ] . peer_id , arg_num - 1 , ( void * ) list , 0 , print_msg_list_success_gw , ev ) ;
2015-09-30 12:49:50 -04:00
//}
2014-09-17 17:03:20 -04:00
}
2015-05-06 07:39:45 -04:00
void do_fwd_media ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-17 17:03:20 -04:00
assert ( arg_num = = 2 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_forward_media ( TLS , args [ 0 ] . peer_id , & args [ 1 ] . msg_id , 0 , print_msg_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_send_contact ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 4 ) ;
2015-04-27 06:43:31 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_send_contact ( TLS , args [ 0 ] . peer_id , ARG2STR ( 1 ) , ARG2STR ( 2 ) , ARG2STR ( 3 ) , TGL_SEND_MSG_FLAG_REPLY ( reply_id ) , print_msg_success_gw , ev ) ;
2015-04-27 06:43:31 -04:00
}
2015-05-14 08:48:20 -04:00
void do_reply_contact ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 4 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-09-30 12:49:50 -04:00
tgl_do_reply_contact ( TLS , & args [ 0 ] . msg_id , ARG2STR ( 1 ) , ARG2STR ( 2 ) , ARG2STR ( 3 ) , 0 , print_msg_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_send_location ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 3 ) ;
2015-04-24 07:08:01 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_send_location ( TLS , args [ 0 ] . peer_id , args [ 1 ] . dval , args [ 2 ] . dval , TGL_SEND_MSG_FLAG_REPLY ( reply_id ) , print_msg_success_gw , ev ) ;
2015-04-24 07:08:01 -04:00
}
2015-09-25 13:01:51 -04:00
void do_post_location ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 3 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_send_location ( TLS , args [ 0 ] . peer_id , args [ 1 ] . dval , args [ 2 ] . dval , TGL_SEND_MSG_FLAG_REPLY ( reply_id ) | TGLMF_POST_AS_CHANNEL , print_msg_success_gw , ev ) ;
2015-09-25 13:01:51 -04:00
}
2015-05-14 08:48:20 -04:00
void do_reply_location ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 3 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-09-30 12:49:50 -04:00
tgl_do_reply_location ( TLS , & args [ 0 ] . msg_id , args [ 1 ] . dval , args [ 2 ] . dval , 0 , print_msg_success_gw , ev ) ;
2015-05-14 08:48:20 -04:00
}
void do_broadcast ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num > = 1 & & arg_num < = 1000 ) ;
static tgl_peer_id_t ids [ 1000 ] ;
int i ;
for ( i = 0 ; i < arg_num - 1 ; i + + ) {
2015-10-01 07:11:31 -04:00
ids [ i ] = args [ i ] . peer_id ;
2015-05-14 08:48:20 -04:00
}
if ( ev ) { ev - > refcnt + + ; }
tgl_do_send_broadcast ( TLS , arg_num - 1 , ids , args [ arg_num - 1 ] . str , strlen ( args [ arg_num - 1 ] . str ) , disable_msg_preview , print_msg_list_success_gw , ev ) ;
}
/* }}} */
/* {{{ EDITING SELF PROFILE */
2015-06-07 08:42:17 -04:00
void do_get_self ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
if ( ev ) { ev - > refcnt + + ; }
2015-09-30 12:49:50 -04:00
tgl_do_get_user_info ( TLS , TLS - > our_id , 0 , print_user_info_gw , ev ) ;
2015-06-07 08:42:17 -04:00
}
2015-05-14 08:48:20 -04:00
void do_set_profile_photo ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-11-28 08:16:51 -05:00
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-05-14 08:48:20 -04:00
tgl_do_set_profile_photo ( TLS , args [ 0 ] . str , print_success_gw , ev ) ;
2014-11-28 08:16:51 -05:00
}
2015-05-14 08:48:20 -04:00
void do_set_profile_name ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
if ( ev ) { ev - > refcnt + + ; }
tgl_do_set_profile_name ( TLS , ARG2STR ( 0 ) , ARG2STR ( 1 ) , print_user_gw , ev ) ;
}
void do_set_username ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-11-28 08:16:51 -05:00
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-05-14 08:48:20 -04:00
tgl_do_set_username ( TLS , ARG2STR ( 0 ) , print_user_gw , ev ) ;
}
void do_status_online ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( ! arg_num ) ;
if ( ev ) { ev - > refcnt + + ; }
tgl_do_update_status ( TLS , 1 , print_success_gw , ev ) ;
}
void do_status_offline ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( ! arg_num ) ;
if ( ev ) { ev - > refcnt + + ; }
tgl_do_update_status ( TLS , 0 , print_success_gw , ev ) ;
}
void do_export_card ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( ! arg_num ) ;
if ( ev ) { ev - > refcnt + + ; }
tgl_do_export_card ( TLS , print_card_gw , ev ) ;
}
/* }}} */
/* {{{ WORKING WITH GROUP CHATS */
void do_chat_set_photo ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_set_chat_photo ( TLS , args [ 0 ] . peer_id , args [ 1 ] . str , print_success_gw , ev ) ;
2014-11-28 08:16:51 -05:00
}
2015-05-06 07:39:45 -04:00
void do_rename_chat ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-17 17:03:20 -04:00
assert ( arg_num = = 2 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_rename_chat ( TLS , args [ 0 ] . peer_id , ARG2STR ( 1 ) , print_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_chat_info ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2015-05-01 13:19:12 -04:00
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_get_chat_info ( TLS , args [ 0 ] . peer_id , offline_mode , print_chat_info_gw , ev ) ;
}
void do_channel_info ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
tgl_do_get_channel_info ( TLS , args [ 0 ] . peer_id , offline_mode , print_channel_info_gw , ev ) ;
2015-05-01 13:19:12 -04:00
}
2015-05-14 08:48:20 -04:00
void do_chat_add_user ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 3 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_add_user_to_chat ( TLS , args [ 0 ] . peer_id , args [ 1 ] . peer_id , args [ 2 ] . num ! = NOT_FOUND ? args [ 2 ] . num : 100 , print_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_chat_del_user ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_del_user_from_chat ( TLS , args [ 0 ] . peer_id , args [ 1 ] . peer_id , print_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_create_group_chat ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num > = 1 & & arg_num < = 1000 ) ;
static tgl_peer_id_t ids [ 1000 ] ;
int i ;
for ( i = 0 ; i < arg_num - 1 ; i + + ) {
2015-10-01 07:11:31 -04:00
ids [ i ] = args [ i + 1 ] . peer_id ;
2015-05-14 08:48:20 -04:00
}
2014-09-17 17:03:20 -04:00
2015-05-14 08:48:20 -04:00
if ( ev ) { ev - > refcnt + + ; }
tgl_do_create_group_chat ( TLS , arg_num - 1 , ids , ARG2STR ( 0 ) , print_success_gw , ev ) ;
}
2014-09-17 17:03:20 -04:00
2015-05-14 08:48:20 -04:00
void do_export_chat_link ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
2014-09-20 18:22:35 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_export_chat_link ( TLS , args [ 0 ] . peer_id , print_string_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_import_chat_link ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-17 17:03:20 -04:00
assert ( arg_num = = 1 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-05-14 08:48:20 -04:00
tgl_do_import_chat_link ( TLS , ARG2STR ( 0 ) , print_success_gw , ev ) ;
}
/* }}} */
/* {{{ WORKING WITH USERS */
void do_user_info ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_get_user_info ( TLS , args [ 0 ] . peer_id , offline_mode , print_user_info_gw , ev ) ;
2015-05-14 08:48:20 -04:00
}
void do_add_contact ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 3 ) ;
if ( ev ) { ev - > refcnt + + ; }
tgl_do_add_contact ( TLS , ARG2STR ( 0 ) , ARG2STR ( 1 ) , ARG2STR ( 2 ) , 0 , print_user_list_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-06 07:39:45 -04:00
void do_rename_contact ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-17 17:03:20 -04:00
assert ( arg_num = = 3 ) ;
2015-10-01 07:11:31 -04:00
tgl_peer_t * P = tgl_peer_get ( TLS , args [ 0 ] . peer_id ) ;
if ( P & & P - > user . phone ) {
2014-09-20 18:22:35 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_add_contact ( TLS , P - > user . phone , strlen ( P - > user . phone ) , args [ 1 ] . str , strlen ( args [ 1 ] . str ) , args [ 2 ] . str , strlen ( args [ 2 ] . str ) , 0 , print_user_list_gw , ev ) ;
2014-10-24 13:43:08 -04:00
} else {
if ( ev ) { ev - > refcnt + + ; }
print_success_gw ( TLS , ev , 0 ) ;
2014-09-17 17:03:20 -04:00
}
}
2015-05-14 08:48:20 -04:00
void do_del_contact ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_del_contact ( TLS , args [ 0 ] . peer_id , print_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_import_card ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
char * s = args [ 0 ] . str ;
int l = strlen ( s ) ;
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 ;
if ( ev ) { ev - > refcnt + + ; }
tgl_do_import_card ( TLS , pp , p , print_user_gw , ev ) ;
}
2014-09-18 11:14:24 -04:00
}
2014-09-17 17:03:20 -04:00
}
2015-05-27 10:16:42 -04:00
void do_block_user ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_block_user ( TLS , args [ 0 ] . peer_id , print_success_gw , ev ) ;
2015-05-27 10:16:42 -04:00
}
void do_unblock_user ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_unblock_user ( TLS , args [ 0 ] . peer_id , print_success_gw , ev ) ;
2015-05-27 10:16:42 -04:00
}
2015-05-14 08:48:20 -04:00
/* }}} */
/* {{{ WORKING WITH SECRET CHATS */
void do_accept_secret_chat ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-17 17:03:20 -04:00
assert ( arg_num = = 1 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_peer_t * P = tgl_peer_get ( TLS , args [ 0 ] . peer_id ) ;
if ( P ) {
tgl_do_accept_encr_chat_request ( TLS , & P - > encr_chat , print_encr_chat_success_gw , ev ) ;
} else {
print_success_gw ( TLS , ev , 0 ) ;
}
2015-05-14 08:48:20 -04:00
}
void do_set_ttl ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 2 ) ;
2015-10-01 07:11:31 -04:00
if ( ev ) { ev - > refcnt + + ; }
tgl_peer_t * P = tgl_peer_get ( TLS , args [ 0 ] . peer_id ) ;
if ( P & & P - > encr_chat . state = = sc_ok ) {
tgl_do_set_encr_chat_ttl ( TLS , & P - > encr_chat , args [ 1 ] . num , print_msg_success_gw , ev ) ;
2015-05-14 08:48:20 -04:00
} else {
print_success_gw ( TLS , ev , 0 ) ;
}
2014-09-17 17:03:20 -04:00
}
2015-05-06 07:39:45 -04:00
void do_visualize_key ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-17 17:03:20 -04:00
assert ( arg_num = = 1 ) ;
static char * colors [ 4 ] = { COLOR_GREY , COLOR_CYAN , COLOR_BLUE , COLOR_GREEN } ;
static unsigned char buf [ 16 ] ;
memset ( buf , 0 , sizeof ( buf ) ) ;
2015-10-01 07:11:31 -04:00
tgl_do_visualize_key ( TLS , args [ 0 ] . peer_id , buf ) ;
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2014-09-17 17:03:20 -04:00
int i ;
for ( i = 0 ; i < 16 ; i + + ) {
int x = buf [ i ] ;
int j ;
for ( j = 0 ; j < 4 ; j + + ) {
2014-09-20 18:22:35 -04:00
if ( ! ev ) {
mpush_color ( ev , colors [ x & 3 ] ) ;
mpush_color ( ev , COLOR_INVERSE ) ;
2015-05-14 08:48:20 -04:00
}
if ( ! disable_colors & & ! ev ) {
mprintf ( ev , " " ) ;
} else {
switch ( x & 3 ) {
case 0 :
mprintf ( ev , " " ) ;
break ;
case 1 :
mprintf ( ev , " -- " ) ;
break ;
case 2 :
mprintf ( ev , " == " ) ;
break ;
case 3 :
mprintf ( ev , " || " ) ;
break ;
}
}
if ( ! ev ) {
mpop_color ( ev ) ;
mpop_color ( ev ) ;
}
x = x > > 2 ;
}
if ( i & 1 ) {
mprintf ( ev , " \n " ) ;
}
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
mprint_end ( ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_create_secret_chat ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_create_secret_chat ( TLS , args [ 0 ] . peer_id , print_secret_chat_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
/* }}} */
2014-09-17 17:03:20 -04:00
2015-05-14 08:48:20 -04:00
/* {{{ WORKING WITH DIALOG LIST */
void do_dialog_list ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num < = 2 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-05-14 08:48:20 -04:00
tgl_do_get_dialog_list ( TLS , args [ 0 ] . num ! = NOT_FOUND ? args [ 0 ] . num : 100 , args [ 1 ] . num ! = NOT_FOUND ? args [ 1 ] . num : 0 , print_dialog_list_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-09-25 11:28:23 -04:00
void do_channel_list ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num < = 2 ) ;
if ( ev ) { ev - > refcnt + + ; }
tgl_do_get_channels_dialog_list ( TLS , args [ 0 ] . num ! = NOT_FOUND ? args [ 0 ] . num : 100 , args [ 1 ] . num ! = NOT_FOUND ? args [ 1 ] . num : 0 , print_dialog_list_gw , ev ) ;
}
2015-06-18 08:54:55 -04:00
void do_resolve_username ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 1 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-09-30 12:49:50 -04:00
tgl_do_contact_search ( TLS , args [ 0 ] . str , strlen ( args [ 0 ] . str ) , print_peer_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_contact_list ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( ! arg_num ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-05-14 08:48:20 -04:00
tgl_do_update_contact_list ( TLS , print_user_list_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
/* }}} */
2014-10-09 13:38:45 -04:00
2015-05-14 08:48:20 -04:00
/* {{{ WORKING WITH ONE DIALOG */
2014-10-12 11:53:57 -04:00
2015-05-14 08:48:20 -04:00
void do_mark_read ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2015-04-30 06:00:16 -04:00
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_mark_read ( TLS , args [ 0 ] . peer_id , print_success_gw , ev ) ;
2015-04-30 06:00:16 -04:00
}
2015-05-14 08:48:20 -04:00
void do_history ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 3 ) ;
2015-04-30 06:00:16 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_get_history ( TLS , args [ 0 ] . peer_id , args [ 2 ] . num ! = NOT_FOUND ? args [ 2 ] . num : 0 , args [ 1 ] . num ! = NOT_FOUND ? args [ 1 ] . num : 40 , offline_mode , print_msg_list_history_gw , ev ) ;
2015-04-30 06:00:16 -04:00
}
2015-05-20 14:21:12 -04:00
void print_fail ( struct in_ev * ev ) ;
2015-05-14 08:48:20 -04:00
void do_send_typing ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2015-05-20 13:39:33 -04:00
assert ( arg_num = = 2 ) ;
enum tgl_typing_status status = tgl_typing_typing ; //de
2015-05-20 14:21:12 -04:00
if ( args [ 1 ] . num ! = NOT_FOUND ) {
if ( args [ 1 ] . num > 0 & & args [ 1 ] . num > 10 ) {
2015-05-27 10:42:08 -04:00
fail_interface ( TLS , ev , ENOSYS , " illegal typing status " ) ;
2015-05-20 14:21:12 -04:00
return ;
}
2015-05-20 14:24:19 -04:00
status = ( enum tgl_typing_status ) args [ 1 ] . num ; // if the status parameter is given, and is in range.
2015-05-20 13:39:33 -04:00
}
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_send_typing ( TLS , args [ 0 ] . peer_id , status , print_success_gw , ev ) ;
2014-10-12 11:53:57 -04:00
}
2015-05-14 08:48:20 -04:00
void do_send_typing_abort ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-17 17:03:20 -04:00
assert ( arg_num = = 1 ) ;
2014-10-24 13:43:08 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_send_typing ( TLS , args [ 0 ] . peer_id , tgl_typing_cancel , print_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
/* }}} */
/* {{{ WORKING WITH MEDIA */
# define DO_LOAD_PHOTO(tp,act,actf) \
void do_ # # act # # _ # # tp ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) { \
assert ( arg_num = = 1 ) ; \
2015-09-30 12:49:50 -04:00
struct tgl_message * M = tgl_message_get ( TLS , & args [ 0 ] . msg_id ) ; \
2015-05-14 08:48:20 -04:00
if ( M & & ! ( M - > flags & TGLMF_SERVICE ) ) { \
if ( ev ) { ev - > refcnt + + ; } \
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 ) ; \
2015-10-01 13:39:29 -04:00
} else if ( M - > media . type = = tgl_message_media_video ) { \
tgl_do_load_video ( TLS , M - > media . document , actf , ev ) ; \
} else if ( M - > media . type = = tgl_message_media_audio ) { \
tgl_do_load_audio ( TLS , M - > media . document , actf , ev ) ; \
2015-05-14 08:48:20 -04:00
} else if ( M - > media . type = = tgl_message_media_document_encr ) { \
tgl_do_load_encr_document ( TLS , M - > media . encr_document , actf , ev ) ; \
} else if ( M - > media . type = = tgl_message_media_webpage ) { \
actf ( TLS , ev , 1 , M - > media . webpage - > url ) ; \
} else if ( M - > media . type = = tgl_message_media_geo | | M - > media . type = = tgl_message_media_venue ) { \
static char s [ 1000 ] ; \
sprintf ( s , " https://maps.google.com/?q=%.6lf,%.6lf " , M - > media . geo . latitude , M - > media . geo . longitude ) ; \
actf ( TLS , ev , 1 , s ) ; \
} \
} \
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
# define DO_LOAD_PHOTO_THUMB(tp,act,actf) \
void do_ # # act # # _ # # tp # # _thumb ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) { \
assert ( arg_num = = 1 ) ; \
2015-09-30 12:49:50 -04:00
struct tgl_message * M = tgl_message_get ( TLS , & args [ 0 ] . msg_id ) ; \
2015-05-14 08:48:20 -04:00
if ( M & & ! ( M - > flags & TGLMF_SERVICE ) ) { \
if ( M - > media . type = = tgl_message_media_document ) { \
if ( ev ) { ev - > refcnt + + ; } \
tgl_do_load_document_thumb ( TLS , M - > media . document , actf , ev ) ; \
} \
} \
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
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 )
DO_LOAD_PHOTO ( any , open , open_filename_gw )
void do_load_user_photo ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2015-05-01 13:19:12 -04:00
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_peer_t * P = tgl_peer_get ( TLS , args [ 0 ] . peer_id ) ;
if ( P ) {
tgl_do_load_file_location ( TLS , & P - > user . photo_big , print_filename_gw , ev ) ;
} else {
print_filename_gw ( TLS , ev , 0 , NULL ) ;
}
2015-05-01 13:19:12 -04:00
}
2015-05-14 08:48:20 -04:00
void do_view_user_photo ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-17 17:03:20 -04:00
assert ( arg_num = = 1 ) ;
2014-09-20 18:22:35 -04:00
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_peer_t * P = tgl_peer_get ( TLS , args [ 0 ] . peer_id ) ;
if ( P ) {
tgl_do_load_file_location ( TLS , & P - > user . photo_big , print_filename_gw , ev ) ;
} else {
open_filename_gw ( TLS , ev , 0 , NULL ) ;
}
2015-04-27 10:52:19 -04:00
}
2015-05-14 08:48:20 -04:00
/* }}} */
2014-09-20 18:22:35 -04:00
2015-05-14 08:48:20 -04:00
/* {{{ ANOTHER MESSAGES FUNCTIONS */
void do_search ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 6 ) ;
int limit ;
if ( args [ 1 ] . num ! = NOT_FOUND ) {
limit = args [ 1 ] . num ;
} else {
limit = 40 ;
}
int from ;
if ( args [ 2 ] . num ! = NOT_FOUND ) {
from = args [ 2 ] . num ;
} else {
from = 0 ;
}
int to ;
if ( args [ 3 ] . num ! = NOT_FOUND ) {
to = args [ 3 ] . num ;
} else {
to = 0 ;
}
int offset ;
if ( args [ 4 ] . num ! = NOT_FOUND ) {
offset = args [ 4 ] . num ;
} else {
offset = 0 ;
2014-09-20 18:22:35 -04:00
}
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_msg_search ( TLS , args [ 0 ] . peer_id , from , to , limit , offset , args [ 5 ] . str , strlen ( args [ 5 ] . str ) , print_msg_list_gw , ev ) ;
2014-11-28 08:16:51 -05:00
}
2015-05-14 08:48:20 -04:00
void do_delete_msg ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-11-28 08:16:51 -05:00
if ( ev ) { ev - > refcnt + + ; }
2015-09-30 12:49:50 -04:00
tgl_do_delete_msg ( TLS , & args [ 0 ] . msg_id , print_success_gw , ev ) ;
2014-09-17 17:03:20 -04:00
}
2015-05-14 08:48:20 -04:00
void do_get_message ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2015-01-11 16:52:40 -05:00
assert ( arg_num = = 1 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-09-30 12:49:50 -04:00
tgl_do_get_message ( TLS , & args [ 0 ] . msg_id , print_msg_gw , ev ) ;
2015-01-11 16:52:40 -05:00
}
2015-05-14 08:48:20 -04:00
/* }}} */
2015-06-24 13:46:12 -04:00
/* {{{ BOT */
void do_start_bot ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
assert ( arg_num = = 3 ) ;
if ( ev ) { ev - > refcnt + + ; }
2015-10-01 07:11:31 -04:00
tgl_do_start_bot ( TLS , args [ 0 ] . peer_id , args [ 1 ] . peer_id , ARG2STR ( 2 ) , print_success_gw , ev ) ;
2015-06-24 13:46:12 -04:00
}
/* }}} */
2014-09-23 08:58:49 -04:00
extern char * default_username ;
extern char * config_filename ;
extern char * prefix ;
extern char * auth_file_name ;
extern char * state_file_name ;
extern char * secret_chat_file_name ;
extern char * downloads_directory ;
extern char * config_directory ;
extern char * binlog_file_name ;
extern char * lua_file ;
2015-05-02 07:49:21 -04:00
extern char * python_file ;
2014-09-23 09:18:42 -04:00
extern struct event * term_ev ;
2014-09-23 08:58:49 -04:00
2015-05-06 07:39:45 -04:00
void do_clear ( struct command * command , int arg_num , struct arg args [ ] , struct in_ev * ev ) {
2014-09-23 10:39:28 -04:00
logprintf ( " Do_clear \n " ) ;
2014-09-23 08:58:49 -04:00
free ( default_username ) ;
free ( config_filename ) ;
2015-04-24 11:48:54 -04:00
//free (prefix);
2014-09-23 08:58:49 -04:00
free ( auth_file_name ) ;
free ( state_file_name ) ;
free ( secret_chat_file_name ) ;
free ( downloads_directory ) ;
free ( config_directory ) ;
free ( binlog_file_name ) ;
free ( lua_file ) ;
2015-05-02 07:49:21 -04:00
free ( python_file ) ;
2014-09-23 09:18:42 -04:00
clear_history ( ) ;
event_free ( term_ev ) ;
2015-04-24 11:48:54 -04:00
struct event_base * ev_base = TLS - > ev_base ;
2014-11-11 12:13:41 -05:00
tgl_free_all ( TLS ) ;
2015-04-24 11:48:54 -04:00
event_base_free ( ev_base ) ;
2014-09-23 08:58:49 -04:00
do_halt ( 0 ) ;
}
2015-05-06 07:39:45 -04:00
# define MAX_COMMANDS_SIZE 1000
struct command commands [ MAX_COMMANDS_SIZE ] = {
{ " accept_secret_chat " , { ca_secret_chat , ca_none } , do_accept_secret_chat , " accept_secret_chat <secret chat> \t Accepts secret chat. Only useful with -E option " , NULL } ,
{ " add_contact " , { ca_string , ca_string , ca_string , ca_none } , do_add_contact , " add_contact <phone> <first name> <last name> \t Tries to add user to contact list " , NULL } ,
2015-05-27 10:16:42 -04:00
{ " block_user " , { ca_user , ca_none } , do_block_user , " block_user <user> \t Blocks user " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " broadcast " , { ca_user , ca_period , ca_string_end , ca_none } , do_broadcast , " broadcast <user>+ <text> \t Sends text to several users at once " , NULL } ,
2015-10-01 07:11:31 -04:00
{ " channel_info " , { ca_channel , ca_none } , do_channel_info , " channel_info <channel> \t Prints info about channel (id, members, admin, etc.) " , NULL } ,
2015-09-25 11:28:23 -04:00
{ " channel_list " , { ca_number | ca_optional , ca_number | ca_optional , ca_none } , do_channel_list , " channel_list [limit=100] [offset=0] \t List of last channels " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " chat_add_user " , { ca_chat , ca_user , ca_number | ca_optional , ca_none } , do_chat_add_user , " chat_add_user <chat> <user> [msgs-to-forward] \t Adds user to chat. Sends him last msgs-to-forward message from this chat. Default 100 " , NULL } ,
{ " chat_del_user " , { ca_chat , ca_user , ca_none } , do_chat_del_user , " chat_del_user <chat> <user> \t Deletes user from chat " , NULL } ,
{ " chat_info " , { ca_chat , ca_none } , do_chat_info , " chat_info <chat> \t Prints info about chat (id, members, admin, etc.) " , NULL } ,
{ " chat_set_photo " , { ca_chat , ca_file_name_end , ca_none } , do_chat_set_photo , " chat_set_photo <chat> <filename> \t Sets chat photo. Photo will be cropped to square " , NULL } ,
{ " chat_with_peer " , { ca_peer , ca_none } , do_chat_with_peer , " chat_with_peer <peer> \t Interface option. All input will be treated as messages to this peer. Type /quit to end this mode " , NULL } ,
{ " clear " , { ca_none } , do_clear , " clear \t Clears all data and exits. For debug. " , NULL } ,
{ " contact_list " , { ca_none } , do_contact_list , " contact_list \t Prints contact list " , NULL } ,
2015-06-18 08:54:55 -04:00
{ " contact_search " , { ca_string , ca_none } , do_resolve_username , " contact_search username \t Searches user by username " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " create_group_chat " , { ca_string , ca_user , ca_period , ca_none } , do_create_group_chat , " create_group_chat <name> <user>+ \t Creates group chat with users " , NULL } ,
{ " create_secret_chat " , { ca_user , ca_none } , do_create_secret_chat , " create_secret_chat <user> \t Starts creation of secret chat " , NULL } ,
{ " del_contact " , { ca_user , ca_none } , do_del_contact , " del_contact <user> \t Deletes contact from contact list " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " delete_msg " , { ca_msg_id , ca_none } , do_delete_msg , " delete_msg <msg-id> \t Deletes message " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " dialog_list " , { ca_number | ca_optional , ca_number | ca_optional , ca_none } , do_dialog_list , " dialog_list [limit=100] [offset=0] \t List of last conversations " , NULL } ,
{ " export_card " , { ca_none } , do_export_card , " export_card \t Prints card that can be imported by another user with import_card method " , NULL } ,
{ " export_chat_link " , { ca_chat , ca_none } , do_export_chat_link , " export_chat_link \t Prints chat link that can be used to join to chat " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " fwd " , { ca_peer , ca_msg_id , ca_period , ca_none } , do_fwd , " fwd <peer> <msg-id>+ \t Forwards message to peer. Forward to secret chats is forbidden " , NULL } ,
{ " fwd_media " , { ca_peer , ca_msg_id , ca_none } , do_fwd_media , " fwd_media <peer> <msg-id> \t Forwards message media to peer. Forward to secret chats is forbidden. Result slightly differs from fwd " , NULL } ,
{ " get_message " , { ca_msg_id , ca_none } , do_get_message , " get_message <msg-id> \t Get message by id " , NULL } ,
2015-06-07 08:42:17 -04:00
{ " get_self " , { ca_none } , do_get_self , " get_self \t Get our user info " , NULL } ,
2015-10-01 07:11:31 -04:00
{ " help " , { ca_command | ca_optional , ca_none } , do_help , " help [command] \t Prints this help " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " history " , { ca_peer , ca_number | ca_optional , ca_number | ca_optional , ca_none } , do_history , " history <peer> [limit] [offset] \t Prints messages with this peer (most recent message lower). Also marks messages as read " , NULL } ,
{ " import_card " , { ca_string , ca_none } , do_import_card , " import_card <card> \t Gets user by card and prints it name. You can then send messages to him as usual " , NULL } ,
2015-05-21 12:30:51 -04:00
{ " import_chat_link " , { ca_string , ca_none } , do_import_chat_link , " import_chat_link <hash> \t Joins to chat by link " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " load_audio " , { ca_msg_id , ca_none } , do_load_audio , " load_audio <msg-id> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " load_chat_photo " , { ca_chat , ca_none } , do_load_user_photo , " load_chat_photo <chat> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " load_document " , { ca_msg_id , ca_none } , do_load_document , " load_document <msg-id> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
{ " load_document_thumb " , { ca_msg_id , ca_none } , do_load_document_thumb , " load_document_thumb <msg-id> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
{ " load_file " , { ca_msg_id , ca_none } , do_load_file , " load_file <msg-id> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
{ " load_file_thumb " , { ca_msg_id , ca_none } , do_load_file_thumb , " load_file_thumb <msg-id> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
{ " load_photo " , { ca_msg_id , ca_none } , do_load_photo , " load_photo <msg-id> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " load_user_photo " , { ca_user , ca_none } , do_load_user_photo , " load_user_photo <user> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " load_video " , { ca_msg_id , ca_none } , do_load_video , " load_video <msg-id> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
{ " load_video_thumb " , { ca_msg_id , ca_none } , do_load_video_thumb , " load_video_thumb <msg-id> \t Downloads file to downloads dirs. Prints file name after download end " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " main_session " , { ca_none } , do_main_session , " main_session \t Sends updates to this connection (or terminal). Useful only with listening socket " , NULL } ,
{ " mark_read " , { ca_peer , ca_none } , do_mark_read , " mark_read <peer> \t Marks messages with peer as read " , NULL } ,
2015-06-17 05:05:57 -04:00
{ " msg " , { ca_peer , ca_msg_string_end , ca_none } , do_msg , " msg <peer> <text> \t Sends text message to peer " , NULL } ,
2015-06-17 09:48:44 -04:00
{ " msg_kbd " , { ca_peer , ca_string , ca_msg_string_end , ca_none } , do_msg_kbd , " msg <peer> <kbd> <text> \t Sends text message to peer with custom kbd " , NULL } ,
2015-09-25 11:28:23 -04:00
{ " post " , { ca_peer , ca_msg_string_end , ca_none } , do_post , " post <peer> <text> \t Sends text message to peer as admin " , NULL } ,
2015-09-25 13:01:51 -04:00
{ " post_audio " , { ca_peer , ca_file_name , ca_none } , do_post_audio , " post_audio <peer> <file> \t Posts audio to peer " , NULL } ,
{ " post_document " , { ca_peer , ca_file_name , ca_none } , do_post_document , " post_document <peer> <file> \t Posts document to peer " , NULL } ,
{ " post_file " , { ca_peer , ca_file_name , ca_none } , do_post_file , " post_file <peer> <file> \t Sends document to peer " , NULL } ,
{ " post_location " , { ca_peer , ca_double , ca_double , ca_none } , do_post_location , " post_location <peer> <latitude> <longitude> \t Sends geo location " , NULL } ,
{ " post_photo " , { ca_peer , ca_file_name , ca_string_end | ca_optional , ca_none } , do_post_photo , " post_photo <peer> <file> [caption] \t Sends photo to peer " , NULL } ,
{ " post_text " , { ca_peer , ca_file_name_end , ca_none } , do_post_text , " post_text <peer> <file> \t Sends contents of text file as plain text message " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " post_video " , { ca_peer , ca_file_name , ca_string_end | ca_optional , ca_none } , do_post_video , " post_video <peer> <file> [caption] \t Sends video to peer " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " quit " , { ca_none } , do_quit , " quit \t Quits immediately " , NULL } ,
{ " rename_chat " , { ca_chat , ca_string_end , ca_none } , do_rename_chat , " rename_chat <chat> <new name> \t Renames chat " , NULL } ,
{ " rename_contact " , { ca_user , ca_string , ca_string , ca_none } , do_rename_contact , " rename_contact <user> <first name> <last name> \t Renames contact " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " reply " , { ca_msg_id , ca_msg_string_end , ca_none } , do_reply , " reply <msg-id> <text> \t Sends text reply to message " , NULL } ,
{ " reply_audio " , { ca_msg_id , ca_file_name , ca_none } , do_send_audio , " reply_audio <msg-id> <file> \t Sends audio to peer " , NULL } ,
{ " reply_contact " , { ca_msg_id , ca_string , ca_string , ca_string , ca_none } , do_reply_contact , " reply_contact <msg-id> <phone> <first-name> <last-name> \t Sends contact (not necessary telegram user) " , NULL } ,
{ " reply_document " , { ca_msg_id , ca_file_name , ca_none } , do_reply_document , " reply_document <msg-id> <file> \t Sends document to peer " , NULL } ,
{ " reply_file " , { ca_msg_id , ca_file_name , ca_none } , do_reply_file , " reply_file <msg-id> <file> \t Sends document to peer " , NULL } ,
{ " reply_location " , { ca_msg_id , ca_double , ca_double , ca_none } , do_reply_location , " reply_location <msg-id> <latitude> <longitude> \t Sends geo location " , NULL } ,
{ " reply_photo " , { ca_msg_id , ca_file_name , ca_string_end | ca_optional , ca_none } , do_reply_photo , " reply_photo <msg-id> <file> [caption] \t Sends photo to peer " , NULL } ,
2015-05-06 07:39:45 -04:00
//{"reply_text", {ca_number, ca_file_name_end, ca_none}, do_reply_text, "reply_text <msg-id> <file>\tSends contents of text file as plain text message", NULL},
2015-09-30 12:49:50 -04:00
{ " reply_video " , { ca_msg_id , ca_file_name , ca_none } , do_reply_video , " reply_video <msg-id> <file> \t Sends video to peer " , NULL } ,
2015-06-18 08:54:55 -04:00
{ " resolve_username " , { ca_string , ca_none } , do_resolve_username , " resolve_username username \t Searches user by username " , NULL } ,
2015-05-20 14:24:19 -04:00
//{"restore_msg", {ca_number, ca_none}, do_restore_msg, "restore_msg <msg-id>\tRestores message. Only available shortly (one hour?) after deletion", NULL},
2015-05-06 07:39:45 -04:00
{ " safe_quit " , { ca_none } , do_safe_quit , " safe_quit \t Waits for all queries to end, then quits " , NULL } ,
{ " search " , { ca_peer | ca_optional , ca_number | ca_optional , ca_number | ca_optional , ca_number | ca_optional , ca_number | ca_optional , ca_string_end } , do_search , " search [peer] [limit] [from] [to] [offset] pattern \t Search for pattern in messages from date from to date to (unixtime) in messages with peer (if peer not present, in all messages) " , NULL } ,
2015-05-14 08:48:20 -04:00
//{"secret_chat_rekey", { ca_secret_chat, ca_none}, do_secret_chat_rekey, "generate new key for active secret chat", NULL},
2015-05-06 07:39:45 -04:00
{ " send_audio " , { ca_peer , ca_file_name , ca_none } , do_send_audio , " send_audio <peer> <file> \t Sends audio to peer " , NULL } ,
{ " send_contact " , { ca_peer , ca_string , ca_string , ca_string , ca_none } , do_send_contact , " send_contact <peer> <phone> <first-name> <last-name> \t Sends contact (not necessary telegram user) " , NULL } ,
{ " send_document " , { ca_peer , ca_file_name , ca_none } , do_send_document , " send_document <peer> <file> \t Sends document to peer " , NULL } ,
{ " send_file " , { ca_peer , ca_file_name , ca_none } , do_send_file , " send_file <peer> <file> \t Sends document to peer " , NULL } ,
{ " send_location " , { ca_peer , ca_double , ca_double , ca_none } , do_send_location , " send_location <peer> <latitude> <longitude> \t Sends geo location " , NULL } ,
{ " send_photo " , { ca_peer , ca_file_name , ca_string_end | ca_optional , ca_none } , do_send_photo , " send_photo <peer> <file> [caption] \t Sends photo to peer " , NULL } ,
{ " send_text " , { ca_peer , ca_file_name_end , ca_none } , do_send_text , " send_text <peer> <file> \t Sends contents of text file as plain text message " , NULL } ,
2015-05-20 13:39:33 -04:00
{ " send_typing " , { ca_peer , ca_number | ca_optional , ca_none } , do_send_typing , " send_typing <peer> [status] \t Sends typing notification. You can supply a custom status (range 0-10): none, typing, cancel, record video, upload video, record audio, upload audio, upload photo, upload document, geo, choose contact. " , NULL } ,
2015-05-20 14:24:19 -04:00
{ " send_typing_abort " , { ca_peer , ca_none } , do_send_typing_abort , " send_typing_abort <peer> \t Sends typing notification abort " , NULL } ,
2015-05-21 10:42:51 -04:00
{ " send_video " , { ca_peer , ca_file_name , ca_string_end | ca_optional , ca_none } , do_send_video , " send_video <peer> <file> [caption] \t Sends video to peer " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " set " , { ca_string , ca_number , ca_none } , do_set , " set <param> <value> \t Sets value of param. Currently available: log_level, debug_verbosity, alarm, msg_num " , NULL } ,
{ " set_password " , { ca_string | ca_optional , ca_none } , do_set_password , " set_password <hint> \t Sets password " , NULL } ,
{ " set_profile_name " , { ca_string , ca_string , ca_none } , do_set_profile_name , " set_profile_name <first-name> <last-name> \t Sets profile name. " , NULL } ,
{ " set_profile_photo " , { ca_file_name_end , ca_none } , do_set_profile_photo , " set_profile_photo <filename> \t Sets profile photo. Photo will be cropped to square " , NULL } ,
{ " set_ttl " , { ca_secret_chat , ca_number , ca_none } , do_set_ttl , " set_ttl <secret chat> \t Sets secret chat ttl. Client itself ignores ttl " , NULL } ,
{ " set_username " , { ca_string , ca_none } , do_set_username , " set_username <name> \t Sets username. " , NULL } ,
{ " show_license " , { ca_none } , do_show_license , " show_license \t Prints contents of GPL license " , NULL } ,
2015-06-24 13:46:12 -04:00
{ " start_bot " , { ca_user , ca_chat , ca_string , ca_none } , do_start_bot , " start_bot <bot> <chat> <data> \t Adds bot to chat " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " stats " , { ca_none } , do_stats , " stats \t For debug purpose " , NULL } ,
{ " status_online " , { ca_none } , do_status_online , " status_online \t Sets status as online " , NULL } ,
{ " status_offline " , { ca_none } , do_status_offline , " status_offline \t Sets status as offline " , NULL } ,
2015-05-27 10:16:42 -04:00
{ " unblock_user " , { ca_user , ca_none } , do_unblock_user , " unblock_user <user> \t Unblocks user " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " user_info " , { ca_user , ca_none } , do_user_info , " user_info <user> \t Prints info about user (id, last online, phone) " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " view_audio " , { ca_msg_id , ca_none } , do_open_audio , " view_audio <msg-id> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " view_chat_photo " , { ca_chat , ca_none } , do_view_user_photo , " view_chat_photo <chat> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " view_document " , { ca_msg_id , ca_none } , do_open_document , " view_document <msg-id> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
{ " view_document_thumb " , { ca_msg_id , ca_none } , do_open_document_thumb , " view_document_thumb <msg-id> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
{ " view_file " , { ca_msg_id , ca_none } , do_open_file , " view_file <msg-id> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
{ " view_file_thumb " , { ca_msg_id , ca_none } , do_open_file_thumb , " view_file_thumb <msg-id> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
2015-10-01 08:54:01 -04:00
{ " view_photo " , { ca_msg_id , ca_none } , do_open_photo , " view_photo <msg-id> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
2015-05-06 07:39:45 -04:00
{ " view_user_photo " , { ca_user , ca_none } , do_view_user_photo , " view_user_photo <user> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
2015-09-30 12:49:50 -04:00
{ " view_video " , { ca_msg_id , ca_none } , do_open_video , " view_video <msg-id> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
{ " view_video_thumb " , { ca_msg_id , ca_none } , do_open_video_thumb , " view_video_thumb <msg-id> \t Downloads file to downloads dirs. Then tries to open it with system default action " , NULL } ,
{ " view " , { ca_msg_id , ca_none } , do_open_any , " view <msg-id> \t Tries to view message contents " , NULL } ,
2015-10-01 07:11:31 -04:00
{ " visualize_key " , { ca_secret_chat , ca_none } , do_visualize_key , " visualize_key <secret chat> \t Prints visualization of encryption key (first 16 bytes sha1 of it in fact) " , NULL }
2014-08-25 12:17:17 -04:00
} ;
2013-11-30 13:52:13 -05:00
2015-05-06 07:39:45 -04:00
void register_new_command ( struct command * cmd ) {
int i = 0 ;
while ( commands [ i ] . name ) {
i + + ;
}
assert ( i < MAX_COMMANDS_SIZE - 1 ) ;
commands [ i ] = * cmd ;
}
2013-11-30 13:52:13 -05:00
2015-06-17 05:05:57 -04:00
tgl_peer_t * autocomplete_peer ;
2015-09-30 12:49:50 -04:00
tgl_message_id_t autocomplete_id ;
2015-06-17 05:05:57 -04:00
2014-08-25 12:17:17 -04:00
enum command_argument get_complete_mode ( void ) {
2014-09-17 17:03:20 -04:00
force_end_mode = 0 ;
2013-10-29 20:08:30 -04:00
line_ptr = rl_line_buffer ;
2015-06-17 05:05:57 -04:00
autocomplete_peer = NULL ;
2015-09-30 12:49:50 -04:00
autocomplete_id . peer_type = NOT_FOUND ;
2014-09-17 17:03:20 -04:00
while ( 1 ) {
next_token ( ) ;
if ( cur_token_quoted ) { return ca_none ; }
if ( cur_token_len < = 0 ) { return ca_command ; }
if ( * cur_token = = ' [ ' ) {
if ( cur_token_end_str ) {
return ca_modifier ;
}
if ( cur_token [ cur_token_len - 1 ] ! = ' ] ' ) {
return ca_none ;
}
continue ;
}
break ;
2013-11-30 13:52:13 -05:00
}
2014-09-17 17:03:20 -04:00
if ( cur_token_quoted ) { return ca_none ; }
if ( cur_token_end_str ) { return ca_command ; }
if ( * cur_token = = ' ( ' ) { return ca_extf ; }
2014-08-25 12:17:17 -04:00
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 ) {
2014-09-17 17:03:20 -04:00
if ( is_same_word ( cur_token , cur_token_len , command - > name ) ) {
2013-10-03 08:38:25 -04:00
break ;
}
n + + ;
command + + ;
}
2014-09-17 17:03:20 -04:00
if ( ! command - > name ) {
return ca_none ;
}
2014-08-25 12:17:17 -04:00
enum command_argument * flags = command - > args ;
2013-10-03 08:38:25 -04:00
while ( 1 ) {
2014-11-28 08:16:51 -05:00
int period = 0 ;
2014-09-17 17:03:20 -04:00
if ( * flags = = ca_period ) {
flags - - ;
2014-11-28 08:16:51 -05:00
period = 1 ;
2014-08-25 12:17:17 -04:00
}
2014-09-17 17:03:20 -04:00
enum command_argument op = ( * flags ) & 255 ;
int opt = ( * flags ) & ca_optional ;
if ( op = = ca_none ) { return ca_none ; }
2015-06-17 05:05:57 -04:00
if ( op = = ca_string_end | | op = = ca_file_name_end | | op = = ca_msg_string_end ) {
next_token_end_ac ( ) ;
2014-09-17 17:03:20 -04:00
if ( cur_token_len < 0 | | ! cur_token_end_str ) {
return ca_none ;
} else {
return op ;
}
2014-08-25 12:17:17 -04:00
}
2014-09-17 17:03:20 -04:00
char * save = line_ptr ;
next_token ( ) ;
2015-10-01 07:11:31 -04:00
if ( op = = ca_user | | op = = ca_chat | | op = = ca_secret_chat | | op = = ca_peer | | op = = ca_number | | op = = ca_double | | op = = ca_msg_id | | op = = ca_command | | op = = ca_channel ) {
2014-09-17 17:03:20 -04:00
if ( cur_token_quoted ) {
if ( opt ) {
line_ptr = save ;
flags + + ;
continue ;
2014-11-28 08:16:51 -05:00
} else if ( period ) {
line_ptr = save ;
flags + = 2 ;
continue ;
2014-09-17 17:03:20 -04:00
} else {
return ca_none ;
}
} else {
if ( cur_token_end_str ) { return op ; }
int ok = 1 ;
switch ( op ) {
case ca_user :
ok = ( tgl_get_peer_type ( cur_token_user ( ) ) ! = NOT_FOUND ) ;
break ;
case ca_chat :
ok = ( tgl_get_peer_type ( cur_token_chat ( ) ) ! = NOT_FOUND ) ;
break ;
case ca_secret_chat :
ok = ( tgl_get_peer_type ( cur_token_encr_chat ( ) ) ! = NOT_FOUND ) ;
break ;
2015-10-01 07:11:31 -04:00
case ca_channel :
ok = ( tgl_get_peer_type ( cur_token_channel ( ) ) ! = NOT_FOUND ) ;
break ;
2014-09-17 17:03:20 -04:00
case ca_peer :
2015-06-17 05:05:57 -04:00
ok = ( tgl_get_peer_type ( cur_token_peer ( ) ) ! = NOT_FOUND ) ;
if ( ok ) {
autocomplete_peer = tgl_peer_get ( TLS , cur_token_peer ( ) ) ;
2015-09-30 12:49:50 -04:00
autocomplete_id . peer_type = NOT_FOUND ;
2015-06-17 05:05:57 -04:00
}
2014-09-17 17:03:20 -04:00
break ;
case ca_number :
ok = ( cur_token_int ( ) ! = NOT_FOUND ) ;
2015-09-30 12:49:50 -04:00
break ;
case ca_msg_id :
ok = ( cur_token_msg_id ( ) . peer_type ! = 0 ) ;
2015-06-17 05:05:57 -04:00
if ( ok ) {
autocomplete_peer = NULL ;
2015-09-30 12:49:50 -04:00
autocomplete_id = cur_token_msg_id ( ) ;
2015-06-17 05:05:57 -04:00
}
2014-09-17 17:03:20 -04:00
break ;
2014-10-03 05:35:02 -04:00
case ca_double :
ok = ( cur_token_double ( ) ! = NOT_FOUND ) ;
break ;
2015-10-01 07:11:31 -04:00
case ca_command :
ok = 1 ;
break ;
2014-09-17 17:03:20 -04:00
default :
assert ( 0 ) ;
}
if ( opt & & ! ok ) {
line_ptr = save ;
flags + + ;
continue ;
}
2014-11-28 08:16:51 -05:00
if ( period & & ! ok ) {
line_ptr = save ;
flags + = 2 ;
continue ;
}
2014-09-17 17:03:20 -04:00
if ( ! ok ) {
return ca_none ;
}
flags + + ;
continue ;
}
2014-08-25 12:17:17 -04:00
}
2014-09-17 17:03:20 -04:00
if ( op = = ca_string | | op = = ca_file_name ) {
if ( cur_token_end_str ) {
return op ;
} else {
flags + + ;
continue ;
}
2013-10-29 20:08:30 -04:00
}
2014-09-17 17:03:20 -04:00
assert ( 0 ) ;
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 ] ) ;
2014-09-11 05:24:06 -04:00
assert ( * R ) ;
2013-10-03 08:38:25 -04:00
return index ;
} else {
* R = 0 ;
return - 1 ;
}
}
2014-11-10 06:32:49 -05:00
void print_msg_success_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_message * M ) ;
void print_encr_chat_success_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_secret_chat * E ) ; ;
void print_success_gw ( struct tgl_state * TLS , void * extra , int success ) ;
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 ) ;
2014-09-11 05:24:06 -04:00
assert ( * R ) ;
2014-08-25 12:17:17 -04:00
return index ;
} else {
* R = 0 ;
return - 1 ;
}
}
2015-06-17 05:05:57 -04:00
int complete_spec_message_answer ( struct tgl_message * M , int index , const char * text , int len , char * * R ) {
if ( ! M | | ! M - > reply_markup | | ! M - > reply_markup - > rows ) {
* R = NULL ;
return - 1 ;
}
index + + ;
int total = M - > reply_markup - > row_start [ M - > reply_markup - > rows ] ;
while ( index < total & & strncmp ( M - > reply_markup - > buttons [ index ] , text , len ) ) {
index + + ;
}
if ( index < total ) {
* R = strdup ( M - > reply_markup - > buttons [ index ] ) ;
assert ( * R ) ;
return index ;
} else {
* R = NULL ;
return - 1 ;
}
}
int complete_message_answer ( tgl_peer_t * P , int index , const char * text , int len , char * * R ) {
struct tgl_message * M = P - > last ;
while ( M & & ( M - > flags & TGLMF_OUT ) ) {
M = M - > next ;
}
return complete_spec_message_answer ( M , index , text , len , R ) ;
}
int complete_user_command ( tgl_peer_t * P , int index , const char * text , int len , char * * R ) {
if ( len < = 0 | | * text ! = ' / ' ) {
return complete_message_answer ( P , index , text , len , R ) ;
}
text + + ;
len - - ;
struct tgl_user * U = ( void * ) P ;
if ( ! U - > bot_info ) {
* R = NULL ;
return - 1 ;
}
2015-06-25 06:34:28 -04:00
if ( index > = U - > bot_info - > commands_num ) {
return U - > bot_info - > commands_num + complete_message_answer ( P , index - U - > bot_info - > commands_num , text - 1 , len + 1 , R ) ;
}
index + + ;
2015-06-17 05:05:57 -04:00
while ( index < U - > bot_info - > commands_num & & strncmp ( U - > bot_info - > commands [ index ] . command , text , len ) ) {
index + + ;
}
if ( index < U - > bot_info - > commands_num ) {
* R = NULL ;
assert ( asprintf ( R , " /%s " , U - > bot_info - > commands [ index ] . command ) > = 0 ) ;
assert ( * R ) ;
return index ;
} else {
2015-06-25 06:34:28 -04:00
return U - > bot_info - > commands_num + complete_message_answer ( P , index - U - > bot_info - > commands_num , text - 1 , len + 1 , R ) ;
2015-06-17 05:05:57 -04:00
}
}
int complete_chat_command ( tgl_peer_t * P , int index , const char * text , int len , char * * R ) {
2015-06-24 13:52:52 -04:00
if ( len < = 0 | | * text ! = ' / ' ) {
return complete_message_answer ( P , index , text , len , R ) ;
}
text + + ;
len - - ;
index + + ;
int tot = 0 ;
int i ;
for ( i = 0 ; i < P - > chat . user_list_size ; i + + ) {
struct tgl_user * U = ( void * ) tgl_peer_get ( TLS , TGL_MK_USER ( P - > chat . user_list [ i ] . user_id ) ) ;
if ( ! U ) { continue ; }
if ( ! U - > bot_info ) { continue ; }
2015-06-25 06:34:28 -04:00
int p = len - 1 ;
while ( p > = 0 & & text [ p ] ! = ' @ ' ) { p - - ; }
if ( p < 0 ) { p = len ; }
while ( index - tot < U - > bot_info - > commands_num & & strncmp ( U - > bot_info - > commands [ index - tot ] . command , text , p ) ) {
2015-06-24 13:52:52 -04:00
index + + ;
}
if ( index - tot < U - > bot_info - > commands_num ) {
* R = NULL ;
2015-06-25 06:34:28 -04:00
if ( U - > username ) {
assert ( asprintf ( R , " /%s@%s " , U - > bot_info - > commands [ index ] . command , U - > username ) > = 0 ) ;
} else {
assert ( asprintf ( R , " /%s " , U - > bot_info - > commands [ index ] . command ) > = 0 ) ;
}
2015-06-24 13:52:52 -04:00
assert ( * R ) ;
return index ;
}
tot + = U - > bot_info - > commands_num ;
}
2015-06-25 06:34:28 -04:00
if ( index = = tot ) {
return tot + complete_message_answer ( P , index - tot , text - 1 , len + 1 , R ) ;
} else {
return tot + complete_message_answer ( P , index - tot - 1 , text - 1 , len + 1 , R ) ;
}
2015-06-17 05:05:57 -04:00
}
2013-10-03 08:38:25 -04:00
char * command_generator ( const char * text , int state ) {
2014-10-21 12:47:57 -04:00
# ifndef DISABLE_EXTF
static int len ;
# endif
static int index ;
2014-08-25 12:17:17 -04:00
static enum command_argument mode ;
2014-09-17 17:03:20 -04:00
static char * command_pos ;
static int command_len ;
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 ;
2014-09-17 17:03:20 -04:00
c = rl_line_buffer [ rl_point ] ;
rl_line_buffer [ rl_point ] = 0 ;
2013-10-03 08:38:25 -04:00
if ( ! state ) {
2014-10-21 12:47:57 -04:00
# ifndef DISABLE_EXTF
2013-10-03 08:38:25 -04:00
len = strlen ( text ) ;
2014-10-21 12:47:57 -04:00
# endif
2013-10-03 08:38:25 -04:00
index = - 1 ;
2013-10-28 17:56:17 -04:00
2013-10-03 08:38:25 -04:00
mode = get_complete_mode ( ) ;
2014-09-17 17:03:20 -04:00
command_pos = cur_token ;
command_len = cur_token_len ;
2013-10-03 08:38:25 -04:00
} else {
2015-05-05 14:08:37 -04:00
if ( mode ! = ca_file_name & & mode ! = ca_file_name_end & & index = = - 1 ) { return 0 ; }
2013-10-03 08:38:25 -04:00
}
2014-08-25 12:17:17 -04:00
2015-09-30 12:49:50 -04:00
if ( mode = = ca_none | | mode = = ca_string | | mode = = ca_string_end | | mode = = ca_number | | mode = = ca_double | | mode = = ca_msg_id ) {
2013-10-28 17:57:22 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
return 0 ;
}
2014-09-17 17:03:20 -04:00
assert ( command_len > = 0 ) ;
2013-10-03 08:38:25 -04:00
char * R = 0 ;
2014-09-17 17:03:20 -04:00
switch ( mode & 255 ) {
2014-08-25 12:17:17 -04:00
case ca_command :
2014-09-17 17:03:20 -04:00
index = complete_command_list ( index , command_pos , command_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-10-24 13:43:08 -04:00
index = tgl_complete_user_list ( TLS , index , command_pos , command_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-10-24 13:43:08 -04:00
index = tgl_complete_peer_list ( TLS , index , command_pos , command_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 :
2013-10-28 17:56:17 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
2014-09-20 18:22:35 -04:00
R = rl_filename_completion_function ( command_pos , state ) ;
2013-10-28 17:56:17 -04:00
return R ;
2014-08-25 12:17:17 -04:00
case ca_chat :
2014-10-24 13:43:08 -04:00
index = tgl_complete_chat_list ( TLS , index , command_pos , command_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-10-24 13:43:08 -04:00
index = tgl_complete_encr_chat_list ( TLS , index , command_pos , command_len , & R ) ;
2013-11-04 18:15:24 -05:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
return R ;
2015-10-01 07:11:31 -04:00
case ca_channel :
index = tgl_complete_channel_list ( TLS , index , command_pos , command_len , & R ) ;
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
return R ;
2014-08-25 12:17:17 -04:00
case ca_modifier :
2014-09-17 17:03:20 -04:00
index = complete_string_list ( modifiers , index , command_pos , command_len , & R ) ;
2013-11-30 13:52:13 -05:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
return R ;
2015-06-17 05:05:57 -04:00
case ca_msg_string_end :
if ( autocomplete_peer ) {
if ( tgl_get_peer_type ( autocomplete_peer - > id ) = = TGL_PEER_USER ) {
index = complete_user_command ( autocomplete_peer , index , command_pos , command_len , & R ) ;
}
if ( tgl_get_peer_type ( autocomplete_peer - > id ) = = TGL_PEER_CHAT ) {
index = complete_chat_command ( autocomplete_peer , index , command_pos , command_len , & R ) ;
}
}
2015-09-30 12:49:50 -04:00
if ( autocomplete_id . peer_type ! = ( unsigned ) NOT_FOUND ) {
struct tgl_message * M = tgl_message_get ( TLS , & autocomplete_id ) ;
2015-06-17 05:05:57 -04:00
if ( M ) {
if ( command_len > 0 & & * command_pos = = ' / ' ) {
tgl_peer_t * P = tgl_peer_get ( TLS , M - > from_id ) ;
if ( P ) {
index = complete_user_command ( autocomplete_peer , index , command_pos , command_len , & R ) ;
}
} else {
index = complete_spec_message_answer ( M , index , command_pos , command_len , & R ) ;
}
}
}
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
return R ;
2014-10-21 12:47:57 -04:00
# ifndef DISABLE_EXTF
2014-09-10 07:52:42 -04:00
case ca_extf :
2014-10-24 13:43:08 -04:00
index = tglf_extf_autocomplete ( TLS , text , len , index , & R , rl_line_buffer , rl_point ) ;
2014-09-17 17:03:20 -04:00
if ( c ) { rl_line_buffer [ rl_point ] = c ; }
2014-09-10 07:52:42 -04:00
return R ;
2014-10-21 12:47:57 -04:00
# endif
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 ;
}
}
2013-11-25 12:16:34 -05:00
int count = 1 ;
void work_modifier ( const char * s , int l ) {
if ( is_same_word ( s , l , " [offline] " ) ) {
offline_mode = 1 ;
}
2015-05-14 08:48:20 -04:00
if ( sscanf ( s , " [reply=%d] " , & reply_id ) > = 1 ) {
}
if ( is_same_word ( s , l , " [disable_preview] " ) ) {
disable_msg_preview = TGL_SEND_MSG_FLAG_DISABLE_PREVIEW ;
}
if ( is_same_word ( s , l , " [enable_preview] " ) ) {
disable_msg_preview = TGL_SEND_MSG_FLAG_ENABLE_PREVIEW ;
}
2013-11-25 12:16:34 -05:00
# ifdef ALLOW_MULT
if ( sscanf ( s , " [x%d] " , & count ) > = 1 ) {
}
# endif
2013-10-29 20:08:30 -04:00
}
2014-10-24 13:43:08 -04:00
void print_fail ( struct in_ev * ev ) {
2015-04-28 08:21:50 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
2015-05-14 08:48:20 -04:00
mprintf ( ev , " FAIL: %d: %s \n " , TLS - > error_code , TLS - > error ) ;
2015-05-11 07:20:34 -04:00
} else {
# ifdef USE_JSON
json_t * res = json_object ( ) ;
assert ( json_object_set ( res , " result " , json_string ( " FAIL " ) ) > = 0 ) ;
2015-05-14 08:48:20 -04:00
assert ( json_object_set ( res , " error_code " , json_integer ( TLS - > error_code ) ) > = 0 ) ;
assert ( json_object_set ( res , " error " , json_string ( TLS - > error ) ) > = 0 ) ;
2015-05-11 07:20:34 -04:00
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2015-04-28 08:21:50 -04:00
mprint_end ( ev ) ;
2014-10-24 13:43:08 -04:00
}
2015-05-15 06:31:38 -04:00
void fail_interface ( struct tgl_state * TLS , struct in_ev * ev , int error_code , const char * format , . . . ) {
static char error [ 1001 ] ;
2015-05-20 14:21:12 -04:00
2015-05-15 06:31:38 -04:00
va_list ap ;
va_start ( ap , format ) ;
int error_len = vsnprintf ( error , 1000 , format , ap ) ;
va_end ( ap ) ;
if ( error_len > 1000 ) { error_len = 1000 ; }
error [ error_len ] = 0 ;
2015-05-20 14:21:12 -04:00
2015-05-15 06:31:38 -04:00
mprint_start ( ev ) ;
if ( ! enable_json ) {
mprintf ( ev , " FAIL: %d: %s \n " , error_code , error ) ;
} else {
# ifdef USE_JSON
json_t * res = json_object ( ) ;
assert ( json_object_set ( res , " result " , json_string ( " FAIL " ) ) > = 0 ) ;
assert ( json_object_set ( res , " error_code " , json_integer ( error_code ) ) > = 0 ) ;
assert ( json_object_set ( res , " error " , json_string ( error ) ) > = 0 ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
mprint_end ( ev ) ;
}
2014-10-24 13:43:08 -04:00
void print_success ( struct in_ev * ev ) {
2015-05-11 07:20:34 -04:00
if ( ev | | enable_json ) {
2014-10-24 13:43:08 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mprintf ( ev , " SUCCESS \n " ) ;
} else {
# ifdef USE_JSON
json_t * res = json_object ( ) ;
assert ( json_object_set ( res , " result " , json_string ( " SUCCESS " ) ) > = 0 ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-10-24 13:43:08 -04:00
mprint_end ( ev ) ;
}
}
2015-05-11 07:20:34 -04:00
2014-10-24 13:43:08 -04:00
void print_success_gw ( struct tgl_state * TLSR , void * extra , int success ) {
assert ( TLS = = TLSR ) ;
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
if ( ! success ) { print_fail ( ev ) ; return ; }
else { print_success ( ev ) ; return ; }
}
void print_msg_success_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_message * M ) {
2014-11-10 06:02:14 -05:00
write_secret_chat_file ( ) ;
2014-10-24 13:43:08 -04:00
print_success_gw ( TLS , extra , success ) ;
}
2014-11-28 08:16:51 -05:00
void print_msg_list_success_gw ( struct tgl_state * TLSR , void * extra , int success , int num , struct tgl_message * ML [ ] ) {
assert ( TLS = = TLSR ) ;
print_success_gw ( TLSR , extra , success ) ;
}
2014-10-24 13:43:08 -04:00
void print_encr_chat_success_gw ( struct tgl_state * TLS , void * extra , int success , struct tgl_secret_chat * E ) {
2014-11-10 06:02:14 -05:00
write_secret_chat_file ( ) ;
2014-10-24 13:43:08 -04:00
print_success_gw ( TLS , extra , success ) ;
}
void print_msg_list_gw ( struct tgl_state * TLSR , void * extra , int success , int num , struct tgl_message * ML [ ] ) {
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2015-05-11 07:20:34 -04:00
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
int i ;
for ( i = num - 1 ; i > = 0 ; i - - ) {
print_message ( ev , ML [ i ] ) ;
}
} else {
# ifdef USE_JSON
json_t * res = json_array ( ) ;
int i ;
for ( i = num - 1 ; i > = 0 ; i - - ) {
json_t * a = json_pack_message ( ML [ i ] ) ;
assert ( json_array_append ( res , a ) > = 0 ) ;
}
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
2014-08-14 18:16:01 -04:00
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
2015-09-25 13:01:51 -04:00
void print_msg_list_history_gw ( struct tgl_state * TLSR , void * extra , int success , int num , struct tgl_message * ML [ ] ) {
print_msg_list_gw ( TLSR , extra , success , num , ML ) ;
if ( num > 0 ) {
2015-09-30 12:49:50 -04:00
if ( tgl_cmp_peer_id ( ML [ 0 ] - > to_id , TLS - > our_id ) ) {
tgl_do_messages_mark_read ( TLS , ML [ 0 ] - > to_id , ML [ 0 ] - > server_id , 0 , NULL , NULL ) ;
2015-09-25 13:20:00 -04:00
} else {
2015-09-30 12:49:50 -04:00
tgl_do_messages_mark_read ( TLS , ML [ 0 ] - > from_id , ML [ 0 ] - > server_id , 0 , NULL , NULL ) ;
2015-09-25 13:01:51 -04:00
}
}
}
2014-10-24 13:43:08 -04:00
void print_msg_gw ( struct tgl_state * TLSR , void * extra , int success , struct tgl_message * M ) {
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
print_message ( ev , M ) ;
} else {
# ifdef USE_JSON
json_t * res = json_pack_message ( M ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
2014-10-24 13:43:08 -04:00
void print_user_list_gw ( struct tgl_state * TLSR , void * extra , int success , int num , struct tgl_user * UL [ ] ) {
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
int i ;
for ( i = num - 1 ; i > = 0 ; i - - ) {
print_user_name ( ev , UL [ i ] - > id , ( void * ) UL [ i ] ) ;
mprintf ( ev , " \n " ) ;
}
} else {
# ifdef USE_JSON
json_t * res = json_array ( ) ;
int i ;
for ( i = num - 1 ; i > = 0 ; i - - ) {
2015-06-07 09:04:37 -04:00
json_t * a = json_pack_peer ( UL [ i ] - > id ) ;
2015-05-11 07:20:34 -04:00
assert ( json_array_append ( res , a ) > = 0 ) ;
}
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
2014-08-14 18:16:01 -04:00
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
2014-10-24 13:43:08 -04:00
void print_user_gw ( struct tgl_state * TLSR , void * extra , int success , struct tgl_user * U ) {
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
print_user_name ( ev , U - > id , ( void * ) U ) ;
mprintf ( ev , " \n " ) ;
} else {
# ifdef USE_JSON
2015-06-07 09:04:37 -04:00
json_t * res = json_pack_peer ( U - > id ) ;
2015-05-11 07:20:34 -04:00
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-29 11:46:04 -04:00
}
2015-09-30 12:49:50 -04:00
void print_chat_gw ( struct tgl_state * TLSR , void * extra , int success , struct tgl_chat * U ) {
assert ( TLS = = TLSR ) ;
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
if ( ! success ) { print_fail ( ev ) ; return ; }
mprint_start ( ev ) ;
if ( ! enable_json ) {
print_chat_name ( ev , U - > id , ( void * ) U ) ;
mprintf ( ev , " \n " ) ;
} else {
# ifdef USE_JSON
json_t * res = json_pack_peer ( U - > id ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
mprint_end ( ev ) ;
}
void print_channel_gw ( struct tgl_state * TLSR , void * extra , int success , struct tgl_channel * U ) {
assert ( TLS = = TLSR ) ;
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
if ( ! success ) { print_fail ( ev ) ; return ; }
mprint_start ( ev ) ;
if ( ! enable_json ) {
print_channel_name ( ev , U - > id , ( void * ) U ) ;
mprintf ( ev , " \n " ) ;
} else {
# ifdef USE_JSON
json_t * res = json_pack_peer ( U - > id ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
mprint_end ( ev ) ;
}
void print_peer_gw ( struct tgl_state * TLSR , void * extra , int success , tgl_peer_t * U ) {
if ( ! success ) {
print_user_gw ( TLSR , extra , success , ( void * ) U ) ;
return ;
}
switch ( tgl_get_peer_type ( U - > id ) ) {
case TGL_PEER_USER :
print_user_gw ( TLSR , extra , success , ( void * ) U ) ;
break ;
case TGL_PEER_CHAT :
print_chat_gw ( TLSR , extra , success , ( void * ) U ) ;
break ;
case TGL_PEER_CHANNEL :
print_channel_gw ( TLSR , extra , success , ( void * ) U ) ;
break ;
default :
assert ( 0 ) ;
}
}
2015-05-14 08:48:20 -04:00
void print_filename_gw ( struct tgl_state * TLSR , void * extra , int success , const char * name ) {
2014-10-24 13:43:08 -04:00
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mprintf ( ev , " Saved to %s \n " , name ) ;
} else {
# ifdef USE_JSON
json_t * res = json_object ( ) ;
assert ( json_object_set ( res , " result " , json_string ( name ) ) > = 0 ) ;
2015-05-15 07:53:57 -04:00
assert ( json_object_set ( res , " event " , json_string ( " download " ) ) > = 0 ) ;
2015-05-11 07:20:34 -04:00
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
2015-05-01 13:19:12 -04:00
void print_string_gw ( struct tgl_state * TLSR , void * extra , int success , const char * name ) {
assert ( TLS = = TLSR ) ;
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
if ( ! success ) { print_fail ( ev ) ; return ; }
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mprintf ( ev , " %s \n " , name ) ;
} else {
# ifdef USE_JSON
json_t * res = json_object ( ) ;
assert ( json_object_set ( res , " result " , json_string ( name ) ) > = 0 ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2015-05-01 13:19:12 -04:00
mprint_end ( ev ) ;
}
2015-05-14 08:48:20 -04:00
void open_filename_gw ( struct tgl_state * TLSR , void * extra , int success , const char * name ) {
2014-10-24 13:43:08 -04:00
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
if ( ev ) { return ; }
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-08-14 18:16:01 -04:00
static char buf [ PATH_MAX ] ;
if ( snprintf ( buf , sizeof ( buf ) , OPEN_BIN , name ) > = ( int ) sizeof ( buf ) ) {
logprintf ( " Open image command buffer overflow \n " ) ;
} else {
2015-04-22 13:09:53 -04:00
int pid = fork ( ) ;
if ( ! pid ) {
execl ( " /bin/sh " , " sh " , " -c " , buf , ( char * ) 0 ) ;
exit ( 0 ) ;
2014-08-14 18:16:01 -04:00
}
}
}
2014-10-24 13:43:08 -04:00
void print_chat_info_gw ( struct tgl_state * TLSR , void * extra , int success , struct tgl_chat * C ) {
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
tgl_peer_t * U = ( void * ) C ;
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " Chat " ) ;
print_chat_name ( ev , U - > id , U ) ;
mprintf ( ev , " (id %d) members: \n " , tgl_get_peer_id ( U - > id ) ) ;
int i ;
for ( i = 0 ; i < C - > user_list_size ; i + + ) {
mprintf ( ev , " \t \t " ) ;
print_user_name ( ev , TGL_MK_USER ( C - > user_list [ i ] . user_id ) , tgl_peer_get ( TLS , TGL_MK_USER ( C - > user_list [ i ] . user_id ) ) ) ;
mprintf ( ev , " invited by " ) ;
print_user_name ( ev , TGL_MK_USER ( C - > user_list [ i ] . inviter_id ) , tgl_peer_get ( TLS , TGL_MK_USER ( C - > user_list [ i ] . inviter_id ) ) ) ;
mprintf ( ev , " at " ) ;
print_date_full ( ev , C - > user_list [ i ] . date ) ;
if ( C - > user_list [ i ] . user_id = = C - > admin_id ) {
mprintf ( ev , " admin " ) ;
}
mprintf ( ev , " \n " ) ;
2014-08-14 18:16:01 -04:00
}
2015-05-11 07:20:34 -04:00
mpop_color ( ev ) ;
} else {
# ifdef USE_JSON
2015-06-07 09:04:37 -04:00
json_t * res = json_pack_peer ( C - > id ) ;
2015-05-11 07:20:34 -04:00
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
2014-08-14 18:16:01 -04:00
}
2015-05-11 07:20:34 -04:00
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
2015-10-01 07:11:31 -04:00
void print_channel_info_gw ( struct tgl_state * TLSR , void * extra , int success , struct tgl_channel * C ) {
assert ( TLS = = TLSR ) ;
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
if ( ! success ) { print_fail ( ev ) ; return ; }
mprint_start ( ev ) ;
if ( ! enable_json ) {
tgl_peer_t * U = ( void * ) C ;
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " Channel " ) ;
print_channel_name ( ev , U - > id , U ) ;
mprintf ( ev , " (id %d): \n " , tgl_get_peer_id ( U - > id ) ) ;
mprintf ( ev , " \t \t %d participants, %d admins, %d kicked \n " , C - > participants_count , C - > admins_count , C - > kicked_count ) ;
mpop_color ( ev ) ;
} else {
# ifdef USE_JSON
json_t * res = json_pack_peer ( C - > id ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
mprint_end ( ev ) ;
}
2014-11-15 06:45:37 -05:00
void print_user_status ( struct tgl_user_status * S , struct in_ev * ev ) {
2015-05-19 18:13:39 -04:00
assert ( ! enable_json ) ; //calling functions print_user_info_gw() and user_status_upd() already check.
2014-11-15 06:45:37 -05:00
if ( S - > online > 0 ) {
2015-01-09 06:54:46 -05:00
mprintf ( ev , " online (was online " ) ;
print_date_full ( ev , S - > when ) ;
mprintf ( ev , " ) " ) ;
2014-11-15 06:45:37 -05:00
} else {
if ( S - > online = = 0 ) {
mprintf ( ev , " offline " ) ;
} else if ( S - > online = = - 1 ) {
mprintf ( ev , " offline (was online " ) ;
print_date_full ( ev , S - > when ) ;
mprintf ( ev , " ) " ) ;
} else if ( S - > online = = - 2 ) {
mprintf ( ev , " offline (was online recently) " ) ;
} else if ( S - > online = = - 3 ) {
mprintf ( ev , " offline (was online last week) " ) ;
} else if ( S - > online = = - 4 ) {
mprintf ( ev , " offline (was online last month) " ) ;
}
}
}
2014-10-24 13:43:08 -04:00
void print_user_info_gw ( struct tgl_state * TLSR , void * extra , int success , struct tgl_user * U ) {
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
tgl_peer_t * C = ( void * ) U ;
if ( ! enable_json ) {
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " User " ) ;
print_user_name ( ev , U - > id , C ) ;
if ( U - > username ) {
mprintf ( ev , " @%s " , U - > username ) ;
}
mprintf ( ev , " (#%d): \n " , tgl_get_peer_id ( U - > id ) ) ;
mprintf ( ev , " \t phone: %s \n " , U - > phone ) ;
mprintf ( ev , " \t " ) ;
print_user_status ( & U - > status , ev ) ;
mprintf ( ev , " \n " ) ;
2015-06-17 05:05:57 -04:00
if ( U - > bot_info ) {
mprintf ( ev , " \t share_text: %s \n " , U - > bot_info - > share_text ) ;
mprintf ( ev , " \t description: %s \n " , U - > bot_info - > description ) ;
mprintf ( ev , " \t commands: \n " ) ;
int i ;
for ( i = 0 ; i < U - > bot_info - > commands_num ; i + + ) {
2015-06-24 13:46:12 -04:00
mprintf ( ev , " \t \t /%s: %s \n " , U - > bot_info - > commands [ i ] . command , U - > bot_info - > commands [ i ] . description ) ;
2015-06-17 05:05:57 -04:00
}
}
2015-05-11 07:20:34 -04:00
mpop_color ( ev ) ;
} else {
# ifdef USE_JSON
2015-06-07 09:04:37 -04:00
json_t * res = json_pack_peer ( U - > id ) ;
2015-05-11 07:20:34 -04:00
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
2014-10-24 13:43:08 -04:00
void print_secret_chat_gw ( struct tgl_state * TLSR , void * extra , int success , struct tgl_secret_chat * E ) {
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " Encrypted chat " ) ;
print_encr_chat_name ( ev , E - > id , ( void * ) E ) ;
mprintf ( ev , " is now in wait state \n " ) ;
mpop_color ( ev ) ;
} else {
# ifdef USE_JSON
2015-06-07 09:04:37 -04:00
json_t * res = json_pack_peer ( E - > id ) ;
2015-05-11 07:20:34 -04:00
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
2013-12-06 12:14:41 -05:00
2015-09-30 12:49:50 -04:00
void print_dialog_list_gw ( struct tgl_state * TLSR , void * extra , int success , int size , tgl_peer_id_t peers [ ] , tgl_message_id_t * last_msg_id [ ] , int unread_count [ ] ) {
2014-10-24 13:43:08 -04:00
assert ( TLS = = TLSR ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mpush_color ( ev , 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 ( TLS , peers [ i ] ) ;
mprintf ( ev , " User " ) ;
print_user_name ( ev , peers [ i ] , UC ) ;
mprintf ( ev , " : %d unread \n " , unread_count [ i ] ) ;
break ;
case TGL_PEER_CHAT :
UC = tgl_peer_get ( TLS , peers [ i ] ) ;
mprintf ( ev , " Chat " ) ;
print_chat_name ( ev , peers [ i ] , UC ) ;
mprintf ( ev , " : %d unread \n " , unread_count [ i ] ) ;
break ;
2015-09-25 11:28:23 -04:00
case TGL_PEER_CHANNEL :
UC = tgl_peer_get ( TLS , peers [ i ] ) ;
mprintf ( ev , " Channel " ) ;
print_channel_name ( ev , peers [ i ] , UC ) ;
mprintf ( ev , " : %d unread \n " , unread_count [ i ] ) ;
break ;
2015-05-11 07:20:34 -04:00
}
2014-08-14 18:16:01 -04:00
}
2015-05-11 07:20:34 -04:00
mpop_color ( ev ) ;
} else {
# ifdef USE_JSON
json_t * res = json_array ( ) ;
int i ;
for ( i = size - 1 ; i > = 0 ; i - - ) {
2015-06-07 09:04:37 -04:00
json_t * a = json_pack_peer ( peers [ i ] ) ;
2015-05-11 07:20:34 -04:00
assert ( json_array_append ( res , a ) > = 0 ) ;
}
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
2014-08-14 18:16:01 -04:00
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
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 ; }
2015-05-14 08:48:20 -04:00
tgl_do_get_history ( TLS , chat_mode_id , 0 , limit , offline_mode , print_msg_list_gw , 0 ) ;
2013-12-19 17:50:31 -05:00
return ;
}
if ( ! strncmp ( line , " /read " , 5 ) ) {
2014-10-24 13:43:08 -04:00
tgl_do_mark_read ( TLS , 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 ) {
2015-06-17 09:48:44 -04:00
tgl_do_send_message ( TLS , chat_mode_id , line , strlen ( line ) , 0 , NULL , 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 ;
2014-09-20 18:22:35 -04:00
2014-08-21 16:35:27 -04:00
void print_read_list ( int num , struct tgl_message * list [ ] ) {
2014-09-20 18:22:35 -04:00
struct in_ev * ev = notify_ev ;
2014-08-21 16:35:27 -04:00
int i ;
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2014-08-21 16:35:27 -04:00
for ( i = 0 ; i < num ; i + + ) if ( list [ i ] ) {
2015-05-15 07:53:57 -04:00
if ( enable_json ) {
# ifdef USE_JSON
json_t * res = json_pack_read ( list [ i ] ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-08-21 16:35:27 -04:00
tgl_peer_id_t to_id ;
2015-09-30 12:49:50 -04:00
if ( ! tgl_cmp_peer_id ( list [ i ] - > to_id , TLS - > our_id ) ) {
2014-08-21 16:35:27 -04:00
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 ;
2015-09-30 12:49:50 -04:00
if ( ! tgl_cmp_peer_id ( list [ j ] - > to_id , TLS - > our_id ) ) {
2014-08-21 16:35:27 -04:00
end_id = list [ j ] - > from_id ;
} else {
end_id = list [ j ] - > to_id ;
}
if ( ! tgl_cmp_peer_id ( to_id , end_id ) ) {
2015-04-22 13:09:53 -04:00
if ( list [ j ] - > flags & TGLMF_OUT ) {
2014-08-21 16:35:27 -04:00
c1 + + ;
} else {
c2 + + ;
}
list [ j ] = 0 ;
}
}
assert ( c1 + c2 > 0 ) ;
2015-05-15 07:53:57 -04:00
if ( ! enable_json ) {
mpush_color ( ev , COLOR_YELLOW ) ;
switch ( tgl_get_peer_type ( to_id ) ) {
case TGL_PEER_USER :
mprintf ( ev , " User " ) ;
print_user_name ( ev , to_id , tgl_peer_get ( TLS , to_id ) ) ;
break ;
case TGL_PEER_CHAT :
mprintf ( ev , " Chat " ) ;
print_chat_name ( ev , to_id , tgl_peer_get ( TLS , to_id ) ) ;
break ;
case TGL_PEER_ENCR_CHAT :
mprintf ( ev , " Secret chat " ) ;
print_encr_chat_name ( ev , to_id , tgl_peer_get ( TLS , to_id ) ) ;
break ;
default :
assert ( 0 ) ;
}
mprintf ( ev , " marked read %d outbox and %d inbox messages \n " , c1 , c2 ) ;
mpop_color ( ev ) ;
2015-05-15 10:50:07 -04:00
}
2014-08-21 16:35:27 -04:00
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-21 16:35:27 -04:00
}
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-10-24 13:43:08 -04:00
void mark_read_upd ( struct tgl_state * TLSR , int num , struct tgl_message * list [ ] ) {
assert ( TLSR = = TLS ) ;
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 ) {
2014-10-24 13:43:08 -04:00
unread_message_event = evtimer_new ( TLS - > ev_base , unread_message_alarm , 0 ) ;
2014-08-21 16:35:27 -04:00
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 ;
}
}
2014-08-14 18:16:01 -04:00
}
2014-09-29 08:11:48 -04:00
void print_typing ( struct in_ev * ev , enum tgl_typing_status status ) {
switch ( status ) {
case tgl_typing_none :
mprintf ( ev , " doing nothing " ) ;
break ;
case tgl_typing_typing :
mprintf ( ev , " typing " ) ;
break ;
case tgl_typing_cancel :
mprintf ( ev , " deleting typed message " ) ;
break ;
case tgl_typing_record_video :
mprintf ( ev , " recording video " ) ;
break ;
case tgl_typing_upload_video :
mprintf ( ev , " uploading video " ) ;
break ;
case tgl_typing_record_audio :
mprintf ( ev , " recording audio " ) ;
break ;
case tgl_typing_upload_audio :
mprintf ( ev , " uploading audio " ) ;
break ;
case tgl_typing_upload_photo :
mprintf ( ev , " uploading photo " ) ;
break ;
case tgl_typing_upload_document :
mprintf ( ev , " uploading document " ) ;
break ;
case tgl_typing_geo :
mprintf ( ev , " choosing location " ) ;
break ;
case tgl_typing_choose_contact :
mprintf ( ev , " choosing contact " ) ;
break ;
}
}
2014-10-24 13:43:08 -04:00
void type_notification_upd ( struct tgl_state * TLSR , struct tgl_user * U , enum tgl_typing_status status ) {
assert ( TLSR = = TLS ) ;
2014-09-20 18:22:35 -04:00
if ( log_level < 2 | | ( disable_output & & ! notify_ev ) ) { return ; }
2015-05-11 07:20:34 -04:00
if ( enable_json ) { return ; }
2014-09-20 18:22:35 -04:00
struct in_ev * ev = notify_ev ;
mprint_start ( ev ) ;
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " User " ) ;
print_user_name ( ev , U - > id , ( void * ) U ) ;
2014-09-29 08:11:48 -04:00
mprintf ( ev , " is " ) ;
print_typing ( ev , status ) ;
mprintf ( ev , " \n " ) ;
2014-09-20 18:22:35 -04:00
mpop_color ( ev ) ;
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
2014-10-24 13:43:08 -04:00
void type_in_chat_notification_upd ( struct tgl_state * TLSR , struct tgl_user * U , struct tgl_chat * C , enum tgl_typing_status status ) {
assert ( TLSR = = TLS ) ;
2014-09-20 18:22:35 -04:00
if ( log_level < 2 | | ( disable_output & & ! notify_ev ) ) { return ; }
2015-05-11 07:20:34 -04:00
if ( enable_json ) { return ; }
2014-09-20 18:22:35 -04:00
struct in_ev * ev = notify_ev ;
mprint_start ( ev ) ;
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " User " ) ;
print_user_name ( ev , U - > id , ( void * ) U ) ;
2014-09-29 08:11:48 -04:00
mprintf ( ev , " is " ) ;
print_typing ( ev , status ) ;
mprintf ( ev , " in chat " ) ;
2014-09-20 18:22:35 -04:00
print_chat_name ( ev , C - > id , ( void * ) C ) ;
mprintf ( ev , " \n " ) ;
mpop_color ( ev ) ;
mprint_end ( ev ) ;
2014-08-14 18:16:01 -04:00
}
2014-10-24 13:43:08 -04:00
void print_message_gw ( struct tgl_state * TLSR , struct tgl_message * M ) {
assert ( TLSR = = TLS ) ;
2014-08-21 11:38:51 -04:00
# ifdef USE_LUA
lua_new_msg ( M ) ;
# endif
2015-05-02 07:49:21 -04:00
# ifdef USE_PYTHON
py_new_msg ( M ) ;
# endif
2014-08-21 11:38:51 -04:00
if ( ! binlog_read ) { return ; }
2014-10-23 12:39:58 -04:00
if ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_ENCR_CHAT ) {
write_secret_chat_file ( ) ;
}
2014-09-20 18:22:35 -04:00
if ( alert_sound ) {
play_sound ( ) ;
}
if ( disable_output & & ! notify_ev ) { return ; }
struct in_ev * ev = notify_ev ;
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
print_message ( ev , M ) ;
} else {
# ifdef USE_JSON
json_t * res = json_pack_message ( M ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-18 12:39:04 -04:00
}
2015-09-30 12:49:50 -04:00
void our_id_gw ( struct tgl_state * TLSR , tgl_peer_id_t id ) {
2014-10-24 13:43:08 -04:00
assert ( TLSR = = TLS ) ;
2014-08-21 11:38:51 -04:00
# ifdef USE_LUA
lua_our_id ( id ) ;
# endif
2015-05-02 07:49:21 -04:00
# ifdef USE_PYTHON
py_our_id ( id ) ;
# endif
2014-08-21 11:38:51 -04:00
}
2014-09-20 18:22:35 -04:00
void print_peer_updates ( struct in_ev * ev , int flags ) {
2014-08-21 11:38:51 -04:00
if ( flags & TGL_UPDATE_PHONE ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " phone " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_CONTACT ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " contact " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_PHOTO ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " photo " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_BLOCKED ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " blocked " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_REAL_NAME ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " name " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_NAME ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " contact_name " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_REQUESTED ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " status " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_WORKING ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " status " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_FLAGS ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " flags " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_TITLE ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " title " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_ADMIN ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " admin " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_MEMBERS ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " members " ) ;
2014-08-21 11:38:51 -04:00
}
if ( flags & TGL_UPDATE_ACCESS_HASH ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " access_hash " ) ;
2014-08-21 11:38:51 -04:00
}
2014-10-12 11:53:57 -04:00
if ( flags & TGL_UPDATE_USERNAME ) {
mprintf ( ev , " username " ) ;
}
2014-08-21 11:38:51 -04:00
}
2015-05-15 10:50:07 -04:00
void json_peer_update ( struct in_ev * ev , tgl_peer_t * P , unsigned flags ) {
2015-05-11 07:20:34 -04:00
# ifdef USE_JSON
json_t * res = json_object ( ) ;
2015-05-15 07:53:57 -04:00
assert ( json_object_set ( res , " event " , json_string ( " updates " ) ) > = 0 ) ;
2015-06-07 09:04:37 -04:00
assert ( json_object_set ( res , " peer " , json_pack_peer ( P - > id ) ) > = 0 ) ;
2015-05-11 07:20:34 -04:00
assert ( json_object_set ( res , " updates " , json_pack_updates ( flags ) ) > = 0 ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-10-24 13:43:08 -04:00
void user_update_gw ( struct tgl_state * TLSR , struct tgl_user * U , unsigned flags ) {
assert ( TLSR = = TLS ) ;
2014-08-21 11:38:51 -04:00
# ifdef USE_LUA
lua_user_update ( U , flags ) ;
# endif
2015-05-02 07:49:21 -04:00
# ifdef USE_PYTHON
py_user_update ( U , flags ) ;
# endif
2014-09-20 18:22:35 -04:00
if ( disable_output & & ! notify_ev ) { return ; }
2014-08-21 11:38:51 -04:00
if ( ! binlog_read ) { return ; }
2014-09-20 18:22:35 -04:00
struct in_ev * ev = notify_ev ;
2014-08-21 11:38:51 -04:00
if ( ! ( flags & TGL_UPDATE_CREATED ) ) {
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " User " ) ;
print_user_name ( ev , U - > id , ( void * ) U ) ;
if ( ! ( flags & TGL_UPDATE_DELETED ) ) {
mprintf ( ev , " updated " ) ;
print_peer_updates ( ev , flags ) ;
} else {
mprintf ( ev , " deleted " ) ;
}
mprintf ( ev , " \n " ) ;
mpop_color ( ev ) ;
2014-08-21 11:38:51 -04:00
} else {
2015-05-11 07:20:34 -04:00
json_peer_update ( ev , ( void * ) U , flags ) ;
2014-08-21 11:38:51 -04:00
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-21 11:38:51 -04:00
}
}
2014-10-24 13:43:08 -04:00
void chat_update_gw ( struct tgl_state * TLSR , struct tgl_chat * U , unsigned flags ) {
assert ( TLSR = = TLS ) ;
2014-08-21 11:38:51 -04:00
# ifdef USE_LUA
lua_chat_update ( U , flags ) ;
# endif
2015-05-02 07:49:21 -04:00
# ifdef USE_PYTHON
py_chat_update ( U , flags ) ;
# endif
2014-09-20 18:22:35 -04:00
if ( disable_output & & ! notify_ev ) { return ; }
2014-08-21 11:38:51 -04:00
if ( ! binlog_read ) { return ; }
2014-09-20 18:22:35 -04:00
struct in_ev * ev = notify_ev ;
2014-08-21 11:38:51 -04:00
if ( ! ( flags & TGL_UPDATE_CREATED ) ) {
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " Chat " ) ;
print_chat_name ( ev , U - > id , ( void * ) U ) ;
if ( ! ( flags & TGL_UPDATE_DELETED ) ) {
mprintf ( ev , " updated " ) ;
print_peer_updates ( ev , flags ) ;
} else {
mprintf ( ev , " deleted " ) ;
}
mprintf ( ev , " \n " ) ;
mpop_color ( ev ) ;
2014-08-21 11:38:51 -04:00
} else {
2015-05-11 07:20:34 -04:00
json_peer_update ( ev , ( void * ) U , flags ) ;
2014-08-21 11:38:51 -04:00
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-21 11:38:51 -04:00
}
}
2014-10-24 13:43:08 -04:00
void secret_chat_update_gw ( struct tgl_state * TLSR , struct tgl_secret_chat * U , unsigned flags ) {
assert ( TLSR = = TLS ) ;
2014-08-21 11:38:51 -04:00
# ifdef USE_LUA
lua_secret_chat_update ( U , flags ) ;
# endif
2015-05-02 07:49:21 -04:00
# ifdef USE_PYTHON
py_secret_chat_update ( U , flags ) ;
# endif
2014-08-21 11:38:51 -04:00
2015-05-02 07:49:21 -04:00
2014-08-31 10:18:19 -04:00
if ( ( flags & TGL_UPDATE_WORKING ) | | ( flags & TGL_UPDATE_DELETED ) ) {
write_secret_chat_file ( ) ;
}
2014-09-20 18:22:35 -04:00
2014-09-21 17:00:46 -04:00
if ( ! binlog_read ) { return ; }
2014-08-26 12:06:30 -04:00
if ( ( flags & TGL_UPDATE_REQUESTED ) & & ! disable_auto_accept ) {
2014-11-10 06:32:49 -05:00
//tgl_do_accept_encr_chat_request (TLS, U, 0, 0);
tgl_do_accept_encr_chat_request ( TLS , U , print_encr_chat_success_gw , 0 ) ;
2014-08-26 12:06:30 -04:00
}
2014-09-20 18:22:35 -04:00
if ( disable_output & & ! notify_ev ) { return ; }
struct in_ev * ev = notify_ev ;
2014-08-26 12:06:30 -04:00
2014-08-21 11:38:51 -04:00
if ( ! ( flags & TGL_UPDATE_CREATED ) ) {
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " Secret chat " ) ;
print_encr_chat_name ( ev , U - > id , ( void * ) U ) ;
if ( ! ( flags & TGL_UPDATE_DELETED ) ) {
mprintf ( ev , " updated " ) ;
print_peer_updates ( ev , flags ) ;
} else {
mprintf ( ev , " deleted " ) ;
}
mprintf ( ev , " \n " ) ;
mpop_color ( ev ) ;
2014-08-21 11:38:51 -04:00
} else {
2015-05-11 07:20:34 -04:00
json_peer_update ( ev , ( void * ) U , flags ) ;
2014-08-21 11:38:51 -04:00
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-21 11:38:51 -04:00
}
}
2014-10-24 13:43:08 -04:00
void print_card_gw ( struct tgl_state * TLSR , void * extra , int success , int size , int * card ) {
assert ( TLSR = = TLS ) ;
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
2014-09-21 04:58:57 -04:00
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mprintf ( ev , " Card: " ) ;
int i ;
for ( i = 0 ; i < size ; i + + ) {
mprintf ( ev , " %08x%c " , card [ i ] , i = = size - 1 ? ' \n ' : ' : ' ) ;
}
} else {
# ifdef USE_JSON
static char q [ 1000 ] ;
int pos = 0 ;
int i ;
for ( i = 0 ; i < size ; i + + ) {
pos + = sprintf ( q + pos , " %08x%s " , card [ i ] , i = = size - 1 ? " " : " : " ) ;
}
json_t * res = json_object ( ) ;
assert ( json_object_set ( res , " result " , json_string ( q ) ) > = 0 ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
2014-08-29 11:46:04 -04:00
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-08-29 11:46:04 -04:00
}
2015-05-14 08:48:20 -04:00
void callback_extf ( struct tgl_state * TLS , void * extra , int success , const char * buf ) {
2014-09-20 18:22:35 -04:00
struct in_ev * ev = extra ;
2014-09-21 04:58:57 -04:00
if ( ev & & ! - - ev - > refcnt ) {
free ( ev ) ;
return ;
}
2014-10-24 13:43:08 -04:00
if ( ! success ) { print_fail ( ev ) ; return ; }
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2015-05-11 07:20:34 -04:00
if ( ! enable_json ) {
mprintf ( ev , " %s \n " , buf ) ;
} else {
# ifdef USE_JSON
json_t * res = json_object ( ) ;
assert ( json_object_set ( res , " result " , json_string ( buf ) ) > = 0 ) ;
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-09-20 18:22:35 -04:00
mprint_end ( ev ) ;
2014-09-10 07:52:42 -04:00
}
2014-11-11 13:10:03 -05:00
void user_status_upd ( struct tgl_state * TLS , struct tgl_user * U ) {
if ( disable_output & & ! notify_ev ) { return ; }
if ( ! binlog_read ) { return ; }
2014-11-11 13:12:03 -05:00
if ( log_level < 3 ) { return ; }
2014-11-11 13:10:03 -05:00
struct in_ev * ev = notify_ev ;
mprint_start ( ev ) ;
2015-05-19 18:13:39 -04:00
if ( ! enable_json )
{
mpush_color ( ev , COLOR_YELLOW ) ;
mprintf ( ev , " User " ) ;
print_user_name ( ev , U - > id , ( void * ) U ) ;
mprintf ( ev , " " ) ;
print_user_status ( & U - > status , ev ) ;
mprintf ( ev , " \n " ) ;
mpop_color ( ev ) ;
} else {
# ifdef USE_JSON
2015-05-19 18:33:10 -04:00
json_t * res = json_pack_user_status ( U ) ;
2015-05-19 18:13:39 -04:00
char * s = json_dumps ( res , 0 ) ;
mprintf ( ev , " %s \n " , s ) ;
json_decref ( res ) ;
free ( s ) ;
# endif
}
2014-11-11 13:10:03 -05:00
mprint_end ( ev ) ;
}
2015-01-11 16:52:40 -05:00
void on_login ( struct tgl_state * TLS ) ;
void on_started ( struct tgl_state * TLS ) ;
2015-07-30 08:17:42 -04:00
void do_get_values ( struct tgl_state * TLS , enum tgl_value_type type , const char * prompt , int num_values ,
void ( * callback ) ( struct tgl_state * TLS , const char * string [ ] , void * arg ) , void * arg ) ;
2015-01-11 16:52:40 -05:00
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 ,
2015-07-30 08:17:42 -04:00
. get_values = do_get_values ,
2015-01-11 16:52:40 -05:00
. logged_in = on_login ,
. started = on_started ,
2014-08-14 18:16:01 -04:00
. 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 ,
2014-11-11 13:10:03 -05:00
. our_id = our_id_gw ,
. user_status_update = user_status_upd
2014-08-14 18:16:01 -04:00
} ;
2015-10-01 07:11:31 -04:00
void interpreter_ex ( char * line , void * ex ) {
2014-09-17 17:03:20 -04:00
force_end_mode = 1 ;
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 ;
2015-05-14 08:48:20 -04:00
reply_id = 0 ;
disable_msg_preview = 0 ;
2013-11-25 12:16:34 -05:00
count = 1 ;
2013-10-29 20:08:30 -04:00
if ( ! line ) {
2015-05-06 07:39:45 -04:00
do_safe_quit ( NULL , 0 , NULL , NULL ) ;
2013-10-29 20:08:30 -04:00
in_readline = 0 ;
return ;
}
2015-05-27 09:49:52 -04:00
if ( ! * line ) {
in_readline = 0 ;
return ;
}
2013-10-13 06:18:08 -04:00
if ( line & & * line ) {
add_history ( line ) ;
}
2014-09-17 17:03:20 -04:00
if ( * line = = ' ( ' ) {
2014-09-21 04:58:57 -04:00
struct in_ev * ev = ex ;
if ( ev ) { ev - > refcnt + + ; }
2014-10-24 13:43:08 -04:00
tgl_do_send_extf ( TLS , line , strlen ( line ) , callback_extf , ev ) ;
2014-09-17 17:03:20 -04:00
in_readline = 0 ;
return ;
}
2013-10-29 20:08:30 -04:00
while ( 1 ) {
2014-09-17 17:03:20 -04:00
next_token ( ) ;
if ( cur_token_quoted ) {
in_readline = 0 ;
2015-05-15 06:31:38 -04:00
fail_interface ( TLS , ex , ENOSYS , " can not parse modifier " ) ;
2014-09-17 17:03:20 -04:00
return ;
2013-10-29 20:08:30 -04:00
}
2013-10-31 19:18:34 -04:00
2014-09-17 17:03:20 -04:00
if ( cur_token_len < = 0 ) {
in_readline = 0 ;
2015-05-15 06:31:38 -04:00
fail_interface ( TLS , ex , ENOSYS , " can not parse modifier " ) ;
2014-09-17 17:03:20 -04:00
return ;
2013-10-29 20:08:30 -04:00
}
2014-09-17 17:03:20 -04:00
if ( * cur_token = = ' [ ' ) {
if ( cur_token_end_str ) {
in_readline = 0 ;
2015-05-15 06:31:38 -04:00
fail_interface ( TLS , ex , ENOSYS , " can not parse modifier " ) ;
2014-09-17 17:03:20 -04:00
return ;
}
if ( cur_token [ cur_token_len - 1 ] ! = ' ] ' ) {
in_readline = 0 ;
2015-05-15 06:31:38 -04:00
fail_interface ( TLS , ex , ENOSYS , " can not parse modifier " ) ;
2014-09-17 17:03:20 -04:00
return ;
}
work_modifier ( cur_token , cur_token_len ) ;
continue ;
2013-10-30 06:10:16 -04:00
}
2014-09-17 17:03:20 -04:00
break ;
}
if ( cur_token_quoted | | cur_token_end_str ) {
2015-05-15 06:31:38 -04:00
fail_interface ( TLS , ex , ENOSYS , " can not parse command name " ) ;
2014-09-17 17:03:20 -04:00
in_readline = 0 ;
return ;
}
struct command * command = commands ;
int n = 0 ;
struct tgl_command ;
while ( command - > name ) {
if ( is_same_word ( cur_token , cur_token_len , command - > name ) ) {
break ;
2013-10-30 06:10:16 -04:00
}
2014-09-17 17:03:20 -04:00
n + + ;
command + + ;
}
if ( ! command - > name ) {
2015-05-20 14:24:19 -04:00
fail_interface ( TLS , ex , ENOSYS , " can not find command '%.*s' " , cur_token_len , cur_token ) ;
2014-09-17 17:03:20 -04:00
in_readline = 0 ;
return ;
}
enum command_argument * flags = command - > args ;
2015-05-06 07:39:45 -04:00
void ( * fun ) ( struct command * , int , struct arg [ ] , struct in_ev * ) = command - > fun ;
2014-09-17 17:03:20 -04:00
int args_num = 0 ;
static struct arg args [ 1000 ] ;
while ( 1 ) {
assert ( args_num < 1000 ) ;
args [ args_num ] . flags = 0 ;
int period = 0 ;
if ( * flags = = ca_period ) {
flags - - ;
2014-11-28 08:16:51 -05:00
period = 1 ;
2013-10-30 06:10:16 -04:00
}
2014-09-17 17:03:20 -04:00
enum command_argument op = ( * flags ) & 255 ;
int opt = ( * flags ) & ca_optional ;
if ( op = = ca_none ) {
next_token ( ) ;
if ( cur_token_end_str ) {
2014-09-29 12:48:27 -04:00
int z ;
for ( z = 0 ; z < count ; z + + ) {
2015-05-06 07:39:45 -04:00
fun ( command , args_num , args , ex ) ;
2014-09-29 12:48:27 -04:00
}
2015-05-15 06:31:38 -04:00
} else {
fail_interface ( TLS , ex , ENOSYS , " too many args #%d " , args_num ) ;
2014-09-17 17:03:20 -04:00
}
break ;
2013-10-30 06:10:16 -04:00
}
2014-09-17 17:03:20 -04:00
2015-06-17 05:05:57 -04:00
if ( op = = ca_string_end | | op = = ca_file_name_end | | op = = ca_msg_string_end ) {
2014-09-17 17:03:20 -04:00
next_token_end ( ) ;
if ( cur_token_len < 0 ) {
2015-05-15 06:31:38 -04:00
fail_interface ( TLS , ex , ENOSYS , " can not parse string_end arg #%d " , args_num ) ;
2014-09-17 17:03:20 -04:00
break ;
} else {
args [ args_num ] . flags = 1 ;
args [ args_num + + ] . str = strndup ( cur_token , cur_token_len ) ;
2014-09-29 12:48:27 -04:00
int z ;
for ( z = 0 ; z < count ; z + + ) {
2015-05-06 07:39:45 -04:00
fun ( command , args_num , args , ex ) ;
2014-09-29 12:48:27 -04:00
}
2014-09-17 17:03:20 -04:00
break ;
}
2013-11-01 11:02:28 -04:00
}
2014-09-17 17:03:20 -04:00
char * save = line_ptr ;
next_token ( ) ;
if ( period & & cur_token_end_str ) {
2014-09-29 12:48:27 -04:00
int z ;
for ( z = 0 ; z < count ; z + + ) {
2015-05-06 07:39:45 -04:00
fun ( command , args_num , args , ex ) ;
2014-09-29 12:48:27 -04:00
}
2014-09-17 17:03:20 -04:00
break ;
2013-11-06 18:12:40 -05:00
}
2014-09-17 17:03:20 -04:00
2015-10-01 07:11:31 -04:00
if ( op = = ca_user | | op = = ca_chat | | op = = ca_secret_chat | | op = = ca_peer | | op = = ca_number | | op = = ca_double | | op = = ca_msg_id | | op = = ca_channel ) {
2014-09-17 17:03:20 -04:00
if ( cur_token_quoted ) {
if ( opt ) {
2015-09-30 12:49:50 -04:00
if ( op ! = ca_number & & op ! = ca_double & & op ! = ca_msg_id ) {
2015-10-01 07:11:31 -04:00
args [ args_num + + ] . peer_id = TGL_PEER_NOT_FOUND ;
2014-09-17 17:03:20 -04:00
} else {
2014-10-03 05:35:02 -04:00
if ( op = = ca_number ) {
args [ args_num + + ] . num = NOT_FOUND ;
2015-09-30 12:49:50 -04:00
} else if ( op = = ca_msg_id ) {
args [ args_num + + ] . msg_id . peer_type = 0 ;
2014-10-03 05:35:02 -04:00
} else {
args [ args_num + + ] . dval = NOT_FOUND ;
}
2014-09-17 17:03:20 -04:00
}
line_ptr = save ;
flags + + ;
continue ;
2014-11-28 08:16:51 -05:00
} else if ( period ) {
line_ptr = save ;
flags + = 2 ;
continue ;
2014-08-26 17:03:50 -04:00
} else {
2014-09-17 17:03:20 -04:00
break ;
}
} else {
if ( cur_token_end_str ) {
if ( opt ) {
2015-09-30 12:49:50 -04:00
if ( op ! = ca_number & & op ! = ca_double & & op ! = ca_msg_id ) {
2015-10-01 07:11:31 -04:00
args [ args_num + + ] . peer_id = TGL_PEER_NOT_FOUND ;
2014-09-17 17:03:20 -04:00
} else {
2014-10-03 05:35:02 -04:00
if ( op = = ca_number ) {
args [ args_num + + ] . num = NOT_FOUND ;
2015-09-30 12:49:50 -04:00
} else if ( op = = ca_msg_id ) {
args [ args_num + + ] . msg_id . peer_type = 0 ;
2014-10-03 05:35:02 -04:00
} else {
args [ args_num + + ] . dval = NOT_FOUND ;
}
2014-09-17 17:03:20 -04:00
}
line_ptr = save ;
flags + + ;
continue ;
2014-11-28 08:16:51 -05:00
} else if ( period ) {
line_ptr = save ;
flags + = 2 ;
continue ;
2014-09-17 17:03:20 -04:00
} else {
2014-08-26 17:03:50 -04:00
break ;
}
}
2014-09-17 17:03:20 -04:00
int ok = 1 ;
switch ( op ) {
case ca_user :
2015-10-01 07:11:31 -04:00
args [ args_num + + ] . peer_id = cur_token_user ( ) ;
ok = tgl_get_peer_id ( args [ args_num - 1 ] . peer_id ) ! = NOT_FOUND ;
2014-09-17 17:03:20 -04:00
break ;
case ca_chat :
2015-10-01 07:11:31 -04:00
args [ args_num + + ] . peer_id = cur_token_chat ( ) ;
ok = tgl_get_peer_id ( args [ args_num - 1 ] . peer_id ) ! = NOT_FOUND ;
2014-09-17 17:03:20 -04:00
break ;
case ca_secret_chat :
2015-10-01 07:11:31 -04:00
args [ args_num + + ] . peer_id = cur_token_encr_chat ( ) ;
ok = tgl_get_peer_id ( args [ args_num - 1 ] . peer_id ) ! = NOT_FOUND ;
break ;
case ca_channel :
args [ args_num + + ] . peer_id = cur_token_channel ( ) ;
ok = tgl_get_peer_id ( args [ args_num - 1 ] . peer_id ) ! = NOT_FOUND ;
2014-09-17 17:03:20 -04:00
break ;
case ca_peer :
2015-10-01 07:11:31 -04:00
args [ args_num + + ] . peer_id = cur_token_peer ( ) ;
ok = tgl_get_peer_id ( args [ args_num - 1 ] . peer_id ) ! = NOT_FOUND ;
2014-09-17 17:03:20 -04:00
break ;
case ca_number :
args [ args_num + + ] . num = cur_token_int ( ) ;
ok = ( args [ args_num - 1 ] . num ! = NOT_FOUND ) ;
break ;
2015-09-30 12:49:50 -04:00
case ca_msg_id :
args [ args_num + + ] . msg_id = cur_token_msg_id ( ) ;
ok = ( args [ args_num - 1 ] . msg_id . peer_type ! = 0 ) ;
break ;
2014-10-03 05:35:02 -04:00
case ca_double :
args [ args_num + + ] . dval = cur_token_double ( ) ;
ok = ( args [ args_num - 1 ] . dval ! = NOT_FOUND ) ;
break ;
2014-09-17 17:03:20 -04:00
default :
assert ( 0 ) ;
}
if ( opt & & ! ok ) {
line_ptr = save ;
flags + + ;
continue ;
2014-08-29 11:46:04 -04:00
}
2014-11-28 08:16:51 -05:00
if ( period & & ! ok ) {
line_ptr = save ;
flags + = 2 ;
args_num - - ;
continue ;
}
2014-09-17 17:03:20 -04:00
if ( ! ok ) {
2015-05-15 06:31:38 -04:00
fail_interface ( TLS , ex , ENOSYS , " can not parse arg #%d " , args_num ) ;
2014-09-17 17:03:20 -04:00
break ;
}
flags + + ;
continue ;
2014-08-29 11:46:04 -04:00
}
}
2015-10-01 07:11:31 -04:00
if ( op = = ca_string | | op = = ca_file_name | | op = = ca_command ) {
2014-09-17 17:03:20 -04:00
if ( cur_token_end_str | | cur_token_len < 0 ) {
2015-05-15 06:31:38 -04:00
fail_interface ( TLS , ex , ENOSYS , " can not parse string arg #%d " , args_num ) ;
2014-09-17 17:03:20 -04:00
break ;
} else {
args [ args_num ] . flags = 1 ;
args [ args_num + + ] . str = strndup ( cur_token , cur_token_len ) ;
flags + + ;
continue ;
}
2014-09-11 07:04:04 -04:00
}
2015-06-17 05:05:57 -04:00
//assert (0);
2013-10-11 16:52:20 -04:00
}
2014-09-17 17:03:20 -04:00
int i ;
for ( i = 0 ; i < args_num ; i + + ) {
if ( args [ i ] . flags & 1 ) {
free ( args [ i ] . str ) ;
}
2013-11-25 12:16:34 -05:00
}
2014-09-17 17:03:20 -04:00
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
}
2014-11-12 09:38:44 -05:00
void interpreter ( char * line ) {
2014-09-20 18:22:35 -04:00
interpreter_ex ( line , 0 ) ;
}
2013-10-13 06:18:08 -04:00
int readline_active ;
2014-09-20 18:22:35 -04:00
/*void rprintf (const char *format, ...) {
mprint_start ( ev ) ;
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 ( ) ;
2014-09-20 18:22:35 -04:00
} */
2013-10-13 06:18:08 -04:00
2013-10-18 15:30:24 -04:00
int saved_point ;
char * saved_line ;
2015-07-26 11:57:05 -04:00
static int prompt_was ;
2015-01-11 16:52:40 -05:00
void deactivate_readline ( void ) {
if ( read_one_string ) {
printf ( " \033 [2K \r " ) ;
fflush ( stdout ) ;
} else {
2013-10-18 15:30:24 -04:00
saved_point = rl_point ;
2014-08-14 18:16:01 -04:00
saved_line = malloc ( rl_end + 1 ) ;
2014-09-11 05:24:06 -04:00
assert ( saved_line ) ;
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 ) ;
rl_redisplay ( ) ;
}
2015-01-11 16:52:40 -05:00
}
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 ( ) ;
}
2013-10-18 15:30:24 -04:00
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 ) {
2015-01-11 16:52:40 -05:00
reactivate_readline ( ) ;
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) {
2014-09-20 18:22:35 -04:00
mprint_start ( ev ) ;
2013-10-13 06:18:08 -04:00
int * ptr = in_ptr ;
2014-09-20 18:22:35 -04:00
while ( ptr < in_end ) { mprintf ( ev , " %08x " , * ( ptr + + ) ) ; }
mprintf ( ev , " \n " ) ;
mprint_end ( ev ) ;
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 ( " *** " ) ;
2015-10-01 07:48:46 -04:00
double T = tglt_get_double_time ( ) ;
printf ( " %.6lf " , T ) ;
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-09-20 18:22:35 -04:00
void print_media ( struct in_ev * ev , 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 :
2015-06-01 08:44:48 -04:00
if ( ! M - > photo ) {
mprintf ( ev , " [photo bad] " ) ;
} else if ( M - > photo - > caption & & strlen ( M - > photo - > caption ) ) {
2015-04-30 06:00:16 -04:00
mprintf ( ev , " [photo %s] " , M - > photo - > caption ) ;
2013-10-21 14:24:31 -04:00
} else {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " [photo] " ) ;
2013-10-21 14:24:31 -04:00
}
2015-05-05 05:48:58 -04:00
if ( M - > caption ) {
mprintf ( ev , " %s " , M - > caption ) ;
}
2013-10-18 15:30:24 -04:00
return ;
2015-01-11 16:52:40 -05:00
case tgl_message_media_document :
2015-10-01 13:39:29 -04:00
case tgl_message_media_audio :
case tgl_message_media_video :
2015-01-11 16:52:40 -05:00
mprintf ( ev , " [ " ) ;
2015-04-30 06:00:16 -04:00
assert ( M - > document ) ;
2015-05-14 08:48:20 -04:00
if ( M - > document - > flags & TGLDF_IMAGE ) {
2015-01-11 16:52:40 -05:00
mprintf ( ev , " image " ) ;
2015-05-14 08:48:20 -04:00
} else if ( M - > document - > flags & TGLDF_AUDIO ) {
2015-01-11 16:52:40 -05:00
mprintf ( ev , " audio " ) ;
2015-05-14 08:48:20 -04:00
} else if ( M - > document - > flags & TGLDF_VIDEO ) {
2015-01-11 16:52:40 -05:00
mprintf ( ev , " video " ) ;
2015-05-14 08:48:20 -04:00
} else if ( M - > document - > flags & TGLDF_STICKER ) {
2015-01-11 16:52:40 -05:00
mprintf ( ev , " sticker " ) ;
2014-08-12 21:22:15 -04:00
} else {
2015-01-11 16:52:40 -05:00
mprintf ( ev , " document " ) ;
2014-08-12 21:22:15 -04:00
}
2015-01-11 16:52:40 -05:00
2015-04-30 06:00:16 -04:00
if ( M - > document - > caption & & strlen ( M - > document - > caption ) ) {
mprintf ( ev , " %s: " , M - > document - > caption ) ;
2014-08-12 21:22:15 -04:00
} else {
2015-01-11 16:52:40 -05:00
mprintf ( ev , " : " ) ;
2014-08-12 21:22:15 -04:00
}
2015-01-11 16:52:40 -05:00
2015-04-30 06:00:16 -04:00
if ( M - > document - > mime_type ) {
mprintf ( ev , " type=%s " , M - > document - > mime_type ) ;
2015-01-11 16:52:40 -05:00
}
2015-04-30 06:00:16 -04:00
if ( M - > document - > w & & M - > document - > h ) {
mprintf ( ev , " size=%dx%d " , M - > document - > w , M - > document - > h ) ;
2015-01-11 16:52:40 -05:00
}
2015-04-30 06:00:16 -04:00
if ( M - > document - > duration ) {
mprintf ( ev , " duration=%d " , M - > document - > duration ) ;
2015-01-11 16:52:40 -05:00
}
mprintf ( ev , " size= " ) ;
2015-04-30 06:00:16 -04:00
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 ) ;
2013-11-15 05:37:14 -05:00
} else {
2015-04-30 06:00:16 -04:00
mprintf ( ev , " %dGiB " , M - > document - > size > > 30 ) ;
2013-11-15 05:37:14 -05:00
}
2015-01-11 16:52:40 -05:00
mprintf ( ev , " ] " ) ;
2015-05-05 05:48:58 -04:00
if ( M - > caption ) {
mprintf ( ev , " %s " , M - > caption ) ;
}
2015-01-11 16:52:40 -05:00
2013-11-04 12:34:27 -05:00
return ;
2015-01-11 16:52:40 -05:00
case tgl_message_media_document_encr :
mprintf ( ev , " [ " ) ;
2015-05-14 08:48:20 -04:00
if ( M - > encr_document - > flags & TGLDF_IMAGE ) {
2015-01-14 11:19:03 -05:00
mprintf ( ev , " image " ) ;
2015-05-14 08:48:20 -04:00
} else if ( M - > encr_document - > flags & TGLDF_AUDIO ) {
2015-01-14 11:19:03 -05:00
mprintf ( ev , " audio " ) ;
2015-05-14 08:48:20 -04:00
} else if ( M - > encr_document - > flags & TGLDF_VIDEO ) {
2015-01-14 11:19:03 -05:00
mprintf ( ev , " video " ) ;
2015-05-14 08:48:20 -04:00
} else if ( M - > encr_document - > flags & TGLDF_STICKER ) {
2015-01-14 11:19:03 -05:00
mprintf ( ev , " sticker " ) ;
2014-08-18 12:39:04 -04:00
} else {
2015-01-14 11:19:03 -05:00
mprintf ( ev , " document " ) ;
2014-08-18 12:39:04 -04:00
}
2015-01-11 16:52:40 -05:00
2015-04-30 06:43:48 -04:00
if ( M - > encr_document - > caption & & strlen ( M - > encr_document - > caption ) ) {
mprintf ( ev , " %s: " , M - > encr_document - > caption ) ;
2014-08-18 12:39:04 -04:00
} else {
2015-01-11 16:52:40 -05:00
mprintf ( ev , " : " ) ;
2014-08-18 12:39:04 -04:00
}
2015-01-11 16:52:40 -05:00
2015-04-30 06:43:48 -04:00
if ( M - > encr_document - > mime_type ) {
mprintf ( ev , " type=%s " , M - > encr_document - > mime_type ) ;
2015-01-11 16:52:40 -05:00
}
2015-04-30 06:43:48 -04:00
if ( M - > encr_document - > w & & M - > encr_document - > h ) {
mprintf ( ev , " size=%dx%d " , M - > encr_document - > w , M - > encr_document - > h ) ;
2014-08-18 12:39:04 -04:00
}
2015-01-11 16:52:40 -05:00
2015-04-30 06:43:48 -04:00
if ( M - > encr_document - > duration ) {
mprintf ( ev , " duration=%d " , M - > encr_document - > duration ) ;
2015-01-14 11:19:03 -05:00
}
mprintf ( ev , " size= " ) ;
2015-04-30 06:43:48 -04:00
if ( M - > encr_document - > size < ( 1 < < 10 ) ) {
mprintf ( ev , " %dB " , M - > encr_document - > size ) ;
} else if ( M - > encr_document - > size < ( 1 < < 20 ) ) {
mprintf ( ev , " %dKiB " , M - > encr_document - > size > > 10 ) ;
} else if ( M - > encr_document - > size < ( 1 < < 30 ) ) {
mprintf ( ev , " %dMiB " , M - > encr_document - > size > > 20 ) ;
2015-01-14 11:19:03 -05:00
} else {
2015-04-30 06:43:48 -04:00
mprintf ( ev , " %dGiB " , M - > encr_document - > size > > 30 ) ;
2015-01-11 16:52:40 -05:00
}
mprintf ( ev , " ] " ) ;
2013-11-15 05:37:14 -05:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_geo :
2015-05-01 13:26:47 -04:00
mprintf ( ev , " [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 :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " [contact] " ) ;
mpush_color ( ev , COLOR_RED ) ;
mprintf ( ev , " %s %s " , M - > first_name , M - > last_name ) ;
mpop_color ( ev ) ;
mprintf ( ev , " %s " , M - > phone ) ;
2013-10-18 15:30:24 -04:00
return ;
2014-08-18 12:39:04 -04:00
case tgl_message_media_unsupported :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " [unsupported] " ) ;
2013-10-18 15:30:24 -04:00
return ;
2015-04-22 13:09:53 -04:00
case tgl_message_media_webpage :
mprintf ( ev , " [webpage: " ) ;
2015-05-01 11:12:07 -04:00
assert ( M - > webpage ) ;
2015-04-30 06:43:48 -04:00
if ( M - > webpage - > url ) {
mprintf ( ev , " url:'%s' " , M - > webpage - > url ) ;
2015-04-22 13:09:53 -04:00
}
2015-04-30 06:43:48 -04:00
if ( M - > webpage - > title ) {
mprintf ( ev , " title:'%s' " , M - > webpage - > title ) ;
2015-04-22 13:09:53 -04:00
}
2015-04-30 06:43:48 -04:00
if ( M - > webpage - > description ) {
mprintf ( ev , " description:'%s' " , M - > webpage - > description ) ;
2015-04-22 13:09:53 -04:00
}
2015-04-30 06:43:48 -04:00
if ( M - > webpage - > author ) {
mprintf ( ev , " author:'%s' " , M - > webpage - > author ) ;
2015-04-22 13:09:53 -04:00
}
mprintf ( ev , " ] " ) ;
break ;
2015-05-01 13:26:47 -04:00
case tgl_message_media_venue :
mprintf ( ev , " [geo https://maps.google.com/?q=%.6lf,%.6lf " , M - > venue . geo . latitude , M - > venue . geo . longitude ) ;
if ( M - > venue . title ) {
mprintf ( ev , " title:'%s' " , M - > venue . title ) ;
}
if ( M - > venue . address ) {
mprintf ( ev , " address:'%s' " , M - > venue . address ) ;
}
if ( M - > venue . provider ) {
mprintf ( ev , " provider:'%s' " , M - > venue . provider ) ;
}
if ( M - > venue . venue_id ) {
mprintf ( ev , " id:'%s' " , M - > venue . venue_id ) ;
}
mprintf ( ev , " ] " ) ;
return ;
2013-10-18 15:30:24 -04:00
default :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " 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 ] ;
2015-09-30 13:41:29 -04:00
void print_peer_permanent_name ( struct in_ev * ev , tgl_peer_id_t id ) {
2015-10-01 07:11:31 -04:00
mprintf ( ev , " %s " , print_permanent_peer_id ( id ) ) ;
2015-09-30 13:41:29 -04:00
}
2014-09-20 18:22:35 -04:00
void print_user_name ( struct in_ev * ev , tgl_peer_id_t id , tgl_peer_t * U ) {
2014-08-13 11:55:16 -04:00
assert ( tgl_get_peer_type ( id ) = = TGL_PEER_USER ) ;
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_RED ) ;
2015-09-30 13:41:29 -04:00
if ( permanent_peer_id_mode ) {
print_peer_permanent_name ( ev , id ) ;
mpop_color ( ev ) ;
return ;
}
2014-10-13 05:46:24 -04:00
if ( ! U ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " 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 {
2015-04-22 13:09:53 -04:00
if ( U - > flags & ( TGLUF_SELF | TGLUF_CONTACT ) ) {
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_REDB ) ;
2013-10-23 06:24:59 -04:00
}
2015-04-22 13:09:53 -04:00
if ( ( U - > flags & TGLUF_DELETED ) ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " deleted user#%d " , tgl_get_peer_id ( id ) ) ;
2015-04-22 13:09:53 -04:00
} else if ( ! ( U - > flags & TGLUF_CREATED ) ) {
2014-10-13 05:46:24 -04:00
mprintf ( ev , " user#%d " , tgl_get_peer_id ( id ) ) ;
} else if ( use_ids ) {
mprintf ( ev , " 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 ) ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " %s " , U - > user . last_name ) ;
2013-11-06 18:12:40 -05:00
} else if ( ! U - > user . last_name | | ! strlen ( U - > user . last_name ) ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " %s " , U - > user . first_name ) ;
2013-10-23 06:24:59 -04:00
} else {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " %s %s " , U - > user . first_name , U - > user . last_name ) ;
2013-10-23 06:24:59 -04:00
}
2015-04-22 13:09:53 -04:00
if ( U - > flags & ( TGLUF_SELF | TGLUF_CONTACT ) ) {
2014-09-20 18:22:35 -04:00
mpop_color ( ev ) ;
2013-10-23 06:24:59 -04:00
}
2013-10-18 15:30:24 -04:00
}
2014-09-20 18:22:35 -04:00
mpop_color ( ev ) ;
2013-10-18 15:30:24 -04:00
}
2014-09-20 18:22:35 -04:00
void print_chat_name ( struct in_ev * ev , tgl_peer_id_t id , tgl_peer_t * C ) {
2014-08-13 11:55:16 -04:00
assert ( tgl_get_peer_type ( id ) = = TGL_PEER_CHAT ) ;
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_MAGENTA ) ;
2015-09-30 13:41:29 -04:00
if ( permanent_peer_id_mode ) {
print_peer_permanent_name ( ev , id ) ;
mpop_color ( ev ) ;
return ;
}
2014-10-11 20:27:34 -04:00
if ( ! C | | use_ids ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " chat#%d " , tgl_get_peer_id ( id ) ) ;
2013-10-18 15:30:24 -04:00
} else {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " %s " , C - > chat . title ) ;
2013-10-18 15:30:24 -04:00
}
2014-09-20 18:22:35 -04:00
mpop_color ( ev ) ;
2013-10-18 15:30:24 -04:00
}
2015-09-25 11:28:23 -04:00
void print_channel_name ( struct in_ev * ev , tgl_peer_id_t id , tgl_peer_t * C ) {
assert ( tgl_get_peer_type ( id ) = = TGL_PEER_CHANNEL ) ;
mpush_color ( ev , COLOR_CYAN ) ;
2015-09-30 13:41:29 -04:00
if ( permanent_peer_id_mode ) {
print_peer_permanent_name ( ev , id ) ;
mpop_color ( ev ) ;
return ;
}
2015-09-25 11:28:23 -04:00
if ( ! C | | use_ids ) {
mprintf ( ev , " channel#%d " , tgl_get_peer_id ( id ) ) ;
} else {
mprintf ( ev , " %s " , C - > channel . title ) ;
}
mpop_color ( ev ) ;
}
2014-09-20 18:22:35 -04:00
void print_encr_chat_name ( struct in_ev * ev , tgl_peer_id_t id , tgl_peer_t * C ) {
2014-08-13 11:55:16 -04:00
assert ( tgl_get_peer_type ( id ) = = TGL_PEER_ENCR_CHAT ) ;
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_MAGENTA ) ;
2015-09-30 13:41:29 -04:00
if ( permanent_peer_id_mode ) {
print_peer_permanent_name ( ev , id ) ;
mpop_color ( ev ) ;
return ;
}
2014-10-11 20:27:34 -04:00
if ( ! C | | use_ids ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " encr_chat#%d " , tgl_get_peer_id ( id ) ) ;
2013-11-02 13:01:22 -04:00
} else {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " %s " , C - > print_name ) ;
2013-11-02 13:01:22 -04:00
}
2014-09-20 18:22:35 -04:00
mpop_color ( ev ) ;
2013-11-02 13:01:22 -04:00
}
2015-09-30 14:06:40 -04:00
void print_peer_name ( struct in_ev * ev , tgl_peer_id_t id , tgl_peer_t * C ) {
switch ( tgl_get_peer_type ( id ) ) {
case TGL_PEER_USER :
print_user_name ( ev , id , C ) ;
return ;
case TGL_PEER_CHAT :
print_chat_name ( ev , id , C ) ;
return ;
case TGL_PEER_CHANNEL :
print_channel_name ( ev , id , C ) ;
return ;
case TGL_PEER_ENCR_CHAT :
print_encr_chat_name ( ev , id , C ) ;
return ;
default :
assert ( 0 ) ;
2013-11-02 13:01:22 -04:00
}
}
2013-10-18 15:30:24 -04:00
static char * monthes [ ] = { " Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " , " Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec " } ;
2014-09-20 18:22:35 -04:00
void print_date ( struct in_ev * ev , 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 ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " [%02d:%02d] " , tm - > tm_hour , tm - > tm_min ) ;
2015-04-24 07:08:01 -04:00
} else if ( time ( 0 ) - t < 24 * 60 * 60 * 180 ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " [%02d %s] " , tm - > tm_mday , monthes [ tm - > tm_mon ] ) ;
2015-04-24 07:08:01 -04:00
} else {
mprintf ( ev , " [%02d %s %d] " , tm - > tm_mday , monthes [ tm - > tm_mon ] , tm - > tm_year + 1900 ) ;
2013-10-18 15:30:24 -04:00
}
}
2014-09-20 18:22:35 -04:00
void print_date_full ( struct in_ev * ev , long t ) {
2014-02-18 13:06:00 -05:00
struct tm * tm = localtime ( ( void * ) & t ) ;
2014-09-20 18:22:35 -04:00
mprintf ( ev , " [%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 ) ;
2013-10-24 03:38:32 -04:00
}
2015-10-01 08:54:01 -04:00
void print_msg_id ( struct in_ev * ev , tgl_message_id_t msg_id , struct tgl_message * M ) {
2015-09-30 12:49:50 -04:00
if ( msg_num_mode ) {
2015-09-30 13:41:29 -04:00
if ( ! permanent_msg_id_mode ) {
2015-10-01 08:54:01 -04:00
if ( M ) {
mprintf ( ev , " %d " , M - > temp_id ) ;
} else {
mprintf ( ev , " ??? " ) ;
}
2015-09-30 12:49:50 -04:00
} else {
2015-10-01 08:54:01 -04:00
mprintf ( ev , " %s " , print_permanent_msg_id ( msg_id ) ) ;
2015-09-30 12:49:50 -04:00
}
}
}
2014-09-20 18:22:35 -04:00
void print_service_message ( struct in_ev * ev , struct tgl_message * M ) {
2013-12-19 17:50:31 -05:00
assert ( M ) ;
2014-08-18 12:39:04 -04:00
//print_start ();
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_GREY ) ;
2015-09-25 11:28:23 -04:00
if ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_CHANNEL ) {
mpush_color ( ev , COLOR_CYAN ) ;
} else {
mpush_color ( ev , COLOR_MAGENTA ) ;
}
2015-10-01 08:54:01 -04:00
print_msg_id ( ev , M - > permanent_id , M ) ;
mprintf ( ev , " " ) ;
2014-09-20 18:22:35 -04:00
print_date ( ev , M - > date ) ;
mpop_color ( ev ) ;
mprintf ( ev , " " ) ;
2014-08-13 11:55:16 -04:00
if ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_CHAT ) {
2014-10-24 13:43:08 -04:00
print_chat_name ( ev , M - > to_id , tgl_peer_get ( TLS , M - > to_id ) ) ;
2015-09-25 11:28:23 -04:00
} else if ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_CHANNEL ) {
print_channel_name ( ev , M - > to_id , tgl_peer_get ( TLS , 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 ) ;
2014-10-24 13:43:08 -04:00
print_encr_chat_name ( ev , M - > to_id , tgl_peer_get ( TLS , M - > to_id ) ) ;
2013-11-15 05:37:14 -05:00
}
2015-09-25 11:28:23 -04:00
if ( tgl_get_peer_type ( M - > from_id ) = = TGL_PEER_USER ) {
mprintf ( ev , " " ) ;
print_user_name ( ev , M - > from_id , tgl_peer_get ( TLS , 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 :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " \n " ) ;
2013-10-21 15:27:29 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_geo_chat_create :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " Created geo chat \n " ) ;
2013-11-22 18:26:35 -05:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_geo_chat_checkin :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " Checkin in geochat \n " ) ;
2013-11-22 18:26:35 -05:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_create :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " created chat %s. %d users \n " , M - > action . title , M - > action . user_num ) ;
2013-10-21 15:27:29 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_edit_title :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " changed title to %s \n " ,
2013-10-21 15:27:29 -04:00
M - > action . new_title ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_edit_photo :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " changed photo \n " ) ;
2013-10-21 15:27:29 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_delete_photo :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " deleted photo \n " ) ;
2013-10-21 15:27:29 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_add_user :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " added user " ) ;
2014-10-24 13:43:08 -04:00
print_user_name ( ev , tgl_set_peer_id ( TGL_PEER_USER , M - > action . user ) , tgl_peer_get ( TLS , tgl_set_peer_id ( TGL_PEER_USER , M - > action . user ) ) ) ;
2014-09-20 18:22:35 -04:00
mprintf ( ev , " \n " ) ;
2013-10-21 15:27:29 -04:00
break ;
2015-05-01 12:32:06 -04:00
case tgl_message_action_chat_add_user_by_link :
mprintf ( ev , " added by link from " ) ;
print_user_name ( ev , tgl_set_peer_id ( TGL_PEER_USER , M - > action . user ) , tgl_peer_get ( TLS , tgl_set_peer_id ( TGL_PEER_USER , M - > action . user ) ) ) ;
mprintf ( ev , " \n " ) ;
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_chat_delete_user :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " deleted user " ) ;
2014-10-24 13:43:08 -04:00
print_user_name ( ev , tgl_set_peer_id ( TGL_PEER_USER , M - > action . user ) , tgl_peer_get ( TLS , tgl_set_peer_id ( TGL_PEER_USER , M - > action . user ) ) ) ;
2014-09-20 18:22:35 -04:00
mprintf ( ev , " \n " ) ;
2013-10-21 15:27:29 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_set_message_ttl :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " set ttl to %d seconds. Unsupported yet \n " , M - > action . ttl ) ;
2013-11-15 05:37:14 -05:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_read_messages :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " %d messages marked read \n " , M - > action . read_cnt ) ;
2014-08-12 21:22:15 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_delete_messages :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " %d messages deleted \n " , M - > action . delete_cnt ) ;
2014-08-12 21:22:15 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_screenshot_messages :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " %d messages screenshoted \n " , M - > action . screenshot_cnt ) ;
2014-08-12 21:22:15 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_flush_history :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " cleared history \n " ) ;
2014-11-11 05:33:03 -05:00
break ;
case tgl_message_action_resend :
mprintf ( ev , " resend query \n " ) ;
2014-08-12 21:22:15 -04:00
break ;
2014-08-18 12:39:04 -04:00
case tgl_message_action_notify_layer :
2014-09-20 18:22:35 -04:00
mprintf ( ev , " updated layer to %d \n " , M - > action . layer ) ;
2014-08-12 21:22:15 -04:00
break ;
2014-09-29 08:11:48 -04:00
case tgl_message_action_typing :
mprintf ( ev , " is " ) ;
print_typing ( ev , M - > action . typing ) ;
break ;
2014-11-13 11:22:12 -05:00
case tgl_message_action_noop :
mprintf ( ev , " noop \n " ) ;
break ;
case tgl_message_action_request_key :
mprintf ( ev , " request rekey #%016llx \n " , M - > action . exchange_id ) ;
break ;
case tgl_message_action_accept_key :
mprintf ( ev , " accept rekey #%016llx \n " , M - > action . exchange_id ) ;
break ;
case tgl_message_action_commit_key :
mprintf ( ev , " commit rekey #%016llx \n " , M - > action . exchange_id ) ;
break ;
case tgl_message_action_abort_key :
mprintf ( ev , " abort rekey #%016llx \n " , M - > action . exchange_id ) ;
break ;
2015-09-25 11:28:23 -04:00
case tgl_message_action_channel_create :
mprintf ( ev , " created channel %s \n " , M - > action . title ) ;
break ;
2013-10-21 15:27:29 -04:00
}
2014-09-20 18:22:35 -04:00
mpop_color ( ev ) ;
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-09-20 18:22:35 -04:00
void print_message ( struct in_ev * ev , struct tgl_message * M ) {
2013-12-19 17:50:31 -05:00
assert ( M ) ;
2015-04-22 13:09:53 -04:00
if ( M - > flags & ( TGLMF_EMPTY | TGLMF_DELETED ) ) {
2013-11-04 12:34:27 -05:00
return ;
}
2015-04-22 13:09:53 -04:00
if ( ! ( M - > flags & TGLMF_CREATED ) ) { return ; }
if ( M - > flags & TGLMF_SERVICE ) {
2014-09-20 18:22:35 -04:00
print_service_message ( ev , 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 ) {
2015-04-22 13:09:53 -04:00
if ( M - > flags & TGLMF_OUT ) {
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_GREEN ) ;
2015-10-01 08:54:01 -04:00
print_msg_id ( ev , M - > permanent_id , M ) ;
mprintf ( ev , " " ) ;
2014-09-20 18:22:35 -04:00
print_date ( ev , M - > date ) ;
mpop_color ( ev ) ;
mprintf ( ev , " " ) ;
2014-10-24 13:43:08 -04:00
print_user_name ( ev , M - > to_id , tgl_peer_get ( TLS , M - > to_id ) ) ;
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_GREEN ) ;
2015-04-22 13:09:53 -04:00
if ( M - > flags & TGLMF_UNREAD ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " <<< " ) ;
2013-10-21 14:24:31 -04:00
} else {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " ««« " ) ;
2013-10-21 14:24:31 -04:00
}
2013-10-16 15:19:39 -04:00
} else {
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_BLUE ) ;
2015-10-01 08:54:01 -04:00
print_msg_id ( ev , M - > permanent_id , M ) ;
mprintf ( ev , " " ) ;
2014-09-20 18:22:35 -04:00
print_date ( ev , M - > date ) ;
mpop_color ( ev ) ;
mprintf ( ev , " " ) ;
2014-10-24 13:43:08 -04:00
print_user_name ( ev , M - > from_id , tgl_peer_get ( TLS , M - > from_id ) ) ;
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_BLUE ) ;
2015-04-22 13:09:53 -04:00
if ( M - > flags & TGLMF_UNREAD ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " >>> " ) ;
2013-10-21 14:24:31 -04:00
} else {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " »»» " ) ;
2014-02-27 03:48:05 -05:00
}
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 ) {
2014-10-24 13:43:08 -04:00
tgl_peer_t * P = tgl_peer_get ( TLS , M - > to_id ) ;
2013-11-04 12:34:27 -05:00
assert ( P ) ;
2015-04-22 13:09:53 -04:00
if ( M - > flags & TGLMF_UNREAD ) {
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_GREEN ) ;
2015-10-01 08:54:01 -04:00
print_msg_id ( ev , M - > permanent_id , M ) ;
mprintf ( ev , " " ) ;
2014-09-20 18:22:35 -04:00
print_date ( ev , M - > date ) ;
mprintf ( ev , " " ) ;
mpush_color ( ev , COLOR_CYAN ) ;
mprintf ( ev , " %s " , P - > print_name ) ;
mpop_color ( ev ) ;
2015-04-22 13:09:53 -04:00
if ( M - > flags & TGLMF_UNREAD ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " <<< " ) ;
2013-11-04 12:34:27 -05:00
} else {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " ««« " ) ;
2013-11-04 12:34:27 -05:00
}
} else {
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_BLUE ) ;
2015-10-01 08:54:01 -04:00
print_msg_id ( ev , M - > permanent_id , M ) ;
mprintf ( ev , " " ) ;
2014-09-20 18:22:35 -04:00
print_date ( ev , M - > date ) ;
mpush_color ( ev , COLOR_CYAN ) ;
mprintf ( ev , " %s " , P - > print_name ) ;
mpop_color ( ev ) ;
2015-04-22 13:09:53 -04:00
if ( M - > flags & TGLMF_UNREAD ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " >>> " ) ;
2013-11-04 12:34:27 -05:00
} else {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " »»» " ) ;
2014-02-27 03:48:05 -05:00
}
2013-11-04 12:34:27 -05:00
}
2015-09-25 11:28:23 -04:00
} else if ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_CHAT ) {
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_MAGENTA ) ;
2015-10-01 08:54:01 -04:00
print_msg_id ( ev , M - > permanent_id , M ) ;
mprintf ( ev , " " ) ;
2014-09-20 18:22:35 -04:00
print_date ( ev , M - > date ) ;
mpop_color ( ev ) ;
mprintf ( ev , " " ) ;
2014-10-24 13:43:08 -04:00
print_chat_name ( ev , M - > to_id , tgl_peer_get ( TLS , M - > to_id ) ) ;
2014-09-20 18:22:35 -04:00
mprintf ( ev , " " ) ;
2014-10-24 13:43:08 -04:00
print_user_name ( ev , M - > from_id , tgl_peer_get ( TLS , M - > from_id ) ) ;
2015-09-30 12:49:50 -04:00
if ( ! tgl_cmp_peer_id ( M - > from_id , TLS - > our_id ) ) {
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_GREEN ) ;
2013-10-18 15:30:24 -04:00
} else {
2014-09-20 18:22:35 -04:00
mpush_color ( ev , COLOR_BLUE ) ;
2013-10-16 15:19:39 -04:00
}
2015-04-22 13:09:53 -04:00
if ( M - > flags & TGLMF_UNREAD ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " >>> " ) ;
2013-10-21 14:24:31 -04:00
} else {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " »»» " ) ;
2013-10-21 14:24:31 -04:00
}
2015-09-25 11:28:23 -04:00
} else {
assert ( tgl_get_peer_type ( M - > to_id ) = = TGL_PEER_CHANNEL ) ;
mpush_color ( ev , COLOR_CYAN ) ;
2015-10-01 08:54:01 -04:00
print_msg_id ( ev , M - > permanent_id , M ) ;
mprintf ( ev , " " ) ;
2015-09-25 11:28:23 -04:00
print_date ( ev , M - > date ) ;
mpop_color ( ev ) ;
mprintf ( ev , " " ) ;
print_channel_name ( ev , M - > to_id , tgl_peer_get ( TLS , M - > to_id ) ) ;
if ( tgl_get_peer_type ( M - > from_id ) = = TGL_PEER_USER ) {
mprintf ( ev , " " ) ;
print_user_name ( ev , M - > from_id , tgl_peer_get ( TLS , M - > from_id ) ) ;
2015-09-30 12:49:50 -04:00
if ( ! tgl_cmp_peer_id ( M - > from_id , TLS - > our_id ) ) {
2015-09-25 11:28:23 -04:00
mpush_color ( ev , COLOR_GREEN ) ;
} else {
mpush_color ( ev , COLOR_BLUE ) ;
}
} else {
mpush_color ( ev , COLOR_BLUE ) ;
}
if ( M - > flags & TGLMF_UNREAD ) {
mprintf ( ev , " >>> " ) ;
} else {
mprintf ( ev , " »»» " ) ;
}
2013-10-18 15:30:24 -04:00
}
2015-09-30 14:06:40 -04:00
if ( tgl_get_peer_type ( M - > fwd_from_id ) > 0 ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " [fwd from " ) ;
2015-09-30 14:06:40 -04:00
print_peer_name ( ev , M - > fwd_from_id , tgl_peer_get ( TLS , M - > fwd_from_id ) ) ;
2014-09-20 18:22:35 -04:00
mprintf ( ev , " ] " ) ;
2013-10-24 18:21:52 -04:00
}
2015-04-23 11:22:11 -04:00
if ( M - > reply_id ) {
2015-10-01 08:54:01 -04:00
mprintf ( ev , " [reply to " ) ;
tgl_message_id_t msg_id = M - > permanent_id ;
msg_id . id = M - > reply_id ;
struct tgl_message * N = tgl_message_get ( TLS , & msg_id ) ;
print_msg_id ( ev , msg_id , N ) ;
mprintf ( ev , " ] " ) ;
2015-04-23 11:22:11 -04:00
}
2015-04-27 10:52:19 -04:00
if ( M - > flags & TGLMF_MENTION ) {
mprintf ( ev , " [mention] " ) ;
}
2013-10-18 15:30:24 -04:00
if ( M - > message & & strlen ( M - > message ) ) {
2014-09-20 18:22:35 -04:00
mprintf ( ev , " %s " , M - > message ) ;
2013-10-18 15:30:24 -04:00
}
2014-08-18 12:39:04 -04:00
if ( M - > media . type ! = tgl_message_media_none ) {
2015-04-22 13:09:53 -04:00
if ( M - > message & & strlen ( M - > message ) ) {
mprintf ( ev , " " ) ;
}
2014-09-20 18:22:35 -04:00
print_media ( ev , & M - > media ) ;
2013-10-16 15:19:39 -04:00
}
2014-09-20 18:22:35 -04:00
mpop_color ( ev ) ;
2013-10-18 15:30:24 -04:00
assert ( ! color_stack_pos ) ;
2014-09-20 18:22:35 -04:00
mprintf ( ev , " \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 ;
2015-05-05 14:08:37 -04:00
rl_filename_quote_characters = strdup ( " " ) ;
rl_basic_word_break_characters = strdup ( " " ) ;
2013-11-09 17:47:19 -05:00
rl_callback_handler_install ( get_default_prompt ( ) , interpreter ) ;
2014-08-25 12:17:17 -04:00
rl_completion_entry_function = command_generator ;
2013-11-09 17:47:19 -05:00
}