1/* ============================================================================
2 * Copyright (C) 1998 Angus Mackay. All rights reserved;
3 *
4 * Redistribution and use are freely permitted provided that:
5 *
6 *   1) This header remain in tact.
7 *   2) The prototype for getpass is not changed from:
8 *         char *getpass(const char *prompt)
9 *   3) This source code is not used outside of this(getpass.c) file.
10 *   3) Any changes to this(getpass.c) source code are made publicly available.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
13 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
14 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
16 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
17 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
18 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
19 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
20 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
21 * POSSIBILITY OF SUCH DAMAGE.
22 * ============================================================================
23 *
24 * $Id: getpass.c,v 1.1.1.1 2008/07/21 09:17:41 james26_jang Exp $
25 *
26 * The spirit of this license is to allow use of this source code in any
27 * project be it open or closed but still encourage the use of the open,
28 * library based equivilents.
29 *
30 * Author(s):
31 *   Angus Mackay <amackay@gus.ml.org>
32 *
33 * Contributor(s):
34 *   Daniel Stenberg <Daniel.Stenberg@sth.frontec.se>
35 */
36
37#ifdef HAVE_CONFIG_H
38#  include <config.h>
39#endif
40
41#ifdef HAVE_TERMIOS_H
42#  if !defined(HAVE_TCGETATTR) && !defined(HAVE_TCSETATTR)
43#    undef HAVE_TERMIOS_H
44#  endif
45#endif
46
47#define INPUT_BUFFER 128
48
49#ifndef RETSIGTYPE
50#  define RETSIGTYPE void
51#endif
52
53#include <unistd.h>
54#include <stdio.h>
55#include <signal.h>
56#ifdef HAVE_TERMIOS_H
57#  include <termios.h>
58#else
59#  ifdef HAVE_TERMIO_H
60#  include <termio.h>
61#  else
62#  endif
63#endif
64
65/* no perror? make an fprintf! */
66#ifndef HAVE_PERROR
67#  define perror(x) fprintf(stderr, "Error in: %s\n", x)
68#endif
69
70char *getpass(const char *prompt)
71{
72  FILE *infp;
73  FILE *outfp;
74  static char buf[INPUT_BUFFER];
75  RETSIGTYPE (*sigint)();
76  RETSIGTYPE (*sigtstp)();
77  size_t bytes_read;
78  int infd;
79  int outfd;
80#ifdef HAVE_TERMIOS_H
81  struct termios orig;
82  struct termios noecho;
83#else
84#  ifdef HAVE_TERMIO_H
85  struct termio orig;
86  struct termio noecho;
87#  else
88#  endif
89#endif
90
91  sigint = signal(SIGINT, SIG_IGN);
92  sigtstp = signal(SIGTSTP, SIG_IGN);
93
94  if( (infp=fopen("/dev/tty", "r")) == NULL )
95  {
96    infp = stdin;
97  }
98  if( (outfp=fopen("/dev/tty", "w")) == NULL )
99  {
100    outfp = stderr;
101  }
102  infd = fileno(infp);
103  outfd = fileno(outfp);
104
105  /* dissable echo */
106#ifdef HAVE_TERMIOS_H
107  if(tcgetattr(outfd, &orig) != 0)
108  {
109    perror("tcgetattr");
110  }
111  noecho = orig;
112  noecho.c_lflag &= ~ECHO;
113  if(tcsetattr(outfd, TCSANOW, &noecho) != 0)
114  {
115    perror("tcgetattr");
116  }
117#else
118#  ifdef HAVE_TERMIO_H
119  if(ioctl(outfd, TCGETA, &orig) != 0)
120  {
121    perror("ioctl");
122  }
123  noecho = orig;
124  noecho.c_lflag &= ~ECHO;
125  if(ioctl(outfd, TCSETA, &noecho) != 0)
126  {
127    perror("ioctl");
128  }
129#  else
130#  endif
131#endif
132
133  fputs(prompt, outfp);
134  fflush(outfp);
135
136  bytes_read=read(infd, buf, INPUT_BUFFER);
137  buf[bytes_read > 0 ? (bytes_read -1) : 0] = '\0';
138
139  /* print a new line if needed */
140#ifdef HAVE_TERMIOS_H
141  fputs("\n", outfp);
142#else
143#  ifdef HAVE_TERMIO_H
144  fputs("\n", outfp);
145#  else
146#  endif
147#endif
148
149  /*
150   * reset term charectaristics, use TCSAFLUSH incase the
151   * user types more than INPUT_BUFFER
152   */
153#ifdef HAVE_TERMIOS_H
154  if(tcsetattr(outfd, TCSAFLUSH, &orig) != 0)
155  {
156    perror("tcgetattr");
157  }
158#else
159#  ifdef HAVE_TERMIO_H
160  if(ioctl(outfd, TCSETA, &orig) != 0)
161  {
162    perror("ioctl");
163  }
164#  else
165#  endif
166#endif
167
168  signal(SIGINT, sigint);
169  signal(SIGTSTP, sigtstp);
170
171  return(buf);
172}
173
174
175