quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

tool_getpass.c (5592B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 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.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  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 #include "tool_setup.h"
     25 
     26 #if defined(__AMIGA__) && !defined(__amigaos4__)
     27 #  undef HAVE_TERMIOS_H
     28 #endif
     29 
     30 #ifndef HAVE_GETPASS_R
     31 /* this file is only for systems without getpass_r() */
     32 
     33 #ifdef HAVE_FCNTL_H
     34 #  include <fcntl.h>
     35 #endif
     36 
     37 #ifdef HAVE_TERMIOS_H
     38 #  include <termios.h>
     39 #elif defined(HAVE_TERMIO_H)
     40 #  include <termio.h>
     41 #endif
     42 
     43 #ifdef __VMS
     44 #  include descrip
     45 #  include starlet
     46 #  include iodef
     47 #endif
     48 
     49 #if defined(_WIN32) && !defined(UNDER_CE)
     50 #  include <conio.h>
     51 #endif
     52 
     53 #ifdef HAVE_UNISTD_H
     54 #include <unistd.h>
     55 #endif
     56 #include "tool_getpass.h"
     57 
     58 #include "memdebug.h" /* keep this as LAST include */
     59 
     60 #ifdef __VMS
     61 /* VMS implementation */
     62 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
     63 {
     64   long sts;
     65   short chan;
     66 
     67   /* MSK, 23-JAN-2004, iosbdef.h was not in VAX V7.2 or CC 6.4  */
     68   /* distribution so I created this. May revert back later to */
     69   /* struct _iosb iosb;                                        */
     70   struct _iosb
     71      {
     72      short int iosb$w_status; /* status     */
     73      short int iosb$w_bcnt;   /* byte count */
     74      int       unused;        /* unused     */
     75      } iosb;
     76 
     77   $DESCRIPTOR(ttdesc, "TT");
     78 
     79   buffer[0] = '\0';
     80   sts = sys$assign(&ttdesc, &chan, 0, 0);
     81   if(sts & 1) {
     82     sts = sys$qiow(0, chan,
     83                    IO$_READPROMPT | IO$M_NOECHO,
     84                    &iosb, 0, 0, buffer, buflen, 0, 0,
     85                    prompt, strlen(prompt));
     86 
     87     if((sts & 1) && (iosb.iosb$w_status & 1))
     88       buffer[iosb.iosb$w_bcnt] = '\0';
     89 
     90     sys$dassgn(chan);
     91   }
     92   return buffer; /* we always return success */
     93 }
     94 #define DONE
     95 #endif /* __VMS */
     96 
     97 #ifdef _WIN32
     98 
     99 char *getpass_r(const char *prompt, char *buffer, size_t buflen)
    100 {
    101   size_t i;
    102   fputs(prompt, tool_stderr);
    103 
    104   for(i = 0; i < buflen; i++) {
    105     buffer[i] = (char)_getch();
    106     if(buffer[i] == '\r' || buffer[i] == '\n') {
    107       buffer[i] = '\0';
    108       break;
    109     }
    110     else
    111       if(buffer[i] == '\b')
    112         /* remove this letter and if this is not the first key, remove the
    113            previous one as well */
    114         i = i - (i >= 1 ? 2 : 1);
    115   }
    116   /* since echo is disabled, print a newline */
    117   fputs("\n", tool_stderr);
    118   /* if user did not hit ENTER, terminate buffer */
    119   if(i == buflen)
    120     buffer[buflen-1] = '\0';
    121 
    122   return buffer; /* we always return success */
    123 }
    124 #define DONE
    125 #endif /* _WIN32 && !UNDER_CE */
    126 
    127 #ifndef DONE /* not previously provided */
    128 
    129 #ifdef HAVE_TERMIOS_H
    130 #  define struct_term  struct termios
    131 #elif defined(HAVE_TERMIO_H)
    132 #  define struct_term  struct termio
    133 #else
    134 #  undef  struct_term
    135 #endif
    136 
    137 static bool ttyecho(bool enable, int fd)
    138 {
    139 #ifdef struct_term
    140   static struct_term withecho;
    141   static struct_term noecho;
    142 #endif
    143   if(!enable) {
    144     /* disable echo by extracting the current 'withecho' mode and remove the
    145        ECHO bit and set back the struct */
    146 #ifdef HAVE_TERMIOS_H
    147     tcgetattr(fd, &withecho);
    148     noecho = withecho;
    149     noecho.c_lflag &= ~(tcflag_t)ECHO;
    150     tcsetattr(fd, TCSANOW, &noecho);
    151 #elif defined(HAVE_TERMIO_H)
    152     ioctl(fd, TCGETA, &withecho);
    153     noecho = withecho;
    154     noecho.c_lflag &= ~(tcflag_t)ECHO;
    155     ioctl(fd, TCSETA, &noecho);
    156 #else
    157     /* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we cannot disable echo! */
    158     (void)fd;
    159     return FALSE; /* not disabled */
    160 #endif
    161     return TRUE; /* disabled */
    162   }
    163   /* re-enable echo, assumes we disabled it before (and set the structs we
    164      now use to reset the terminal status) */
    165 #ifdef HAVE_TERMIOS_H
    166   tcsetattr(fd, TCSAFLUSH, &withecho);
    167 #elif defined(HAVE_TERMIO_H)
    168   ioctl(fd, TCSETA, &withecho);
    169 #else
    170   return FALSE; /* not enabled */
    171 #endif
    172   return TRUE; /* enabled */
    173 }
    174 
    175 char *getpass_r(const char *prompt, /* prompt to display */
    176                 char *password,     /* buffer to store password in */
    177                 size_t buflen)      /* size of buffer to store password in */
    178 {
    179   ssize_t nread;
    180   bool disabled;
    181   int fd = open("/dev/tty", O_RDONLY);
    182   if(-1 == fd)
    183     fd = STDIN_FILENO; /* use stdin if the tty could not be used */
    184 
    185   disabled = ttyecho(FALSE, fd); /* disable terminal echo */
    186 
    187   fputs(prompt, tool_stderr);
    188   nread = read(fd, password, buflen);
    189   if(nread > 0)
    190     password[--nread] = '\0'; /* null-terminate where enter is stored */
    191   else
    192     password[0] = '\0'; /* got nothing */
    193 
    194   if(disabled) {
    195     /* if echo actually was disabled, add a newline */
    196     fputs("\n", tool_stderr);
    197     (void)ttyecho(TRUE, fd); /* enable echo */
    198   }
    199 
    200   if(STDIN_FILENO != fd)
    201     close(fd);
    202 
    203   return password; /* return pointer to buffer */
    204 }
    205 
    206 #endif /* DONE */
    207 #endif /* HAVE_GETPASS_R */