chiark / gitweb /
preload-hacks: Some patches to make it work.
[termux-packages] / packages / krb5 / netbsd_getpass.c
1 /*      $NetBSD: getpass.c,v 1.15 2003/08/07 16:42:50 agc Exp $ */
2 /*
3  * Copyright (c) 1988, 1993
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the University nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 #if 0
31 #include <sys/cdefs.h>
32 #if defined(LIBC_SCCS) && !defined(lint)
33 #if 0
34 static char sccsid[] = "@(#)getpass.c   8.1 (Berkeley) 6/4/93";
35 #else
36 __RCSID("$NetBSD: getpass.c,v 1.15 2003/08/07 16:42:50 agc Exp $");
37 #endif
38 #endif /* LIBC_SCCS and not lint */
39 #include "namespace.h"
40 #endif
41 #include <assert.h>
42 #include <paths.h>
43 #include <pwd.h>
44 #include <signal.h>
45 #include <stdio.h>
46 #include <termios.h>
47 #include <unistd.h>
48 #if 0
49 #ifdef __weak_alias
50 __weak_alias(getpass,_getpass)
51 #endif
52 #endif
53 char *
54 getpass(prompt)
55         const char *prompt;
56 {
57         struct termios term;
58         int ch;
59         char *p;
60         FILE *fp, *outfp;
61         int echo;
62         static char buf[_PASSWORD_LEN + 1];
63         sigset_t oset, nset;
64 #if 0
65         _DIAGASSERT(prompt != NULL);
66 #endif
67         /*
68          * read and write to /dev/tty if possible; else read from
69          * stdin and write to stderr.
70          */
71         if ((outfp = fp = fopen(_PATH_TTY, "w+")) == NULL) {
72                 outfp = stderr;
73                 fp = stdin;
74         }
75         /*
76          * note - blocking signals isn't necessarily the
77          * right thing, but we leave it for now.
78          */
79         sigemptyset(&nset);
80         sigaddset(&nset, SIGINT);
81         sigaddset(&nset, SIGTSTP);
82         (void)sigprocmask(SIG_BLOCK, &nset, &oset);
83         (void)tcgetattr(fileno(fp), &term);
84         if ((echo = (term.c_lflag & ECHO)) != 0) {
85                 term.c_lflag &= ~ECHO;
86                 (void)tcsetattr(fileno(fp), TCSAFLUSH /*|TCSASOFT*/, &term);
87         }
88         if (prompt != NULL)
89                 (void)fputs(prompt, outfp);
90         rewind(outfp);                  /* implied flush */
91         for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
92                 if (p < buf + _PASSWORD_LEN)
93                         *p++ = ch;
94         *p = '\0';
95         (void)write(fileno(outfp), "\n", 1);
96         if (echo) {
97                 term.c_lflag |= ECHO;
98                 (void)tcsetattr(fileno(fp), TCSAFLUSH/*|TCSASOFT*/, &term);
99         }
100         (void)sigprocmask(SIG_SETMASK, &oset, NULL);
101         if (fp != stdin)
102                 (void)fclose(fp);
103         return(buf);
104 }