LCOV - code coverage report
Current view: top level - libcli/smbreadline - smbreadline.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 33 46 71.7 %
Date: 2021-09-23 10:06:22 Functions: 3 6 50.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba readline wrapper implementation
       4             :    Copyright (C) Simo Sorce 2001
       5             :    Copyright (C) Andrew Tridgell 2001
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "../lib/util/select.h"
      23             : #include "system/filesys.h"
      24             : #include "system/select.h"
      25             : #include "system/readline.h"
      26             : #include "libcli/smbreadline/smbreadline.h"
      27             : 
      28             : #undef malloc
      29             : 
      30             : #ifdef HAVE_LIBREADLINE
      31             : #  ifdef HAVE_READLINE_READLINE_H
      32             : #    include <readline/readline.h>
      33             : #    ifdef HAVE_READLINE_HISTORY_H
      34             : #      include <readline/history.h>
      35             : #    endif
      36             : #  else
      37             : #    ifdef HAVE_READLINE_H
      38             : #      include <readline.h>
      39             : #      ifdef HAVE_HISTORY_H
      40             : #        include <history.h>
      41             : #      endif
      42             : #    else
      43             : #      undef HAVE_LIBREADLINE
      44             : #    endif
      45             : #  endif
      46             : #endif
      47             : 
      48             : static bool smb_rl_done;
      49             : 
      50             : #ifdef HAVE_LIBREADLINE
      51             : /*
      52             :  * MacOS/X does not have rl_done in readline.h, but
      53             :  * readline.so has it
      54             :  */
      55             : extern int rl_done;
      56             : #endif
      57             : 
      58           2 : void smb_readline_done(void)
      59             : {
      60           2 :         smb_rl_done = true;
      61             : #ifdef HAVE_LIBREADLINE
      62           2 :         rl_done = 1;
      63             : #endif
      64           2 : }
      65             : 
      66             : /****************************************************************************
      67             :  Display the prompt and wait for input. Call callback() regularly
      68             : ****************************************************************************/
      69             : 
      70         295 : static char *smb_readline_replacement(const char *prompt, void (*callback)(void),
      71             :                                 char **(completion_fn)(const char *text, int start, int end))
      72             : {
      73         295 :         char *line = NULL;
      74         295 :         int fd = fileno(stdin);
      75             :         char *ret;
      76             : 
      77             :         /* Prompt might be NULL in non-interactive mode. */
      78         295 :         if (prompt) {
      79           0 :                 printf("%s", prompt);
      80           0 :                 fflush(stdout);
      81             :         }
      82             : 
      83         295 :         line = (char *)malloc(BUFSIZ);
      84         295 :         if (!line) {
      85           0 :                 return NULL;
      86             :         }
      87             : 
      88         558 :         while (!smb_rl_done) {
      89             :                 struct pollfd pfd;
      90             : 
      91         295 :                 ZERO_STRUCT(pfd);
      92         295 :                 pfd.fd = fd;
      93         295 :                 pfd.events = POLLIN|POLLHUP;
      94             : 
      95         295 :                 if (sys_poll_intr(&pfd, 1, 5000) == 1) {
      96         295 :                         ret = fgets(line, BUFSIZ, stdin);
      97         295 :                         if (ret == 0) {
      98          80 :                                 SAFE_FREE(line);
      99             :                         }
     100         295 :                         return ret;
     101             :                 }
     102           0 :                 if (callback) {
     103           0 :                         callback();
     104             :                 }
     105             :         }
     106           0 :         SAFE_FREE(line);
     107           0 :         return NULL;
     108             : }
     109             : 
     110             : /****************************************************************************
     111             :  Display the prompt and wait for input. Call callback() regularly.
     112             : ****************************************************************************/
     113             : 
     114        3582 : char *smb_readline(const char *prompt, void (*callback)(void),
     115             :                    char **(completion_fn)(const char *text, int start, int end))
     116             : {
     117             :         char *ret;
     118             :         bool interactive;
     119             : 
     120        3582 :         interactive = isatty(fileno(stdin)) || getenv("CLI_FORCE_INTERACTIVE");
     121        3582 :         if (!interactive) {
     122         295 :                 return smb_readline_replacement(NULL, callback, completion_fn);
     123             :         }
     124             : 
     125             : #ifdef HAVE_LIBREADLINE
     126             : 
     127             :         /* Aargh!  Readline does bizzare things with the terminal width
     128             :         that mucks up expect(1).  Set CLI_NO_READLINE in the environment
     129             :         to force readline not to be used. */
     130             : 
     131        3287 :         if (getenv("CLI_NO_READLINE"))
     132           0 :                 return smb_readline_replacement(prompt, callback, completion_fn);
     133             : 
     134        3287 :         if (completion_fn) {
     135             :                 /* The callback prototype has changed slightly between
     136             :                 different versions of Readline, so the same function
     137             :                 works in all of them to date, but we get compiler
     138             :                 warnings in some.  */
     139        3287 :                 rl_attempted_completion_function = RL_COMPLETION_CAST completion_fn;
     140             : 
     141             :                 /*
     142             :                  * We only want sensible characters as the word-break chars
     143             :                  * for the most part. This allows us to tab through a path.
     144             :                  */
     145        3287 :                 rl_basic_word_break_characters = " \t\n";
     146             :         }
     147             : 
     148             : #ifdef HAVE_DECL_RL_EVENT_HOOK
     149        3287 :         if (callback)
     150        3287 :                 rl_event_hook = (rl_hook_func_t *)callback;
     151             : #endif
     152        3287 :         ret = readline(prompt);
     153        3287 :         if (ret && *ret)
     154        3285 :                 add_history(ret);
     155             : 
     156             : #else
     157             :         ret = smb_readline_replacement(prompt, callback, completion_fn);
     158             : #endif
     159             : 
     160        3287 :         return ret;
     161             : }
     162             : 
     163             : /****************************************************************************
     164             :  * return line buffer text
     165             :  ****************************************************************************/
     166           0 : const char *smb_readline_get_line_buffer(void)
     167             : {
     168             : #if defined(HAVE_LIBREADLINE)
     169           0 :         return rl_line_buffer;
     170             : #else
     171             :         return NULL;
     172             : #endif
     173             : }
     174             : 
     175             : 
     176             : /****************************************************************************
     177             :  * set completion append character
     178             :  ***************************************************************************/
     179           0 : void smb_readline_ca_char(char c)
     180             : {
     181             : #if defined(HAVE_LIBREADLINE)
     182           0 :         rl_completion_append_character = c;
     183             : #endif
     184           0 : }

Generated by: LCOV version 1.13