8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / gss_mechs / mech_krb5 / krb5 / os / promptusr.c
blob768f14f2d18cf2b9e3f1c468d68ed11cb8d8cbb1
1 #pragma ident "%Z%%M% %I% %E% SMI"
2 /*
3 * promptusr.c --- prompt user for input/output
4 */
6 #include <k5-int.h>
7 #if !defined(_WIN32)
9 #include <stdio.h>
10 #include <stdlib.h>
11 #ifdef HAVE_UNISTD_H
12 #include <unistd.h>
13 #endif
14 #include <termios.h>
15 #include <signal.h>
16 #include <setjmp.h>
18 typedef struct _krb5_uio {
19 krb5_magic magic;
20 int flags;
21 char * prompt;
22 char * response;
23 struct _krb5_uio *next;
24 } *krb5_uio;
26 #define KRB5_UIO_GETRESPONSE 0x0001
27 #define KRB5_UIO_ECHORESPONSE 0x0002
28 #define KRB5_UIO_FREE_PROMPT 0x0004
30 static jmp_buf pwd_jump;
32 /*ARGSUSED*/
33 static krb5_sigtype
34 intr_routine(int signo)
36 longjmp(pwd_jump, 1);
37 /*NOTREACHED*/
40 /*ARGSUSED*/
41 krb5_error_code
42 krb5_os_get_tty_uio(krb5_context context, krb5_uio uio)
44 volatile krb5_error_code retval;
45 krb5_sigtype (*volatile ointrfunc)();
46 krb5_uio p;
47 struct termios echo_control, save_control;
48 int fd;
49 char read_string[BUFSIZ];
50 char *cp;
51 int ch;
53 /* get the file descriptor associated with stdin */
54 fd=fileno(stdin);
56 if (tcgetattr(fd, &echo_control) == -1)
57 return errno;
59 save_control = echo_control;
60 echo_control.c_lflag &= ~(ECHO|ECHONL);
62 if (setjmp(pwd_jump)) {
63 retval = KRB5_LIBOS_PWDINTR; /* we were interrupted... */
64 goto cleanup;
66 /* save intrfunc */
67 ointrfunc = signal(SIGINT, intr_routine);
69 for (p = uio; p; p = p->next) {
70 if (p->prompt) {
71 fputs(p->prompt, stdout);
72 fflush(stdout);
74 if ((p->flags & KRB5_UIO_GETRESPONSE) == 0)
75 continue;
77 if ((p->flags & KRB5_UIO_ECHORESPONSE) == 0)
78 if (tcsetattr(fd, TCSANOW, &echo_control) == -1)
79 return errno;
81 if (fgets(read_string, sizeof(read_string), stdin) == NULL) {
82 (void) putchar('\n');
83 retval = KRB5_LIBOS_CANTREADPWD;
84 goto cleanup;
87 /* replace newline with null */
88 if ((cp = strchr(read_string, '\n')))
89 *cp = '\0';
90 else /* flush rest of input line */
91 do {
92 ch = getchar();
93 } while (ch != EOF && ch != '\n');
94 read_string[sizeof(read_string)-1] = 0;
96 if ((p->response = malloc(strlen(read_string)+1)) == NULL) {
97 errno = ENOMEM;
98 goto cleanup;
100 strcpy(p->response, read_string);
102 if ((p->flags & KRB5_UIO_ECHORESPONSE) == 0) {
103 (void) putchar('\n');
104 if (tcsetattr(fd, TCSANOW, &save_control) == -1) {
105 retval = errno;
106 goto cleanup;
110 retval = 0;
112 cleanup:
113 (void) signal(SIGINT, ointrfunc);
114 if (retval) {
115 for (p = uio; p; p = p->next) {
116 if (p->response) {
117 memset(p->response, 0, strlen(p->response));
118 free(p->response);
119 p->response = 0;
123 memset(read_string, 0, sizeof(read_string));
124 tcsetattr(fd, TCSANOW, &save_control);
125 return retval;
128 /*ARGSUSED*/
129 void
130 krb5_free_uio(krb5_context context, krb5_uio uio)
132 krb5_uio p, next;
134 for (p = uio; p; p = next) {
135 next = p->next;
136 if (p->prompt && (p->flags & KRB5_UIO_FREE_PROMPT))
137 free(p->prompt);
138 if (p->response)
139 free(p->response);
140 free(p);
144 #ifdef TEST_DRIVER
146 struct _krb5_uio uio_a = { 0, KRB5_UIO_GETRESPONSE, "Password 1: " };
147 struct _krb5_uio uio_b = { 0, KRB5_UIO_GETRESPONSE |
148 KRB5_UIO_ECHORESPONSE, "Password 2: " };
149 struct _krb5_uio uio_c = { 0, KRB5_UIO_GETRESPONSE, "Password 3: " };
152 void
153 main(int argc, char **argv)
155 uio_a.next = &uio_b;
156 uio_b.next = &uio_c;
158 krb5_os_get_tty_uio(0, &uio_a);
159 exit(0);
162 #endif
164 #endif /* !_MSODS */