From 06491a4cb12d8753c63525b3ba4d754d2ab1e822 Mon Sep 17 00:00:00 2001 From: James Peach Date: Thu, 15 Jun 2006 23:51:20 +0000 Subject: r16274: Fix the smbclient prompting behaviour for both systems that have libreadline and those that don't. We always use the built-in readline replacement for non-interactive mode. Interactive prompts are always emitted to stdout and non-interactive mode never prompts at all. Introduce x_fdup to avoid spuriously closing stdout when a logfile is specified on the command line and setup_logging is called a second time. (This used to be commit 848ac756f651a4be231e5635580c0fd5f3d3fa0e) --- source3/client/client.c | 5 ++-- source3/client/smbctool.c | 7 ++--- source3/lib/readline.c | 65 +++++++++++++++++++++++++++-------------------- source3/lib/xfile.c | 24 ++++++++++++++++- 4 files changed, 68 insertions(+), 33 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 94fcaaca00..d7fe4d43c3 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -3422,8 +3422,9 @@ static int do_message_op(void) /* set default debug level to 0 regardless of what smb.conf sets */ setup_logging( "smbclient", True ); DEBUGLEVEL_CLASS[DBGC_ALL] = 1; - dbf = x_stderr; - x_setbuf( x_stderr, NULL ); + if ((dbf = x_fdup(x_stderr))) { + x_setbuf( dbf, NULL ); + } pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); diff --git a/source3/client/smbctool.c b/source3/client/smbctool.c index 5b21d195b7..b3acca5573 100644 --- a/source3/client/smbctool.c +++ b/source3/client/smbctool.c @@ -3561,10 +3561,11 @@ static int do_message_op(void) set_global_myname( "" ); /* set default debug level to 0 regardless of what smb.conf sets */ - setup_logging( "smbclient", True ); + setup_logging( "smbctool", True ); DEBUGLEVEL_CLASS[DBGC_ALL] = 1; - dbf = x_stderr; - x_setbuf( x_stderr, NULL ); + if ((dbf = x_fdup(x_stderr))) { + x_setbuf( dbf, NULL ); + } pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); diff --git a/source3/lib/readline.c b/source3/lib/readline.c index c1f1dc7f40..1f599dc0a7 100644 --- a/source3/lib/readline.c +++ b/source3/lib/readline.c @@ -59,8 +59,11 @@ static char *smb_readline_replacement(const char *prompt, void (*callback)(void) int fd = x_fileno(x_stdin); char *ret; - x_fprintf(dbf, "%s", prompt); - x_fflush(dbf); + /* Prompt might be NULL in non-interactive mode. */ + if (prompt) { + x_fprintf(x_stdout, "%s", prompt); + x_fflush(x_stdout); + } while (1) { timeout.tv_sec = 5; @@ -85,34 +88,42 @@ static char *smb_readline_replacement(const char *prompt, void (*callback)(void) char *smb_readline(const char *prompt, void (*callback)(void), char **(completion_fn)(const char *text, int start, int end)) { + char *ret; + BOOL interactive; + + interactive = isatty(x_fileno(x_stdin)) || getenv("CLI_FORCE_INTERACTIVE"); + if (!interactive) { + return smb_readline_replacement(NULL, callback, completion_fn); + } + #if HAVE_LIBREADLINE - if (isatty(x_fileno(x_stdin))) { - 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 + /* 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); + +#else + ret = smb_readline_replacement(prompt, callback, completion_fn); #endif - return smb_readline_replacement(prompt, callback, completion_fn); + + return ret; } /**************************************************************************** diff --git a/source3/lib/xfile.c b/source3/lib/xfile.c index 71f8bdbcbb..ef33c7894f 100644 --- a/source3/lib/xfile.c +++ b/source3/lib/xfile.c @@ -123,6 +123,28 @@ XFILE *x_fopen(const char *fname, int flags, mode_t mode) return ret; } +XFILE *x_fdup(const XFILE *f) +{ + XFILE *ret; + int fd; + + fd = dup(x_fileno(f)); + if (fd < 0) { + return NULL; + } + + ret = SMB_CALLOC_ARRAY(XFILE, 1); + if (!ret) { + close(fd); + return NULL; + } + + ret->fd = fd; + ret->open_flags = f->open_flags; + x_setvbuf(ret, NULL, X_IOFBF, XBUFSIZE); + return ret; +} + /* simulate fclose() */ int x_fclose(XFILE *f) { @@ -220,7 +242,7 @@ size_t x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f) } /* at least fileno() is simple! */ -int x_fileno(XFILE *f) +int x_fileno(const XFILE *f) { return f->fd; } -- cgit