xref: /freebsd/crypto/heimdal/appl/login/read_string.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1b528cefcSMark Murray /*
2*ae771770SStanislav Sedov  * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray  * modification, are permitted provided that the following conditions
8b528cefcSMark Murray  * are met:
9b528cefcSMark Murray  *
10b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray  *
13b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray  *
17b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
19b528cefcSMark Murray  *    without specific prior written permission.
20b528cefcSMark Murray  *
21b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray  * SUCH DAMAGE.
32b528cefcSMark Murray  */
33b528cefcSMark Murray 
34b528cefcSMark Murray #include "login_locl.h"
35b528cefcSMark Murray 
36*ae771770SStanislav Sedov RCSID("$Id$");
37b528cefcSMark Murray 
38b528cefcSMark Murray static sig_atomic_t intr_flag;
39b528cefcSMark Murray 
40b528cefcSMark Murray static void
intr(int sig)41b528cefcSMark Murray intr(int sig)
42b528cefcSMark Murray {
43b528cefcSMark Murray     intr_flag++;
44b528cefcSMark Murray }
45b528cefcSMark Murray 
46c19800e8SDoug Rabson #ifndef NSIG
47c19800e8SDoug Rabson #define NSIG 47
48c19800e8SDoug Rabson #endif
49c19800e8SDoug Rabson 
50b528cefcSMark Murray int
read_string(const char * prompt,char * buf,size_t len,int echo)51b528cefcSMark Murray read_string(const char *prompt, char *buf, size_t len, int echo)
52b528cefcSMark Murray {
53c19800e8SDoug Rabson     struct sigaction sigs[NSIG];
54c19800e8SDoug Rabson     int oksigs[NSIG];
55b528cefcSMark Murray     struct sigaction sa;
56b528cefcSMark Murray     FILE *tty;
57b528cefcSMark Murray     int ret = 0;
58b528cefcSMark Murray     int of = 0;
59b528cefcSMark Murray     int i;
60b528cefcSMark Murray     int c;
61b528cefcSMark Murray     char *p;
62b528cefcSMark Murray 
63b528cefcSMark Murray     struct termios t_new, t_old;
64b528cefcSMark Murray 
65c19800e8SDoug Rabson     memset(&oksigs, 0, sizeof(oksigs));
66c19800e8SDoug Rabson 
67b528cefcSMark Murray     memset(&sa, 0, sizeof(sa));
68b528cefcSMark Murray     sa.sa_handler = intr;
69b528cefcSMark Murray     sigemptyset(&sa.sa_mask);
70b528cefcSMark Murray     sa.sa_flags = 0;
71c19800e8SDoug Rabson     for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++)
72c19800e8SDoug Rabson 	if (i != SIGALRM)
73c19800e8SDoug Rabson 	    if (sigaction(i, &sa, &sigs[i]) == 0)
74c19800e8SDoug Rabson 		oksigs[i] = 1;
75b528cefcSMark Murray 
76b528cefcSMark Murray     if((tty = fopen("/dev/tty", "r")) == NULL)
77b528cefcSMark Murray 	tty = stdin;
78b528cefcSMark Murray 
79b528cefcSMark Murray     fprintf(stderr, "%s", prompt);
80b528cefcSMark Murray     fflush(stderr);
81b528cefcSMark Murray 
82b528cefcSMark Murray     if(echo == 0){
83b528cefcSMark Murray 	tcgetattr(fileno(tty), &t_old);
84b528cefcSMark Murray 	memcpy(&t_new, &t_old, sizeof(t_new));
85b528cefcSMark Murray 	t_new.c_lflag &= ~ECHO;
86b528cefcSMark Murray 	tcsetattr(fileno(tty), TCSANOW, &t_new);
87b528cefcSMark Murray     }
88b528cefcSMark Murray     intr_flag = 0;
89b528cefcSMark Murray     p = buf;
90b528cefcSMark Murray     while(intr_flag == 0){
91b528cefcSMark Murray 	c = getc(tty);
92b528cefcSMark Murray 	if(c == EOF){
93b528cefcSMark Murray 	    if(!ferror(tty))
94b528cefcSMark Murray 		ret = 1;
95b528cefcSMark Murray 	    break;
96b528cefcSMark Murray 	}
97b528cefcSMark Murray 	if(c == '\n')
98b528cefcSMark Murray 	    break;
99b528cefcSMark Murray 	if(of == 0)
100b528cefcSMark Murray 	    *p++ = c;
101b528cefcSMark Murray 	of = (p == buf + len);
102b528cefcSMark Murray     }
103b528cefcSMark Murray     if(of)
104b528cefcSMark Murray 	p--;
105b528cefcSMark Murray     *p = 0;
106b528cefcSMark Murray 
107b528cefcSMark Murray     if(echo == 0){
108b528cefcSMark Murray 	printf("\n");
109b528cefcSMark Murray 	tcsetattr(fileno(tty), TCSANOW, &t_old);
110b528cefcSMark Murray     }
111b528cefcSMark Murray 
112b528cefcSMark Murray     if(tty != stdin)
113b528cefcSMark Murray 	fclose(tty);
114b528cefcSMark Murray 
115c19800e8SDoug Rabson     for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++)
116c19800e8SDoug Rabson 	if (oksigs[i])
117c19800e8SDoug Rabson 	    sigaction(i, &sigs[i], NULL);
118b528cefcSMark Murray 
119b528cefcSMark Murray     if(ret)
120b528cefcSMark Murray 	return -3;
121b528cefcSMark Murray     if(intr_flag)
122b528cefcSMark Murray 	return -2;
123b528cefcSMark Murray     if(of)
124b528cefcSMark Murray 	return -1;
125b528cefcSMark Murray     return 0;
126b528cefcSMark Murray }
127b528cefcSMark Murray 
128b528cefcSMark Murray 
129b528cefcSMark Murray #if 0
130b528cefcSMark Murray int main()
131b528cefcSMark Murray {
132b528cefcSMark Murray     char s[128];
133b528cefcSMark Murray     int ret;
134b528cefcSMark Murray     ret = read_string("foo: ", s, sizeof(s), 0);
135b528cefcSMark Murray     printf("%d ->%s<-\n", ret, s);
136b528cefcSMark Murray }
137b528cefcSMark Murray #endif
138