common: Add substitute code for libgpg-error < 1.22.
[gnupg.git] / common / ttyio.c
index 92671f1..6167412 100644 (file)
@@ -4,12 +4,22 @@
  *
  * This file is part of GnuPG.
  *
- * GnuPG 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 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - 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.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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.
@@ -43,6 +53,9 @@
 #endif
 #endif
 #ifdef USE_W32_CONSOLE
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
 # include <windows.h>
 # ifdef HAVE_TCGETATTR
 #  error mingw32 and termios
@@ -121,7 +134,7 @@ tty_get_ttyname (void)
       got_name = 1;
     }
 #endif /*HAVE_CTERMID*/
-  /* Assume the standard tty on memory error or when tehre is no
+  /* Assume the standard tty on memory error or when there is no
      ctermid. */
   return name? name : "/dev/tty";
 }
@@ -179,14 +192,14 @@ init_ttyfp(void)
 #else
     ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+");
     if( !ttyfp ) {
-       log_error("cannot open `%s': %s\n", tty_get_ttyname (),
+       log_error("cannot open '%s': %s\n", tty_get_ttyname (),
                   strerror(errno) );
        exit(2);
     }
     if (my_rl_init_stream)
       my_rl_init_stream (ttyfp);
 #endif
-    
+
 
 #ifdef HAVE_TCGETATTR
     atexit( cleanup );
@@ -225,7 +238,7 @@ tty_printf( const char *fmt, ... )
 
     va_start( arg_ptr, fmt ) ;
 #ifdef USE_W32_CONSOLE
-    {   
+    {
         char *buf = NULL;
         int n;
        DWORD nwritten;
@@ -233,7 +246,7 @@ tty_printf( const char *fmt, ... )
        n = vasprintf(&buf, fmt, arg_ptr);
        if( !buf )
            log_bug("vasprintf() failed\n");
-        
+
        if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) )
            log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() );
        if( n != nwritten )
@@ -272,15 +285,15 @@ tty_fprintf (estream_t fp, const char *fmt, ... )
 
   va_start (arg_ptr, fmt);
 #ifdef USE_W32_CONSOLE
