Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/gen - If fd == NULL, do the dance with opening /dev...



details:   https://anonhg.NetBSD.org/src/rev/946f5f17a84c
branches:  trunk
changeset: 778803:946f5f17a84c
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Apr 14 01:33:43 2012 +0000

description:
- If fd == NULL, do the dance with opening /dev/tty
- Add a flag to enter a newline when we are done.

diffstat:

 lib/libc/gen/getpass.3 |  40 +++++++++++++++++++---
 lib/libc/gen/getpass.c |  88 ++++++++++++++++++++++++++++++-------------------
 2 files changed, 87 insertions(+), 41 deletions(-)

diffs (233 lines):

diff -r 7288ab35464b -r 946f5f17a84c lib/libc/gen/getpass.3
--- a/lib/libc/gen/getpass.3    Sat Apr 14 00:14:22 2012 +0000
+++ b/lib/libc/gen/getpass.3    Sat Apr 14 01:33:43 2012 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: getpass.3,v 1.19 2012/04/13 14:39:34 christos Exp $
+.\"    $NetBSD: getpass.3,v 1.20 2012/04/14 01:33:43 christos Exp $
 .\"
 .\" Copyright (c) 1989, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -44,7 +44,7 @@
 .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" "int timeout"
+.Fn getpassfd "const char *prompt" "char *buf" "size_t buflen" "int *fd" "int flags" "int timeout"
 .Sh DESCRIPTION
 The
 .Fn getpass
@@ -81,11 +81,31 @@
 .Pp
 The
 .Fn getpassfd
-function allows one to specify the file descriptors used to be specified in
-.Fa fd ,
-and provides an extra
+function allows one to specify the three file descriptors corresponding to
+.Dv stdin ,
+.Dv stdout ,
+and
+.Dv stderr 
+in the
+.Fa fd 
+argument, or if
+.Fa fd
+is
+.Dv NULL ,
+.Fn getpassfd
+first attempts to open
+.Pa /dev/tty
+and if that fails, defaults to
+.Dv STDIN_FILENO
+for input and
+.Dv STDERR_FILENO
+for output.
+.Pp
+The behavior of
+.Fn getpassfd
+is controlled by the
 .Fa flags
-argument to control its behavior:
+argument:
 .Bl -tag -width GETPASS_BUF_LIMIT
 .It Dv GETPASS_NEED_TTY
 Fail if we are unable to set the tty modes like we want.
@@ -104,6 +124,14 @@
 for each character entered.
 .It Dv GETPASS_ECHO
 Echo characters as they are typed.
+.It Dv GETPASS_ECHO_NL
+Echoes a newline if successful.
+.It Dv GETPASS_7BIT
+Mask the high bit for each entered character.
+.It Dv GETPASS_FORCE_LOWER
+Lowcase each entered character.
+.It Dv GETPASS_FORCE_UPPER
+Upcase each entered character.
 .El
 Finally if the
 .Fa timeout
diff -r 7288ab35464b -r 946f5f17a84c lib/libc/gen/getpass.c
--- a/lib/libc/gen/getpass.c    Sat Apr 14 00:14:22 2012 +0000
+++ b/lib/libc/gen/getpass.c    Sat Apr 14 01:33:43 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: getpass.c,v 1.24 2012/04/13 14:42:18 christos Exp $    */
+/*     $NetBSD: getpass.c,v 1.25 2012/04/14 01:33:43 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.24 2012/04/13 14:42:18 christos Exp $");
+__RCSID("$NetBSD: getpass.c,v 1.25 2012/04/14 01:33:43 christos Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
@@ -76,21 +76,45 @@
  *     - GETPASS_NO_BEEP disables beeping.
  *     - GETPASS_ECHO_STAR will echo '*' for each character of the password
  *     - GETPASS_ECHO will echo the password (as pam likes it)
+ *     - GETPASS_7BIT strips the 8th bit
+ *     - GETPASS_FORCE_UPPER forces to uppercase
+ *     - GETPASS_FORCE_LOWER forces to uppercase
+ *     - GETPASS_ECHO_NL echo's a new line on success if echo was off.
  */
 char *
 /*ARGSUSED*/
