r16274: Fix the smbclient prompting behaviour for both systems that have
authorJames Peach <jpeach@samba.org>
Thu, 15 Jun 2006 23:51:20 +0000 (23:51 +0000)
committerJames Peach <jpeach@samba.org>
Thu, 15 Jun 2006 23:51:20 +0000 (23:51 +0000)
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.

source/client/client.c
source/client/smbctool.c
source/lib/readline.c
source/lib/xfile.c

index 36029ea3de68f9564b4d79823d545da2753972b5..a56b8583bb1b6066dd50d7b6253587cc69ab8274 100644 (file)
@@ -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);
index a6a657a30a58369cdbde0c2b20074aa6fb6e89e7..178c05df85099b5d066964c0b5f14e81ee216240 100644 (file)
@@ -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);
index c1f1dc7f4003c872a01b0e29bb48f94d86e76bdf..1f599dc0a7f8061e031cfc6d583df9fd6cbda294 100644 (file)
@@ -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;
 }
 
 /****************************************************************************
index 71f8bdbcbb6873f3c4dbe77589fbd26b1356efc5..ef33c7894f75fe3152a5459201c046a150586852 100644 (file)
@@ -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;
 }