1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
/* GetPass.c */
#include "Sys.h"
#include <signal.h>
#include "Util.h"
#include "GetPass.h"
/* This is responsible for turning off character echoing so a user
* can type a password without it showing up on the screen. Why
* not just the getpass() library function? Some systems' getpass
* only returns 8 characters. We require longer "passwords" so
* users can use their email addresses when prompted for a password.
*
* We have one function, Echo, which turns character echoing on/off.
* GetPass then uses Echo to turn it off, reads the password,
* and turns it back on again.
*
* Unfortunately this whole thing isn't very portable. Some systems
* have termio, others, sgtty. Some have both. Newer systems support
* termios, too.
*/
#ifdef CANNOT_HIDE_TEXT
/* If you can't get it to compile, you an always do this. */
void Echo(FILE *fp, int on)
{
return;
}
#else
#ifdef HAVE_TERMIOS_H
# include <termios.h>
#else
# ifdef HAVE_TERMIO_H
# include <termio.h>
# else
# ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h> /* For TIOxxxx constants. */
# endif
# include <sgtty.h>
# endif
#endif /* !HAVE_TERMIOS_H */
#ifdef STRICT_PROTOS
int ioctl(int, int, ...);
#endif
extern int gWinInit;
void Echo(FILE *fp, int on)
{
#ifdef HAVE_TERMIOS_H
static struct termios orig, noecho, *tp;
#else
# ifdef HAVE_TERMIO_H
static struct termio orig, noecho, *tp;
# else
static struct sgttyb orig, noecho, *tp;
# endif
#endif
static int state = 0;
int fd = fileno(fp);
/* Don't do this if we've setup curses, which makes this crap
* irrelevant anyway.
*/
if (gWinInit)
return;
if (!isatty(fd))
return;
if (state == 0) {
#ifdef HAVE_TERMIOS_H
if (tcgetattr(fd, &orig) < 0)
perror("tcgetattr");
noecho = orig;
noecho.c_lflag &= ~ECHO;
#else
# ifdef HAVE_TERMIO_H
if (ioctl(fd, TCGETA, &orig) < 0)
perror("ioctl");
noecho = orig;
noecho.c_lflag &= ~ECHO;
# else
if (ioctl(fd, TIOCGETP, &orig) < 0)
perror("ioctl");
noecho = orig;
noecho.sg_flags &= ~ECHO;
# endif
#endif
state = 1;
}
tp = NULL;
if (on && state == 2) {
/* Turn echo back on. */
tp = &orig;
state = 1;
} else if (!on && state == 1) {
/* Turn echo off. */
tp = &noecho;
state = 2;
}
if (tp != NULL) {
#ifdef HAVE_TERMIOS_H
if (tcsetattr(fd, TCSANOW, tp) < 0)
perror("tcsetattr");
#else
# ifdef HAVE_TERMIO_H
if (ioctl(fd, TCSETA, tp) < 0)
perror("ioctl");
# else
if (ioctl(fd, TIOCSETP, tp) < 0)
perror("ioctl");
# endif
#endif /* !HAVE_TERMIOS_H */
}
} /* Echo */
#endif /* CANNOT_HIDE_TEXT */
void GetPass(char *promptstr, char *answer, size_t siz)
{
FILE *fp, *outfp;
Sig_t oldintr;
#ifdef SIGTSTP
Sig_t oldtstp;
#endif
/*
* read and write to /dev/tty if possible; else read from
* stdin and write to stderr.
*/
if ((outfp = fp = fopen("/dev/tty", "r+")) == NULL) {
outfp = stderr;
fp = stdin;
}
/* Ignore some signals that could cause problems. We don't want
* to return with echoing off.
*/
oldintr = SIGNAL(SIGINT, SIG_IGN);
#ifdef SIGTSTP
oldtstp = SIGNAL(SIGTSTP, SIG_IGN);
#endif
Echo(fp, 0); /* Turn echoing off. */
(void) fputs(promptstr, outfp);
(void) fflush(outfp);
(void) rewind(outfp);
answer[0] = '\0';
if (fgets(answer, (int) siz, fp) != NULL)
answer[strlen(answer) - 1] = '\0';
(void) fflush(fp);
Echo(fp, 1);
(void) rewind(outfp);
(void) fputc('\n', outfp);
(void) SIGNAL(SIGINT, oldintr);
#ifdef SIGTSTP
(void) SIGNAL(SIGTSTP, oldtstp);
#endif
if (fp != stdin)
(void)fclose(fp);
} /* Getpass */
/* eof Getpass.c */
|