155682Smarkm/*
2233294Sstas * Copyright (c) 1997 - 2000 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
555682Smarkm *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
955682Smarkm *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
18233294Sstas *    may be used to endorse or promote products derived from this software
19233294Sstas *    without specific prior written permission.
2055682Smarkm *
21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31233294Sstas * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "login_locl.h"
3555682Smarkm
36233294SstasRCSID("$Id$");
3755682Smarkm
3855682Smarkmstatic sig_atomic_t intr_flag;
3955682Smarkm
4055682Smarkmstatic void
4155682Smarkmintr(int sig)
4255682Smarkm{
4355682Smarkm    intr_flag++;
4455682Smarkm}
4555682Smarkm
46178825Sdfr#ifndef NSIG
47178825Sdfr#define NSIG 47
48178825Sdfr#endif
49178825Sdfr
5055682Smarkmint
5155682Smarkmread_string(const char *prompt, char *buf, size_t len, int echo)
5255682Smarkm{
53178825Sdfr    struct sigaction sigs[NSIG];
54178825Sdfr    int oksigs[NSIG];
5555682Smarkm    struct sigaction sa;
5655682Smarkm    FILE *tty;
5755682Smarkm    int ret = 0;
5855682Smarkm    int of = 0;
5955682Smarkm    int i;
6055682Smarkm    int c;
6155682Smarkm    char *p;
6255682Smarkm
6355682Smarkm    struct termios t_new, t_old;
6455682Smarkm
65178825Sdfr    memset(&oksigs, 0, sizeof(oksigs));
66178825Sdfr
6755682Smarkm    memset(&sa, 0, sizeof(sa));
6855682Smarkm    sa.sa_handler = intr;
6955682Smarkm    sigemptyset(&sa.sa_mask);
7055682Smarkm    sa.sa_flags = 0;
71178825Sdfr    for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++)
72233294Sstas	if (i != SIGALRM)
73178825Sdfr	    if (sigaction(i, &sa, &sigs[i]) == 0)
74178825Sdfr		oksigs[i] = 1;
7555682Smarkm
7655682Smarkm    if((tty = fopen("/dev/tty", "r")) == NULL)
7755682Smarkm	tty = stdin;
78233294Sstas
7955682Smarkm    fprintf(stderr, "%s", prompt);
8055682Smarkm    fflush(stderr);
8155682Smarkm
8255682Smarkm    if(echo == 0){
8355682Smarkm	tcgetattr(fileno(tty), &t_old);
8455682Smarkm	memcpy(&t_new, &t_old, sizeof(t_new));
8555682Smarkm	t_new.c_lflag &= ~ECHO;
8655682Smarkm	tcsetattr(fileno(tty), TCSANOW, &t_new);
8755682Smarkm    }
8855682Smarkm    intr_flag = 0;
8955682Smarkm    p = buf;
9055682Smarkm    while(intr_flag == 0){
9155682Smarkm	c = getc(tty);
9255682Smarkm	if(c == EOF){
9355682Smarkm	    if(!ferror(tty))
9455682Smarkm		ret = 1;
9555682Smarkm	    break;
9655682Smarkm	}
9755682Smarkm	if(c == '\n')
9855682Smarkm	    break;
9955682Smarkm	if(of == 0)
10055682Smarkm	    *p++ = c;
10155682Smarkm	of = (p == buf + len);
10255682Smarkm    }
10355682Smarkm    if(of)
10455682Smarkm	p--;
10555682Smarkm    *p = 0;
106233294Sstas
10755682Smarkm    if(echo == 0){
10855682Smarkm	printf("\n");
10955682Smarkm	tcsetattr(fileno(tty), TCSANOW, &t_old);
11055682Smarkm    }
111233294Sstas
11255682Smarkm    if(tty != stdin)
11355682Smarkm	fclose(tty);
11455682Smarkm
115178825Sdfr    for(i = 1; i < sizeof(sigs) / sizeof(sigs[0]); i++)
116178825Sdfr	if (oksigs[i])
117178825Sdfr	    sigaction(i, &sigs[i], NULL);
118233294Sstas
11955682Smarkm    if(ret)
12055682Smarkm	return -3;
12155682Smarkm    if(intr_flag)
12255682Smarkm	return -2;
12355682Smarkm    if(of)
12455682Smarkm	return -1;
12555682Smarkm    return 0;
12655682Smarkm}
12755682Smarkm
12855682Smarkm
12955682Smarkm#if 0
13055682Smarkmint main()
13155682Smarkm{
13255682Smarkm    char s[128];
13355682Smarkm    int ret;
13455682Smarkm    ret = read_string("foo: ", s, sizeof(s), 0);
13555682Smarkm    printf("%d ->%s<-\n", ret, s);
13655682Smarkm}
13755682Smarkm#endif
138