xref: /illumos-gate/usr/src/lib/krb5/ss/listen.c (revision 7c478bd9)
1 /*
2  * Copyright (c) 2000 by Sun Microsystems, Inc.
3  * All rights reserved.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 /*
9  * Listener loop for subsystem library libss.a.
10  *
11  *	util/ss/listen.c
12  *
13  * Copyright 1987, 1988 by MIT Student Information Processing Board
14  *
15  * For copyright information, see copyright.h.
16  */
17 
18 #include "copyright.h"
19 #include "ss_internal.h"
20 #include <stdio.h>
21 #include <setjmp.h>
22 #include <signal.h>
23 #include <libintl.h>
24 #include <sys/param.h>
25 #ifdef BSD
26 #include <sgtty.h>
27 #endif
28 
29 static ss_data *current_info;
30 static jmp_buf listen_jmpb;
31 
32 static RETSIGTYPE print_prompt()
33 {
34 #ifdef BSD
35     /* put input into a reasonable mode */
36     struct sgttyb ttyb;
37     if (ioctl(fileno(stdin), TIOCGETP, &ttyb) != -1) {
38 	if (ttyb.sg_flags & (CBREAK|RAW)) {
39 	    ttyb.sg_flags &= ~(CBREAK|RAW);
40 	    (void) ioctl(0, TIOCSETP, &ttyb);
41 	}
42     }
43 #endif
44     (void) fputs(current_info->prompt, stdout);
45     (void) fflush(stdout);
46 }
47 
48 static RETSIGTYPE listen_int_handler(signo)
49     int signo;
50 {
51     putc('\n', stdout);
52     longjmp(listen_jmpb, 1);
53 }
54 
55 int ss_listen (sci_idx)
56     int sci_idx;
57 {
58     register char *cp;
59     register ss_data *info;
60     char input[BUFSIZ];
61     char buffer[BUFSIZ];
62     char *end = buffer;
63     int code;
64     jmp_buf old_jmpb;
65     ss_data *old_info = current_info;
66 #ifdef POSIX_SIGNALS
67     struct sigaction isig, csig, nsig, osig;
68     sigset_t nmask, omask;
69 #else
70     register RETSIGTYPE (*sig_cont)();
71     RETSIGTYPE (*sig_int)(), (*old_sig_cont)();
72     int mask;
73 #endif
74 
75     current_info = info = ss_info(sci_idx);
76     info->abort = 0;
77 
78 #ifdef POSIX_SIGNALS
79     csig.sa_handler = (RETSIGTYPE (*)())0;
80     sigemptyset(&nmask);
81     sigaddset(&nmask, SIGINT);
82     sigprocmask(SIG_BLOCK, &nmask, &omask);
83 #else
84     sig_cont = (RETSIGTYPE (*)())0;
85     mask = sigblock(sigmask(SIGINT));
86 #endif
87 
88     memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf));
89 
90 #ifdef POSIX_SIGNALS
91     nsig.sa_handler = listen_int_handler;
92     sigemptyset(&nsig.sa_mask);
93     nsig.sa_flags = 0;
94     sigaction(SIGINT, &nsig, &isig);
95 #else
96     sig_int = signal(SIGINT, listen_int_handler);
97 #endif
98 
99     setjmp(listen_jmpb);
100 
101 #ifdef POSIX_SIGNALS
102     sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
103 #else
104     (void) sigsetmask(mask);
105 #endif
106     while(!info->abort) {
107 	print_prompt();
108 	*end = '\0';
109 #ifdef POSIX_SIGNALS
110 	nsig.sa_handler = listen_int_handler;	/* fgets is not signal-safe */
111 	osig = csig;
112 	sigaction(SIGCONT, &nsig, &csig);
113 	if ((RETSIGTYPE (*)())csig.sa_handler==(RETSIGTYPE (*)())listen_int_handler)
114 	    csig = osig;
115 #else
116 	old_sig_cont = sig_cont;
117 	sig_cont = signal(SIGCONT, print_prompt);
118 	if (sig_cont == print_prompt)
119 	    sig_cont = old_sig_cont;
120 #endif
121 	if (fgets(input, BUFSIZ, stdin) != input) {
122 	    code = SS_ET_EOF;
123 	    goto egress;
124 	}
125 	cp = strchr(input, '\n');
126 	if (cp) {
127 	    *cp = '\0';
128 	    if (cp == input)
129 		continue;
130 	}
131 #ifdef POSIX_SIGNALS
132 	sigaction(SIGCONT, &csig, (struct sigaction *)0);
133 #else
134 	(void) signal(SIGCONT, sig_cont);
135 #endif
136 	for (end = input; *end; end++)
137 	    ;
138 
139 	code = ss_execute_line (sci_idx, input);
140 	if (code == SS_ET_COMMAND_NOT_FOUND) {
141 	    register char *c = input;
142 	    while (*c == ' ' || *c == '\t')
143 		c++;
144 	    cp = strchr (c, ' ');
145 	    if (cp)
146 		*cp = '\0';
147 	    cp = strchr (c, '\t');
148 	    if (cp)
149 		*cp = '\0';
150 	    ss_error (sci_idx, 0, dgettext(TEXT_DOMAIN,
151 		    "Unknown request \"%s\".  Type \"?\" for a request list."),
152 		       c);
153 	}
154     }
155     code = 0;
156 egress:
157 #ifdef POSIX_SIGNALS
158     sigaction(SIGINT, &isig, (struct sigaction *)0);
159 #else
160     (void) signal(SIGINT, sig_int);
161 #endif
162     memcpy(listen_jmpb, old_jmpb, sizeof(jmp_buf));
163     current_info = old_info;
164     return code;
165 }
166 
167 void ss_abort_subsystem(sci_idx, code)
168     int sci_idx;
169     int code;
170 {
171     ss_info(sci_idx)->abort = 1;
172     ss_info(sci_idx)->exit_status = code;
173 
174 }
175 
176 void ss_quit(argc, argv, sci_idx, infop)
177     int argc;
178     char **argv;
179     int sci_idx;
180     pointer infop;
181 {
182     ss_abort_subsystem(sci_idx, 0);
183 }
184