-  {   
+  {
     char *buf = NULL;
     int n;
     DWORD nwritten;
-    
+
     n = vasprintf(&buf, fmt, arg_ptr);
     if (!buf)
       log_bug("vasprintf() failed\n");
-    
+
     if (!WriteConsoleA( con.out, buf, n, &nwritten, NULL ))
       log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() );
     if (n != nwritten)
@@ -297,53 +310,101 @@ tty_fprintf (estream_t fp, const char *fmt, ... )
 
 
 /****************
- * Print a string, but filter all control characters out.
+ * Print a string, but filter all control characters out.  If FP is
+ * not NULL print to that stream instead to the tty.
  */
 void
-tty_print_string ( const byte *p, size_t n )
+tty_print_string (estream_t fp, const byte *p, size_t n )
 {
-    if (no_terminal)
+    if (no_terminal && !fp)
        return;
 
-    if( !initialized )
+    if( !initialized & !fp)
        init_ttyfp();
 
 #ifdef USE_W32_CONSOLE
     /* not so effective, change it if you want */
-    for( ; n; n--, p++ )
-       if( iscntrl( *p ) ) {
-           if( *p == '\n' )
-               tty_printf("\\n");
-           else if( !*p )
-               tty_printf("\\0");
-           else
-               tty_printf("\\x%02x", *p);
-       }
-       else
-           tty_printf("%c", *p);
+    if (fp)
+      {
+        for( ; n; n--, p++ )
+          {
+            if( iscntrl( *p ) )
+              {
+                if( *p == '\n' )
+                  tty_fprintf (fp, "\\n");
+                else if( !*p )
+                  tty_fprintf (fp, "\\0");
+                else
+                  tty_fprintf (fp, "\\x%02x", *p);
+              }
+            else
+              tty_fprintf (fp, "%c", *p);
+          }
+      }
+    else
+      {
+        for( ; n; n--, p++ )
+          {
+            if( iscntrl( *p ) )
+              {
+                if( *p == '\n' )
+                  tty_printf ("\\n");
+                else if( !*p )
+                  tty_printf ("\\0");
+                else
+                  tty_printf ("\\x%02x", *p);
+              }
+            else
+              tty_printf ("%c", *p);
+          }
+      }
 #else
-    for( ; n; n--, p++ )
-       if( iscntrl( *p ) ) {
-           putc('\\', ttyfp);
-           if( *p == '\n' )
-               putc('n', ttyfp);
-           else if( !*p )
-               putc('0', ttyfp);
-           else
-               fprintf(ttyfp, "x%02x", *p );
-       }
-       else
-           putc(*p, ttyfp);
+    if (fp)
+      {
+        for( ; n; n--, p++ )
+          {
+            if (iscntrl (*p))
+              {
+                es_putc ('\\', fp);
+                if ( *p == '\n' )
+                  es_putc ('n', fp);
+                else if ( !*p )
+                  es_putc ('0', fp);
+                else
+                  es_fprintf (fp, "x%02x", *p);
+              }
+            else
+              es_putc (*p, fp);
+          }
+      }
+    else
+      {
+        for (; n; n--, p++)
+          {
+            if (iscntrl (*p))
+              {
+                putc ('\\', ttyfp);
+                if ( *p == '\n' )
+                  putc ('n', ttyfp);
+                else if ( !*p )
+                  putc ('0', ttyfp);
+                else
+                  fprintf (ttyfp, "x%02x", *p );
+              }
+            else
+              putc (*p, ttyfp);
+          }
+      }
 #endif
 }
 
 void
-tty_print_utf8_string2( const byte *p, size_t n, size_t max_n )
+tty_print_utf8_string2 (estream_t fp, const byte *p, size_t n, size_t max_n)
 {
     size_t i;
     char *buf;
 
-    if (no_terminal)
+    if (no_terminal && !fp)
        return;
 
     /* we can handle plain ascii simpler, so check for it first */
@@ -357,21 +418,22 @@ tty_print_utf8_string2( const byte *p, size_t n, size_t max_n )
            buf[max_n] = 0;
        }
        /*(utf8 conversion already does the control character quoting)*/
-       tty_printf("%s", buf );
-       xfree( buf );
+       tty_fprintf (fp, "%s", buf);
+       xfree (buf);
     }
     else {
        if( max_n && (n > max_n) ) {
            n = max_n;
        }
-       tty_print_string( p, n );
+       tty_print_string (fp, p, n );
     }
 }
 
+
 void
 tty_print_utf8_string( const byte *p, size_t n )
 {
-    tty_print_utf8_string2( p, n, 0 );
+  tty_print_utf8_string2 (NULL, p, n, 0);
 }
 
 
@@ -440,7 +502,7 @@ do_get( const char *prompt, int hidden )
     do {
 #ifdef HAVE_W32CE_SYSTEM
       /* Using getchar is not a correct solution but for now it
-         doesn't matter becuase we have no real console at all.  We
+         doesn't matter because we have no real console at all.  We
          should rework this as soon as we have switched this entire
          module to estream.  */
         c = getchar();
@@ -545,7 +607,7 @@ tty_get( const char *prompt )
     {
       char *line;
       char *buf;
-      
+
       if (!initialized)
        init_ttyfp();
 
@@ -586,7 +648,7 @@ tty_getf (const char *promptfmt, ... )
   char *answer;
 
   va_start (arg_ptr, promptfmt);
-  if (estream_vasprintf (&prompt, promptfmt, arg_ptr) < 0)
+  if (gpgrt_vasprintf (&prompt, promptfmt, arg_ptr) < 0)
     log_fatal ("estream_vasprintf failed: %s\n", strerror (errno));
   va_end (arg_ptr);
   answer = tty_get (prompt);