diff options
Diffstat (limited to 'source4/lib/replace')
-rw-r--r-- | source4/lib/replace/README | 2 | ||||
-rw-r--r-- | source4/lib/replace/config.m4 | 3 | ||||
-rw-r--r-- | source4/lib/replace/config.mk | 4 | ||||
-rw-r--r-- | source4/lib/replace/getpass.c | 158 | ||||
-rw-r--r-- | source4/lib/replace/getpass.m4 | 15 | ||||
-rw-r--r-- | source4/lib/replace/readline.c | 119 | ||||
-rw-r--r-- | source4/lib/replace/readline.m4 | 72 |
7 files changed, 371 insertions, 2 deletions
diff --git a/source4/lib/replace/README b/source4/lib/replace/README index 80a2d5c163..19364e2faa 100644 --- a/source4/lib/replace/README +++ b/source4/lib/replace/README @@ -48,6 +48,8 @@ errno mkstemp (a secure one!) pread pwrite +getpass +readline (the library) Types: socklen_t diff --git a/source4/lib/replace/config.m4 b/source4/lib/replace/config.m4 index 70d13e40fd..379c14e776 100644 --- a/source4/lib/replace/config.m4 +++ b/source4/lib/replace/config.m4 @@ -124,3 +124,6 @@ LIBS="$SAVE_LIBS" AC_CHECK_FUNCS([syslog memset setnetgrent getnetgrent endnetgrent memcpy],, [AC_MSG_ERROR([Required function not found])]) + +sinclude(lib/replace/readline.m4) +sinclude(lib/replace/getpass.m4) diff --git a/source4/lib/replace/config.mk b/source4/lib/replace/config.mk index 7ed33b2dc0..459465c64f 100644 --- a/source4/lib/replace/config.mk +++ b/source4/lib/replace/config.mk @@ -7,13 +7,13 @@ NOPROTO = YES # End SUBSYSTEM REPLACE_READDIR ############################## - ############################## # Start SUBSYSTEM LIBREPLACE [SUBSYSTEM::LIBREPLACE] OBJ_FILES = replace.o \ snprintf.o \ - dlfcn.o + dlfcn.o \ + getpass.o NOPROTO = YES REQUIRED_SUBSYSTEMS = REPLACE_READDIR # End SUBSYSTEM LIBREPLACE diff --git a/source4/lib/replace/getpass.c b/source4/lib/replace/getpass.c new file mode 100644 index 0000000000..4ffcde8dfd --- /dev/null +++ b/source4/lib/replace/getpass.c @@ -0,0 +1,158 @@ +/* Copyright (C) 1992-1998 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Modified to use with samba by Jeremy Allison, 8th July 1995. */ + +#include "includes.h" +#include "system/terminal.h" +#include "system/wait.h" + +#ifdef REPLACE_GETPASS + +#ifdef SYSV_TERMIO + +/* SYSTEM V TERMIO HANDLING */ + +static struct termio t; + +#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) +#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) +#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) + +#ifndef TCSAFLUSH +#define TCSAFLUSH 1 +#endif + +#ifndef TCSANOW +#define TCSANOW 0 +#endif + +static int tcgetattr(int fd, struct termio *_t) +{ + return ioctl(fd, TCGETA, _t); +} + +static int tcsetattr(int fd, int flags, struct termio *_t) +{ + if(flags & TCSAFLUSH) + ioctl(fd, TCFLSH, TCIOFLUSH); + return ioctl(fd, TCSETS, _t); +} + +#elif !defined(TCSAFLUSH) + +/* BSD TERMIO HANDLING */ + +static struct sgttyb t; + +#define ECHO_IS_ON(t) ((t).sg_flags & ECHO) +#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO) +#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO) + +#define TCSAFLUSH 1 +#define TCSANOW 0 + +static int tcgetattr(int fd, struct sgttyb *_t) +{ + return ioctl(fd, TIOCGETP, (char *)_t); +} + +static int tcsetattr(int fd, int flags, struct sgttyb *_t) +{ + return ioctl(fd, TIOCSETP, (char *)_t); +} + +#else /* POSIX TERMIO HANDLING */ +#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) +#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) +#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) + +static struct termios t; +#endif /* SYSV_TERMIO */ + +char *getsmbpass(const char *prompt) +{ + FILE *in, *out; + int echo_off; + static char buf[256]; + static size_t bufsize = sizeof(buf); + size_t nread; + + /* Catch problematic signals */ + CatchSignal(SIGINT, SIGNAL_CAST SIG_IGN); + + /* Try to write to and read from the terminal if we can. + If we can't open the terminal, use stderr and stdin. */ + + in = fopen ("/dev/tty", "w+"); + if (in == NULL) + { + in = stdin; + out = stderr; + } + else + out = in; + + setvbuf(in, NULL, _IONBF, 0); + + /* Turn echoing off if it is on now. */ + + if (tcgetattr (fileno (in), &t) == 0) + { + if (ECHO_IS_ON(t)) + { + TURN_ECHO_OFF(t); + echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0; + TURN_ECHO_ON(t); + } + else + echo_off = 0; + } + else + echo_off = 0; + + /* Write the prompt. */ + fputs (prompt, out); + fflush (out); + + /* Read the password. */ + buf[0] = 0; + fgets(buf, bufsize, in); + nread = strlen(buf); + if (buf[nread - 1] == '\n') + buf[nread - 1] = '\0'; + + /* Restore echoing. */ + if (echo_off) + (void) tcsetattr (fileno (in), TCSANOW, &t); + + if (in != stdin) + /* We opened the terminal; now close it. */ + fclose (in); + + /* Catch problematic signals */ + CatchSignal(SIGINT, SIGNAL_CAST SIG_DFL); + + printf("\n"); + return buf; +} + +#else + void getsmbpasswd_dummy(void); + void getsmbpasswd_dummy(void) {;} +#endif diff --git a/source4/lib/replace/getpass.m4 b/source4/lib/replace/getpass.m4 new file mode 100644 index 0000000000..2bd9d7bc1a --- /dev/null +++ b/source4/lib/replace/getpass.m4 @@ -0,0 +1,15 @@ +AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[ +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper" +AC_TRY_COMPILE([ +#define REPLACE_GETPASS 1 +#define NO_CONFIG_H 1 +#define main dont_declare_main +#include "${srcdir-.}/lib/cmdline/getsmbpass.c" +#undef main +],[],samba_cv_REPLACE_GETPASS=yes,samba_cv_REPLACE_GETPASS=no) +CPPFLAGS="$SAVE_CPPFLAGS" +]) +if test x"$samba_cv_REPLACE_GETPASS" = x"yes"; then + AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) +fi diff --git a/source4/lib/replace/readline.c b/source4/lib/replace/readline.c new file mode 100644 index 0000000000..52f45eb759 --- /dev/null +++ b/source4/lib/replace/readline.c @@ -0,0 +1,119 @@ +/* + Unix SMB/CIFS implementation. + Samba readline wrapper implementation + Copyright (C) Simo Sorce 2001 + Copyright (C) Andrew Tridgell 2001 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "pstring.h" + +#include <unistd.h> +#include "system/readline.h" + +/**************************************************************************** + Display the prompt and wait for input. Call callback() regularly +****************************************************************************/ + +static char *smb_readline_replacement(const char *prompt, void (*callback)(void), + char **(completion_fn)(const char *text, int start, int end)) +{ + fd_set fds; + static pstring line; + struct timeval timeout; + int fd = STDIN_FILENO; + char *ret; + + do_debug("%s", prompt); + + while (1) { + timeout.tv_sec = 5; + timeout.tv_usec = 0; + + FD_ZERO(&fds); + FD_SET(fd,&fds); + + if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) { + ret = x_fgets(line, sizeof(line), x_stdin); + return ret; + } + if (callback) + callback(); + } +} + +/**************************************************************************** + Display the prompt and wait for input. Call callback() regularly. +****************************************************************************/ + +char *smb_readline(const char *prompt, void (*callback)(void), + char **(completion_fn)(const char *text, int start, int end)) +{ +#if HAVE_LIBREADLINE + if (isatty(STDIN_FILENO)) { + char *ret; + + /* 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; + } + + if (callback) + rl_event_hook = (Function *)callback; + ret = readline(prompt); + if (ret && *ret) + add_history(ret); + return ret; + } else +#endif + return smb_readline_replacement(prompt, callback, completion_fn); +} + +/**************************************************************************** + * 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 +} + + + diff --git a/source4/lib/replace/readline.m4 b/source4/lib/replace/readline.m4 new file mode 100644 index 0000000000..0d1aa60d17 --- /dev/null +++ b/source4/lib/replace/readline.m4 @@ -0,0 +1,72 @@ +############################################### +# Readline included by default unless explicitly asked not to +test "${with_readline+set}" != "set" && with_readline=yes + +# test for where we get readline() from +AC_MSG_CHECKING(whether to use readline) +AC_ARG_WITH(readline, +[ --with-readline[=DIR] Look for readline include/libs in DIR (default=auto) ], +[ case "$with_readline" in + yes) + AC_MSG_RESULT(yes) + + AC_CHECK_HEADERS(readline.h history.h readline/readline.h) + AC_CHECK_HEADERS(readline/history.h) + + AC_CHECK_HEADERS(readline.h readline/readline.h,[ + for termlib in ncurses curses termcap terminfo termlib tinfo; do + AC_CHECK_LIB(${termlib}, tgetent, [TERMLIBS="-l${termlib}"; break]) + done + AC_CHECK_LIB(readline, rl_callback_handler_install, + [TERMLIBS="-lreadline $TERMLIBS" + AC_DEFINE(HAVE_LIBREADLINE,1,[Whether the system has readline]) + break], [TERMLIBS=], $TERMLIBS)]) + ;; + no) + AC_MSG_RESULT(no) + ;; + *) + AC_MSG_RESULT(yes) + + # Needed for AC_CHECK_HEADERS and AC_CHECK_LIB to look at + # alternate readline path + _ldflags=${LDFLAGS} + _cppflags=${CPPFLAGS} + + # Add additional search path + LDFLAGS="-L$with_readline/lib $LDFLAGS" + CPPFLAGS="-I$with_readline/include $CPPFLAGS" + + AC_CHECK_HEADERS(readline.h history.h readline/readline.h) + AC_CHECK_HEADERS(readline/history.h) + + AC_CHECK_HEADERS(readline.h readline/readline.h,[ + for termlib in ncurses curses termcap terminfo termlib; do + AC_CHECK_LIB(${termlib}, tgetent, [TERMLIBS="-l${termlib}"; break]) + done + AC_CHECK_LIB(readline, rl_callback_handler_install, + [TERMLDFLAGS="-L$with_readline/lib" + TERMCPPFLAGS="-I$with_readline/include" + LDFLAGS="-L$with_readline/lib $LDFLAGS" + CPPFLAGS="-I$with_readline/include $CPPFLAGS" + TERMLIBS="-lreadline $TERMLIBS" + AC_DEFINE(HAVE_LIBREADLINE,1,[Whether the system has readline]) + break], [TERMLIBS= CPPFLAGS=$_cppflags], $TERMLIBS)]) + + ;; + esac], + AC_MSG_RESULT(no) +) + +# The readline API changed slightly from readline3 to readline4, so +# code will generate warnings on one of them unless we have a few +# special cases. +AC_CHECK_LIB(readline, rl_completion_matches, + [AC_DEFINE(HAVE_NEW_LIBREADLINE, 1, + [Do we have rl_completion_matches?])], + [], + [$TERMLIBS]) + +SMB_EXT_LIB(READLINE, [${TERMLIBS}]) + +SMB_SUBSYSTEM(LIBREADLINE, [lib/replace/readline.o], [EXT_LIB_READLINE]) |