summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/lib/getsmbpass.c148
1 files changed, 86 insertions, 62 deletions
diff --git a/source3/lib/getsmbpass.c b/source3/lib/getsmbpass.c
index b6ae09b318..93449b004d 100644
--- a/source3/lib/getsmbpass.c
+++ b/source3/lib/getsmbpass.c
@@ -83,71 +83,95 @@ static int tcsetattr(int fd, int flags, struct sgttyb *t)
static struct termios t;
#endif /* SYSV_TERMIO */
+static SIG_ATOMIC_T gotintr;
+static int in_fd = -1;
+
+/***************************************************************
+ Signal function to tell us were ^C'ed.
+****************************************************************/
+
+static void gotintr_sig(void)
+{
+ gotintr = 1;
+ if (in_fd != -1)
+ close(in_fd); /* Safe way to force a return. */
+ in_fd = -1;
+}
+
char *getsmbpass(const char *prompt)
{
- FILE *in, *out;
- int echo_off;
- static char buf[256];
- static size_t bufsize = sizeof(buf);
- size_t nread;
-
- /* Catch problematic signals */
- CatchSignal(SIGINT, SIGNAL_CAST SIG_IGN);
-
- /* Try to write to and read from the terminal if we can.
- If we can't open the terminal, use stderr and stdin. */
-
- in = fopen ("/dev/tty", "w+");
- if (in == NULL)
- {
- in = stdin;
- out = stderr;
- }
- else
- out = in;
-
- setvbuf(in, NULL, _IONBF, 0);
-
- /* Turn echoing off if it is on now. */
-
- if (tcgetattr (fileno (in), &t) == 0)
- {
- if (ECHO_IS_ON(t))
- {
- TURN_ECHO_OFF(t);
- echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0;
- TURN_ECHO_ON(t);
+ FILE *in, *out;
+ int echo_off;
+ static char buf[256];
+ static size_t bufsize = sizeof(buf);
+ size_t nread;
+
+ /* Catch problematic signals */
+ CatchSignal(SIGINT, SIGNAL_CAST gotintr_sig);
+
+ /* Try to write to and read from the terminal if we can.
+ If we can't open the terminal, use stderr and stdin. */
+
+ in = fopen ("/dev/tty", "w+");
+ if (in == NULL) {
+ in = stdin;
+ out = stderr;
+ } else {
+ out = in;
+ }
+
+ setvbuf(in, NULL, _IONBF, 0);
+
+ /* Turn echoing off if it is on now. */
+
+ if (tcgetattr (fileno (in), &t) == 0) {
+ if (ECHO_IS_ON(t)) {
+ TURN_ECHO_OFF(t);
+ echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0;
+ TURN_ECHO_ON(t);
+ } else {
+ echo_off = 0;
+ }
+ } else {
+ echo_off = 0;
+ }
+
+ /* Write the prompt. */
+ fputs(prompt, out);
+ fflush(out);
+
+ /* Read the password. */
+ buf[0] = 0;
+ if (!gotintr) {
+ in_fd = fileno(in);
+ fgets(buf, bufsize, in);
+ }
+ nread = strlen(buf);
+ if (buf[nread - 1] == '\n')
+ buf[nread - 1] = '\0';
+
+ /* Restore echoing. */
+ if (echo_off) {
+ if (gotintr && in_fd == -1)
+ in = fopen ("/dev/tty", "w+");
+ if (in != NULL)
+ tcsetattr (fileno (in), TCSANOW, &t);
+ }
+
+ if (in != stdin) /* We opened the terminal; now close it. */
+ fclose(in);
+
+ /* Catch problematic signals */
+ CatchSignal(SIGINT, SIGNAL_CAST SIG_DFL);
+
+ printf("\n");
+
+ if (gotintr_sig) {
+ printf("Interupted by signal.\n");
+ fflush(stdout);
+ exit(1);
}
- else
- echo_off = 0;
- }
- else
- echo_off = 0;
-
- /* Write the prompt. */
- fputs (prompt, out);
- fflush (out);
-
- /* Read the password. */
- buf[0] = 0;
- fgets(buf, bufsize, in);
- nread = strlen(buf);
- if (buf[nread - 1] == '\n')
- buf[nread - 1] = '\0';
-
- /* Restore echoing. */
- if (echo_off)
- (void) tcsetattr (fileno (in), TCSANOW, &t);
-
- if (in != stdin)
- /* We opened the terminal; now close it. */
- fclose (in);
-
- /* Catch problematic signals */
- CatchSignal(SIGINT, SIGNAL_CAST SIG_DFL);
-
- printf("\n");
- return buf;
+ return buf;
}
#else