| 1 | /* |
| 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
| 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 5 | * |
| 6 | * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V. |
| 7 | */ |
| 8 | |
| 9 | #include "monetdb_config.h" |
| 10 | #include <unistd.h> |
| 11 | #include <string.h> |
| 12 | #ifndef _MSC_VER |
| 13 | #ifdef HAVE_TERMIOS_H |
| 14 | #include <termios.h> |
| 15 | #endif |
| 16 | #endif |
| 17 | #include "mprompt.h" |
| 18 | |
| 19 | #ifdef _MSC_VER |
| 20 | #define fileno _fileno |
| 21 | #include <conio.h> |
| 22 | #endif |
| 23 | |
| 24 | #ifndef HAVE_GETLOGIN |
| 25 | /* we assume this must be windows */ |
| 26 | static char *defaultlogin = "win32" ; |
| 27 | #endif |
| 28 | |
| 29 | char * |
| 30 | prompt_getlogin(void) |
| 31 | { |
| 32 | #ifdef HAVE_GETLOGIN |
| 33 | # ifdef __sun__ |
| 34 | /* from Solaris' getlogin manpage: |
| 35 | * The correct procedure for determining the login name is to call |
| 36 | * cuserid(3C), or to call getlogin() and if it fails to call |
| 37 | * getpwuid(3C). */ |
| 38 | return cuserid(NULL); |
| 39 | # else |
| 40 | return getlogin(); |
| 41 | # endif |
| 42 | #else |
| 43 | return defaultlogin; |
| 44 | #endif |
| 45 | } |
| 46 | |
| 47 | #ifdef _MSC_VER |
| 48 | char * |
| 49 | simple_prompt(const char *prompt, int maxlen, int echo, const char *def) |
| 50 | { |
| 51 | size_t length = 0; |
| 52 | char *destination = NULL; |
| 53 | |
| 54 | destination = (char *) malloc(maxlen + 2); |
| 55 | if (!destination) |
| 56 | return NULL; |
| 57 | |
| 58 | if (prompt) { |
| 59 | _cputs(prompt); |
| 60 | if (def) { |
| 61 | _cputs("(" ); |
| 62 | _cputs(def); |
| 63 | _cputs(")" ); |
| 64 | } |
| 65 | _cputs(":" ); |
| 66 | } |
| 67 | if (echo) { |
| 68 | _cgets_s(destination, maxlen, &length); |
| 69 | while (length > 0 && |
| 70 | (destination[length - 1] == '\n' || |
| 71 | destination[length - 1] == '\r')) |
| 72 | destination[--length] = 0; |
| 73 | } else { |
| 74 | int c; |
| 75 | |
| 76 | while ((c = _getch()) != '\r' && c != '\n') { |
| 77 | if (length < (size_t) maxlen) |
| 78 | destination[length++] = c; |
| 79 | } |
| 80 | destination[length] = 0; |
| 81 | _cputs("\r\n" ); |
| 82 | } |
| 83 | if (length == 0 && def) |
| 84 | strcpy(destination, def); |
| 85 | return destination; |
| 86 | } |
| 87 | #else |
| 88 | char * |
| 89 | simple_prompt(const char *prompt, int maxlen, int echo, const char *def) |
| 90 | { |
| 91 | size_t length = 0; |
| 92 | char *destination = NULL; |
| 93 | FILE *termin = NULL, *termout = NULL; |
| 94 | |
| 95 | #ifdef HAVE_TERMIOS_H |
| 96 | struct termios t_orig, t; |
| 97 | #else |
| 98 | (void) echo; |
| 99 | #endif |
| 100 | |
| 101 | destination = (char *) malloc(maxlen + 2); |
| 102 | if (!destination) |
| 103 | return NULL; |
| 104 | |
| 105 | termin = fopen("/dev/tty" , "r" ); |
| 106 | termout = fopen("/dev/tty" , "w" ); |
| 107 | |
| 108 | if (termin == NULL || termout == NULL) { |
| 109 | if (termin) |
| 110 | fclose(termin); |
| 111 | if (termout) |
| 112 | fclose(termout); |
| 113 | termin = stdin; |
| 114 | termout = stderr; |
| 115 | } |
| 116 | |
| 117 | #ifdef HAVE_TERMIOS_H |
| 118 | if (!echo) { |
| 119 | tcgetattr(fileno(termin), &t); |
| 120 | t_orig = t; |
| 121 | t.c_lflag &= ~ECHO; |
| 122 | tcsetattr(fileno(termin), TCSAFLUSH, &t); |
| 123 | } |
| 124 | #endif |
| 125 | if (prompt) { |
| 126 | if (def) |
| 127 | fprintf(termout, "%s(%s):" , prompt, def); |
| 128 | else |
| 129 | fprintf(termout, "%s:" , prompt); |
| 130 | fflush(termout); |
| 131 | } |
| 132 | if (fgets(destination, maxlen, termin) == NULL) |
| 133 | destination[0] = '\0'; |
| 134 | |
| 135 | length = strlen(destination); |
| 136 | if (length > 0 && destination[length - 1] != '\n') { |
| 137 | char buf[128]; |
| 138 | size_t buflen; |
| 139 | |
| 140 | do { |
| 141 | if (fgets(buf, sizeof(buf), termin) == NULL) |
| 142 | break; |
| 143 | buflen = strlen(buf); |
| 144 | } while (buflen > 0 && buf[buflen - 1] != '\n'); |
| 145 | } |
| 146 | |
| 147 | if (length > 0 && destination[length - 1] == '\n') |
| 148 | destination[length - 1] = '\0'; |
| 149 | #ifdef HAVE_TERMIOS_H |
| 150 | if (!echo) { |
| 151 | tcsetattr(fileno(termin), TCSAFLUSH, &t_orig); |
| 152 | fputs("\n" , termout); |
| 153 | fflush(termout); |
| 154 | } |
| 155 | #endif |
| 156 | if (termin != stdin) |
| 157 | fclose(termin); |
| 158 | if (termout != stdout) |
| 159 | fclose(termout); |
| 160 | if (destination[0] == 0 && def) |
| 161 | strcpy(destination, def); |
| 162 | return destination; |
| 163 | } |
| 164 | #endif /* _MSC_VER */ |
| 165 | |