1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
24 #ifndef HAVE_GETPASS_R
25 /* this file is only for systems without getpass_r() */
37 #elif defined(HAVE_TERMIO_H)
52 # ifdef __NOVELL_LIBC__
59 #define _MPRINTF_REPLACE
60 #include <curl/mprintf.h>
62 #include "tool_getpass.h"
64 #include "memdebug.h" /* keep this as LAST include */
67 /* VMS implementation */
68 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
73 /* MSK, 23-JAN-2004, iosbdef.h wasn't in VAX V7.2 or CC 6.4 */
74 /* distribution so I created this. May revert back later to */
75 /* struct _iosb iosb; */
78 short int iosb$w_status; /* status */
79 short int iosb$w_bcnt; /* byte count */
80 int unused; /* unused */
83 $DESCRIPTOR(ttdesc, "TT");
86 sts = sys$assign(&ttdesc, &chan, 0, 0);
88 sts = sys$qiow(0, chan,
89 IO$_READPROMPT | IO$M_NOECHO,
90 &iosb, 0, 0, buffer, buflen, 0, 0,
91 prompt, strlen(prompt));
93 if((sts & 1) && (iosb.iosb$w_status & 1))
94 buffer[iosb.iosb$w_bcnt] = '\0';
96 sts = sys$dassgn(chan);
98 return buffer; /* we always return success */
104 # define getch() getchar()
107 #if defined(WIN32) || defined(__SYMBIAN32__)
109 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
112 fputs(prompt, stderr);
114 for(i = 0; i < buflen; i++) {
115 buffer[i] = (char)getch();
116 if(buffer[i] == '\r' || buffer[i] == '\n') {
121 if(buffer[i] == '\b')
122 /* remove this letter and if this is not the first key, remove the
123 previous one as well */
124 i = i - (i >= 1) ? 2 : 1;
126 #ifndef __SYMBIAN32__
127 /* since echo is disabled, print a newline */
130 /* if user didn't hit ENTER, terminate buffer */
132 buffer[buflen-1] = '\0';
134 return buffer; /* we always return success */
137 #endif /* WIN32 || __SYMBIAN32__ */
140 /* NetWare implementation */
141 #ifdef __NOVELL_LIBC__
142 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
144 return getpassword(prompt, buffer, buflen);
147 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
151 printf("%s", prompt);
153 buffer[i++] = getch();
154 if(buffer[i-1] == '\b') {
155 /* remove this letter and if this is not the first key,
156 remove the previous one as well */
166 else if(buffer[i-1] != 13)
169 } while((buffer[i-1] != 13) && (i < buflen));
174 #endif /* __NOVELL_LIBC__ */
178 #ifndef DONE /* not previously provided */
180 #ifdef HAVE_TERMIOS_H
181 # define struct_term struct termios
182 #elif defined(HAVE_TERMIO_H)
183 # define struct_term struct termio
188 static bool ttyecho(bool enable, int fd)
191 static struct_term withecho;
192 static struct_term noecho;
195 /* disable echo by extracting the current 'withecho' mode and remove the
196 ECHO bit and set back the struct */
197 #ifdef HAVE_TERMIOS_H
198 tcgetattr(fd, &withecho);
200 noecho.c_lflag &= ~ECHO;
201 tcsetattr(fd, TCSANOW, &noecho);
202 #elif defined(HAVE_TERMIO_H)
203 ioctl(fd, TCGETA, &withecho);
205 noecho.c_lflag &= ~ECHO;
206 ioctl(fd, TCSETA, &noecho);
208 /* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we can't disable echo! */
210 return FALSE; /* not disabled */
212 return TRUE; /* disabled */
215 /* re-enable echo, assumes we disabled it before (and set the structs we
216 now use to reset the terminal status) */
217 #ifdef HAVE_TERMIOS_H
218 tcsetattr(fd, TCSAFLUSH, &withecho);
219 #elif defined(HAVE_TERMIO_H)
220 ioctl(fd, TCSETA, &withecho);
222 return FALSE; /* not enabled */
224 return TRUE; /* enabled */
228 char *getpass_r(const char *prompt, /* prompt to display */
229 char *password, /* buffer to store password in */
230 size_t buflen) /* size of buffer to store password in */
234 int fd = open("/dev/tty", O_RDONLY);
236 fd = 1; /* use stdin if the tty couldn't be used */
238 disabled = ttyecho(FALSE, fd); /* disable terminal echo */
240 fputs(prompt, stderr);
241 nread = read(fd, password, buflen);
243 password[--nread] = '\0'; /* zero terminate where enter is stored */
245 password[0] = '\0'; /* got nothing */
248 /* if echo actually was disabled, add a newline */
250 (void)ttyecho(TRUE, fd); /* enable echo */
256 return password; /* return pointer to buffer */
260 #endif /* HAVE_GETPASS_R */