dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / gss_mechs / mech_krb5 / krb5 / os / promptusr.c
blob3ce8af2b3dc6a70f66afec2c4e0b2dbf911e7c01
1 /*
2 * promptusr.c --- prompt user for input/output
3 */
5 #include <k5-int.h>
6 #if !defined(_WIN32)
8 #include <stdio.h>
9 #include <stdlib.h>
10 #ifdef HAVE_UNISTD_H
11 #include <unistd.h>
12 #endif
13 #include <termios.h>
14 #include <signal.h>
15 #include <setjmp.h>
17 typedef struct _krb5_uio {
18 krb5_magic magic;
19 int flags;
20 char * prompt;
21 char * response;
22 struct _krb5_uio *next;
23 } *krb5_uio;
25 #define KRB5_UIO_GETRESPONSE 0x0001
26 #define KRB5_UIO_ECHORESPONSE 0x0002
27 #define KRB5_UIO_FREE_PROMPT 0x0004
29 static jmp_buf pwd_jump;
31 /*ARGSUSED*/
32 static krb5_sigtype
33 intr_routine(int signo)
35 longjmp(pwd_jump, 1);
36 /*NOTREACHED*/
39 /*ARGSUSED*/
40 krb5_error_code
41 krb5_os_get_tty_uio(krb5_context context, krb5_uio uio)
43 volatile krb5_error_code retval;
44 krb5_sigtype (*volatile ointrfunc)();
45 krb5_uio p;
46 struct termios echo_control, save_control;
47 int fd;
48 char read_string[BUFSIZ];
49 char *cp;
50 int ch;
52 /* get the file descriptor associated with stdin */
53 fd=fileno(stdin);
55 if (tcgetattr(fd, &echo_control) == -1)
56 return errno;
58 save_control = echo_control;
59 echo_control.c_lflag &= ~(ECHO|ECHONL);
61 if (setjmp(pwd_jump)) {
62 retval = KRB5_LIBOS_PWDINTR; /* we were interrupted... */
63 goto cleanup;
65 /* save intrfunc */
66 ointrfunc = signal(SIGINT, intr_routine);
68 for (p = uio; p; p = p->next) {
69 if (p->prompt) {
70 fputs(p->prompt, stdout);
71 fflush(stdout);
73 if ((p->flags & KRB5_UIO_GETRESPONSE) == 0)
74 continue;
76 if ((p->flags & KRB5_UIO_ECHORESPONSE) == 0)
77 if (tcsetattr(fd, TCSANOW, &echo_control) == -1)
78 return errno;
80 if (fgets(read_string, sizeof(read_string), stdin) == NULL) {
81 (void) putchar('\n');
82 retval = KRB5_LIBOS_CANTREADPWD;
83 goto cleanup;
86 /* replace newline with null */
87 if ((cp = strchr(read_string, '\n')))
88 *cp = '\0';
89 else /* flush rest of input line */
90 do {
91 ch = getchar();
92 } while (ch != EOF && ch != '\n');
93 read_string[sizeof(read_string)-1] = 0;
95 if ((p->response = malloc(strlen(read_string)+1)) == NULL) {
96 errno = ENOMEM;
97 goto cleanup;
99 strcpy(p->response, read_string);
101 if ((p->flags & KRB5_UIO_ECHORESPONSE) == 0) {
102 (void) putchar('\n');
103 if (tcsetattr(fd, TCSANOW, &save_control) == -1) {
104 retval = errno;
105 goto cleanup;
109 retval = 0;
111 cleanup:
112 (void) signal(SIGINT, ointrfunc);
113 if (retval) {
114 for (p = uio; p; p = p->next) {
115 if (p->response) {
116 memset(p->response, 0, strlen(p->response));
117 free(p->response);
118 p->response = 0;
122 memset(read_string, 0, sizeof(read_string));
123 tcsetattr(fd, TCSANOW, &save_control);
124 return retval;
127 /*ARGSUSED*/
128 void
129 krb5_free_uio(krb5_context context, krb5_uio uio)
131 krb5_uio p, next;
133 for (p = uio; p; p = next) {
134 next = p->next;
135 if (p->prompt && (p->flags & KRB5_UIO_FREE_PROMPT))
136 free(p->prompt);
137 free(p->response);
138 free(p);
142 #ifdef TEST_DRIVER
144 struct _krb5_uio uio_a = { 0, KRB5_UIO_GETRESPONSE, "Password 1: " };
145 struct _krb5_uio uio_b = { 0, KRB5_UIO_GETRESPONSE |
146 KRB5_UIO_ECHORESPONSE, "Password 2: " };
147 struct _krb5_uio uio_c = { 0, KRB5_UIO_GETRESPONSE, "Password 3: " };
150 void
151 main(int argc, char **argv)
153 uio_a.next = &uio_b;
154 uio_b.next = &uio_c;
156 krb5_os_get_tty_uio(0, &uio_a);
157 exit(0);
160 #endif
162 #endif /* !_MSODS */