Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/gen add getpassfd() that gives us even more fine gr...
details: https://anonhg.NetBSD.org/src/rev/1f20bff4ba68
branches: trunk
changeset: 778760:1f20bff4ba68
user: christos <christos%NetBSD.org@localhost>
date: Thu Apr 12 22:07:44 2012 +0000
description:
add getpassfd() that gives us even more fine grain control on how to get
the password.
diffstat:
lib/libc/gen/getpass.3 | 40 ++++++++++-
lib/libc/gen/getpass.c | 169 +++++++++++++++++++++++++++++++++---------------
2 files changed, 152 insertions(+), 57 deletions(-)
diffs (truncated from 365 to 300 lines):
diff -r 022acdaca724 -r 1f20bff4ba68 lib/libc/gen/getpass.3
--- a/lib/libc/gen/getpass.3 Thu Apr 12 20:15:37 2012 +0000
+++ b/lib/libc/gen/getpass.3 Thu Apr 12 22:07:44 2012 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: getpass.3,v 1.15 2012/04/12 20:15:37 wiz Exp $
+.\" $NetBSD: getpass.3,v 1.16 2012/04/12 22:07:44 christos Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -43,6 +43,8 @@
.Fn getpass "const char *prompt"
.Ft char *
.Fn getpass_r "const char *prompt" "char *buf" "size_t buflen"
+.Ft char *
+.Fn getpassfd "const char *prompt" "char *buf" "size_t buflen" "int fd[3]" "int flags"
.Sh DESCRIPTION
The
.Fn getpass
@@ -71,6 +73,34 @@
for up to
.Fa buflen
characters.
+If the
+.Fa buf
+argument is
+.Dv NULL ,
+then a buffer will be dynamically allocated.
+.Pp
+The
+.Fn getpassfd
+function allows one to specify the file descriptors used to be specified in
+.Fa fd ,
+and provides an extra
+.Fa flags
+argument to control its behavior:
+.Bl -tag -width GETPASS_BUF_LIMIT
+.It Dv GETPASS_NEED_TTY
+Fail if we are unable to set the tty modes like we want.
+.It Dv GETPASS_FAIL_EOF
+Fail if we get the end-of-file character instead of returning the result so far.
+.It Dv GETPASS_BUF_LIMIT
+Beep when the buffer limit is reached, instead of silently absorbing it.
+.It Dv GETPASS_NO_SIGNAL
+Don't make ttychars send signals.
+.It Dv GETPASS_NO_BEEP
+Don't beep if we erase past the beginning of the buffer or we try to enter past
+the end.
+.It Dv GETPASS_ECHO
+Echo characters as they are typed.
+.El
.Sh RETURN VALUES
The
.Fn getpass
@@ -78,7 +108,9 @@
string on error.
The
.Fn getpass_r
-function returns a pointer to the NUL terminated password, or
+and
+.Fn getpassfd
+functions return a pointer to the NUL terminated password, or
.Dv NULL
on error.
.Sh FILES
@@ -103,7 +135,9 @@
.At v7 .
The
.Fn getpass_r
-function appeared in
+and
+.Fn getpassfd
+functions appeared in
.Nx 7.0 .
.Sh BUGS
The
diff -r 022acdaca724 -r 1f20bff4ba68 lib/libc/gen/getpass.c
--- a/lib/libc/gen/getpass.c Thu Apr 12 20:15:37 2012 +0000
+++ b/lib/libc/gen/getpass.c Thu Apr 12 22:07:44 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: getpass.c,v 1.18 2012/04/12 20:08:01 christos Exp $ */
+/* $NetBSD: getpass.c,v 1.19 2012/04/12 22:07:44 christos Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: getpass.c,v 1.18 2012/04/12 20:08:01 christos Exp $");
+__RCSID("$NetBSD: getpass.c,v 1.19 2012/04/12 22:07:44 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@@ -50,6 +50,7 @@
#include <fcntl.h>
#ifdef __weak_alias
+__weak_alias(getpassfd,_getpassfd)
__weak_alias(getpass_r,_getpass_r)
__weak_alias(getpass,_getpass)
#endif
@@ -58,46 +59,40 @@
* Notes:
* - There is no getpass_r in POSIX
* - Historically EOF is documented to be treated as EOL, we provide a
- * tunable for that DONT_TREAT_EOF_AS_EOL to disable this.
+ * tunable for that GETPASS_FAIL_EOF to disable this.
* - Historically getpass ate extra characters silently, we provide
- * a tunable for that DONT_DISCARD_SILENTLY to disable this.
+ * a tunable for that GETPASS_BUF_LIMIT to disable this.
* - Historically getpass "worked" by echoing characters when turning
- * off echo failed, we provide a tunable DONT_WORK_AND_ECHO to
+ * off echo failed, we provide a tunable GETPASS_NEED_TTY to
* disable this.
* - Some implementations say that on interrupt the program shall
* receive an interrupt signal before the function returns. We
* send all the tty signals before we return, but we don't expect
* suspend to do something useful unless the caller calls us again.
+ * We also provide a tunable to disable signal delivery
+ * GETPASS_NO_SIGNAL.
+ * - GETPASS_NO_BEEP disables beeping.
+ * - GETPASS_ECHO will echo the password (as pam likes it)
*/
char *
-getpass_r(const char *prompt, char *ret, size_t len)
+/*ARGSUSED*/
+getpassfd(const char *prompt, char *buf, size_t len, int fd[], int flags)
{
struct termios gt;
char c;
- int infd, outfd, sig;
- bool lnext, havetty;
+ int sig;
+ bool lnext, havetty, allocated;
_DIAGASSERT(prompt != NULL);
sig = 0;
- /*
- * Try to use /dev/tty if possible; otherwise read from stdin and
- * write to stderr.
- */
- if ((outfd = infd = open(_PATH_TTY, O_RDWR)) == -1) {
- infd = STDIN_FILENO;
- outfd = STDERR_FILENO;
+
+ allocated = buf == NULL;
+ if (tcgetattr(fd[0], >) == -1) {
havetty = false;
- } else
- havetty = true;
-
- if (tcgetattr(infd, >) == -1) {
- havetty = false;
-#ifdef DONT_WORK_AND_ECHO
- goto out;
-#else
+ if (flags & GETPASS_NEED_TTY)
+ goto out;
memset(>, -1, sizeof(gt));
-#endif
} else
havetty = true;
@@ -108,22 +103,33 @@
st.c_lflag &= ~(ECHO|ECHOK|ECHOE|ECHOKE|ECHOCTL|ISIG|ICANON);
st.c_cc[VMIN] = 1;
st.c_cc[VTIME] = 0;
- if (tcsetattr(infd, TCSAFLUSH|TCSASOFT, &st) == -1)
+ if (tcsetattr(fd[0], TCSAFLUSH|TCSASOFT, &st) == -1)
goto out;
}
if (prompt != NULL) {
size_t plen = strlen(prompt);
- (void)write(outfd, prompt, plen);
+ (void)write(fd[1], prompt, plen);
+ }
+
+ if (allocated) {
+ len = 1024;
+ if ((buf = malloc(len)) == NULL)
+ goto restore;
}
c = '\1';
lnext = false;
for (size_t l = 0; c != '\0'; ) {
- if (read(infd, &c, 1) != 1)
+ if (read(fd[0], &c, 1) != 1)
goto restore;
-#define beep() write(outfd, "\a", 1)
+#define beep() do \
+ if (flags & GETPASS_NO_BEEP) \
+ (void)write(fd[2], "\a", 1); \
+ while (/*CONSTCOND*/ 0)
+#define erase() (void)write(fd[1], "\b \b", 3)
+
#define C(a, b) (gt.c_cc[(a)] == _POSIX_VDISABLE ? (b) : gt.c_cc[(a)])
if (lnext) {
@@ -145,6 +151,10 @@
/* Line or word kill, treat as reset */
if (c == C(VKILL, CTRL('u')) || c == C(VWERASE, CTRL('w'))) {
+ if (flags & GETPASS_ECHO) {
+ while (l--)
+ erase();
+ }
l = 0;
continue;
}
@@ -153,8 +163,11 @@
if (c == C(VERASE, CTRL('h'))) {
if (l == 0)
beep();
- else
+ else {
l--;
+ if (flags & GETPASS_ECHO)
+ erase();
+ }
continue;
}
@@ -174,13 +187,13 @@
/* EOF */
if (c == C(VEOF, CTRL('d'))) {
-#ifdef DONT_TREAT_EOF_AS_EOL
- errno = ENODATA;
- goto out;
-#else
- c = '\0';
- goto add;
-#endif
+ if (flags & GETPASS_FAIL_EOF) {
+ errno = ENODATA;
+ goto out;
+ } else {
+ c = '\0';
+ goto add;
+ }
}
/* End of line */
@@ -188,36 +201,78 @@
c = '\0';
add:
if (l >= len) {
-#ifdef DONT_DISCARD_SILENTLY
- beep();
- continue;
-#else
- if (c == '\0' && l > 0)
- l--;
- else
- continue;
-#endif
+ if (allocated) {
+ len += 1024;
+ char *b = realloc(buf, len);
+ if (b == NULL)
+ goto restore;
+ buf = b;
+ } else {
+ if (flags & GETPASS_BUF_LIMIT) {
+ beep();
+ continue;
+ }
+ if (c == '\0' && l > 0)
+ l--;
+ else
+ continue;
+ }
}
- ret[l++] = c;
+ buf[l++] = c;
+ if (c && (flags & GETPASS_ECHO))
+ (void)write(fd[1], &c, 1);
}
if (havetty)
- (void)tcsetattr(infd, TCSAFLUSH|TCSASOFT, >);
- return ret;
+ (void)tcsetattr(fd[0], TCSAFLUSH|TCSASOFT, >);
+ return buf;
restore:
- c = errno;
- if (havetty)
- (void)tcsetattr(infd, TCSAFLUSH|TCSASOFT, >);
- errno = c;
+ if (havetty) {
+ c = errno;
+ (void)tcsetattr(fd[0], TCSAFLUSH|TCSASOFT, >);
+ errno = c;
+ }
out:
if (sig) {
Home |
Main Index |
Thread Index |
Old Index