summaryrefslogtreecommitdiff
path: root/passwd
diff options
context:
space:
mode:
authorWilliam A. Rowe Jr <wrowe@apache.org>2002-09-14 20:41:10 +0000
committerWilliam A. Rowe Jr <wrowe@apache.org>2002-09-14 20:41:10 +0000
commit20bd7485b70eb47cf6d3d1bd77f05f6edbcbfc3b (patch)
tree63aff7acd462d0a9238497f42ebb0123568394ec /passwd
parent96b7f3030268f4be84c57ebad9cc688a8493cc92 (diff)
downloadapr-20bd7485b70eb47cf6d3d1bd77f05f6edbcbfc3b.tar.gz
Improve the getpass() situation on win32. Respect BS/DEL/left-arrows
and generally clean up this feature. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@63868 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'passwd')
-rw-r--r--passwd/apr_getpass.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/passwd/apr_getpass.c b/passwd/apr_getpass.c
index a9fbcf233..78bab6623 100644
--- a/passwd/apr_getpass.c
+++ b/passwd/apr_getpass.c
@@ -172,35 +172,63 @@ static char *getpass(const char *prompt)
/* WCE lacks console. So the getpass is unsuported
* The only way is to use the GUI so the getpass should be implemented
* on per-application basis.
-*/
+ */
#ifdef _WIN32_WCE
return NULL;
#else
- static char password[MAX_STRING_LEN];
+ static char password[128];
int n = 0;
+ int ch;
fputs(prompt, stderr);
- while ((password[n] = _getch()) != '\r') {
- if (n < sizeof(password) - 1 && password[n] >= ' ' && password[n] <= '~') {
- n++;
- printf("*");
+ while ((ch = _getch()) != '\r') {
+ if (ch == EOF) /* EOF */ {
+ fputs("[EOF]\n", stderr);
+ return NULL;
}
- else {
- printf("\n");
+ else if (ch == 0 || ch == 0xE0) {
+ /* FN Keys (0 or E0) are a sentinal for a FN code */
+ ch = (ch << 4) | _getch();
+ /* Catch {DELETE}, {<--}, Num{DEL} and Num{<--} */
+ if ((ch == 0xE53 || ch == 0xE4B || ch == 0x053 || ch == 0x04b) && n) {
+ password[--n] = '\0';
+ fputs("\b \b", stderr);
+ }
+ else {
+ fputc('\a', stderr);
+ }
+ }
+ else if ((ch == '\b' || ch == 127) && n) /* BS/DEL */ {
+ password[--n] = '\0';
+ fputs("\b \b", stderr);
+ }
+ else if (ch == 3) /* CTRL+C */ {
+ /* _getch() bypasses Ctrl+C but not Ctrl+Break detection! */
+ fputs("^C\n", stderr);
+ exit(-1);
+ }
+ else if (ch == 26) /* CTRL+Z */ {
+ fputs("^Z\n", stderr);
+ return NULL;
+ }
+ else if (ch == 27) /* ESC */ {
+ fputc('\n', stderr);
fputs(prompt, stderr);
n = 0;
}
+ else if ((n < sizeof(password) - 1) && !apr_iscntrl(ch)) {
+ password[n++] = ch;
+ fputc('*', stderr);
+ }
+ else {
+ fputc('\a', stderr);
+ }
}
+ fputc('\n', stderr);
password[n] = '\0';
- printf("\n");
-
- if (n > (MAX_STRING_LEN - 1)) {
- password[MAX_STRING_LEN - 1] = '\0';
- }
-
- return (char *) &password;
+ return password;
#endif
}