New function for doing generic tty input and output. Eventually
authorTheodore Tso <tytso@mit.edu>
Wed, 20 Dec 1995 01:50:53 +0000 (01:50 +0000)
committerTheodore Tso <tytso@mit.edu>
Wed, 20 Dec 1995 01:50:53 +0000 (01:50 +0000)
read_password should use this function.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7239 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/os/ChangeLog
src/lib/krb5/os/Makefile.in
src/lib/krb5/os/promptusr.c [new file with mode: 0644]

index bd58f06e87c3af6cffd660c34be9d729787ded56..c8132de6b41e7ac1f5323509eb1429c6e03344dd 100644 (file)
@@ -1,3 +1,8 @@
+Wed Nov 15 10:53:16 1995    <tytso@rsts-11.mit.edu>
+
+       * promptusr.c: New function for doing generic tty input and output.
+               Eventually read_password should use this function.
+
 Wed Nov 15 20:40:03 1995  Mark Eichin  <eichin@cygnus.com>
 
        * lock_file.c (krb5_lock_file): initialize lock_arg to a copy of a
index bf530e02fd0632534d9f91159f88bbfd38134d3f..8d25ddefedb365f3ff112bbd420d8bcb3c34e2c7 100644 (file)
@@ -36,6 +36,7 @@ OBJS= \
        net_write.$(OBJEXT)     \
        osconfig.$(OBJEXT)      \
        port2ip.$(OBJEXT)       \
+       promptusr.$(OBJEXT)     \
        read_msg.$(OBJEXT)      \
        read_pwd.$(OBJEXT)      \
        realm_dom.$(OBJEXT)     \
@@ -73,6 +74,7 @@ SRCS= \
        $(srcdir)/net_read.c    \
        $(srcdir)/net_write.c   \
        $(srcdir)/osconfig.c    \
+       $(srcdir)/promptusr.c   \
        $(srcdir)/read_msg.c    \
        $(srcdir)/read_pwd.c    \
        $(srcdir)/realm_dom.c   \
diff --git a/src/lib/krb5/os/promptusr.c b/src/lib/krb5/os/promptusr.c
new file mode 100644 (file)
index 0000000..a15cd87
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * promptusr.c --- prompt user for input/output
+ */
+
+#include "k5-int.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+#include <signal.h>
+#include <setjmp.h>
+
+typedef struct _krb5_uio {
+    krb5_magic         magic;
+    int                flags;
+    char *             prompt;
+    char *             response;
+    struct _krb5_uio   *next;
+} *krb5_uio;
+
+#define KRB5_UIO_GETRESPONSE   0x0001
+#define KRB5_UIO_ECHORESPONSE  0x0002
+#define KRB5_UIO_FREE_PROMPT   0x0004
+
+static jmp_buf pwd_jump;
+
+static krb5_sigtype
+intr_routine(signo)
+    int signo;
+{
+    longjmp(pwd_jump, 1);
+    /*NOTREACHED*/
+}
+
+krb5_error_code
+krb5_os_get_tty_uio(context, uio)
+    krb5_context       context;
+    krb5_uio           uio;
+{
+    krb5_error_code    retval;
+    krb5_sigtype       (*ointrfunc)();
+    krb5_uio           p;
+    struct termios     echo_control, save_control;
+    int                fd;
+    char               read_string[BUFSIZ];
+    char               *cp;
+    char               ch;
+
+    /* get the file descriptor associated with stdin */
+    fd=fileno(stdin);
+
+    if (tcgetattr(fd, &echo_control) == -1)
+       return errno;
+
+    save_control = echo_control;
+    echo_control.c_lflag &= ~(ECHO|ECHONL);
+
+    if (setjmp(pwd_jump)) {
+       retval = KRB5_LIBOS_PWDINTR;    /* we were interrupted... */
+       goto cleanup;
+    }
+    /* save intrfunc */
+    ointrfunc = signal(SIGINT, intr_routine);
+    
+    for (p = uio; p; p = p->next) {
+       if (p->prompt) {
+           fputs(p->prompt, stdout);
+           fflush(stdout);
+       }
+       if ((p->flags & KRB5_UIO_GETRESPONSE) == 0)
+           continue;
+
+       if ((p->flags & KRB5_UIO_ECHORESPONSE) == 0) 
+           if (tcsetattr(fd, TCSANOW, &echo_control) == -1)
+               return errno;
+
+       if (fgets(read_string, sizeof(read_string), stdin) == NULL) {
+           (void) putchar('\n');
+           retval = KRB5_LIBOS_CANTREADPWD;
+           goto cleanup;
+       }
+       
+       /* replace newline with null */
+       if ((cp = strchr(read_string, '\n')))
+           *cp = '\0';
+       else /* flush rest of input line */
+           do {
+               ch = getchar();
+           } while (ch != EOF && ch != '\n');
+       read_string[sizeof(read_string)-1] = 0;
+
+       if ((p->response = malloc(strlen(read_string)+1)) == NULL) {
+           errno = ENOMEM;
+           goto cleanup;
+       }
+       strcpy(p->response, read_string);
+
+       if ((p->flags & KRB5_UIO_ECHORESPONSE) == 0) {
+           (void) putchar('\n');
+           if (tcsetattr(fd, TCSANOW, &save_control) == -1) {
+               retval = errno;
+               goto cleanup;
+           }
+       }
+    }
+    retval = 0;
+    
+ cleanup:
+    (void) signal(SIGINT, ointrfunc);
+    if (retval) {
+       for (p = uio; p; p = p->next) {
+           if (p->response) {
+               memset(p->response, 0, strlen(p->response));
+               free(p->response);
+               p->response = 0;
+           }
+       }
+    }
+    memset(read_string, 0, sizeof(read_string));
+    tcsetattr(fd, TCSANOW, &save_control);
+    return retval;
+}
+
+void
+krb5_free_uio(context, uio)
+    krb5_context       context;
+    krb5_uio           uio;
+{
+    krb5_uio           p, next;
+
+    for (p = uio; p; p = next) {
+       next = p->next;
+       if (p->prompt && (p->flags & KRB5_UIO_FREE_PROMPT))
+           free(p->prompt);
+       if (p->response)
+           free(p->response);
+       free(p);
+    }
+}
+
+#ifdef TEST_DRIVER
+
+struct _krb5_uio uio_a = { 0, KRB5_UIO_GETRESPONSE, "Password 1: " };
+struct _krb5_uio uio_b = { 0, KRB5_UIO_GETRESPONSE |
+                              KRB5_UIO_ECHORESPONSE, "Password 2: " };
+struct _krb5_uio uio_c = { 0, KRB5_UIO_GETRESPONSE, "Password 3: " };
+
+
+void
+main(int argc, char **argv)
+{
+    uio_a.next = &uio_b;
+    uio_b.next = &uio_c;
+
+    krb5_os_get_tty_uio(0, &uio_a);
+    exit(0);
+}
+
+#endif
+       
+       
+    
+