summaryrefslogtreecommitdiff
path: root/gl
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2004-08-15 10:28:45 +0000
committerSimon Josefsson <simon@josefsson.org>2004-08-15 10:28:45 +0000
commitd30a9c7494351bb538acbecb13cddcaefbbe2f45 (patch)
treef84af7482d7bad396d7d3f091d35ebdb197f5d82 /gl
parentecf58cb15a0e3c7ff410d4517395256ba9e50d1a (diff)
downloadgnutls-d30a9c7494351bb538acbecb13cddcaefbbe2f45.tar.gz
Replace ad-hoc 'read_pass' with gnulib module 'getpass-gnu'.
Diffstat (limited to 'gl')
-rw-r--r--gl/Makefile.am13
-rw-r--r--gl/getpass.c196
-rw-r--r--gl/getpass.h31
-rw-r--r--gl/m4/getpass.m438
-rw-r--r--gl/m4/gnulib.m42
-rw-r--r--gl/m4/stdbool.m495
-rw-r--r--gl/stdbool_.h93
7 files changed, 468 insertions, 0 deletions
diff --git a/gl/Makefile.am b/gl/Makefile.am
index b1cad13b1c..c4988f8c9d 100644
--- a/gl/Makefile.am
+++ b/gl/Makefile.am
@@ -31,9 +31,22 @@ libgnu_la_SOURCES += exit.h
libgnu_la_SOURCES += getline.h
EXTRA_DIST += getndelim2.h getndelim2.c
+libgnu_la_SOURCES += getpass.h
+
libgnu_la_SOURCES += gettext.h
libgnu_la_SOURCES += progname.h progname.c
+BUILT_SOURCES += $(STDBOOL_H)
+EXTRA_DIST += stdbool_.h
+
+# We need the following in order to create an <stdbool.h> when the system
+# doesn't have one that works.
+all-local $(libgnu_la_OBJECTS): $(STDBOOL_H)
+stdbool.h: stdbool_.h
+ sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool_.h > $@-t
+ mv $@-t $@
+MOSTLYCLEANFILES += stdbool.h stdbool.h-t
+
libgnu_la_SOURCES += unlocked-io.h
diff --git a/gl/getpass.c b/gl/getpass.c
new file mode 100644
index 0000000000..9ac01f2277
--- /dev/null
+++ b/gl/getpass.c
@@ -0,0 +1,196 @@
+/* Copyright (C) 1992-2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program 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 2, or (at your option)
+ any later version.
+
+ This program 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.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !_LIBC
+# include "getpass.h"
+#endif
+
+#if _LIBC
+# define HAVE_STDIO_EXT_H 1
+#endif
+
+#include <stdbool.h>
+
+#include <stdio.h>
+#if HAVE_STDIO_EXT_H
+# include <stdio_ext.h>
+#else
+# define __fsetlocking(stream, type) /* empty */
+#endif
+#if !_LIBC
+# include "getline.h"
+#endif
+
+#include <termios.h>
+#include <unistd.h>
+
+#if _LIBC
+# include <wchar.h>
+#endif
+
+#if _LIBC
+# define NOTCANCEL_MODE "c"
+#else
+# define NOTCANCEL_MODE
+#endif
+
+#if _LIBC
+# define flockfile(s) _IO_flockfile (s)
+# define funlockfile(s) _IO_funlockfile (s)
+#else
+# include "unlocked-io.h"
+#endif
+
+#if _LIBC
+# include <bits/libc-lock.h>
+#else
+# define __libc_cleanup_push(function, arg) /* empty */
+# define __libc_cleanup_pop(execute) /* empty */
+#endif
+
+#if !_LIBC
+# define __getline getline
+# define __tcgetattr tcgetattr
+#endif
+
+/* It is desirable to use this bit on systems that have it.
+ The only bit of terminal state we want to twiddle is echoing, which is
+ done in software; there is no need to change the state of the terminal
+ hardware. */
+
+#ifndef TCSASOFT
+# define TCSASOFT 0
+#endif
+
+static void
+call_fclose (void *arg)
+{
+ if (arg != NULL)
+ fclose (arg);
+}
+
+char *
+getpass (const char *prompt)
+{
+ FILE *tty;
+ FILE *in, *out;
+ struct termios s, t;
+ bool tty_changed;
+ static char *buf;
+ static size_t bufsize;
+ ssize_t nread;
+
+ /* Try to write to and read from the terminal if we can.
+ If we can't open the terminal, use stderr and stdin. */
+
+ tty = fopen ("/dev/tty", "w+" NOTCANCEL_MODE);
+ if (tty == NULL)
+ {
+ in = stdin;
+ out = stderr;
+ }
+ else
+ {
+ /* We do the locking ourselves. */
+ __fsetlocking (tty, FSETLOCKING_BYCALLER);
+
+ out = in = tty;
+ }
+
+ /* Make sure the stream we opened is closed even if the thread is
+ canceled. */
+ __libc_cleanup_push (call_fclose, tty);
+
+ flockfile (out);
+
+ /* Turn echoing off if it is on now. */
+
+ if (__tcgetattr (fileno (in), &t) == 0)
+ {
+ /* Save the old one. */
+ s = t;
+ /* Tricky, tricky. */
+ t.c_lflag &= ~(ECHO|ISIG);
+ tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0);
+ }
+ else
+ tty_changed = false;
+
+ /* Write the prompt. */
+#ifdef USE_IN_LIBIO
+ if (_IO_fwide (out, 0) > 0)
+ __fwprintf (out, L"%s", prompt);
+ else
+#endif
+ fputs_unlocked (prompt, out);
+ fflush_unlocked (out);
+
+ /* Read the password. */
+ nread = __getline (&buf, &bufsize, in);
+
+#if !_LIBC
+ /* As far as is known, glibc doesn't need this no-op fseek. */
+
+ /* According to the C standard, input may not be followed by output
+ on the same stream without an intervening call to a file
+ positioning function. Suppose in == out; then without this fseek
+ call, on Solaris, HP-UX, AIX, OSF/1, the previous input gets
+ echoed, whereas on IRIX, the following newline is not output as
+ it should be. POSIX imposes similar restrictions if fileno (in)
+ == fileno (out). The POSIX restrictions are tricky and change
+ from POSIX version to POSIX version, so play it safe and invoke
+ fseek even if in != out. */
+ fseek (out, 0, SEEK_CUR);
+#endif
+
+ if (buf != NULL)
+ {
+ if (nread < 0)
+ buf[0] = '\0';
+ else if (buf[nread - 1] == '\n')
+ {
+ /* Remove the newline. */
+ buf[nread - 1] = '\0';
+ if (tty_changed)
+ {
+ /* Write the newline that was not echoed. */
+#ifdef USE_IN_LIBIO
+ if (_IO_fwide (out, 0) > 0)
+ putwc_unlocked (L'\n', out);
+ else
+#endif
+ putc_unlocked ('\n', out);
+ }
+ }
+ }
+
+ /* Restore the original setting. */
+ if (tty_changed)
+ (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s);
+
+ funlockfile (out);
+
+ __libc_cleanup_pop (0);
+
+ call_fclose (tty);
+
+ return buf;
+}
diff --git a/gl/getpass.h b/gl/getpass.h
new file mode 100644
index 0000000000..6502126497
--- /dev/null
+++ b/gl/getpass.h
@@ -0,0 +1,31 @@
+/* getpass.h -- Read a password of arbitrary length from /dev/tty or stdin.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Simon Josefsson <jas@extundo.com>, 2004.
+
+ This program 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 2, or (at your option)
+ any later version.
+
+ This program 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef GETPASS_H
+#define GETPASS_H
+
+/* Get getpass declaration, if available. */
+#include <unistd.h>
+
+#if defined HAVE_DECL_GETPASS && !HAVE_DECL_GETPASS
+/* Read a password of arbitrary length from /dev/tty or stdin. */
+char *getpass (const char *prompt);
+
+#endif
+
+#endif /* GETPASS_H */
diff --git a/gl/m4/getpass.m4 b/gl/m4/getpass.m4
new file mode 100644
index 0000000000..0c4d8050f2
--- /dev/null
+++ b/gl/m4/getpass.m4
@@ -0,0 +1,38 @@
+# getpass.m4 serial 4
+dnl Copyright (C) 2002-2003 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License. As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+# Provide a getpass() function if the system doesn't have it.
+AC_DEFUN([gl_FUNC_GETPASS],
+[
+ AC_REPLACE_FUNCS(getpass)
+ AC_CHECK_DECLS_ONCE(getpass)
+ if test $ac_cv_func_getpass = no; then
+ gl_PREREQ_GETPASS
+ fi
+])
+
+# Provide the GNU getpass() implementation. It supports passwords of
+# arbitrary length (not just 8 bytes as on HP-UX).
+AC_DEFUN([gl_FUNC_GETPASS_GNU],
+[
+ AC_CHECK_DECLS_ONCE(getpass)
+ dnl TODO: Detect when GNU getpass() is already found in glibc.
+ AC_LIBOBJ(getpass)
+ gl_PREREQ_GETPASS
+ dnl We must choose a different name for our function, since on ELF systems
+ dnl an unusable getpass() in libc.so would override our getpass() if it is
+ dnl compiled into a shared library.
+ AC_DEFINE([getpass], [gnu_getpass],
+ [Define to a replacement function name for getpass().])
+])
+
+# Prerequisites of lib/getpass.c.
+AC_DEFUN([gl_PREREQ_GETPASS], [
+ AC_CHECK_HEADERS_ONCE(stdio_ext.h)
+ :
+])
diff --git a/gl/m4/gnulib.m4 b/gl/m4/gnulib.m4
index 58e69eb100..38a1ad5af6 100644
--- a/gl/m4/gnulib.m4
+++ b/gl/m4/gnulib.m4
@@ -20,7 +20,9 @@ AC_DEFUN([gl_INIT],
gl_ERROR
dnl gl_USE_SYSTEM_EXTENSIONS must be added quite early to configure.ac.
AM_FUNC_GETLINE
+ gl_FUNC_GETPASS_GNU
dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac.
+ AM_STDBOOL_H
gl_FUNC_GLIBC_UNLOCKED_IO
])
diff --git a/gl/m4/stdbool.m4 b/gl/m4/stdbool.m4
new file mode 100644
index 0000000000..b25b7d2440
--- /dev/null
+++ b/gl/m4/stdbool.m4
@@ -0,0 +1,95 @@
+# Check for stdbool.h that conforms to C99.
+
+# Copyright (C) 2002-2004 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# Prepare for substituting <stdbool.h> if it is not supported.
+
+AC_DEFUN([AM_STDBOOL_H],
+[
+ AC_REQUIRE([AC_HEADER_STDBOOL])
+
+ # Define two additional variables used in the Makefile substitution.
+
+ if test "$ac_cv_header_stdbool_h" = yes; then
+ STDBOOL_H=''
+ else
+ STDBOOL_H='stdbool.h'
+ fi
+ AC_SUBST([STDBOOL_H])
+
+ if test "$ac_cv_type__Bool" = yes; then
+ HAVE__BOOL=1
+ else
+ HAVE__BOOL=0
+ fi
+ AC_SUBST([HAVE__BOOL])
+])
+
+# This macro is only needed in autoconf <= 2.59. Newer versions of autoconf
+# have this macro built-in.
+
+AC_DEFUN([AC_HEADER_STDBOOL],
+ [AC_CACHE_CHECK([for stdbool.h that conforms to C99],
+ [ac_cv_header_stdbool_h],
+ [AC_TRY_COMPILE(
+ [
+ #include <stdbool.h>
+ #ifndef bool
+ "error: bool is not defined"
+ #endif
+ #ifndef false
+ "error: false is not defined"
+ #endif
+ #if false
+ "error: false is not 0"
+ #endif
+ #ifndef true
+ "error: true is not defined"
+ #endif
+ #if true != 1
+ "error: true is not 1"
+ #endif
+ #ifndef __bool_true_false_are_defined
+ "error: __bool_true_false_are_defined is not defined"
+ #endif
+
+ struct s { _Bool s: 1; _Bool t; } s;
+
+ char a[true == 1 ? 1 : -1];
+ char b[false == 0 ? 1 : -1];
+ char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+ char d[(bool) -0.5 == true ? 1 : -1];
+ bool e = &s;
+ char f[(_Bool) -0.0 == false ? 1 : -1];
+ char g[true];
+ char h[sizeof (_Bool)];
+ char i[sizeof s.t];
+ enum { j = false, k = true, l = false * true, m = true * 256 };
+ _Bool n[m];
+ char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+ ],
+ [
+ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !j + !k + !l
+ + !m + !n + !o);
+ ],
+ [ac_cv_header_stdbool_h=yes],
+ [ac_cv_header_stdbool_h=no])])
+ AC_CHECK_TYPES([_Bool])
+ if test $ac_cv_header_stdbool_h = yes; then
+ AC_DEFINE(HAVE_STDBOOL_H, 1, [Define to 1 if stdbool.h conforms to C99.])
+ fi])
diff --git a/gl/stdbool_.h b/gl/stdbool_.h
new file mode 100644
index 0000000000..e33715a615
--- /dev/null
+++ b/gl/stdbool_.h
@@ -0,0 +1,93 @@
+/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Written by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+ This program 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 2, or (at your option)
+ any later version.
+
+ This program 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+/* ISO C 99 <stdbool.h> for platforms that lack it. */
+
+/* Usage suggestions:
+
+ Programs that use <stdbool.h> should be aware of some limitations
+ and standards compliance issues.
+
+ Standards compliance:
+
+ - <stdbool.h> must be #included before 'bool', 'false', 'true'
+ can be used.
+
+ - You cannot assume that sizeof (bool) == 1.
+
+ - Programs should not undefine the macros bool, true, and false,
+ as C99 lists that as an "obsolescent feature".
+
+ Limitations of this substitute, when used in a C89 environment:
+
+ - <stdbool.h> must be #included before the '_Bool' type can be used.
+
+ - You cannot assume that _Bool is a typedef; it might be a macro.
+
+ - In C99, casts and automatic conversions to '_Bool' or 'bool' are
+ performed in such a way that every nonzero value gets converted
+ to 'true', and zero gets converted to 'false'. This doesn't work
+ with this substitute. With this substitute, only the values 0 and 1
+ give the expected result when converted to _Bool' or 'bool'.
+
+ Also, it is suggested that programs use 'bool' rather than '_Bool';
+ this isn't required, but 'bool' is more common. */
+
+
+/* 7.16. Boolean type and values */
+
+/* BeOS <sys/socket.h> already #defines false 0, true 1. We use the same
+ definitions below, but temporarily we have to #undef them. */
+#ifdef __BEOS__
+# include <OS.h> /* defines bool but not _Bool */
+# undef false
+# undef true
+#endif
+
+/* For the sake of symbolic names in gdb, we define true and false as
+ enum constants, not only as macros.
+ It is tempting to write
+ typedef enum { false = 0, true = 1 } _Bool;
+ so that gdb prints values of type 'bool' symbolically. But if we do
+ this, values of type '_Bool' may promote to 'int' or 'unsigned int'
+ (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int'
+ (see ISO C 99 6.3.1.1.(2)). So we add a negative value to the
+ enum; this ensures that '_Bool' promotes to 'int'. */
+#if !(defined __cplusplus || defined __BEOS__)
+# if !@HAVE__BOOL@
+# if defined __SUNPRO_C && (__SUNPRO_C < 0x550 || __STDC__ == 1)
+ /* Avoid stupid "warning: _Bool is a keyword in ISO C99". */
+# define _Bool signed char
+enum { false = 0, true = 1 };
+# else
+typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
+# endif
+# endif
+#else
+typedef bool _Bool;
+#endif
+#define bool _Bool
+
+/* The other macros must be usable in preprocessor directives. */
+#define false 0
+#define true 1
+#define __bool_true_false_are_defined 1
+
+#endif /* _STDBOOL_H */