* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "tool_setup.h"
#if defined(__AMIGA__) && !defined(__amigaos4__)
# undef HAVE_TERMIOS_H
#endif
#ifndef HAVE_GETPASS_R
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef HAVE_TERMIOS_H
# include <termios.h>
#elif defined(HAVE_TERMIO_H)
# include <termio.h>
#endif
#ifdef __VMS
# include descrip
# include starlet
# include iodef
#endif
#ifdef _WIN32
# include <conio.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "tool_getpass.h"
#include "memdebug.h"
#ifdef __VMS
char *getpass_r(const char *prompt, char *buffer, size_t buflen)
{
long sts;
short chan;
struct _iosb
{
short int iosb$w_status;
short int iosb$w_bcnt;
int unused;
} iosb;
$DESCRIPTOR(ttdesc, "TT");
buffer[0] = '\0';
sts = sys$assign(&ttdesc, &chan, 0, 0);
if(sts & 1) {
sts = sys$qiow(0, chan,
IO$_READPROMPT | IO$M_NOECHO,
&iosb, 0, 0, buffer, buflen, 0, 0,
prompt, strlen(prompt));
if((sts & 1) && (iosb.iosb$w_status & 1))
buffer[iosb.iosb$w_bcnt] = '\0';
sys$dassgn(chan);
}
return buffer;
}
#define DONE
#endif
#if defined(_WIN32)
char *getpass_r(const char *prompt, char *buffer, size_t buflen)
{
size_t i;
fputs(prompt, tool_stderr);
for(i = 0; i < buflen; i++) {
buffer[i] = (char)getch();
if(buffer[i] == '\r' || buffer[i] == '\n') {
buffer[i] = '\0';
break;
}
else
if(buffer[i] == '\b')
previous one as well */
i = i - (i >= 1 ? 2 : 1);
}
fputs("\n", tool_stderr);
if(i == buflen)
buffer[buflen-1] = '\0';
return buffer;
}
#define DONE
#endif
#ifndef DONE
#ifdef HAVE_TERMIOS_H
# define struct_term struct termios
#elif defined(HAVE_TERMIO_H)
# define struct_term struct termio
#else
# undef struct_term
#endif
static bool ttyecho(bool enable, int fd)
{
#ifdef struct_term
static struct_term withecho;
static struct_term noecho;
#endif
if(!enable) {
ECHO bit and set back the struct */
#ifdef HAVE_TERMIOS_H
tcgetattr(fd, &withecho);
noecho = withecho;
noecho.c_lflag &= ~(tcflag_t)ECHO;
tcsetattr(fd, TCSANOW, &noecho);
#elif defined(HAVE_TERMIO_H)
ioctl(fd, TCGETA, &withecho);
noecho = withecho;
noecho.c_lflag &= ~(tcflag_t)ECHO;
ioctl(fd, TCSETA, &noecho);
#else
(void)fd;
return FALSE;
#endif
return TRUE;
}
now use to reset the terminal status) */
#ifdef HAVE_TERMIOS_H
tcsetattr(fd, TCSAFLUSH, &withecho);
#elif defined(HAVE_TERMIO_H)
ioctl(fd, TCSETA, &withecho);
#else
return FALSE;
#endif
return TRUE;
}
char *getpass_r(const char *prompt,
char *password,
size_t buflen)
{
ssize_t nread;
bool disabled;
int fd = open("/dev/tty", O_RDONLY);
if(-1 == fd)
fd = STDIN_FILENO;
disabled = ttyecho(FALSE, fd);
fputs(prompt, tool_stderr);
nread = read(fd, password, buflen);
if(nread > 0)
password[--nread] = '\0';
else
password[0] = '\0';
if(disabled) {
fputs("\n", tool_stderr);
(void)ttyecho(TRUE, fd);
}
if(STDIN_FILENO != fd)
close(fd);
return password;
}
#endif
#endif