-getpassfd(const char *prompt, char *buf, size_t len, int fd[], int flags,
+getpassfd(const char *prompt, char *buf, size_t len, int *fd, int flags,
     int tout)
 {
        struct termios gt;
        char c;
        int sig;
-       bool lnext, havetty, allocated;
+       bool lnext, havetty, allocated, opentty, good;
+       int fdc[3];
 
        _DIAGASSERT(prompt != NULL);
 
+       if (buf != NULL && len == 0) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       good = false;
+       opentty = false;
+       if (fd == NULL) {
+               /*
+                * Try to use /dev/tty if possible; otherwise read from stdin
+                * and write to stderr.
+                */
+               fd = fdc;
+               if ((fd[0] = fd[1] = fd[2] = open(_PATH_TTY, O_RDWR)) == -1) {
+                       fd[0] = STDIN_FILENO;
+                       fd[1] = fd[2] = STDERR_FILENO;
+               } else
+                       opentty = true;
+       }
+                
        sig = 0;
-
        allocated = buf == NULL;
        if (tcgetattr(fd[0], &gt) == -1) {
                havetty = false;
@@ -100,7 +124,6 @@
        } else
                havetty = true;
                
-
        if (havetty) {
                struct termios st = gt;
 
@@ -238,6 +261,14 @@
                                        continue;
                        }
                }
+
+               if (flags & GETPASS_7BIT)
+                       c &= 0x7f;
+               if ((flags & GETPASS_FORCE_LOWER) && isupper((unsigned char)c))
+                       c = tolower((unsigned char)c);
+               if ((flags & GETPASS_FORCE_UPPER) && islower((unsigned char)c))
+                       c = toupper((unsigned char)c);
+
                buf[l++] = c;
                if (c) {
                        if (flags & GETPASS_ECHO_STAR)
@@ -247,10 +278,8 @@
                                    &c : "?", 1);
                }
        }
+       good = true;
 
-       if (havetty)
-               (void)tcsetattr(fd[0], TCSAFLUSH|TCSASOFT, &gt);
-       return buf;
 restore:
        if (havetty) {
                c = errno;
@@ -258,6 +287,18 @@
                errno = c;
        }
 out:
+       if (good && (flags & GETPASS_ECHO_NL))
+               (void)write(fd[1], "\n", 1);
+
+       if (opentty) {
+               c = errno;
+               (void)close(fd[0]);
+               errno = c;
+       }
+
+       if (good)
+               return buf;
+
        if (sig) {
                if ((flags & GETPASS_NO_SIGNAL) == 0)
                        (void)raise(sig);
@@ -272,29 +313,7 @@
 char *
 getpass_r(const char *prompt, char *buf, size_t len)
 {
-       bool opentty;
-       int fd[3];
-       char *rv;
-
-       /*
-        * Try to use /dev/tty if possible; otherwise read from stdin and
-        * write to stderr.
-        */
-       if ((fd[0] = fd[1] = fd[2] = open(_PATH_TTY, O_RDWR)) == -1) {
-               opentty = false;
-               fd[0] = STDIN_FILENO;
-               fd[1] = fd[2] = STDERR_FILENO;
-       } else
-               opentty = true;
-
-       rv = getpassfd(prompt, buf, len, fd, 0, 0);
-
-       if (opentty) {
-               int serrno = errno;
-               (void)close(fd[0]);
-               errno = serrno;
-       }
-       return rv;
+       return getpassfd(prompt, buf, len, NULL, 0, 0);
 }
 
 char *
@@ -328,9 +347,8 @@
 main(int argc, char *argv[])
 {
        char buf[28];
-       int fd[3] = { 0, 1, 2 };
-       printf("[%s]\n", getpassfd("foo>", buf, sizeof(buf), fd,
-           GETPASS_ECHO_STAR, 2));
+       printf("[%s]\n", getpassfd("foo>", buf, sizeof(buf), NULL,
+           GETPASS_ECHO_STAR|GETPASS_ECHO_NL, 2));
        return 0;
 }
 #endif



Home | Main Index | Thread Index | Old Index