Annotation of embedaddon/curl/src/tool_getpass.c, revision 1.1
1.1 ! misho 1: /***************************************************************************
! 2: * _ _ ____ _
! 3: * Project ___| | | | _ \| |
! 4: * / __| | | | |_) | |
! 5: * | (__| |_| | _ <| |___
! 6: * \___|\___/|_| \_\_____|
! 7: *
! 8: * Copyright (C) 1998 - 2019, 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: #if defined(__AMIGA__) && !defined(__amigaos4__)
! 25: # undef HAVE_TERMIOS_H
! 26: #endif
! 27:
! 28: #ifndef HAVE_GETPASS_R
! 29: /* this file is only for systems without getpass_r() */
! 30:
! 31: #ifdef HAVE_FCNTL_H
! 32: # include <fcntl.h>
! 33: #endif
! 34:
! 35: #ifdef HAVE_TERMIOS_H
! 36: # include <termios.h>
! 37: #elif defined(HAVE_TERMIO_H)
! 38: # include <termio.h>
! 39: #endif
! 40:
! 41: #ifdef __VMS
! 42: # include descrip
! 43: # include starlet
! 44: # include iodef
! 45: #endif
! 46:
! 47: #ifdef WIN32
! 48: # include <conio.h>
! 49: #endif
! 50:
! 51: #ifdef NETWARE
! 52: # ifdef __NOVELL_LIBC__
! 53: # include <screen.h>
! 54: # else
! 55: # include <nwconio.h>
! 56: # endif
! 57: #endif
! 58:
! 59: #ifdef HAVE_UNISTD_H
! 60: #include <unistd.h>
! 61: #endif
! 62: #include "tool_getpass.h"
! 63:
! 64: #include "memdebug.h" /* keep this as LAST include */
! 65:
! 66: #ifdef __VMS
! 67: /* VMS implementation */
! 68: char *getpass_r(const char *prompt, char *buffer, size_t buflen)
! 69: {
! 70: long sts;
! 71: short chan;
! 72:
! 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; */
! 76: struct _iosb
! 77: {
! 78: short int iosb$w_status; /* status */
! 79: short int iosb$w_bcnt; /* byte count */
! 80: int unused; /* unused */
! 81: } iosb;
! 82:
! 83: $DESCRIPTOR(ttdesc, "TT");
! 84:
! 85: buffer[0] = '\0';
! 86: sts = sys$assign(&ttdesc, &chan, 0, 0);
! 87: if(sts & 1) {
! 88: sts = sys$qiow(0, chan,
! 89: IO$_READPROMPT | IO$M_NOECHO,
! 90: &iosb, 0, 0, buffer, buflen, 0, 0,
! 91: prompt, strlen(prompt));
! 92:
! 93: if((sts & 1) && (iosb.iosb$w_status & 1))
! 94: buffer[iosb.iosb$w_bcnt] = '\0';
! 95:
! 96: sys$dassgn(chan);
! 97: }
! 98: return buffer; /* we always return success */
! 99: }
! 100: #define DONE
! 101: #endif /* __VMS */
! 102:
! 103: #ifdef __SYMBIAN32__
! 104: # define getch() getchar()
! 105: #endif
! 106:
! 107: #if defined(WIN32) || defined(__SYMBIAN32__)
! 108:
! 109: char *getpass_r(const char *prompt, char *buffer, size_t buflen)
! 110: {
! 111: size_t i;
! 112: fputs(prompt, stderr);
! 113:
! 114: for(i = 0; i < buflen; i++) {
! 115: buffer[i] = (char)getch();
! 116: if(buffer[i] == '\r' || buffer[i] == '\n') {
! 117: buffer[i] = '\0';
! 118: break;
! 119: }
! 120: else
! 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);
! 125: }
! 126: #ifndef __SYMBIAN32__
! 127: /* since echo is disabled, print a newline */
! 128: fputs("\n", stderr);
! 129: #endif
! 130: /* if user didn't hit ENTER, terminate buffer */
! 131: if(i == buflen)
! 132: buffer[buflen-1] = '\0';
! 133:
! 134: return buffer; /* we always return success */
! 135: }
! 136: #define DONE
! 137: #endif /* WIN32 || __SYMBIAN32__ */
! 138:
! 139: #ifdef NETWARE
! 140: /* NetWare implementation */
! 141: #ifdef __NOVELL_LIBC__
! 142: char *getpass_r(const char *prompt, char *buffer, size_t buflen)
! 143: {
! 144: return getpassword(prompt, buffer, buflen);
! 145: }
! 146: #else
! 147: char *getpass_r(const char *prompt, char *buffer, size_t buflen)
! 148: {
! 149: size_t i = 0;
! 150:
! 151: printf("%s", prompt);
! 152: do {
! 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 */
! 157: if(i > 1) {
! 158: printf("\b \b");
! 159: i = i - 2;
! 160: }
! 161: else {
! 162: RingTheBell();
! 163: i = i - 1;
! 164: }
! 165: }
! 166: else if(buffer[i-1] != 13)
! 167: putchar('*');
! 168:
! 169: } while((buffer[i-1] != 13) && (i < buflen));
! 170: buffer[i-1] = '\0';
! 171: printf("\r\n");
! 172: return buffer;
! 173: }
! 174: #endif /* __NOVELL_LIBC__ */
! 175: #define DONE
! 176: #endif /* NETWARE */
! 177:
! 178: #ifndef DONE /* not previously provided */
! 179:
! 180: #ifdef HAVE_TERMIOS_H
! 181: # define struct_term struct termios
! 182: #elif defined(HAVE_TERMIO_H)
! 183: # define struct_term struct termio
! 184: #else
! 185: # undef struct_term
! 186: #endif
! 187:
! 188: static bool ttyecho(bool enable, int fd)
! 189: {
! 190: #ifdef struct_term
! 191: static struct_term withecho;
! 192: static struct_term noecho;
! 193: #endif
! 194: if(!enable) {
! 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);
! 199: noecho = withecho;
! 200: noecho.c_lflag &= ~ECHO;
! 201: tcsetattr(fd, TCSANOW, &noecho);
! 202: #elif defined(HAVE_TERMIO_H)
! 203: ioctl(fd, TCGETA, &withecho);
! 204: noecho = withecho;
! 205: noecho.c_lflag &= ~ECHO;
! 206: ioctl(fd, TCSETA, &noecho);
! 207: #else
! 208: /* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we can't disable echo! */
! 209: (void)fd;
! 210: return FALSE; /* not disabled */
! 211: #endif
! 212: return TRUE; /* disabled */
! 213: }
! 214: /* re-enable echo, assumes we disabled it before (and set the structs we
! 215: now use to reset the terminal status) */
! 216: #ifdef HAVE_TERMIOS_H
! 217: tcsetattr(fd, TCSAFLUSH, &withecho);
! 218: #elif defined(HAVE_TERMIO_H)
! 219: ioctl(fd, TCSETA, &withecho);
! 220: #else
! 221: return FALSE; /* not enabled */
! 222: #endif
! 223: return TRUE; /* enabled */
! 224: }
! 225:
! 226: char *getpass_r(const char *prompt, /* prompt to display */
! 227: char *password, /* buffer to store password in */
! 228: size_t buflen) /* size of buffer to store password in */
! 229: {
! 230: ssize_t nread;
! 231: bool disabled;
! 232: int fd = open("/dev/tty", O_RDONLY);
! 233: if(-1 == fd)
! 234: fd = STDIN_FILENO; /* use stdin if the tty couldn't be used */
! 235:
! 236: disabled = ttyecho(FALSE, fd); /* disable terminal echo */
! 237:
! 238: fputs(prompt, stderr);
! 239: nread = read(fd, password, buflen);
! 240: if(nread > 0)
! 241: password[--nread] = '\0'; /* zero terminate where enter is stored */
! 242: else
! 243: password[0] = '\0'; /* got nothing */
! 244:
! 245: if(disabled) {
! 246: /* if echo actually was disabled, add a newline */
! 247: fputs("\n", stderr);
! 248: (void)ttyecho(TRUE, fd); /* enable echo */
! 249: }
! 250:
! 251: if(STDIN_FILENO != fd)
! 252: close(fd);
! 253:
! 254: return password; /* return pointer to buffer */
! 255: }
! 256:
! 257: #endif /* DONE */
! 258: #endif /* HAVE_GETPASS_R */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>