summaryrefslogtreecommitdiffstats
path: root/usr.bin/ncftp/getpass.c
blob: a039e7a94f5498ad17b0682cfa7636e20d3f75c8 (plain)
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
/* Getpass.c */

/*  $RCSfile: getpass.c,v $
 *  $Revision: 14020.11 $
 *  $Date: 93/05/21 05:44:36 $
 */

#include "sys.h"

#include <signal.h>

#include "util.h"
#include "cmds.h"
#include "getpass.h"
#include "copyright.h"

#ifndef GETPASS

#ifndef sun	/* ...both unnecessary, and conflicting with <termios.h> */
#include <sys/ioctl.h>
#endif

#ifdef TERMIOS
#		include <termios.h>
#else
#	ifdef SGTTYB
#		include <sgtty.h>
#	else
#		include <termio.h>
#	endif
#endif /* !TERMIOS */

#ifdef STRICT_PROTOS
int ioctl(int, int, ...);
#endif

#endif	/* GETPASS */




void Echo(FILE *fp, int on)
{
#ifndef GETPASS		/* Otherwise just do nothing which is ok. */

#ifdef TERMIOS
	static struct termios orig, noecho, *tp;
#else
#	ifdef SGTTYB
	static struct sgttyb orig, noecho, *tp;
#	else
	static struct termio orig, noecho, *tp;
#	endif
#endif
	static int state = 0;
	int fd = fileno(fp);
	
	if (!isatty(fd))
		return;

	if (state == 0) {
#ifdef TERMIOS
		if (tcgetattr(fd, &orig) < 0)
			PERROR("echo", "tcgetattr");
		noecho = orig;
		noecho.c_lflag &= ~ECHO;
#else
#	ifdef SGTTYB
		if (ioctl(fd, TIOCGETP, &orig) < 0)
			PERROR("echo", "ioctl");
		noecho = orig;
		noecho.sg_flags &= ~ECHO;
#	else
		if (ioctl(fd, TCGETA, &orig) < 0)
			PERROR("echo", "ioctl");
		noecho = orig;
		noecho.c_lflag &= ~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 TERMIOS
		if (tcsetattr(fd, TCSANOW, tp) < 0)
			PERROR("echo", "tcsetattr");
#else
#	ifdef SGTTYB
		if (ioctl(fd, TIOCSETP, tp) < 0)
			PERROR("echo", "ioctl");
#	else
		if (ioctl(fd, TCSETA, tp) < 0)
			PERROR("echo", "ioctl");
#	endif
#endif	/* !TERMIOS */
	}

#endif	/* GETPASS */
}	/* Echo */



#ifndef GETPASS

char *Getpass(char *promptstr)
{
	register int ch;
	register char *p;
	FILE *fp, *outfp;
	Sig_t oldintr;
	static char buf[kMaxPassLen + 1];

	/*
	 * read and write to /dev/tty if possible; else read from
	 * stdin and write to stderr.
	 */
#if !defined(BOTCHED_FOPEN_RW)
  	if ((outfp = fp = fopen("/dev/tty", "w+")) == NULL) {
  		outfp = stderr;
  		fp = stdin;
  	}
#else
	/* SCO 32v2 botches "w+" open */
	if ((fp = fopen("/dev/tty", "r")) == NULL)
		fp = stdin;
	if ((outfp = fopen("/dev/tty", "w")) == NULL)
		outfp = stderr;
#endif
	oldintr = Signal(SIGINT, SIG_IGN);
	Echo(fp, 0);		/* Turn echoing off. */
	(void) fputs(promptstr, outfp);
	(void) rewind(outfp);			/* implied flush */
	for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
		if (p < buf + kMaxPassLen)
			*p++ = ch;
	*p = '\0';
	(void)write(fileno(outfp), "\n", 1);
	Echo(fp, 1);
	(void) Signal(SIGINT, oldintr);
	if (fp != stdin)
		(void)fclose(fp);
#if defined(BOTCHED_FOPEN_RW)
	if (outfp != stderr)
		(void)fclose(outfp);
#endif
	return(buf);
}	/* Getpass */

#endif /* GETPASS */

/* eof Getpass.c */
OpenPOWER on IntegriCloud