tool_getpass.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
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 https://curl.haxx.se/docs/copyright.html.
13  *
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.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 #include "tool_setup.h"
23 
24 #ifndef HAVE_GETPASS_R
25 /* this file is only for systems without getpass_r() */
26 
27 #ifdef HAVE_FCNTL_H
28 # include <fcntl.h>
29 #endif
30 
31 #ifdef HAVE_TERMIOS_H
32 # include <termios.h>
33 #elif defined(HAVE_TERMIO_H)
34 # include <termio.h>
35 #endif
36 
37 #ifdef __VMS
38 # include descrip
39 # include starlet
40 # include iodef
41 #endif
42 
43 #ifdef WIN32
44 # include <conio.h>
45 #endif
46 
47 #ifdef NETWARE
48 # ifdef __NOVELL_LIBC__
49 # include <screen.h>
50 # else
51 # include <nwconio.h>
52 # endif
53 #endif
54 
55 #ifdef HAVE_UNISTD_H
56 #include <unistd.h>
57 #endif
58 #include "tool_getpass.h"
59 
60 #include "memdebug.h" /* keep this as LAST include */
61 
62 #ifdef __VMS
63 /* VMS implementation */
64 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
65 {
66  long sts;
67  short chan;
68 
69  /* MSK, 23-JAN-2004, iosbdef.h wasn't in VAX V7.2 or CC 6.4 */
70  /* distribution so I created this. May revert back later to */
71  /* struct _iosb iosb; */
72  struct _iosb
73  {
74  short int iosb$w_status; /* status */
75  short int iosb$w_bcnt; /* byte count */
76  int unused; /* unused */
77  } iosb;
78 
79  $DESCRIPTOR(ttdesc, "TT");
80 
81  buffer[0] = '\0';
82  sts = sys$assign(&ttdesc, &chan, 0, 0);
83  if(sts & 1) {
84  sts = sys$qiow(0, chan,
85  IO$_READPROMPT | IO$M_NOECHO,
86  &iosb, 0, 0, buffer, buflen, 0, 0,
87  prompt, strlen(prompt));
88 
89  if((sts & 1) && (iosb.iosb$w_status & 1))
90  buffer[iosb.iosb$w_bcnt] = '\0';
91 
92  sts = sys$dassgn(chan);
93  }
94  return buffer; /* we always return success */
95 }
96 #define DONE
97 #endif /* __VMS */
98 
99 #ifdef __SYMBIAN32__
100 # define getch() getchar()
101 #endif
102 
103 #if defined(WIN32) || defined(__SYMBIAN32__)
104 
105 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
106 {
107  size_t i;
108  fputs(prompt, stderr);
109 
110  for(i = 0; i < buflen; i++) {
111  buffer[i] = (char)getch();
112  if(buffer[i] == '\r' || buffer[i] == '\n') {
113  buffer[i] = '\0';
114  break;
115  }
116  else
117  if(buffer[i] == '\b')
118  /* remove this letter and if this is not the first key, remove the
119  previous one as well */
120  i = i - (i >= 1 ? 2 : 1);
121  }
122 #ifndef __SYMBIAN32__
123  /* since echo is disabled, print a newline */
124  fputs("\n", stderr);
125 #endif
126  /* if user didn't hit ENTER, terminate buffer */
127  if(i == buflen)
128  buffer[buflen-1] = '\0';
129 
130  return buffer; /* we always return success */
131 }
132 #define DONE
133 #endif /* WIN32 || __SYMBIAN32__ */
134 
135 #ifdef NETWARE
136 /* NetWare implementation */
137 #ifdef __NOVELL_LIBC__
138 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
139 {
140  return getpassword(prompt, buffer, buflen);
141 }
142 #else
143 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
144 {
145  size_t i = 0;
146 
147  printf("%s", prompt);
148  do {
149  buffer[i++] = getch();
150  if(buffer[i-1] == '\b') {
151  /* remove this letter and if this is not the first key,
152  remove the previous one as well */
153  if(i > 1) {
154  printf("\b \b");
155  i = i - 2;
156  }
157  else {
158  RingTheBell();
159  i = i - 1;
160  }
161  }
162  else if(buffer[i-1] != 13)
163  putchar('*');
164 
165  } while((buffer[i-1] != 13) && (i < buflen));
166  buffer[i-1] = '\0';
167  printf("\r\n");
168  return buffer;
169 }
170 #endif /* __NOVELL_LIBC__ */
171 #define DONE
172 #endif /* NETWARE */
173 
174 #ifndef DONE /* not previously provided */
175 
176 #ifdef HAVE_TERMIOS_H
177 # define struct_term struct termios
178 #elif defined(HAVE_TERMIO_H)
179 # define struct_term struct termio
180 #else
181 # undef struct_term
182 #endif
183 
184 static bool ttyecho(bool enable, int fd)
185 {
186 #ifdef struct_term
187  static struct_term withecho;
188  static struct_term noecho;
189 #endif
190  if(!enable) {
191  /* disable echo by extracting the current 'withecho' mode and remove the
192  ECHO bit and set back the struct */
193 #ifdef HAVE_TERMIOS_H
194  tcgetattr(fd, &withecho);
195  noecho = withecho;
196  noecho.c_lflag &= ~ECHO;
197  tcsetattr(fd, TCSANOW, &noecho);
198 #elif defined(HAVE_TERMIO_H)
199  ioctl(fd, TCGETA, &withecho);
200  noecho = withecho;
201  noecho.c_lflag &= ~ECHO;
202  ioctl(fd, TCSETA, &noecho);
203 #else
204  /* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we can't disable echo! */
205  (void)fd;
206  return FALSE; /* not disabled */
207 #endif
208  return TRUE; /* disabled */
209  }
210  /* re-enable echo, assumes we disabled it before (and set the structs we
211  now use to reset the terminal status) */
212 #ifdef HAVE_TERMIOS_H
213  tcsetattr(fd, TCSAFLUSH, &withecho);
214 #elif defined(HAVE_TERMIO_H)
215  ioctl(fd, TCSETA, &withecho);
216 #else
217  return FALSE; /* not enabled */
218 #endif
219  return TRUE; /* enabled */
220 }
221 
222 char *getpass_r(const char *prompt, /* prompt to display */
223  char *password, /* buffer to store password in */
224  size_t buflen) /* size of buffer to store password in */
225 {
226  ssize_t nread;
227  bool disabled;
228  int fd = open("/dev/tty", O_RDONLY);
229  if(-1 == fd)
230  fd = STDIN_FILENO; /* use stdin if the tty couldn't be used */
231 
232  disabled = ttyecho(FALSE, fd); /* disable terminal echo */
233 
234  fputs(prompt, stderr);
235  nread = read(fd, password, buflen);
236  if(nread > 0)
237  password[--nread] = '\0'; /* zero terminate where enter is stored */
238  else
239  password[0] = '\0'; /* got nothing */
240 
241  if(disabled) {
242  /* if echo actually was disabled, add a newline */
243  fputs("\n", stderr);
244  (void)ttyecho(TRUE, fd); /* enable echo */
245  }
246 
247  if(STDIN_FILENO != fd)
248  close(fd);
249 
250  return password; /* return pointer to buffer */
251 }
252 
253 #endif /* DONE */
254 #endif /* HAVE_GETPASS_R */
#define sys
Definition: setup-vms.h:58
static char * password
Definition: unit1304.c:27
char buffer[]
Definition: unit1308.c:48
unsigned int i
Definition: unit1303.c:79
#define FALSE
#define printf
Definition: curl_printf.h:40
char * getpass_r(const char *prompt, char *password, size_t buflen)
Definition: tool_getpass.c:222
#define ssize_t
Definition: config-win32.h:382
#define STDIN_FILENO
Definition: tool_main.h:32
#define TRUE
static bool ttyecho(bool enable, int fd)
Definition: tool_getpass.c:184


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16