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 */
26static char *defaultlogin = "win32";
27#endif
28
29char *
30prompt_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
48char *
49simple_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
88char *
89simple_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