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