~drizzle-trunk/drizzle/development

928.1.1 by Eric Day
Started client changes.
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
20
/*
21
** Ask for a password from tty
22
** This is an own file to avoid conflicts with curses
23
*/
24
25
#include <drizzled/global.h>
994.2.4 by Monty Taylor
Blast. Fixed some make distcheck issues.
26
#include "client/get_password.h"
928.1.1 by Eric Day
Started client changes.
27
28
#include <string.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <ctype.h>
32
#include <unistd.h>
33
34
#include <sys/ioctl.h>
35
#ifdef HAVE_TERMIOS_H				/* For tty-password */
36
# include	<termios.h>
37
#  define TERMIO	struct termios
38
#else
39
#  ifdef HAVE_TERMIO_H				/* For tty-password */
40
#    include	<termio.h>
41
#    define TERMIO	struct termio
42
#  else
43
#    include	<sgtty.h>
44
#    define TERMIO	struct sgttyb
45
#  endif
46
#endif
47
48
/*
49
  Can't use fgets, because readline will get confused
50
  length is max number of chars in to, not counting \0
51
  to will not include the eol characters.
52
*/
53
54
static void get_password(char *to, uint32_t length,int fd, bool echo)
55
{
56
  char *pos=to,*end=to+length;
57
58
  for (;;)
59
  {
60
    char tmp;
61
    if (read(fd,&tmp,1) != 1)
62
      break;
63
    if (tmp == '\b' || (int) tmp == 127)
64
    {
65
      if (pos != to)
66
      {
67
	if (echo)
68
	{
69
	  fputs("\b \b",stdout);
70
	  fflush(stdout);
71
	}
72
	pos--;
73
	continue;
74
      }
75
    }
76
    if (tmp == '\n' || tmp == '\r' || tmp == 3)
77
      break;
78
    if (iscntrl(tmp) || pos == end)
79
      continue;
80
    if (echo)
81
    {
82
      fputc('*',stdout);
83
      fflush(stdout);
84
    }
85
    *(pos++) = tmp;
86
  }
87
  while (pos != to && isspace(pos[-1]) == ' ')
88
    pos--;					/* Allow dummy space at end */
89
  *pos=0;
90
  return;
91
}
92
93
94
char *client_get_tty_password(const char *opt_message)
95
{
96
  TERMIO org,tmp;
97
  char buff[80];
98
99
  if (isatty(fileno(stdout)))
100
  {
101
    fputs(opt_message ? opt_message : "Enter password: ",stdout);
102
    fflush(stdout);
103
  }
104
#  if defined(HAVE_TERMIOS_H)
105
  tcgetattr(fileno(stdin), &org);
106
  tmp = org;
107
  tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
108
  tmp.c_cc[VMIN] = 1;
109
  tmp.c_cc[VTIME] = 0;
110
  tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
111
  get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout)));
112
  tcsetattr(fileno(stdin), TCSADRAIN, &org);
113
#  elif defined(HAVE_TERMIO_H)
114
  ioctl(fileno(stdin), (int) TCGETA, &org);
115
  tmp=org;
116
  tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
117
  tmp.c_cc[VMIN] = 1;
118
  tmp.c_cc[VTIME]= 0;
119
  ioctl(fileno(stdin),(int) TCSETA, &tmp);
120
  get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
121
  ioctl(fileno(stdin),(int) TCSETA, &org);
122
#  else
123
  gtty(fileno(stdin), &org);
124
  tmp=org;
125
  tmp.sg_flags &= ~ECHO;
126
  tmp.sg_flags |= RAW;
127
  stty(fileno(stdin), &tmp);
128
  get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
129
  stty(fileno(stdin), &org);
130
#  endif
131
  if (isatty(fileno(stdout)))
132
    fputc('\n',stdout);
133
134
  return strdup(buff);
135
}