LCOV - code coverage report
Current view: top level - common - ttyio.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 11 207 5.3 %
Date: 2015-11-05 17:10:59 Functions: 2 19 10.5 %

          Line data    Source code
       1             : /* ttyio.c -  tty i/O functions
       2             :  * Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2006,2007,
       3             :  *               2009, 2010 Free Software Foundation, Inc.
       4             :  *
       5             :  * This file is part of GnuPG.
       6             :  *
       7             :  * This file is free software; you can redistribute it and/or modify
       8             :  * it under the terms of either
       9             :  *
      10             :  *   - the GNU Lesser General Public License as published by the Free
      11             :  *     Software Foundation; either version 3 of the License, or (at
      12             :  *     your option) any later version.
      13             :  *
      14             :  * or
      15             :  *
      16             :  *   - the GNU General Public License as published by the Free
      17             :  *     Software Foundation; either version 2 of the License, or (at
      18             :  *     your option) any later version.
      19             :  *
      20             :  * or both in parallel, as here.
      21             :  *
      22             :  * This file is distributed in the hope that it will be useful,
      23             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      24             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      25             :  * GNU General Public License for more details.
      26             :  *
      27             :  * You should have received a copy of the GNU General Public License
      28             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      29             :  */
      30             : 
      31             : #include <config.h>
      32             : #include <stdio.h>
      33             : #include <stdlib.h>
      34             : #include <string.h>
      35             : #include <stdarg.h>
      36             : #include <unistd.h>
      37             : 
      38             : #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
      39             : # define USE_W32_CONSOLE 1
      40             : #endif
      41             : 
      42             : #ifdef HAVE_TCGETATTR
      43             : #include <termios.h>
      44             : #else
      45             : #ifdef HAVE_TERMIO_H
      46             : /* simulate termios with termio */
      47             : #include <termio.h>
      48             : #define termios termio
      49             : #define tcsetattr ioctl
      50             : #define TCSAFLUSH TCSETAF
      51             : #define tcgetattr(A,B) ioctl(A,TCGETA,B)
      52             : #define HAVE_TCGETATTR
      53             : #endif
      54             : #endif
      55             : #ifdef USE_W32_CONSOLE
      56             : # ifdef HAVE_WINSOCK2_H
      57             : #  include <winsock2.h>
      58             : # endif
      59             : # include <windows.h>
      60             : # ifdef HAVE_TCGETATTR
      61             : #  error mingw32 and termios
      62             : # endif
      63             : #endif
      64             : #include <errno.h>
      65             : #include <ctype.h>
      66             : 
      67             : #include "util.h"
      68             : #include "ttyio.h"
      69             : #include "common-defs.h"
      70             : 
      71             : #define CONTROL_D ('D' - 'A' + 1)
      72             : 
      73             : 
      74             : #ifdef USE_W32_CONSOLE
      75             : static struct {
      76             :     HANDLE in, out;
      77             : } con;
      78             : #define DEF_INPMODE  (ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT    \
      79             :                                         |ENABLE_PROCESSED_INPUT )
      80             : #define HID_INPMODE  (ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT )
      81             : #define DEF_OUTMODE  (ENABLE_WRAP_AT_EOL_OUTPUT|ENABLE_PROCESSED_OUTPUT)
      82             : 
      83             : #else /* yeah, we have a real OS */
      84             : static FILE *ttyfp = NULL;
      85             : #endif
      86             : 
      87             : static int initialized;
      88             : static int last_prompt_len;
      89             : static int batchmode;
      90             : static int no_terminal;
      91             : 
      92             : #ifdef HAVE_TCGETATTR
      93             :     static struct termios termsave;
      94             :     static int restore_termios;
      95             : #endif
      96             : 
      97             : /* Hooks set by gpgrlhelp.c if required. */
      98             : static void (*my_rl_set_completer) (rl_completion_func_t *);
      99             : static void (*my_rl_inhibit_completion) (int);
     100             : static void (*my_rl_cleanup_after_signal) (void);
     101             : static void (*my_rl_init_stream) (FILE *);
     102             : static char *(*my_rl_readline) (const char*);
     103             : static void (*my_rl_add_history) (const char*);
     104             : 
     105             : 
     106             : /* This is a wrapper around ttyname so that we can use it even when
     107             :    the standard streams are redirected.  It figures the name out the
     108             :    first time and returns it in a statically allocated buffer. */
     109             : const char *
     110           0 : tty_get_ttyname (void)
     111             : {
     112             :   static char *name;
     113             : 
     114             :   /* On a GNU system ctermid() always return /dev/tty, so this does
     115             :      not make much sense - however if it is ever changed we do the
     116             :      Right Thing now. */
     117             : #ifdef HAVE_CTERMID
     118             :   static int got_name;
     119             : 
     120           0 :   if (!got_name)
     121             :     {
     122             :       const char *s;
     123             :       /* Note that despite our checks for these macros the function is
     124             :          not necessarily thread save.  We mainly do this for
     125             :          portability reasons, in case L_ctermid is not defined. */
     126             : # if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_TRHEADS)
     127             :       char buffer[L_ctermid];
     128           0 :       s = ctermid (buffer);
     129             : # else
     130             :       s = ctermid (NULL);
     131             : # endif
     132           0 :       if (s)
     133           0 :         name = strdup (s);
     134           0 :       got_name = 1;
     135             :     }
     136             : #endif /*HAVE_CTERMID*/
     137             :   /* Assume the standard tty on memory error or when there is no
     138             :      ctermid. */
     139           0 :   return name? name : "/dev/tty";
     140             : }
     141             : 
     142             : 
     143             : 
     144             : #ifdef HAVE_TCGETATTR
     145             : static void
     146           0 : cleanup(void)
     147             : {
     148           0 :     if( restore_termios ) {
     149           0 :         restore_termios = 0; /* do it prios in case it is interrupted again */
     150           0 :         if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) )
     151           0 :             log_error("tcsetattr() failed: %s\n", strerror(errno) );
     152             :     }
     153           0 : }
     154             : #endif
     155             : 
     156             : static void
     157           0 : init_ttyfp(void)
     158             : {
     159           0 :     if( initialized )
     160           0 :         return;
     161             : 
     162             : #if defined(USE_W32_CONSOLE)
     163             :     {
     164             :         SECURITY_ATTRIBUTES sa;
     165             : 
     166             :         memset(&sa, 0, sizeof(sa));
     167             :         sa.nLength = sizeof(sa);
     168             :         sa.bInheritHandle = TRUE;
     169             :         con.out = CreateFileA( "CONOUT$", GENERIC_READ|GENERIC_WRITE,
     170             :                                FILE_SHARE_READ|FILE_SHARE_WRITE,
     171             :                                &sa, OPEN_EXISTING, 0, 0 );
     172             :         if( con.out == INVALID_HANDLE_VALUE )
     173             :             log_fatal("open(CONOUT$) failed: rc=%d", (int)GetLastError() );
     174             :         memset(&sa, 0, sizeof(sa));
     175             :         sa.nLength = sizeof(sa);
     176             :         sa.bInheritHandle = TRUE;
     177             :         con.in = CreateFileA( "CONIN$", GENERIC_READ|GENERIC_WRITE,
     178             :                                FILE_SHARE_READ|FILE_SHARE_WRITE,
     179             :                                &sa, OPEN_EXISTING, 0, 0 );
     180             :         if( con.in == INVALID_HANDLE_VALUE )
     181             :             log_fatal("open(CONIN$) failed: rc=%d", (int)GetLastError() );
     182             :     }
     183             :     SetConsoleMode(con.in, DEF_INPMODE );
     184             :     SetConsoleMode(con.out, DEF_OUTMODE );
     185             : 
     186             : #elif defined(__EMX__)
     187             :     ttyfp = stdout; /* Fixme: replace by the real functions: see wklib */
     188             :     if (my_rl_init_stream)
     189             :       my_rl_init_stream (ttyfp);
     190             : #elif defined (HAVE_W32CE_SYSTEM)
     191             :     ttyfp = stderr;
     192             : #else
     193           0 :     ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+");
     194           0 :     if( !ttyfp ) {
     195           0 :         log_error("cannot open '%s': %s\n", tty_get_ttyname (),
     196           0 :                   strerror(errno) );
     197           0 :         exit(2);
     198             :     }
     199           0 :     if (my_rl_init_stream)
     200           0 :       my_rl_init_stream (ttyfp);
     201             : #endif
     202             : 
     203             : 
     204             : #ifdef HAVE_TCGETATTR
     205           0 :     atexit( cleanup );
     206             : #endif
     207           0 :     initialized = 1;
     208             : }
     209             : 
     210             : 
     211             : int
     212        1276 : tty_batchmode( int onoff )
     213             : {
     214        1276 :     int old = batchmode;
     215        1276 :     if( onoff != -1 )
     216        1276 :         batchmode = onoff;
     217        1276 :     return old;
     218             : }
     219             : 
     220             : int
     221           0 : tty_no_terminal(int onoff)
     222             : {
     223           0 :     int old = no_terminal;
     224           0 :     no_terminal = onoff ? 1 : 0;
     225           0 :     return old;
     226             : }
     227             : 
     228             : void
     229           0 : tty_printf( const char *fmt, ... )
     230             : {
     231             :     va_list arg_ptr;
     232             : 
     233           0 :     if (no_terminal)
     234           0 :         return;
     235             : 
     236           0 :     if( !initialized )
     237           0 :         init_ttyfp();
     238             : 
     239           0 :     va_start( arg_ptr, fmt ) ;
     240             : #ifdef USE_W32_CONSOLE
     241             :     {
     242             :         char *buf = NULL;
     243             :         int n;
     244             :         DWORD nwritten;
     245             : 
     246             :         n = vasprintf(&buf, fmt, arg_ptr);
     247             :         if( !buf )
     248             :             log_bug("vasprintf() failed\n");
     249             : 
     250             :         if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) )
     251             :             log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() );
     252             :         if( n != nwritten )
     253             :             log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten );
     254             :         last_prompt_len += n;
     255             :         xfree (buf);
     256             :     }
     257             : #else
     258           0 :     last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ;
     259           0 :     fflush(ttyfp);
     260             : #endif
     261           0 :     va_end(arg_ptr);
     262             : }
     263             : 
     264             : 
     265             : /* Same as tty_printf but if FP is not NULL, behave like a regular
     266             :    fprintf. */
     267             : void
     268        1740 : tty_fprintf (estream_t fp, const char *fmt, ... )
     269             : {
     270             :   va_list arg_ptr;
     271             : 
     272        1740 :   if (fp)
     273             :     {
     274        1740 :       va_start (arg_ptr, fmt) ;
     275        1740 :       es_vfprintf (fp, fmt, arg_ptr );
     276        1740 :       va_end (arg_ptr);
     277        3480 :       return;
     278             :     }
     279             : 
     280           0 :   if (no_terminal)
     281           0 :     return;
     282             : 
     283           0 :   if (!initialized)
     284           0 :     init_ttyfp ();
     285             : 
     286           0 :   va_start (arg_ptr, fmt);
     287             : #ifdef USE_W32_CONSOLE
     288             :   {
     289             :     char *buf = NULL;
     290             :     int n;
     291             :     DWORD nwritten;
     292             : 
     293             :     n = vasprintf(&buf, fmt, arg_ptr);
     294             :     if (!buf)
     295             :       log_bug("vasprintf() failed\n");
     296             : 
     297             :     if (!WriteConsoleA( con.out, buf, n, &nwritten, NULL ))
     298             :       log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() );
     299             :     if (n != nwritten)
     300             :       log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten );
     301             :     last_prompt_len += n;
     302             :     xfree (buf);
     303             :   }
     304             : #else
     305           0 :   last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ;
     306           0 :   fflush(ttyfp);
     307             : #endif
     308           0 :   va_end(arg_ptr);
     309             : }
     310             : 
     311             : 
     312             : /****************
     313             :  * Print a string, but filter all control characters out.  If FP is
     314             :  * not NULL print to that stream instead to the tty.
     315             :  */
     316             : void
     317           0 : tty_print_string (estream_t fp, const byte *p, size_t n )
     318             : {
     319           0 :     if (no_terminal && !fp)
     320           0 :         return;
     321             : 
     322           0 :     if( !initialized & !fp)
     323           0 :         init_ttyfp();
     324             : 
     325             : #ifdef USE_W32_CONSOLE
     326             :     /* not so effective, change it if you want */
     327             :     if (fp)
     328             :       {
     329             :         for( ; n; n--, p++ )
     330             :           {
     331             :             if( iscntrl( *p ) )
     332             :               {
     333             :                 if( *p == '\n' )
     334             :                   tty_fprintf (fp, "\\n");
     335             :                 else if( !*p )
     336             :                   tty_fprintf (fp, "\\0");
     337             :                 else
     338             :                   tty_fprintf (fp, "\\x%02x", *p);
     339             :               }
     340             :             else
     341             :               tty_fprintf (fp, "%c", *p);
     342             :           }
     343             :       }
     344             :     else
     345             :       {
     346             :         for( ; n; n--, p++ )
     347             :           {
     348             :             if( iscntrl( *p ) )
     349             :               {
     350             :                 if( *p == '\n' )
     351             :                   tty_printf ("\\n");
     352             :                 else if( !*p )
     353             :                   tty_printf ("\\0");
     354             :                 else
     355             :                   tty_printf ("\\x%02x", *p);
     356             :               }
     357             :             else
     358             :               tty_printf ("%c", *p);
     359             :           }
     360             :       }
     361             : #else
     362           0 :     if (fp)
     363             :       {
     364           0 :         for( ; n; n--, p++ )
     365             :           {
     366           0 :             if (iscntrl (*p))
     367             :               {
     368           0 :                 es_putc ('\\', fp);
     369           0 :                 if ( *p == '\n' )
     370           0 :                   es_putc ('n', fp);
     371           0 :                 else if ( !*p )
     372           0 :                   es_putc ('0', fp);
     373             :                 else
     374           0 :                   es_fprintf (fp, "x%02x", *p);
     375             :               }
     376             :             else
     377           0 :               es_putc (*p, fp);
     378             :           }
     379             :       }
     380             :     else
     381             :       {
     382           0 :         for (; n; n--, p++)
     383             :           {
     384           0 :             if (iscntrl (*p))
     385             :               {
     386           0 :                 putc ('\\', ttyfp);
     387           0 :                 if ( *p == '\n' )
     388           0 :                   putc ('n', ttyfp);
     389           0 :                 else if ( !*p )
     390           0 :                   putc ('0', ttyfp);
     391             :                 else
     392           0 :                   fprintf (ttyfp, "x%02x", *p );
     393             :               }
     394             :             else
     395           0 :               putc (*p, ttyfp);
     396             :           }
     397             :       }
     398             : #endif
     399             : }
     400             : 
     401             : void
     402           0 : tty_print_utf8_string2 (estream_t fp, const byte *p, size_t n, size_t max_n)
     403             : {
     404             :     size_t i;
     405             :     char *buf;
     406             : 
     407           0 :     if (no_terminal && !fp)
     408           0 :         return;
     409             : 
     410             :     /* we can handle plain ascii simpler, so check for it first */
     411           0 :     for(i=0; i < n; i++ ) {
     412           0 :         if( p[i] & 0x80 )
     413           0 :             break;
     414             :     }
     415           0 :     if( i < n ) {
     416           0 :         buf = utf8_to_native( (const char *)p, n, 0 );
     417           0 :         if( max_n && (strlen( buf ) > max_n )) {
     418           0 :             buf[max_n] = 0;
     419             :         }
     420             :         /*(utf8 conversion already does the control character quoting)*/
     421           0 :         tty_fprintf (fp, "%s", buf);
     422           0 :         xfree (buf);
     423             :     }
     424             :     else {
     425           0 :         if( max_n && (n > max_n) ) {
     426           0 :             n = max_n;
     427             :         }
     428           0 :         tty_print_string (fp, p, n );
     429             :     }
     430             : }
     431             : 
     432             : 
     433             : void
     434           0 : tty_print_utf8_string( const byte *p, size_t n )
     435             : {
     436           0 :   tty_print_utf8_string2 (NULL, p, n, 0);
     437           0 : }
     438             : 
     439             : 
     440             : static char *
     441           0 : do_get( const char *prompt, int hidden )
     442             : {
     443             :     char *buf;
     444             : #ifndef __riscos__
     445             :     byte cbuf[1];
     446             : #endif
     447             :     int c, n, i;
     448             : 
     449           0 :     if( batchmode ) {
     450           0 :         log_error("Sorry, we are in batchmode - can't get input\n");
     451           0 :         exit(2);
     452             :     }
     453             : 
     454           0 :     if (no_terminal) {
     455           0 :         log_error("Sorry, no terminal at all requested - can't get input\n");
     456           0 :         exit(2);
     457             :     }
     458             : 
     459           0 :     if( !initialized )
     460           0 :         init_ttyfp();
     461             : 
     462           0 :     last_prompt_len = 0;
     463           0 :     tty_printf( "%s", prompt );
     464           0 :     buf = xmalloc((n=50));
     465           0 :     i = 0;
     466             : 
     467             : #ifdef USE_W32_CONSOLE
     468             :     if( hidden )
     469             :         SetConsoleMode(con.in, HID_INPMODE );
     470             : 
     471             :     for(;;) {
     472             :         DWORD nread;
     473             : 
     474             :         if( !ReadConsoleA( con.in, cbuf, 1, &nread, NULL ) )
     475             :             log_fatal("ReadConsole failed: rc=%d", (int)GetLastError() );
     476             :         if( !nread )
     477             :             continue;
     478             :         if( *cbuf == '\n' )
     479             :             break;
     480             : 
     481             :         if( !hidden )
     482             :             last_prompt_len++;
     483             :         c = *cbuf;
     484             :         if( c == '\t' )
     485             :             c = ' ';
     486             :         else if( c > 0xa0 )
     487             :             ; /* we don't allow 0xa0, as this is a protected blank which may
     488             :                * confuse the user */
     489             :         else if( iscntrl(c) )
     490             :             continue;
     491             :         if( !(i < n-1) ) {
     492             :             n += 50;
     493             :             buf = xrealloc (buf, n);
     494             :         }
     495             :         buf[i++] = c;
     496             :     }
     497             : 
     498             :     if( hidden )
     499             :         SetConsoleMode(con.in, DEF_INPMODE );
     500             : 
     501             : #elif defined(__riscos__) || defined(HAVE_W32CE_SYSTEM)
     502             :     do {
     503             : #ifdef HAVE_W32CE_SYSTEM
     504             :       /* Using getchar is not a correct solution but for now it
     505             :          doesn't matter becuase we have no real console at all.  We
     506             :          should rework this as soon as we have switched this entire
     507             :          module to estream.  */
     508             :         c = getchar();
     509             : #else
     510             :         c = riscos_getchar();
     511             : #endif
     512             :         if (c == 0xa || c == 0xd) { /* Return || Enter */
     513             :             c = (int) '\n';
     514             :         } else if (c == 0x8 || c == 0x7f) { /* Backspace || Delete */
     515             :             if (i>0) {
     516             :                 i--;
     517             :                 if (!hidden) {
     518             :                     last_prompt_len--;
     519             :                     fputc(8, ttyfp);
     520             :                     fputc(32, ttyfp);
     521             :                     fputc(8, ttyfp);
     522             :                     fflush(ttyfp);
     523             :                 }
     524             :             } else {
     525             :                 fputc(7, ttyfp);
     526             :                 fflush(ttyfp);
     527             :             }
     528             :             continue;
     529             :         } else if (c == (int) '\t') { /* Tab */
     530             :             c = ' ';
     531             :         } else if (c > 0xa0) {
     532             :             ; /* we don't allow 0xa0, as this is a protected blank which may
     533             :                * confuse the user */
     534             :         } else if (iscntrl(c)) {
     535             :             continue;
     536             :         }
     537             :         if(!(i < n-1)) {
     538             :             n += 50;
     539             :             buf = xrealloc (buf, n);
     540             :         }
     541             :         buf[i++] = c;
     542             :         if (!hidden) {
     543             :             last_prompt_len++;
     544             :             fputc(c, ttyfp);
     545             :             fflush(ttyfp);
     546             :         }
     547             :     } while (c != '\n');
     548             :     i = (i>0) ? i-1 : 0;
     549             : #else /* Other systems. */
     550           0 :     if( hidden ) {
     551             : #ifdef HAVE_TCGETATTR
     552             :         struct termios term;
     553             : 
     554           0 :         if( tcgetattr(fileno(ttyfp), &termsave) )
     555           0 :             log_fatal("tcgetattr() failed: %s\n", strerror(errno) );
     556           0 :         restore_termios = 1;
     557           0 :         term = termsave;
     558           0 :         term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
     559           0 :         if( tcsetattr( fileno(ttyfp), TCSAFLUSH, &term ) )
     560           0 :             log_fatal("tcsetattr() failed: %s\n", strerror(errno) );
     561             : #endif
     562             :     }
     563             : 
     564             :     /* fixme: How can we avoid that the \n is echoed w/o disabling
     565             :      * canonical mode - w/o this kill_prompt can't work */
     566           0 :     while( read(fileno(ttyfp), cbuf, 1) == 1 && *cbuf != '\n' ) {
     567           0 :         if( !hidden )
     568           0 :             last_prompt_len++;
     569           0 :         c = *cbuf;
     570           0 :         if( c == CONTROL_D )
     571           0 :             log_info("control d found\n");
     572           0 :         if( c == '\t' )
     573           0 :             c = ' ';
     574           0 :         else if( c > 0xa0 )
     575             :             ; /* we don't allow 0xa0, as this is a protected blank which may
     576             :                * confuse the user */
     577           0 :         else if( iscntrl(c) )
     578           0 :             continue;
     579           0 :         if( !(i < n-1) ) {
     580           0 :             n += 50;
     581           0 :             buf = xrealloc (buf, n );
     582             :         }
     583           0 :         buf[i++] = c;
     584             :     }
     585           0 :     if( *cbuf != '\n' ) {
     586           0 :         buf[0] = CONTROL_D;
     587           0 :         i = 1;
     588             :     }
     589             : 
     590           0 :     if( hidden ) {
     591             : #ifdef HAVE_TCGETATTR
     592           0 :         if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) )
     593           0 :             log_error("tcsetattr() failed: %s\n", strerror(errno) );
     594           0 :         restore_termios = 0;
     595             : #endif
     596             :     }
     597             : #endif /* end unix version */
     598           0 :     buf[i] = 0;
     599           0 :     return buf;
     600             : }
     601             : 
     602             : 
     603             : char *
     604           0 : tty_get( const char *prompt )
     605             : {
     606           0 :   if (!batchmode && !no_terminal && my_rl_readline && my_rl_add_history)
     607             :     {
     608             :       char *line;
     609             :       char *buf;
     610             : 
     611           0 :       if (!initialized)
     612           0 :         init_ttyfp();
     613             : 
     614           0 :       last_prompt_len = 0;
     615             : 
     616           0 :       line = my_rl_readline (prompt?prompt:"");
     617             : 
     618             :       /* We need to copy it to memory controlled by our malloc
     619             :          implementations; further we need to convert an EOF to our
     620             :          convention. */
     621           0 :       buf = xmalloc(line? strlen(line)+1:2);
     622           0 :       if (line)
     623             :         {
     624           0 :           strcpy (buf, line);
     625           0 :           trim_spaces (buf);
     626           0 :           if (strlen (buf) > 2 )
     627           0 :             my_rl_add_history (line); /* Note that we test BUF but add LINE. */
     628           0 :           free (line);
     629             :         }
     630             :       else
     631             :         {
     632           0 :           buf[0] = CONTROL_D;
     633           0 :           buf[1] = 0;
     634             :         }
     635           0 :       return buf;
     636             :     }
     637             :   else
     638           0 :     return do_get ( prompt, 0 );
     639             : }
     640             : 
     641             : /* Variable argument version of tty_get.  The prompt is is actually a
     642             :    format string with arguments.  */
     643             : char *
     644           0 : tty_getf (const char *promptfmt, ... )
     645             : {
     646             :   va_list arg_ptr;
     647             :   char *prompt;
     648             :   char *answer;
     649             : 
     650           0 :   va_start (arg_ptr, promptfmt);
     651           0 :   if (gpgrt_vasprintf (&prompt, promptfmt, arg_ptr) < 0)
     652           0 :     log_fatal ("estream_vasprintf failed: %s\n", strerror (errno));
     653           0 :   va_end (arg_ptr);
     654           0 :   answer = tty_get (prompt);
     655           0 :   xfree (prompt);
     656           0 :   return answer;
     657             : }
     658             : 
     659             : 
     660             : 
     661             : char *
     662           0 : tty_get_hidden( const char *prompt )
     663             : {
     664           0 :     return do_get( prompt, 1 );
     665             : }
     666             : 
     667             : 
     668             : void
     669           0 : tty_kill_prompt()
     670             : {
     671           0 :     if ( no_terminal )
     672           0 :         return;
     673             : 
     674           0 :     if( !initialized )
     675           0 :         init_ttyfp();
     676             : 
     677           0 :     if( batchmode )
     678           0 :         last_prompt_len = 0;
     679           0 :     if( !last_prompt_len )
     680           0 :         return;
     681             : #ifdef USE_W32_CONSOLE
     682             :     tty_printf("\r%*s\r", last_prompt_len, "");
     683             : #else
     684             :     {
     685             :         int i;
     686           0 :         putc('\r', ttyfp);
     687           0 :         for(i=0; i < last_prompt_len; i ++ )
     688           0 :             putc(' ', ttyfp);
     689           0 :         putc('\r', ttyfp);
     690           0 :         fflush(ttyfp);
     691             :     }
     692             : #endif
     693           0 :     last_prompt_len = 0;
     694             : }
     695             : 
     696             : 
     697             : int
     698           0 : tty_get_answer_is_yes( const char *prompt )
     699             : {
     700             :     int yes;
     701           0 :     char *p = tty_get( prompt );
     702           0 :     tty_kill_prompt();
     703           0 :     yes = answer_is_yes(p);
     704           0 :     xfree(p);
     705           0 :     return yes;
     706             : }
     707             : 
     708             : 
     709             : /* Called by gnupg_rl_initialize to setup the readline support. */
     710             : void
     711           0 : tty_private_set_rl_hooks (void (*init_stream) (FILE *),
     712             :                           void (*set_completer) (rl_completion_func_t*),
     713             :                           void (*inhibit_completion) (int),
     714             :                           void (*cleanup_after_signal) (void),
     715             :                           char *(*readline_fun) (const char*),
     716             :                           void (*add_history_fun) (const char*))
     717             : {
     718           0 :   my_rl_init_stream = init_stream;
     719           0 :   my_rl_set_completer = set_completer;
     720           0 :   my_rl_inhibit_completion = inhibit_completion;
     721           0 :   my_rl_cleanup_after_signal = cleanup_after_signal;
     722           0 :   my_rl_readline = readline_fun;
     723           0 :   my_rl_add_history = add_history_fun;
     724           0 : }
     725             : 
     726             : 
     727             : #ifdef HAVE_LIBREADLINE
     728             : void
     729             : tty_enable_completion (rl_completion_func_t *completer)
     730             : {
     731             :   if (no_terminal || !my_rl_set_completer )
     732             :     return;
     733             : 
     734             :   if (!initialized)
     735             :     init_ttyfp();
     736             : 
     737             :   my_rl_set_completer (completer);
     738             : }
     739             : 
     740             : void
     741             : tty_disable_completion (void)
     742             : {
     743             :   if (no_terminal || !my_rl_inhibit_completion)
     744             :     return;
     745             : 
     746             :   if (!initialized)
     747             :     init_ttyfp();
     748             : 
     749             :   my_rl_inhibit_completion (1);
     750             : }
     751             : #endif
     752             : 
     753             : void
     754           0 : tty_cleanup_after_signal (void)
     755             : {
     756             : #ifdef HAVE_TCGETATTR
     757           0 :   cleanup ();
     758             : #endif
     759           0 : }
     760             : 
     761             : void
     762           0 : tty_cleanup_rl_after_signal (void)
     763             : {
     764           0 :   if (my_rl_cleanup_after_signal)
     765           0 :     my_rl_cleanup_after_signal ();
     766           0 : }

Generated by: LCOV version 1.11