1/* Copyright (c) 2000, 2001, 2003, 2006, 2008 MySQL AB
2 Use is subject to license terms
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16
17/*
18** Ask for a password from tty
19** This is an own file to avoid conflicts with curses
20*/
21#include <my_global.h>
22#include <my_sys.h>
23#include "mysql.h"
24#include <m_string.h>
25#include <m_ctype.h>
26
27#ifdef HAVE_GETPASS
28#ifdef HAVE_PWD_H
29#include <pwd.h>
30#endif /* HAVE_PWD_H */
31#else /* ! HAVE_GETPASS */
32#ifndef __WIN__
33#include <sys/ioctl.h>
34#ifdef HAVE_TERMIOS_H /* For tty-password */
35#include <termios.h>
36#define TERMIO struct termios
37#else
38#ifdef HAVE_TERMIO_H /* For tty-password */
39#include <termio.h>
40#define TERMIO struct termio
41#else
42#include <sgtty.h>
43#define TERMIO struct sgttyb
44#endif
45#endif
46#ifdef alpha_linux_port
47#include <asm/ioctls.h> /* QQ; Fix this in configure */
48#include <asm/termiobits.h>
49#endif
50#else
51#include <conio.h>
52#endif /* __WIN__ */
53#endif /* HAVE_GETPASS */
54
55#ifdef HAVE_GETPASSPHRASE /* For Solaris */
56#define getpass(A) getpassphrase(A)
57#endif
58
59#ifdef __WIN__
60/* were just going to fake it here and get input from
61 the keyboard */
62
63char *get_tty_password(const char *opt_message)
64{
65 char to[80];
66 char *pos=to,*end=to+sizeof(to)-1;
67 DBUG_ENTER("get_tty_password");
68 _cputs(opt_message ? opt_message : "Enter password: ");
69 for (;;)
70 {
71 char tmp;
72 tmp=_getch();
73 if (tmp == '\b' || (int) tmp == 127)
74 {
75 if (pos != to)
76 {
77 _cputs("\b \b");
78 pos--;
79 continue;
80 }
81 }
82 if (tmp == '\n' || tmp == '\r' || tmp == 3)
83 break;
84 if (iscntrl(tmp) || pos == end)
85 continue;
86 _cputs("*");
87 *(pos++) = tmp;
88 }
89 while (pos != to && isspace(pos[-1]) == ' ')
90 pos--; /* Allow dummy space at end */
91 *pos=0;
92 _cputs("\n");
93 DBUG_RETURN(my_strdup(to,MYF(MY_FAE)));
94}
95
96#else
97
98
99#ifndef HAVE_GETPASS
100/*
101** Can't use fgets, because readline will get confused
102** length is max number of chars in to, not counting \0
103* to will not include the eol characters.
104*/
105
106static void get_password(char *to,uint length,int fd, my_bool echo)
107{
108 char *pos=to,*end=to+length;
109
110 for (;;)
111 {
112 uchar tmp;
113 if (my_read(fd,&tmp,1,MYF(0)) != 1)
114 break;
115 if (tmp == '\b' || (int) tmp == 127)
116 {
117 if (pos != to)
118 {
119 if (echo)
120 {
121 fputs("\b \b",stderr);
122 fflush(stderr);
123 }
124 pos--;
125 continue;
126 }
127 }
128 if (tmp == '\n' || tmp == '\r' || tmp == 3)
129 break;
130 if (iscntrl(tmp) || pos == end)
131 continue;
132 if (echo)
133 {
134 fputc('*',stderr);
135 fflush(stderr);
136 }
137 *(pos++)= (char) tmp;
138 }
139 while (pos != to && isspace(pos[-1]) == ' ')
140 pos--; /* Allow dummy space at end */
141 *pos=0;
142 return;
143}
144
145#endif /* ! HAVE_GETPASS */
146
147
148char *get_tty_password(const char *opt_message)
149{
150#ifdef HAVE_GETPASS
151 char *passbuff;
152#else /* ! HAVE_GETPASS */
153 TERMIO org,tmp;
154#endif /* HAVE_GETPASS */
155 char buff[80];
156
157 DBUG_ENTER("get_tty_password");
158
159#ifdef HAVE_GETPASS
160 passbuff = getpass(opt_message ? opt_message : "Enter password: ");
161
162 /* copy the password to buff and clear original (static) buffer */
163 strnmov(buff, passbuff, sizeof(buff) - 1);
164#ifdef _PASSWORD_LEN
165 memset(passbuff, 0, _PASSWORD_LEN);
166#endif
167#else
168 if (isatty(fileno(stderr)))
169 {
170 fputs(opt_message ? opt_message : "Enter password: ",stderr);
171 fflush(stderr);
172 }
173#if defined(HAVE_TERMIOS_H)
174 tcgetattr(fileno(stdin), &org);
175 tmp = org;
176 tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
177 tmp.c_cc[VMIN] = 1;
178 tmp.c_cc[VTIME] = 0;
179 tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
180 get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stderr)));
181 tcsetattr(fileno(stdin), TCSADRAIN, &org);
182#elif defined(HAVE_TERMIO_H)
183 ioctl(fileno(stdin), (int) TCGETA, &org);
184 tmp=org;
185 tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
186 tmp.c_cc[VMIN] = 1;
187 tmp.c_cc[VTIME]= 0;
188 ioctl(fileno(stdin),(int) TCSETA, &tmp);
189 get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
190 ioctl(fileno(stdin),(int) TCSETA, &org);
191#else
192 gtty(fileno(stdin), &org);
193 tmp=org;
194 tmp.sg_flags &= ~ECHO;
195 tmp.sg_flags |= RAW;
196 stty(fileno(stdin), &tmp);
197 get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
198 stty(fileno(stdin), &org);
199#endif
200 if (isatty(fileno(stderr)))
201 fputc('\n',stderr);
202#endif /* HAVE_GETPASS */
203
204 DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
205}
206
207#endif /*__WIN__*/
208