2010-10-01 12:34:14 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-03-18 16:24:57 +03:00
Samba readline wrapper implementation
2001-03-19 02:41:53 +03:00
Copyright ( C ) Simo Sorce 2001
2001-03-18 16:24:57 +03:00
Copyright ( C ) Andrew Tridgell 2001
2010-10-01 12:34:14 +04:00
2001-03-18 16:24:57 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2001-03-18 16:24:57 +03:00
( at your option ) any later version .
2010-10-01 12:34:14 +04:00
2001-03-18 16:24:57 +03:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2010-10-01 12:34:14 +04:00
2001-03-18 16:24:57 +03:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2001-03-18 16:24:57 +03:00
*/
# include "includes.h"
2010-10-01 12:08:15 +04:00
# include "../lib/util/select.h"
2010-10-01 12:34:14 +04:00
# include "system/filesys.h"
# include "system/select.h"
# include "system/readline.h"
# include "libcli/smbreadline/smbreadline.h"
# undef malloc
2001-03-18 16:24:57 +03:00
2002-09-25 19:19:00 +04:00
# ifdef HAVE_LIBREADLINE
# ifdef HAVE_READLINE_READLINE_H
# include <readline / readline.h>
# ifdef HAVE_READLINE_HISTORY_H
# include <readline / history.h>
# endif
# else
# ifdef HAVE_READLINE_H
# include <readline.h>
# ifdef HAVE_HISTORY_H
# include <history.h>
# endif
# else
# undef HAVE_LIBREADLINE
# endif
# endif
# endif
2008-10-04 01:58:41 +04:00
static bool smb_rl_done ;
2018-11-20 16:06:21 +03:00
# ifdef HAVE_LIBREADLINE
2008-10-05 15:12:31 +04:00
/*
* MacOS / X does not have rl_done in readline . h , but
* readline . so has it
*/
extern int rl_done ;
# endif
2008-10-04 01:58:41 +04:00
void smb_readline_done ( void )
{
smb_rl_done = true ;
2018-11-20 16:06:21 +03:00
# ifdef HAVE_LIBREADLINE
2008-10-04 01:58:41 +04:00
rl_done = 1 ;
# endif
}
2001-03-18 16:24:57 +03:00
/****************************************************************************
2002-01-20 01:54:13 +03:00
Display the prompt and wait for input . Call callback ( ) regularly
2001-03-18 16:24:57 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-20 01:54:13 +03:00
2010-10-01 12:34:14 +04:00
static char * smb_readline_replacement ( const char * prompt , void ( * callback ) ( void ) ,
2003-08-11 23:11:43 +04:00
char * * ( completion_fn ) ( const char * text , int start , int end ) )
2001-03-18 16:24:57 +03:00
{
2007-12-07 04:16:33 +03:00
char * line = NULL ;
2016-11-23 12:07:48 +03:00
int fd = fileno ( stdin ) ;
2002-01-20 01:54:13 +03:00
char * ret ;
2001-03-19 02:41:53 +03:00
2006-06-16 03:51:20 +04:00
/* Prompt might be NULL in non-interactive mode. */
if ( prompt ) {
2016-11-23 12:07:48 +03:00
printf ( " %s " , prompt ) ;
fflush ( stdout ) ;
2006-06-16 03:51:20 +04:00
}
2001-03-18 16:24:57 +03:00
2010-10-01 12:34:14 +04:00
line = ( char * ) malloc ( BUFSIZ ) ;
2007-12-07 04:16:33 +03:00
if ( ! line ) {
return NULL ;
2007-11-16 01:19:52 +03:00
}
2008-10-04 01:58:41 +04:00
while ( ! smb_rl_done ) {
2011-02-14 14:14:12 +03:00
struct pollfd pfd ;
2001-03-18 16:24:57 +03:00
2011-02-14 14:14:12 +03:00
ZERO_STRUCT ( pfd ) ;
pfd . fd = fd ;
pfd . events = POLLIN | POLLHUP ;
2007-11-16 01:19:52 +03:00
2011-02-14 14:14:12 +03:00
if ( sys_poll_intr ( & pfd , 1 , 5000 ) = = 1 ) {
2016-11-23 12:07:48 +03:00
ret = fgets ( line , BUFSIZ , stdin ) ;
2007-12-07 04:16:33 +03:00
if ( ret = = 0 ) {
SAFE_FREE ( line ) ;
}
2001-03-19 02:41:53 +03:00
return ret ;
}
2007-12-07 04:16:33 +03:00
if ( callback ) {
2002-01-20 01:54:13 +03:00
callback ( ) ;
2007-12-07 04:16:33 +03:00
}
2001-03-19 02:41:53 +03:00
}
2008-10-30 01:55:45 +03:00
SAFE_FREE ( line ) ;
2008-10-04 01:58:41 +04:00
return NULL ;
2001-07-20 11:46:39 +04:00
}
/****************************************************************************
2002-01-20 01:54:13 +03:00
Display the prompt and wait for input . Call callback ( ) regularly .
2001-07-20 11:46:39 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-20 01:54:13 +03:00
2007-12-07 04:16:33 +03:00
char * smb_readline ( const char * prompt , void ( * callback ) ( void ) ,
2003-08-11 23:11:43 +04:00
char * * ( completion_fn ) ( const char * text , int start , int end ) )
2001-07-20 11:46:39 +04:00
{
2006-06-16 03:51:20 +04:00
char * ret ;
2007-10-19 04:40:25 +04:00
bool interactive ;
2006-06-16 03:51:20 +04:00
2016-11-23 12:07:48 +03:00
interactive = isatty ( fileno ( stdin ) ) | | getenv ( " CLI_FORCE_INTERACTIVE " ) ;
2006-06-16 03:51:20 +04:00
if ( ! interactive ) {
2007-12-07 04:16:33 +03:00
return smb_readline_replacement ( NULL , callback , completion_fn ) ;
2006-06-16 03:51:20 +04:00
}
2018-11-20 16:06:21 +03:00
# ifdef HAVE_LIBREADLINE
2002-01-20 01:54:13 +03:00
2006-06-16 03:51:20 +04:00
/* Aargh! Readline does bizzare things with the terminal width
that mucks up expect ( 1 ) . Set CLI_NO_READLINE in the environment
to force readline not to be used . */
if ( getenv ( " CLI_NO_READLINE " ) )
return smb_readline_replacement ( prompt , callback , completion_fn ) ;
if ( completion_fn ) {
/* The callback prototype has changed slightly between
different versions of Readline , so the same function
works in all of them to date , but we get compiler
warnings in some . */
rl_attempted_completion_function = RL_COMPLETION_CAST completion_fn ;
2015-09-19 02:19:54 +03:00
/*
* We only want sensible characters as the word - break chars
* for the most part . This allows us to tab through a path .
*/
rl_basic_word_break_characters = " \t \n " ;
2006-06-16 03:51:20 +04:00
}
2018-11-20 16:06:21 +03:00
# ifdef HAVE_DECL_RL_EVENT_HOOK
2006-06-16 03:51:20 +04:00
if ( callback )
2014-03-07 01:57:40 +04:00
rl_event_hook = ( rl_hook_func_t * ) callback ;
2006-10-11 17:59:03 +04:00
# endif
2006-06-16 03:51:20 +04:00
ret = readline ( prompt ) ;
if ( ret & & * ret )
add_history ( ret ) ;
# else
ret = smb_readline_replacement ( prompt , callback , completion_fn ) ;
2001-03-18 16:24:57 +03:00
# endif
2006-06-16 03:51:20 +04:00
return ret ;
2001-03-18 16:24:57 +03:00
}
2003-05-12 22:12:31 +04:00
/****************************************************************************
* return line buffer text
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
const char * smb_readline_get_line_buffer ( void )
{
# if defined(HAVE_LIBREADLINE)
return rl_line_buffer ;
# else
return NULL ;
# endif
}
/****************************************************************************
* set completion append character
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void smb_readline_ca_char ( char c )
{
# if defined(HAVE_LIBREADLINE)
rl_completion_append_character = c ;
# endif
}