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