1fdad9c93SAxel Dörfler /*
2fdad9c93SAxel Dörfler * Copyright (c) 1989, 1993
3fdad9c93SAxel Dörfler * The Regents of the University of California. All rights reserved.
4fdad9c93SAxel Dörfler *
5fdad9c93SAxel Dörfler * Redistribution and use in source and binary forms, with or without
6fdad9c93SAxel Dörfler * modification, are permitted provided that the following conditions
7fdad9c93SAxel Dörfler * are met:
8fdad9c93SAxel Dörfler * 1. Redistributions of source code must retain the above copyright
9fdad9c93SAxel Dörfler * notice, this list of conditions and the following disclaimer.
10fdad9c93SAxel Dörfler * 2. Redistributions in binary form must reproduce the above copyright
11fdad9c93SAxel Dörfler * notice, this list of conditions and the following disclaimer in the
12fdad9c93SAxel Dörfler * documentation and/or other materials provided with the distribution.
13*6b99b206SAugustin Cavalier * 3. Neither the name of the University nor the names of its contributors
14fdad9c93SAxel Dörfler * may be used to endorse or promote products derived from this software
15fdad9c93SAxel Dörfler * without specific prior written permission.
16fdad9c93SAxel Dörfler *
17fdad9c93SAxel Dörfler * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18fdad9c93SAxel Dörfler * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19fdad9c93SAxel Dörfler * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20fdad9c93SAxel Dörfler * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21fdad9c93SAxel Dörfler * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22fdad9c93SAxel Dörfler * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23fdad9c93SAxel Dörfler * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24fdad9c93SAxel Dörfler * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25fdad9c93SAxel Dörfler * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26fdad9c93SAxel Dörfler * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27fdad9c93SAxel Dörfler * SUCH DAMAGE.
28fdad9c93SAxel Dörfler */
29fdad9c93SAxel Dörfler
30fdad9c93SAxel Dörfler #if 0
31fdad9c93SAxel Dörfler #ifndef lint
32fdad9c93SAxel Dörfler static const char sccsid[] = "@(#)sys_term.c 8.4+1 (Berkeley) 5/30/95";
33fdad9c93SAxel Dörfler #endif
34fdad9c93SAxel Dörfler #endif
35fdad9c93SAxel Dörfler #include <sys/cdefs.h>
36*6b99b206SAugustin Cavalier __FBSDID("$FreeBSD$");
37fdad9c93SAxel Dörfler
38fdad9c93SAxel Dörfler #include <sys/types.h>
39*6b99b206SAugustin Cavalier //#include <sys/tty.h>
40fdad9c93SAxel Dörfler #include <libutil.h>
41fdad9c93SAxel Dörfler #include <stdlib.h>
42fdad9c93SAxel Dörfler
43fdad9c93SAxel Dörfler #include "telnetd.h"
44fdad9c93SAxel Dörfler #include "pathnames.h"
45*6b99b206SAugustin Cavalier #include "types.h"
46*6b99b206SAugustin Cavalier #include "baud.h"
47fdad9c93SAxel Dörfler
48fdad9c93SAxel Dörfler #ifdef AUTHENTICATION
49fdad9c93SAxel Dörfler #include <libtelnet/auth.h>
50fdad9c93SAxel Dörfler #endif
51fdad9c93SAxel Dörfler
52fdad9c93SAxel Dörfler int cleanopen(char *);
53fdad9c93SAxel Dörfler void scrub_env(void);
54fdad9c93SAxel Dörfler
55fdad9c93SAxel Dörfler char *envinit[3];
56fdad9c93SAxel Dörfler extern char **environ;
57fdad9c93SAxel Dörfler
58fdad9c93SAxel Dörfler #define SCPYN(a, b) (void) strncpy(a, b, sizeof(a))
59fdad9c93SAxel Dörfler #define SCMPN(a, b) strncmp(a, b, sizeof(a))
60fdad9c93SAxel Dörfler
61fdad9c93SAxel Dörfler #ifdef t_erase
62fdad9c93SAxel Dörfler #undef t_erase
63fdad9c93SAxel Dörfler #undef t_kill
64fdad9c93SAxel Dörfler #undef t_intrc
65fdad9c93SAxel Dörfler #undef t_quitc
66fdad9c93SAxel Dörfler #undef t_startc
67fdad9c93SAxel Dörfler #undef t_stopc
68fdad9c93SAxel Dörfler #undef t_eofc
69fdad9c93SAxel Dörfler #undef t_brkc
70fdad9c93SAxel Dörfler #undef t_suspc
71fdad9c93SAxel Dörfler #undef t_dsuspc
72fdad9c93SAxel Dörfler #undef t_rprntc
73fdad9c93SAxel Dörfler #undef t_flushc
74fdad9c93SAxel Dörfler #undef t_werasc
75fdad9c93SAxel Dörfler #undef t_lnextc
76fdad9c93SAxel Dörfler #endif
77fdad9c93SAxel Dörfler
78fdad9c93SAxel Dörfler #ifndef USE_TERMIO
79fdad9c93SAxel Dörfler struct termbuf {
80fdad9c93SAxel Dörfler struct sgttyb sg;
81fdad9c93SAxel Dörfler struct tchars tc;
82fdad9c93SAxel Dörfler struct ltchars ltc;
83fdad9c93SAxel Dörfler int state;
84fdad9c93SAxel Dörfler int lflags;
85fdad9c93SAxel Dörfler } termbuf, termbuf2;
86fdad9c93SAxel Dörfler # define cfsetospeed(tp, val) (tp)->sg.sg_ospeed = (val)
87fdad9c93SAxel Dörfler # define cfsetispeed(tp, val) (tp)->sg.sg_ispeed = (val)
88fdad9c93SAxel Dörfler # define cfgetospeed(tp) (tp)->sg.sg_ospeed
89fdad9c93SAxel Dörfler # define cfgetispeed(tp) (tp)->sg.sg_ispeed
90fdad9c93SAxel Dörfler #else /* USE_TERMIO */
91fdad9c93SAxel Dörfler # ifndef TCSANOW
92fdad9c93SAxel Dörfler # ifdef TCSETS
93fdad9c93SAxel Dörfler # define TCSANOW TCSETS
94fdad9c93SAxel Dörfler # define TCSADRAIN TCSETSW
95fdad9c93SAxel Dörfler # define tcgetattr(f, t) ioctl(f, TCGETS, (char *)t)
96fdad9c93SAxel Dörfler # else
97fdad9c93SAxel Dörfler # ifdef TCSETA
98fdad9c93SAxel Dörfler # define TCSANOW TCSETA
99fdad9c93SAxel Dörfler # define TCSADRAIN TCSETAW
100fdad9c93SAxel Dörfler # define tcgetattr(f, t) ioctl(f, TCGETA, (char *)t)
101fdad9c93SAxel Dörfler # else
102fdad9c93SAxel Dörfler # define TCSANOW TIOCSETA
103fdad9c93SAxel Dörfler # define TCSADRAIN TIOCSETAW
104fdad9c93SAxel Dörfler # define tcgetattr(f, t) ioctl(f, TIOCGETA, (char *)t)
105fdad9c93SAxel Dörfler # endif
106fdad9c93SAxel Dörfler # endif
107fdad9c93SAxel Dörfler # define tcsetattr(f, a, t) ioctl(f, a, t)
108fdad9c93SAxel Dörfler # define cfsetospeed(tp, val) (tp)->c_cflag &= ~CBAUD; \
109fdad9c93SAxel Dörfler (tp)->c_cflag |= (val)
110fdad9c93SAxel Dörfler # define cfgetospeed(tp) ((tp)->c_cflag & CBAUD)
111fdad9c93SAxel Dörfler # ifdef CIBAUD
112fdad9c93SAxel Dörfler # define cfsetispeed(tp, val) (tp)->c_cflag &= ~CIBAUD; \
113fdad9c93SAxel Dörfler (tp)->c_cflag |= ((val)<<IBSHIFT)
114fdad9c93SAxel Dörfler # define cfgetispeed(tp) (((tp)->c_cflag & CIBAUD)>>IBSHIFT)
115fdad9c93SAxel Dörfler # else
116fdad9c93SAxel Dörfler # define cfsetispeed(tp, val) (tp)->c_cflag &= ~CBAUD; \
117fdad9c93SAxel Dörfler (tp)->c_cflag |= (val)
118fdad9c93SAxel Dörfler # define cfgetispeed(tp) ((tp)->c_cflag & CBAUD)
119fdad9c93SAxel Dörfler # endif
120fdad9c93SAxel Dörfler # endif /* TCSANOW */
121fdad9c93SAxel Dörfler struct termios termbuf, termbuf2; /* pty control structure */
122fdad9c93SAxel Dörfler #endif /* USE_TERMIO */
123fdad9c93SAxel Dörfler
124fdad9c93SAxel Dörfler #include <sys/types.h>
125fdad9c93SAxel Dörfler #include <libutil.h>
126fdad9c93SAxel Dörfler
127fdad9c93SAxel Dörfler int cleanopen(char *);
128fdad9c93SAxel Dörfler void scrub_env(void);
129fdad9c93SAxel Dörfler static char **addarg(char **, const char *);
130fdad9c93SAxel Dörfler
131fdad9c93SAxel Dörfler /*
132fdad9c93SAxel Dörfler * init_termbuf()
133fdad9c93SAxel Dörfler * copy_termbuf(cp)
134fdad9c93SAxel Dörfler * set_termbuf()
135fdad9c93SAxel Dörfler *
136fdad9c93SAxel Dörfler * These three routines are used to get and set the "termbuf" structure
137fdad9c93SAxel Dörfler * to and from the kernel. init_termbuf() gets the current settings.
138fdad9c93SAxel Dörfler * copy_termbuf() hands in a new "termbuf" to write to the kernel, and
139fdad9c93SAxel Dörfler * set_termbuf() writes the structure into the kernel.
140fdad9c93SAxel Dörfler */
141fdad9c93SAxel Dörfler
142fdad9c93SAxel Dörfler void
init_termbuf(void)143fdad9c93SAxel Dörfler init_termbuf(void)
144fdad9c93SAxel Dörfler {
145fdad9c93SAxel Dörfler #ifndef USE_TERMIO
146fdad9c93SAxel Dörfler (void) ioctl(pty, TIOCGETP, (char *)&termbuf.sg);
147fdad9c93SAxel Dörfler (void) ioctl(pty, TIOCGETC, (char *)&termbuf.tc);
148fdad9c93SAxel Dörfler (void) ioctl(pty, TIOCGLTC, (char *)&termbuf.ltc);
149fdad9c93SAxel Dörfler # ifdef TIOCGSTATE
150fdad9c93SAxel Dörfler (void) ioctl(pty, TIOCGSTATE, (char *)&termbuf.state);
151fdad9c93SAxel Dörfler # endif
152fdad9c93SAxel Dörfler #else
153fdad9c93SAxel Dörfler (void) tcgetattr(pty, &termbuf);
154fdad9c93SAxel Dörfler #endif
155fdad9c93SAxel Dörfler termbuf2 = termbuf;
156fdad9c93SAxel Dörfler }
157fdad9c93SAxel Dörfler
158fdad9c93SAxel Dörfler #if defined(LINEMODE) && defined(TIOCPKT_IOCTL)
159fdad9c93SAxel Dörfler void
copy_termbuf(char * cp,size_t len)160fdad9c93SAxel Dörfler copy_termbuf(char *cp, size_t len)
161fdad9c93SAxel Dörfler {
162fdad9c93SAxel Dörfler if (len > sizeof(termbuf))
163fdad9c93SAxel Dörfler len = sizeof(termbuf);
164fdad9c93SAxel Dörfler memmove((char *)&termbuf, cp, len);
165fdad9c93SAxel Dörfler termbuf2 = termbuf;
166fdad9c93SAxel Dörfler }
167fdad9c93SAxel Dörfler #endif /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
168fdad9c93SAxel Dörfler
169fdad9c93SAxel Dörfler void
set_termbuf(void)170fdad9c93SAxel Dörfler set_termbuf(void)
171fdad9c93SAxel Dörfler {
172fdad9c93SAxel Dörfler /*
173fdad9c93SAxel Dörfler * Only make the necessary changes.
174fdad9c93SAxel Dörfler */
175fdad9c93SAxel Dörfler #ifndef USE_TERMIO
176fdad9c93SAxel Dörfler if (memcmp((char *)&termbuf.sg, (char *)&termbuf2.sg,
177fdad9c93SAxel Dörfler sizeof(termbuf.sg)))
178fdad9c93SAxel Dörfler (void) ioctl(pty, TIOCSETN, (char *)&termbuf.sg);
179fdad9c93SAxel Dörfler if (memcmp((char *)&termbuf.tc, (char *)&termbuf2.tc,
180fdad9c93SAxel Dörfler sizeof(termbuf.tc)))
181fdad9c93SAxel Dörfler (void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc);
182fdad9c93SAxel Dörfler if (memcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc,
183fdad9c93SAxel Dörfler sizeof(termbuf.ltc)))
184fdad9c93SAxel Dörfler (void) ioctl(pty, TIOCSLTC, (char *)&termbuf.ltc);
185fdad9c93SAxel Dörfler if (termbuf.lflags != termbuf2.lflags)
186fdad9c93SAxel Dörfler (void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags);
187fdad9c93SAxel Dörfler #else /* USE_TERMIO */
188fdad9c93SAxel Dörfler if (memcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))
189fdad9c93SAxel Dörfler (void) tcsetattr(pty, TCSANOW, &termbuf);
190fdad9c93SAxel Dörfler #endif /* USE_TERMIO */
191fdad9c93SAxel Dörfler }
192fdad9c93SAxel Dörfler
193fdad9c93SAxel Dörfler
194fdad9c93SAxel Dörfler /*
195fdad9c93SAxel Dörfler * spcset(func, valp, valpp)
196fdad9c93SAxel Dörfler *
197fdad9c93SAxel Dörfler * This function takes various special characters (func), and
198fdad9c93SAxel Dörfler * sets *valp to the current value of that character, and
199fdad9c93SAxel Dörfler * *valpp to point to where in the "termbuf" structure that
200fdad9c93SAxel Dörfler * value is kept.
201fdad9c93SAxel Dörfler *
202fdad9c93SAxel Dörfler * It returns the SLC_ level of support for this function.
203fdad9c93SAxel Dörfler */
204fdad9c93SAxel Dörfler
205fdad9c93SAxel Dörfler #ifndef USE_TERMIO
206fdad9c93SAxel Dörfler int
spcset(int func,cc_t * valp,cc_t ** valpp)207fdad9c93SAxel Dörfler spcset(int func, cc_t *valp, cc_t **valpp)
208fdad9c93SAxel Dörfler {
209fdad9c93SAxel Dörfler switch(func) {
210fdad9c93SAxel Dörfler case SLC_EOF:
211fdad9c93SAxel Dörfler *valp = termbuf.tc.t_eofc;
212fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.tc.t_eofc;
213fdad9c93SAxel Dörfler return(SLC_VARIABLE);
214fdad9c93SAxel Dörfler case SLC_EC:
215fdad9c93SAxel Dörfler *valp = termbuf.sg.sg_erase;
216fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.sg.sg_erase;
217fdad9c93SAxel Dörfler return(SLC_VARIABLE);
218fdad9c93SAxel Dörfler case SLC_EL:
219fdad9c93SAxel Dörfler *valp = termbuf.sg.sg_kill;
220fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.sg.sg_kill;
221fdad9c93SAxel Dörfler return(SLC_VARIABLE);
222fdad9c93SAxel Dörfler case SLC_IP:
223fdad9c93SAxel Dörfler *valp = termbuf.tc.t_intrc;
224fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.tc.t_intrc;
225fdad9c93SAxel Dörfler return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
226fdad9c93SAxel Dörfler case SLC_ABORT:
227fdad9c93SAxel Dörfler *valp = termbuf.tc.t_quitc;
228fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.tc.t_quitc;
229fdad9c93SAxel Dörfler return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
230fdad9c93SAxel Dörfler case SLC_XON:
231fdad9c93SAxel Dörfler *valp = termbuf.tc.t_startc;
232fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.tc.t_startc;
233fdad9c93SAxel Dörfler return(SLC_VARIABLE);
234fdad9c93SAxel Dörfler case SLC_XOFF:
235fdad9c93SAxel Dörfler *valp = termbuf.tc.t_stopc;
236fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.tc.t_stopc;
237fdad9c93SAxel Dörfler return(SLC_VARIABLE);
238fdad9c93SAxel Dörfler case SLC_AO:
239fdad9c93SAxel Dörfler *valp = termbuf.ltc.t_flushc;
240fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.ltc.t_flushc;
241fdad9c93SAxel Dörfler return(SLC_VARIABLE);
242fdad9c93SAxel Dörfler case SLC_SUSP:
243fdad9c93SAxel Dörfler *valp = termbuf.ltc.t_suspc;
244fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.ltc.t_suspc;
245fdad9c93SAxel Dörfler return(SLC_VARIABLE);
246fdad9c93SAxel Dörfler case SLC_EW:
247fdad9c93SAxel Dörfler *valp = termbuf.ltc.t_werasc;
248fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.ltc.t_werasc;
249fdad9c93SAxel Dörfler return(SLC_VARIABLE);
250fdad9c93SAxel Dörfler case SLC_RP:
251fdad9c93SAxel Dörfler *valp = termbuf.ltc.t_rprntc;
252fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.ltc.t_rprntc;
253fdad9c93SAxel Dörfler return(SLC_VARIABLE);
254fdad9c93SAxel Dörfler case SLC_LNEXT:
255fdad9c93SAxel Dörfler *valp = termbuf.ltc.t_lnextc;
256fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.ltc.t_lnextc;
257fdad9c93SAxel Dörfler return(SLC_VARIABLE);
258fdad9c93SAxel Dörfler case SLC_FORW1:
259fdad9c93SAxel Dörfler *valp = termbuf.tc.t_brkc;
260fdad9c93SAxel Dörfler *valpp = (cc_t *)&termbuf.ltc.t_lnextc;
261fdad9c93SAxel Dörfler return(SLC_VARIABLE);
262fdad9c93SAxel Dörfler case SLC_BRK:
263fdad9c93SAxel Dörfler case SLC_SYNCH:
264fdad9c93SAxel Dörfler case SLC_AYT:
265fdad9c93SAxel Dörfler case SLC_EOR:
266fdad9c93SAxel Dörfler *valp = (cc_t)0;
267fdad9c93SAxel Dörfler *valpp = (cc_t *)0;
268fdad9c93SAxel Dörfler return(SLC_DEFAULT);
269fdad9c93SAxel Dörfler default:
270fdad9c93SAxel Dörfler *valp = (cc_t)0;
271fdad9c93SAxel Dörfler *valpp = (cc_t *)0;
272fdad9c93SAxel Dörfler return(SLC_NOSUPPORT);
273fdad9c93SAxel Dörfler }
274fdad9c93SAxel Dörfler }
275fdad9c93SAxel Dörfler
276fdad9c93SAxel Dörfler #else /* USE_TERMIO */
277fdad9c93SAxel Dörfler
278fdad9c93SAxel Dörfler
279fdad9c93SAxel Dörfler #define setval(a, b) *valp = termbuf.c_cc[a]; \
280fdad9c93SAxel Dörfler *valpp = &termbuf.c_cc[a]; \
281fdad9c93SAxel Dörfler return(b);
282fdad9c93SAxel Dörfler #define defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT);
283fdad9c93SAxel Dörfler
284fdad9c93SAxel Dörfler int
spcset(int func,cc_t * valp,cc_t ** valpp)285fdad9c93SAxel Dörfler spcset(int func, cc_t *valp, cc_t **valpp)
286fdad9c93SAxel Dörfler {
287fdad9c93SAxel Dörfler switch(func) {
288fdad9c93SAxel Dörfler case SLC_EOF:
289fdad9c93SAxel Dörfler setval(VEOF, SLC_VARIABLE);
290fdad9c93SAxel Dörfler case SLC_EC:
291fdad9c93SAxel Dörfler setval(VERASE, SLC_VARIABLE);
292fdad9c93SAxel Dörfler case SLC_EL:
293fdad9c93SAxel Dörfler setval(VKILL, SLC_VARIABLE);
294fdad9c93SAxel Dörfler case SLC_IP:
295fdad9c93SAxel Dörfler setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
296fdad9c93SAxel Dörfler case SLC_ABORT:
297fdad9c93SAxel Dörfler setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
298fdad9c93SAxel Dörfler case SLC_XON:
299fdad9c93SAxel Dörfler #ifdef VSTART
300fdad9c93SAxel Dörfler setval(VSTART, SLC_VARIABLE);
301fdad9c93SAxel Dörfler #else
302fdad9c93SAxel Dörfler defval(0x13);
303fdad9c93SAxel Dörfler #endif
304fdad9c93SAxel Dörfler case SLC_XOFF:
305fdad9c93SAxel Dörfler #ifdef VSTOP
306fdad9c93SAxel Dörfler setval(VSTOP, SLC_VARIABLE);
307fdad9c93SAxel Dörfler #else
308fdad9c93SAxel Dörfler defval(0x11);
309fdad9c93SAxel Dörfler #endif
310fdad9c93SAxel Dörfler case SLC_EW:
311fdad9c93SAxel Dörfler #ifdef VWERASE
312fdad9c93SAxel Dörfler setval(VWERASE, SLC_VARIABLE);
313fdad9c93SAxel Dörfler #else
314fdad9c93SAxel Dörfler defval(0);
315fdad9c93SAxel Dörfler #endif
316fdad9c93SAxel Dörfler case SLC_RP:
317fdad9c93SAxel Dörfler #ifdef VREPRINT
318fdad9c93SAxel Dörfler setval(VREPRINT, SLC_VARIABLE);
319fdad9c93SAxel Dörfler #else
320fdad9c93SAxel Dörfler defval(0);
321fdad9c93SAxel Dörfler #endif
322fdad9c93SAxel Dörfler case SLC_LNEXT:
323fdad9c93SAxel Dörfler #ifdef VLNEXT
324fdad9c93SAxel Dörfler setval(VLNEXT, SLC_VARIABLE);
325fdad9c93SAxel Dörfler #else
326fdad9c93SAxel Dörfler defval(0);
327fdad9c93SAxel Dörfler #endif
328fdad9c93SAxel Dörfler case SLC_AO:
329fdad9c93SAxel Dörfler #if !defined(VDISCARD) && defined(VFLUSHO)
330fdad9c93SAxel Dörfler # define VDISCARD VFLUSHO
331fdad9c93SAxel Dörfler #endif
332fdad9c93SAxel Dörfler #ifdef VDISCARD
333fdad9c93SAxel Dörfler setval(VDISCARD, SLC_VARIABLE|SLC_FLUSHOUT);
334fdad9c93SAxel Dörfler #else
335fdad9c93SAxel Dörfler defval(0);
336fdad9c93SAxel Dörfler #endif
337fdad9c93SAxel Dörfler case SLC_SUSP:
338fdad9c93SAxel Dörfler #ifdef VSUSP
339fdad9c93SAxel Dörfler setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
340fdad9c93SAxel Dörfler #else
341fdad9c93SAxel Dörfler defval(0);
342fdad9c93SAxel Dörfler #endif
343fdad9c93SAxel Dörfler #ifdef VEOL
344fdad9c93SAxel Dörfler case SLC_FORW1:
345fdad9c93SAxel Dörfler setval(VEOL, SLC_VARIABLE);
346fdad9c93SAxel Dörfler #endif
347fdad9c93SAxel Dörfler #ifdef VEOL2
348fdad9c93SAxel Dörfler case SLC_FORW2:
349fdad9c93SAxel Dörfler setval(VEOL2, SLC_VARIABLE);
350fdad9c93SAxel Dörfler #endif
351fdad9c93SAxel Dörfler case SLC_AYT:
352fdad9c93SAxel Dörfler #ifdef VSTATUS
353fdad9c93SAxel Dörfler setval(VSTATUS, SLC_VARIABLE);
354fdad9c93SAxel Dörfler #else
355fdad9c93SAxel Dörfler defval(0);
356fdad9c93SAxel Dörfler #endif
357fdad9c93SAxel Dörfler
358fdad9c93SAxel Dörfler case SLC_BRK:
359fdad9c93SAxel Dörfler case SLC_SYNCH:
360fdad9c93SAxel Dörfler case SLC_EOR:
361fdad9c93SAxel Dörfler defval(0);
362fdad9c93SAxel Dörfler
363fdad9c93SAxel Dörfler default:
364fdad9c93SAxel Dörfler *valp = 0;
365fdad9c93SAxel Dörfler *valpp = 0;
366fdad9c93SAxel Dörfler return(SLC_NOSUPPORT);
367fdad9c93SAxel Dörfler }
368fdad9c93SAxel Dörfler }
369fdad9c93SAxel Dörfler #endif /* USE_TERMIO */
370fdad9c93SAxel Dörfler
371fdad9c93SAxel Dörfler /*
372fdad9c93SAxel Dörfler * getpty()
373fdad9c93SAxel Dörfler *
374fdad9c93SAxel Dörfler * Allocate a pty. As a side effect, the external character
375fdad9c93SAxel Dörfler * array "line" contains the name of the slave side.
376fdad9c93SAxel Dörfler *
377fdad9c93SAxel Dörfler * Returns the file descriptor of the opened pty.
378fdad9c93SAxel Dörfler */
379fdad9c93SAxel Dörfler int
getpty(int * ptynum __unused)380fdad9c93SAxel Dörfler getpty(int *ptynum __unused)
381fdad9c93SAxel Dörfler {
382fdad9c93SAxel Dörfler int p;
383*6b99b206SAugustin Cavalier const char *pn;
384fdad9c93SAxel Dörfler
385*6b99b206SAugustin Cavalier p = posix_openpt(O_RDWR|O_NOCTTY);
386*6b99b206SAugustin Cavalier if (p < 0)
387fdad9c93SAxel Dörfler return (-1);
388*6b99b206SAugustin Cavalier
389*6b99b206SAugustin Cavalier if (grantpt(p) == -1)
390*6b99b206SAugustin Cavalier return (-1);
391*6b99b206SAugustin Cavalier
392*6b99b206SAugustin Cavalier if (unlockpt(p) == -1)
393*6b99b206SAugustin Cavalier return (-1);
394*6b99b206SAugustin Cavalier
395*6b99b206SAugustin Cavalier pn = ptsname(p);
396*6b99b206SAugustin Cavalier if (pn == NULL)
397*6b99b206SAugustin Cavalier return (-1);
398*6b99b206SAugustin Cavalier
399*6b99b206SAugustin Cavalier if (strlcpy(line, pn, sizeof line) >= sizeof line)
400*6b99b206SAugustin Cavalier return (-1);
401*6b99b206SAugustin Cavalier
402*6b99b206SAugustin Cavalier return (p);
403fdad9c93SAxel Dörfler }
404fdad9c93SAxel Dörfler
405fdad9c93SAxel Dörfler #ifdef LINEMODE
406fdad9c93SAxel Dörfler /*
407fdad9c93SAxel Dörfler * tty_flowmode() Find out if flow control is enabled or disabled.
408fdad9c93SAxel Dörfler * tty_linemode() Find out if linemode (external processing) is enabled.
409fdad9c93SAxel Dörfler * tty_setlinemod(on) Turn on/off linemode.
410fdad9c93SAxel Dörfler * tty_isecho() Find out if echoing is turned on.
411fdad9c93SAxel Dörfler * tty_setecho(on) Enable/disable character echoing.
412fdad9c93SAxel Dörfler * tty_israw() Find out if terminal is in RAW mode.
413fdad9c93SAxel Dörfler * tty_binaryin(on) Turn on/off BINARY on input.
414fdad9c93SAxel Dörfler * tty_binaryout(on) Turn on/off BINARY on output.
415fdad9c93SAxel Dörfler * tty_isediting() Find out if line editing is enabled.
416fdad9c93SAxel Dörfler * tty_istrapsig() Find out if signal trapping is enabled.
417fdad9c93SAxel Dörfler * tty_setedit(on) Turn on/off line editing.
418fdad9c93SAxel Dörfler * tty_setsig(on) Turn on/off signal trapping.
419fdad9c93SAxel Dörfler * tty_issofttab() Find out if tab expansion is enabled.
420fdad9c93SAxel Dörfler * tty_setsofttab(on) Turn on/off soft tab expansion.
421fdad9c93SAxel Dörfler * tty_islitecho() Find out if typed control chars are echoed literally
422fdad9c93SAxel Dörfler * tty_setlitecho() Turn on/off literal echo of control chars
423fdad9c93SAxel Dörfler * tty_tspeed(val) Set transmit speed to val.
424fdad9c93SAxel Dörfler * tty_rspeed(val) Set receive speed to val.
425fdad9c93SAxel Dörfler */
426fdad9c93SAxel Dörfler
427fdad9c93SAxel Dörfler
428fdad9c93SAxel Dörfler int
tty_linemode(void)429fdad9c93SAxel Dörfler tty_linemode(void)
430fdad9c93SAxel Dörfler {
431fdad9c93SAxel Dörfler #ifndef USE_TERMIO
432fdad9c93SAxel Dörfler return(termbuf.state & TS_EXTPROC);
433fdad9c93SAxel Dörfler #else
434fdad9c93SAxel Dörfler return(termbuf.c_lflag & EXTPROC);
435fdad9c93SAxel Dörfler #endif
436fdad9c93SAxel Dörfler }
437fdad9c93SAxel Dörfler
438fdad9c93SAxel Dörfler void
tty_setlinemode(int on)439fdad9c93SAxel Dörfler tty_setlinemode(int on)
440fdad9c93SAxel Dörfler {
441fdad9c93SAxel Dörfler #ifdef TIOCEXT
442fdad9c93SAxel Dörfler set_termbuf();
443fdad9c93SAxel Dörfler (void) ioctl(pty, TIOCEXT, (char *)&on);
444fdad9c93SAxel Dörfler init_termbuf();
445fdad9c93SAxel Dörfler #else /* !TIOCEXT */
446fdad9c93SAxel Dörfler # ifdef EXTPROC
447fdad9c93SAxel Dörfler if (on)
448fdad9c93SAxel Dörfler termbuf.c_lflag |= EXTPROC;
449fdad9c93SAxel Dörfler else
450fdad9c93SAxel Dörfler termbuf.c_lflag &= ~EXTPROC;
451fdad9c93SAxel Dörfler # endif
452fdad9c93SAxel Dörfler #endif /* TIOCEXT */
453fdad9c93SAxel Dörfler }
454fdad9c93SAxel Dörfler #endif /* LINEMODE */
455fdad9c93SAxel Dörfler
456fdad9c93SAxel Dörfler int
tty_isecho(void)457fdad9c93SAxel Dörfler tty_isecho(void)
458fdad9c93SAxel Dörfler {
459fdad9c93SAxel Dörfler #ifndef USE_TERMIO
460fdad9c93SAxel Dörfler return (termbuf.sg.sg_flags & ECHO);
461fdad9c93SAxel Dörfler #else
462fdad9c93SAxel Dörfler return (termbuf.c_lflag & ECHO);
463fdad9c93SAxel Dörfler #endif
464fdad9c93SAxel Dörfler }
465fdad9c93SAxel Dörfler
466fdad9c93SAxel Dörfler int
tty_flowmode(void)467fdad9c93SAxel Dörfler tty_flowmode(void)
468fdad9c93SAxel Dörfler {
469fdad9c93SAxel Dörfler #ifndef USE_TERMIO
470fdad9c93SAxel Dörfler return(((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0) ? 1 : 0);
471fdad9c93SAxel Dörfler #else
472fdad9c93SAxel Dörfler return((termbuf.c_iflag & IXON) ? 1 : 0);
473fdad9c93SAxel Dörfler #endif
474fdad9c93SAxel Dörfler }
475fdad9c93SAxel Dörfler
476fdad9c93SAxel Dörfler int
tty_restartany(void)477fdad9c93SAxel Dörfler tty_restartany(void)
478fdad9c93SAxel Dörfler {
479fdad9c93SAxel Dörfler #ifndef USE_TERMIO
480fdad9c93SAxel Dörfler # ifdef DECCTQ
481fdad9c93SAxel Dörfler return((termbuf.lflags & DECCTQ) ? 0 : 1);
482fdad9c93SAxel Dörfler # else
483fdad9c93SAxel Dörfler return(-1);
484fdad9c93SAxel Dörfler # endif
485fdad9c93SAxel Dörfler #else
486fdad9c93SAxel Dörfler return((termbuf.c_iflag & IXANY) ? 1 : 0);
487fdad9c93SAxel Dörfler #endif
488fdad9c93SAxel Dörfler }
489fdad9c93SAxel Dörfler
490fdad9c93SAxel Dörfler void
tty_setecho(int on)491fdad9c93SAxel Dörfler tty_setecho(int on)
492fdad9c93SAxel Dörfler {
493fdad9c93SAxel Dörfler #ifndef USE_TERMIO
494fdad9c93SAxel Dörfler if (on)
495fdad9c93SAxel Dörfler termbuf.sg.sg_flags |= ECHO|CRMOD;
496fdad9c93SAxel Dörfler else
497fdad9c93SAxel Dörfler termbuf.sg.sg_flags &= ~(ECHO|CRMOD);
498fdad9c93SAxel Dörfler #else
499fdad9c93SAxel Dörfler if (on)
500fdad9c93SAxel Dörfler termbuf.c_lflag |= ECHO;
501fdad9c93SAxel Dörfler else
502fdad9c93SAxel Dörfler termbuf.c_lflag &= ~ECHO;
503fdad9c93SAxel Dörfler #endif
504fdad9c93SAxel Dörfler }
505fdad9c93SAxel Dörfler
506fdad9c93SAxel Dörfler int
tty_israw(void)507fdad9c93SAxel Dörfler tty_israw(void)
508fdad9c93SAxel Dörfler {
509fdad9c93SAxel Dörfler #ifndef USE_TERMIO
510fdad9c93SAxel Dörfler return(termbuf.sg.sg_flags & RAW);
511fdad9c93SAxel Dörfler #else
512fdad9c93SAxel Dörfler return(!(termbuf.c_lflag & ICANON));
513fdad9c93SAxel Dörfler #endif
514fdad9c93SAxel Dörfler }
515fdad9c93SAxel Dörfler
516fdad9c93SAxel Dörfler #ifdef AUTHENTICATION
517fdad9c93SAxel Dörfler #if defined(NO_LOGIN_F) && defined(LOGIN_R)
518fdad9c93SAxel Dörfler int
tty_setraw(int on)519fdad9c93SAxel Dörfler tty_setraw(int on)
520fdad9c93SAxel Dörfler {
521fdad9c93SAxel Dörfler # ifndef USE_TERMIO
522fdad9c93SAxel Dörfler if (on)
523fdad9c93SAxel Dörfler termbuf.sg.sg_flags |= RAW;
524fdad9c93SAxel Dörfler else
525fdad9c93SAxel Dörfler termbuf.sg.sg_flags &= ~RAW;
526fdad9c93SAxel Dörfler # else
527fdad9c93SAxel Dörfler if (on)
528fdad9c93SAxel Dörfler termbuf.c_lflag &= ~ICANON;
529fdad9c93SAxel Dörfler else
530fdad9c93SAxel Dörfler termbuf.c_lflag |= ICANON;
531fdad9c93SAxel Dörfler # endif
532fdad9c93SAxel Dörfler }
533fdad9c93SAxel Dörfler #endif
534fdad9c93SAxel Dörfler #endif /* AUTHENTICATION */
535fdad9c93SAxel Dörfler
536fdad9c93SAxel Dörfler void
tty_binaryin(int on)537fdad9c93SAxel Dörfler tty_binaryin(int on)
538fdad9c93SAxel Dörfler {
539fdad9c93SAxel Dörfler #ifndef USE_TERMIO
540fdad9c93SAxel Dörfler if (on)
541fdad9c93SAxel Dörfler termbuf.lflags |= LPASS8;
542fdad9c93SAxel Dörfler else
543fdad9c93SAxel Dörfler termbuf.lflags &= ~LPASS8;
544fdad9c93SAxel Dörfler #else
545fdad9c93SAxel Dörfler if (on) {
546fdad9c93SAxel Dörfler termbuf.c_iflag &= ~ISTRIP;
547fdad9c93SAxel Dörfler } else {
548fdad9c93SAxel Dörfler termbuf.c_iflag |= ISTRIP;
549fdad9c93SAxel Dörfler }
550fdad9c93SAxel Dörfler #endif
551fdad9c93SAxel Dörfler }
552fdad9c93SAxel Dörfler
553fdad9c93SAxel Dörfler void
tty_binaryout(int on)554fdad9c93SAxel Dörfler tty_binaryout(int on)
555fdad9c93SAxel Dörfler {
556fdad9c93SAxel Dörfler #ifndef USE_TERMIO
557fdad9c93SAxel Dörfler if (on)
558fdad9c93SAxel Dörfler termbuf.lflags |= LLITOUT;
559fdad9c93SAxel Dörfler else
560fdad9c93SAxel Dörfler termbuf.lflags &= ~LLITOUT;
561fdad9c93SAxel Dörfler #else
562fdad9c93SAxel Dörfler if (on) {
563fdad9c93SAxel Dörfler termbuf.c_cflag &= ~(CSIZE|PARENB);
564fdad9c93SAxel Dörfler termbuf.c_cflag |= CS8;
565fdad9c93SAxel Dörfler termbuf.c_oflag &= ~OPOST;
566fdad9c93SAxel Dörfler } else {
567fdad9c93SAxel Dörfler termbuf.c_cflag &= ~CSIZE;
568fdad9c93SAxel Dörfler termbuf.c_cflag |= CS7|PARENB;
569fdad9c93SAxel Dörfler termbuf.c_oflag |= OPOST;
570fdad9c93SAxel Dörfler }
571fdad9c93SAxel Dörfler #endif
572fdad9c93SAxel Dörfler }
573fdad9c93SAxel Dörfler
574fdad9c93SAxel Dörfler int
tty_isbinaryin(void)575fdad9c93SAxel Dörfler tty_isbinaryin(void)
576fdad9c93SAxel Dörfler {
577fdad9c93SAxel Dörfler #ifndef USE_TERMIO
578fdad9c93SAxel Dörfler return(termbuf.lflags & LPASS8);
579fdad9c93SAxel Dörfler #else
580fdad9c93SAxel Dörfler return(!(termbuf.c_iflag & ISTRIP));
581fdad9c93SAxel Dörfler #endif
582fdad9c93SAxel Dörfler }
583fdad9c93SAxel Dörfler
584fdad9c93SAxel Dörfler int
tty_isbinaryout(void)585fdad9c93SAxel Dörfler tty_isbinaryout(void)
586fdad9c93SAxel Dörfler {
587fdad9c93SAxel Dörfler #ifndef USE_TERMIO
588fdad9c93SAxel Dörfler return(termbuf.lflags & LLITOUT);
589fdad9c93SAxel Dörfler #else
590fdad9c93SAxel Dörfler return(!(termbuf.c_oflag&OPOST));
591fdad9c93SAxel Dörfler #endif
592fdad9c93SAxel Dörfler }
593fdad9c93SAxel Dörfler
594fdad9c93SAxel Dörfler #ifdef LINEMODE
595fdad9c93SAxel Dörfler int
tty_isediting(void)596fdad9c93SAxel Dörfler tty_isediting(void)
597fdad9c93SAxel Dörfler {
598fdad9c93SAxel Dörfler #ifndef USE_TERMIO
599fdad9c93SAxel Dörfler return(!(termbuf.sg.sg_flags & (CBREAK|RAW)));
600fdad9c93SAxel Dörfler #else
601fdad9c93SAxel Dörfler return(termbuf.c_lflag & ICANON);
602fdad9c93SAxel Dörfler #endif
603fdad9c93SAxel Dörfler }
604fdad9c93SAxel Dörfler
605fdad9c93SAxel Dörfler int
tty_istrapsig(void)606fdad9c93SAxel Dörfler tty_istrapsig(void)
607fdad9c93SAxel Dörfler {
608fdad9c93SAxel Dörfler #ifndef USE_TERMIO
609fdad9c93SAxel Dörfler return(!(termbuf.sg.sg_flags&RAW));
610fdad9c93SAxel Dörfler #else
611fdad9c93SAxel Dörfler return(termbuf.c_lflag & ISIG);
612fdad9c93SAxel Dörfler #endif
613fdad9c93SAxel Dörfler }
614fdad9c93SAxel Dörfler
615fdad9c93SAxel Dörfler void
tty_setedit(int on)616fdad9c93SAxel Dörfler tty_setedit(int on)
617fdad9c93SAxel Dörfler {
618fdad9c93SAxel Dörfler #ifndef USE_TERMIO
619fdad9c93SAxel Dörfler if (on)
620fdad9c93SAxel Dörfler termbuf.sg.sg_flags &= ~CBREAK;
621fdad9c93SAxel Dörfler else
622fdad9c93SAxel Dörfler termbuf.sg.sg_flags |= CBREAK;
623fdad9c93SAxel Dörfler #else
624fdad9c93SAxel Dörfler if (on)
625fdad9c93SAxel Dörfler termbuf.c_lflag |= ICANON;
626fdad9c93SAxel Dörfler else
627fdad9c93SAxel Dörfler termbuf.c_lflag &= ~ICANON;
628fdad9c93SAxel Dörfler #endif
629fdad9c93SAxel Dörfler }
630fdad9c93SAxel Dörfler
631fdad9c93SAxel Dörfler void
tty_setsig(int on)632fdad9c93SAxel Dörfler tty_setsig(int on)
633fdad9c93SAxel Dörfler {
634fdad9c93SAxel Dörfler #ifndef USE_TERMIO
635fdad9c93SAxel Dörfler if (on)
636fdad9c93SAxel Dörfler ;
637fdad9c93SAxel Dörfler #else
638fdad9c93SAxel Dörfler if (on)
639fdad9c93SAxel Dörfler termbuf.c_lflag |= ISIG;
640fdad9c93SAxel Dörfler else
641fdad9c93SAxel Dörfler termbuf.c_lflag &= ~ISIG;
642fdad9c93SAxel Dörfler #endif
643fdad9c93SAxel Dörfler }
644fdad9c93SAxel Dörfler #endif /* LINEMODE */
645fdad9c93SAxel Dörfler
646fdad9c93SAxel Dörfler int
tty_issofttab(void)647fdad9c93SAxel Dörfler tty_issofttab(void)
648fdad9c93SAxel Dörfler {
649fdad9c93SAxel Dörfler #ifndef USE_TERMIO
650fdad9c93SAxel Dörfler return (termbuf.sg.sg_flags & XTABS);
651fdad9c93SAxel Dörfler #else
652fdad9c93SAxel Dörfler # ifdef OXTABS
653fdad9c93SAxel Dörfler return (termbuf.c_oflag & OXTABS);
654fdad9c93SAxel Dörfler # endif
655fdad9c93SAxel Dörfler # ifdef TABDLY
656fdad9c93SAxel Dörfler return ((termbuf.c_oflag & TABDLY) == TAB3);
657fdad9c93SAxel Dörfler # endif
658fdad9c93SAxel Dörfler #endif
659fdad9c93SAxel Dörfler }
660fdad9c93SAxel Dörfler
661fdad9c93SAxel Dörfler void
tty_setsofttab(int on)662fdad9c93SAxel Dörfler tty_setsofttab(int on)
663fdad9c93SAxel Dörfler {
664fdad9c93SAxel Dörfler #ifndef USE_TERMIO
665fdad9c93SAxel Dörfler if (on)
666fdad9c93SAxel Dörfler termbuf.sg.sg_flags |= XTABS;
667fdad9c93SAxel Dörfler else
668fdad9c93SAxel Dörfler termbuf.sg.sg_flags &= ~XTABS;
669fdad9c93SAxel Dörfler #else
670fdad9c93SAxel Dörfler if (on) {
671fdad9c93SAxel Dörfler # ifdef OXTABS
672fdad9c93SAxel Dörfler termbuf.c_oflag |= OXTABS;
673fdad9c93SAxel Dörfler # endif
674fdad9c93SAxel Dörfler # ifdef TABDLY
675fdad9c93SAxel Dörfler termbuf.c_oflag &= ~TABDLY;
676fdad9c93SAxel Dörfler termbuf.c_oflag |= TAB3;
677fdad9c93SAxel Dörfler # endif
678fdad9c93SAxel Dörfler } else {
679fdad9c93SAxel Dörfler # ifdef OXTABS
680fdad9c93SAxel Dörfler termbuf.c_oflag &= ~OXTABS;
681fdad9c93SAxel Dörfler # endif
682fdad9c93SAxel Dörfler # ifdef TABDLY
683fdad9c93SAxel Dörfler termbuf.c_oflag &= ~TABDLY;
684fdad9c93SAxel Dörfler termbuf.c_oflag |= TAB0;
685fdad9c93SAxel Dörfler # endif
686fdad9c93SAxel Dörfler }
687fdad9c93SAxel Dörfler #endif
688fdad9c93SAxel Dörfler }
689fdad9c93SAxel Dörfler
690fdad9c93SAxel Dörfler int
tty_islitecho(void)691fdad9c93SAxel Dörfler tty_islitecho(void)
692fdad9c93SAxel Dörfler {
693fdad9c93SAxel Dörfler #ifndef USE_TERMIO
694fdad9c93SAxel Dörfler return (!(termbuf.lflags & LCTLECH));
695fdad9c93SAxel Dörfler #else
696fdad9c93SAxel Dörfler # ifdef ECHOCTL
697fdad9c93SAxel Dörfler return (!(termbuf.c_lflag & ECHOCTL));
698fdad9c93SAxel Dörfler # endif
699fdad9c93SAxel Dörfler # ifdef TCTLECH
700fdad9c93SAxel Dörfler return (!(termbuf.c_lflag & TCTLECH));
701fdad9c93SAxel Dörfler # endif
702fdad9c93SAxel Dörfler # if !defined(ECHOCTL) && !defined(TCTLECH)
703fdad9c93SAxel Dörfler return (0); /* assumes ctl chars are echoed '^x' */
704fdad9c93SAxel Dörfler # endif
705fdad9c93SAxel Dörfler #endif
706fdad9c93SAxel Dörfler }
707fdad9c93SAxel Dörfler
708fdad9c93SAxel Dörfler void
tty_setlitecho(int on)709fdad9c93SAxel Dörfler tty_setlitecho(int on)
710fdad9c93SAxel Dörfler {
711fdad9c93SAxel Dörfler #ifndef USE_TERMIO
712fdad9c93SAxel Dörfler if (on)
713fdad9c93SAxel Dörfler termbuf.lflags &= ~LCTLECH;
714fdad9c93SAxel Dörfler else
715fdad9c93SAxel Dörfler termbuf.lflags |= LCTLECH;
716fdad9c93SAxel Dörfler #else
717fdad9c93SAxel Dörfler # ifdef ECHOCTL
718fdad9c93SAxel Dörfler if (on)
719fdad9c93SAxel Dörfler termbuf.c_lflag &= ~ECHOCTL;
720fdad9c93SAxel Dörfler else
721fdad9c93SAxel Dörfler termbuf.c_lflag |= ECHOCTL;
722fdad9c93SAxel Dörfler # endif
723fdad9c93SAxel Dörfler # ifdef TCTLECH
724fdad9c93SAxel Dörfler if (on)
725fdad9c93SAxel Dörfler termbuf.c_lflag &= ~TCTLECH;
726fdad9c93SAxel Dörfler else
727fdad9c93SAxel Dörfler termbuf.c_lflag |= TCTLECH;
728fdad9c93SAxel Dörfler # endif
729fdad9c93SAxel Dörfler #endif
730fdad9c93SAxel Dörfler }
731fdad9c93SAxel Dörfler
732fdad9c93SAxel Dörfler int
tty_iscrnl(void)733fdad9c93SAxel Dörfler tty_iscrnl(void)
734fdad9c93SAxel Dörfler {
735fdad9c93SAxel Dörfler #ifndef USE_TERMIO
736fdad9c93SAxel Dörfler return (termbuf.sg.sg_flags & CRMOD);
737fdad9c93SAxel Dörfler #else
738fdad9c93SAxel Dörfler return (termbuf.c_iflag & ICRNL);
739fdad9c93SAxel Dörfler #endif
740fdad9c93SAxel Dörfler }
741fdad9c93SAxel Dörfler
742fdad9c93SAxel Dörfler void
tty_tspeed(int val)743fdad9c93SAxel Dörfler tty_tspeed(int val)
744fdad9c93SAxel Dörfler {
745fdad9c93SAxel Dörfler #ifdef DECODE_BAUD
746fdad9c93SAxel Dörfler struct termspeeds *tp;
747fdad9c93SAxel Dörfler
748fdad9c93SAxel Dörfler for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
749fdad9c93SAxel Dörfler ;
750fdad9c93SAxel Dörfler if (tp->speed == -1) /* back up to last valid value */
751fdad9c93SAxel Dörfler --tp;
752fdad9c93SAxel Dörfler cfsetospeed(&termbuf, tp->value);
753fdad9c93SAxel Dörfler #else /* DECODE_BAUD */
754fdad9c93SAxel Dörfler cfsetospeed(&termbuf, val);
755fdad9c93SAxel Dörfler #endif /* DECODE_BAUD */
756fdad9c93SAxel Dörfler }
757fdad9c93SAxel Dörfler
758fdad9c93SAxel Dörfler void
tty_rspeed(int val)759fdad9c93SAxel Dörfler tty_rspeed(int val)
760fdad9c93SAxel Dörfler {
761fdad9c93SAxel Dörfler #ifdef DECODE_BAUD
762fdad9c93SAxel Dörfler struct termspeeds *tp;
763fdad9c93SAxel Dörfler
764fdad9c93SAxel Dörfler for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
765fdad9c93SAxel Dörfler ;
766fdad9c93SAxel Dörfler if (tp->speed == -1) /* back up to last valid value */
767fdad9c93SAxel Dörfler --tp;
768fdad9c93SAxel Dörfler cfsetispeed(&termbuf, tp->value);
769fdad9c93SAxel Dörfler #else /* DECODE_BAUD */
770fdad9c93SAxel Dörfler cfsetispeed(&termbuf, val);
771fdad9c93SAxel Dörfler #endif /* DECODE_BAUD */
772fdad9c93SAxel Dörfler }
773fdad9c93SAxel Dörfler
774fdad9c93SAxel Dörfler /*
775fdad9c93SAxel Dörfler * getptyslave()
776fdad9c93SAxel Dörfler *
777fdad9c93SAxel Dörfler * Open the slave side of the pty, and do any initialization
778fdad9c93SAxel Dörfler * that is necessary.
779fdad9c93SAxel Dörfler */
780fdad9c93SAxel Dörfler static void
getptyslave(void)781fdad9c93SAxel Dörfler getptyslave(void)
782fdad9c93SAxel Dörfler {
783fdad9c93SAxel Dörfler int t = -1;
784fdad9c93SAxel Dörfler char erase;
785fdad9c93SAxel Dörfler
786fdad9c93SAxel Dörfler # ifdef LINEMODE
787fdad9c93SAxel Dörfler int waslm;
788fdad9c93SAxel Dörfler # endif
789fdad9c93SAxel Dörfler # ifdef TIOCGWINSZ
790fdad9c93SAxel Dörfler struct winsize ws;
791fdad9c93SAxel Dörfler extern int def_row, def_col;
792fdad9c93SAxel Dörfler # endif
793fdad9c93SAxel Dörfler extern int def_tspeed, def_rspeed;
794fdad9c93SAxel Dörfler /*
795fdad9c93SAxel Dörfler * Opening the slave side may cause initilization of the
796fdad9c93SAxel Dörfler * kernel tty structure. We need remember the state of
797fdad9c93SAxel Dörfler * if linemode was turned on
798fdad9c93SAxel Dörfler * terminal window size
799fdad9c93SAxel Dörfler * terminal speed
800fdad9c93SAxel Dörfler * erase character
801fdad9c93SAxel Dörfler * so that we can re-set them if we need to.
802fdad9c93SAxel Dörfler */
803fdad9c93SAxel Dörfler # ifdef LINEMODE
804fdad9c93SAxel Dörfler waslm = tty_linemode();
805fdad9c93SAxel Dörfler # endif
806fdad9c93SAxel Dörfler erase = termbuf.c_cc[VERASE];
807fdad9c93SAxel Dörfler
808fdad9c93SAxel Dörfler /*
809fdad9c93SAxel Dörfler * Make sure that we don't have a controlling tty, and
810fdad9c93SAxel Dörfler * that we are the session (process group) leader.
811fdad9c93SAxel Dörfler */
812fdad9c93SAxel Dörfler # ifdef TIOCNOTTY
813fdad9c93SAxel Dörfler t = open(_PATH_TTY, O_RDWR);
814fdad9c93SAxel Dörfler if (t >= 0) {
815fdad9c93SAxel Dörfler (void) ioctl(t, TIOCNOTTY, (char *)0);
816fdad9c93SAxel Dörfler (void) close(t);
817fdad9c93SAxel Dörfler }
818fdad9c93SAxel Dörfler # endif
819fdad9c93SAxel Dörfler
820fdad9c93SAxel Dörfler t = cleanopen(line);
821fdad9c93SAxel Dörfler if (t < 0)
822fdad9c93SAxel Dörfler fatalperror(net, line);
823fdad9c93SAxel Dörfler
824fdad9c93SAxel Dörfler
825fdad9c93SAxel Dörfler /*
826fdad9c93SAxel Dörfler * set up the tty modes as we like them to be.
827fdad9c93SAxel Dörfler */
828fdad9c93SAxel Dörfler init_termbuf();
829fdad9c93SAxel Dörfler # ifdef TIOCGWINSZ
830fdad9c93SAxel Dörfler if (def_row || def_col) {
831fdad9c93SAxel Dörfler memset((char *)&ws, 0, sizeof(ws));
832fdad9c93SAxel Dörfler ws.ws_col = def_col;
833fdad9c93SAxel Dörfler ws.ws_row = def_row;
834fdad9c93SAxel Dörfler (void)ioctl(t, TIOCSWINSZ, (char *)&ws);
835fdad9c93SAxel Dörfler }
836fdad9c93SAxel Dörfler # endif
837fdad9c93SAxel Dörfler
838fdad9c93SAxel Dörfler /*
839fdad9c93SAxel Dörfler * Settings for sgtty based systems
840fdad9c93SAxel Dörfler */
841fdad9c93SAxel Dörfler # ifndef USE_TERMIO
842fdad9c93SAxel Dörfler termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS;
843fdad9c93SAxel Dörfler # endif /* USE_TERMIO */
844fdad9c93SAxel Dörfler
845fdad9c93SAxel Dörfler /*
846fdad9c93SAxel Dörfler * Settings for all other termios/termio based
847fdad9c93SAxel Dörfler * systems, other than 4.4BSD. In 4.4BSD the
848fdad9c93SAxel Dörfler * kernel does the initial terminal setup.
849fdad9c93SAxel Dörfler */
850fdad9c93SAxel Dörfler tty_rspeed((def_rspeed > 0) ? def_rspeed : 9600);
851fdad9c93SAxel Dörfler tty_tspeed((def_tspeed > 0) ? def_tspeed : 9600);
852fdad9c93SAxel Dörfler if (erase)
853fdad9c93SAxel Dörfler termbuf.c_cc[VERASE] = erase;
854fdad9c93SAxel Dörfler # ifdef LINEMODE
855fdad9c93SAxel Dörfler if (waslm)
856fdad9c93SAxel Dörfler tty_setlinemode(1);
857fdad9c93SAxel Dörfler # endif /* LINEMODE */
858fdad9c93SAxel Dörfler
859fdad9c93SAxel Dörfler /*
860fdad9c93SAxel Dörfler * Set the tty modes, and make this our controlling tty.
861fdad9c93SAxel Dörfler */
862fdad9c93SAxel Dörfler set_termbuf();
863fdad9c93SAxel Dörfler if (login_tty(t) == -1)
864fdad9c93SAxel Dörfler fatalperror(net, "login_tty");
865fdad9c93SAxel Dörfler if (net > 2)
866fdad9c93SAxel Dörfler (void) close(net);
867fdad9c93SAxel Dörfler #ifdef AUTHENTICATION
868fdad9c93SAxel Dörfler #if defined(NO_LOGIN_F) && defined(LOGIN_R)
869fdad9c93SAxel Dörfler /*
870fdad9c93SAxel Dörfler * Leave the pty open so that we can write out the rlogin
871fdad9c93SAxel Dörfler * protocol for /bin/login, if the authentication works.
872fdad9c93SAxel Dörfler */
873fdad9c93SAxel Dörfler #else
874fdad9c93SAxel Dörfler if (pty > 2) {
875fdad9c93SAxel Dörfler (void) close(pty);
876fdad9c93SAxel Dörfler pty = -1;
877fdad9c93SAxel Dörfler }
878fdad9c93SAxel Dörfler #endif
879fdad9c93SAxel Dörfler #endif /* AUTHENTICATION */
880fdad9c93SAxel Dörfler }
881fdad9c93SAxel Dörfler
882fdad9c93SAxel Dörfler #ifndef O_NOCTTY
883fdad9c93SAxel Dörfler #define O_NOCTTY 0
884fdad9c93SAxel Dörfler #endif
885fdad9c93SAxel Dörfler /*
886fdad9c93SAxel Dörfler * Open the specified slave side of the pty,
887fdad9c93SAxel Dörfler * making sure that we have a clean tty.
888fdad9c93SAxel Dörfler */
889fdad9c93SAxel Dörfler int
cleanopen(char * li)890fdad9c93SAxel Dörfler cleanopen(char *li)
891fdad9c93SAxel Dörfler {
892fdad9c93SAxel Dörfler int t;
893fdad9c93SAxel Dörfler
894fdad9c93SAxel Dörfler /*
895fdad9c93SAxel Dörfler * Make sure that other people can't open the
896fdad9c93SAxel Dörfler * slave side of the connection.
897fdad9c93SAxel Dörfler */
898fdad9c93SAxel Dörfler (void) chown(li, 0, 0);
899fdad9c93SAxel Dörfler (void) chmod(li, 0600);
900fdad9c93SAxel Dörfler
901bc3955feSIngo Weinhold #if (!defined(__BEOS__) && !defined(__HAIKU__))
902fdad9c93SAxel Dörfler (void) revoke(li);
903fdad9c93SAxel Dörfler #endif
904fdad9c93SAxel Dörfler
905fdad9c93SAxel Dörfler t = open(line, O_RDWR|O_NOCTTY);
906fdad9c93SAxel Dörfler
907fdad9c93SAxel Dörfler if (t < 0)
908fdad9c93SAxel Dörfler return(-1);
909fdad9c93SAxel Dörfler
910fdad9c93SAxel Dörfler return(t);
911fdad9c93SAxel Dörfler }
912fdad9c93SAxel Dörfler
913fdad9c93SAxel Dörfler /*
914fdad9c93SAxel Dörfler * startslave(host)
915fdad9c93SAxel Dörfler *
916fdad9c93SAxel Dörfler * Given a hostname, do whatever
917fdad9c93SAxel Dörfler * is necessary to startup the login process on the slave side of the pty.
918fdad9c93SAxel Dörfler */
919fdad9c93SAxel Dörfler
920fdad9c93SAxel Dörfler /* ARGSUSED */
921fdad9c93SAxel Dörfler void
startslave(char * host,int autologin,char * autoname)922fdad9c93SAxel Dörfler startslave(char *host, int autologin, char *autoname)
923fdad9c93SAxel Dörfler {
924fdad9c93SAxel Dörfler int i;
925fdad9c93SAxel Dörfler
926fdad9c93SAxel Dörfler #ifdef AUTHENTICATION
927fdad9c93SAxel Dörfler if (!autoname || !autoname[0])
928fdad9c93SAxel Dörfler autologin = 0;
929fdad9c93SAxel Dörfler
930fdad9c93SAxel Dörfler if (autologin < auth_level) {
931fdad9c93SAxel Dörfler fatal(net, "Authorization failed");
932fdad9c93SAxel Dörfler exit(1);
933fdad9c93SAxel Dörfler }
934fdad9c93SAxel Dörfler #endif
935fdad9c93SAxel Dörfler
936fdad9c93SAxel Dörfler
937fdad9c93SAxel Dörfler if ((i = fork()) < 0)
938fdad9c93SAxel Dörfler fatalperror(net, "fork");
939fdad9c93SAxel Dörfler if (i) {
940fdad9c93SAxel Dörfler } else {
941fdad9c93SAxel Dörfler getptyslave();
942fdad9c93SAxel Dörfler start_login(host, autologin, autoname);
943fdad9c93SAxel Dörfler /*NOTREACHED*/
944fdad9c93SAxel Dörfler }
945fdad9c93SAxel Dörfler }
946fdad9c93SAxel Dörfler
947fdad9c93SAxel Dörfler void
init_env(void)948fdad9c93SAxel Dörfler init_env(void)
949fdad9c93SAxel Dörfler {
950fdad9c93SAxel Dörfler char **envp;
951fdad9c93SAxel Dörfler
952fdad9c93SAxel Dörfler envp = envinit;
953fdad9c93SAxel Dörfler if ((*envp = getenv("TZ")))
954fdad9c93SAxel Dörfler *envp++ -= 3;
955fdad9c93SAxel Dörfler *envp = 0;
956fdad9c93SAxel Dörfler environ = envinit;
957fdad9c93SAxel Dörfler }
958fdad9c93SAxel Dörfler
959fdad9c93SAxel Dörfler
960fdad9c93SAxel Dörfler /*
961fdad9c93SAxel Dörfler * start_login(host)
962fdad9c93SAxel Dörfler *
963fdad9c93SAxel Dörfler * Assuming that we are now running as a child processes, this
964fdad9c93SAxel Dörfler * function will turn us into the login process.
965fdad9c93SAxel Dörfler */
966fdad9c93SAxel Dörfler
967fdad9c93SAxel Dörfler #ifndef AUTHENTICATION
968fdad9c93SAxel Dörfler #define undef1 __unused
969fdad9c93SAxel Dörfler #else
970fdad9c93SAxel Dörfler #define undef1
971fdad9c93SAxel Dörfler #endif
972fdad9c93SAxel Dörfler
973fdad9c93SAxel Dörfler void
start_login(char * host undef1,int autologin undef1,char * name undef1)974fdad9c93SAxel Dörfler start_login(char *host undef1, int autologin undef1, char *name undef1)
975fdad9c93SAxel Dörfler {
976fdad9c93SAxel Dörfler char **argv;
977*6b99b206SAugustin Cavalier char *user;
978*6b99b206SAugustin Cavalier
979*6b99b206SAugustin Cavalier user = getenv("USER");
980*6b99b206SAugustin Cavalier user = (user != NULL) ? strdup(user) : NULL;
981fdad9c93SAxel Dörfler
982fdad9c93SAxel Dörfler scrub_env();
983fdad9c93SAxel Dörfler
984fdad9c93SAxel Dörfler /*
985fdad9c93SAxel Dörfler * -h : pass on name of host.
986fdad9c93SAxel Dörfler * WARNING: -h is accepted by login if and only if
987fdad9c93SAxel Dörfler * getuid() == 0.
988fdad9c93SAxel Dörfler * -p : don't clobber the environment (so terminal type stays set).
989fdad9c93SAxel Dörfler *
990fdad9c93SAxel Dörfler * -f : force this login, he has already been authenticated
991fdad9c93SAxel Dörfler */
992fdad9c93SAxel Dörfler argv = addarg(0, "login");
993fdad9c93SAxel Dörfler
994fdad9c93SAxel Dörfler #if !defined(NO_LOGIN_H)
995fdad9c93SAxel Dörfler #ifdef AUTHENTICATION
996fdad9c93SAxel Dörfler # if defined(NO_LOGIN_F) && defined(LOGIN_R)
997fdad9c93SAxel Dörfler /*
998fdad9c93SAxel Dörfler * Don't add the "-h host" option if we are going
999fdad9c93SAxel Dörfler * to be adding the "-r host" option down below...
1000fdad9c93SAxel Dörfler */
1001fdad9c93SAxel Dörfler if ((auth_level < 0) || (autologin != AUTH_VALID))
1002fdad9c93SAxel Dörfler # endif
1003*6b99b206SAugustin Cavalier #endif /* AUTHENTICATION */
1004fdad9c93SAxel Dörfler {
1005fdad9c93SAxel Dörfler argv = addarg(argv, "-h");
1006fdad9c93SAxel Dörfler argv = addarg(argv, host);
1007fdad9c93SAxel Dörfler }
1008fdad9c93SAxel Dörfler #endif
1009fdad9c93SAxel Dörfler #if !defined(NO_LOGIN_P)
1010fdad9c93SAxel Dörfler argv = addarg(argv, "-p");
1011fdad9c93SAxel Dörfler #endif
1012fdad9c93SAxel Dörfler #ifdef LINEMODE
1013fdad9c93SAxel Dörfler /*
1014fdad9c93SAxel Dörfler * Set the environment variable "LINEMODE" to either
1015fdad9c93SAxel Dörfler * "real" or "kludge" if we are operating in either
1016fdad9c93SAxel Dörfler * real or kludge linemode.
1017fdad9c93SAxel Dörfler */
1018fdad9c93SAxel Dörfler if (lmodetype == REAL_LINEMODE)
1019fdad9c93SAxel Dörfler setenv("LINEMODE", "real", 1);
1020fdad9c93SAxel Dörfler # ifdef KLUDGELINEMODE
1021fdad9c93SAxel Dörfler else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK)
1022fdad9c93SAxel Dörfler setenv("LINEMODE", "kludge", 1);
1023fdad9c93SAxel Dörfler # endif
1024fdad9c93SAxel Dörfler #endif
1025fdad9c93SAxel Dörfler #ifdef BFTPDAEMON
1026fdad9c93SAxel Dörfler /*
1027fdad9c93SAxel Dörfler * Are we working as the bftp daemon? If so, then ask login
1028fdad9c93SAxel Dörfler * to start bftp instead of shell.
1029fdad9c93SAxel Dörfler */
1030fdad9c93SAxel Dörfler if (bftpd) {
1031fdad9c93SAxel Dörfler argv = addarg(argv, "-e");
1032fdad9c93SAxel Dörfler argv = addarg(argv, BFTPPATH);
1033fdad9c93SAxel Dörfler } else
1034fdad9c93SAxel Dörfler #endif
1035fdad9c93SAxel Dörfler #ifdef AUTHENTICATION
1036fdad9c93SAxel Dörfler if (auth_level >= 0 && autologin == AUTH_VALID) {
1037fdad9c93SAxel Dörfler # if !defined(NO_LOGIN_F)
1038fdad9c93SAxel Dörfler argv = addarg(argv, "-f");
1039fdad9c93SAxel Dörfler argv = addarg(argv, "--");
1040fdad9c93SAxel Dörfler argv = addarg(argv, name);
1041fdad9c93SAxel Dörfler # else
1042fdad9c93SAxel Dörfler # if defined(LOGIN_R)
1043fdad9c93SAxel Dörfler /*
1044fdad9c93SAxel Dörfler * We don't have support for "login -f", but we
1045fdad9c93SAxel Dörfler * can fool /bin/login into thinking that we are
1046fdad9c93SAxel Dörfler * rlogind, and allow us to log in without a
1047fdad9c93SAxel Dörfler * password. The rlogin protocol expects
1048fdad9c93SAxel Dörfler * local-user\0remote-user\0term/speed\0
1049fdad9c93SAxel Dörfler */
1050fdad9c93SAxel Dörfler
1051fdad9c93SAxel Dörfler if (pty > 2) {
1052fdad9c93SAxel Dörfler char *cp;
1053fdad9c93SAxel Dörfler char speed[128];
1054fdad9c93SAxel Dörfler int isecho, israw, xpty, len;
1055fdad9c93SAxel Dörfler extern int def_rspeed;
1056fdad9c93SAxel Dörfler # ifndef LOGIN_HOST
1057fdad9c93SAxel Dörfler /*
1058fdad9c93SAxel Dörfler * Tell login that we are coming from "localhost".
1059fdad9c93SAxel Dörfler * If we passed in the real host name, then the
1060fdad9c93SAxel Dörfler * user would have to allow .rhost access from
1061fdad9c93SAxel Dörfler * every machine that they want authenticated
1062fdad9c93SAxel Dörfler * access to work from, which sort of defeats
1063fdad9c93SAxel Dörfler * the purpose of an authenticated login...
1064fdad9c93SAxel Dörfler * So, we tell login that the session is coming
1065fdad9c93SAxel Dörfler * from "localhost", and the user will only have
1066fdad9c93SAxel Dörfler * to have "localhost" in their .rhost file.
1067fdad9c93SAxel Dörfler */
1068fdad9c93SAxel Dörfler # define LOGIN_HOST "localhost"
1069fdad9c93SAxel Dörfler # endif
1070fdad9c93SAxel Dörfler argv = addarg(argv, "-r");
1071fdad9c93SAxel Dörfler argv = addarg(argv, LOGIN_HOST);
1072fdad9c93SAxel Dörfler
1073fdad9c93SAxel Dörfler xpty = pty;
1074fdad9c93SAxel Dörfler pty = 0;
1075fdad9c93SAxel Dörfler init_termbuf();
1076fdad9c93SAxel Dörfler isecho = tty_isecho();
1077fdad9c93SAxel Dörfler israw = tty_israw();
1078fdad9c93SAxel Dörfler if (isecho || !israw) {
1079fdad9c93SAxel Dörfler tty_setecho(0); /* Turn off echo */
1080fdad9c93SAxel Dörfler tty_setraw(1); /* Turn on raw */
1081fdad9c93SAxel Dörfler set_termbuf();
1082fdad9c93SAxel Dörfler }
1083fdad9c93SAxel Dörfler len = strlen(name)+1;
1084fdad9c93SAxel Dörfler write(xpty, name, len);
1085fdad9c93SAxel Dörfler write(xpty, name, len);
1086fdad9c93SAxel Dörfler snprintf(speed, sizeof(speed),
1087fdad9c93SAxel Dörfler "%s/%d", (cp = getenv("TERM")) ? cp : "",
1088fdad9c93SAxel Dörfler (def_rspeed > 0) ? def_rspeed : 9600);
1089fdad9c93SAxel Dörfler len = strlen(speed)+1;
1090fdad9c93SAxel Dörfler write(xpty, speed, len);
1091fdad9c93SAxel Dörfler
1092fdad9c93SAxel Dörfler if (isecho || !israw) {
1093fdad9c93SAxel Dörfler init_termbuf();
1094fdad9c93SAxel Dörfler tty_setecho(isecho);
1095fdad9c93SAxel Dörfler tty_setraw(israw);
1096fdad9c93SAxel Dörfler set_termbuf();
1097fdad9c93SAxel Dörfler if (!israw) {
1098fdad9c93SAxel Dörfler /*
1099fdad9c93SAxel Dörfler * Write a newline to ensure
1100fdad9c93SAxel Dörfler * that login will be able to
1101fdad9c93SAxel Dörfler * read the line...
1102fdad9c93SAxel Dörfler */
1103fdad9c93SAxel Dörfler write(xpty, "\n", 1);
1104fdad9c93SAxel Dörfler }
1105fdad9c93SAxel Dörfler }
1106fdad9c93SAxel Dörfler pty = xpty;
1107fdad9c93SAxel Dörfler }
1108fdad9c93SAxel Dörfler # else
1109fdad9c93SAxel Dörfler argv = addarg(argv, "--");
1110fdad9c93SAxel Dörfler argv = addarg(argv, name);
1111fdad9c93SAxel Dörfler # endif
1112fdad9c93SAxel Dörfler # endif
1113fdad9c93SAxel Dörfler } else
1114fdad9c93SAxel Dörfler #endif
1115*6b99b206SAugustin Cavalier if (user != NULL) {
1116fdad9c93SAxel Dörfler argv = addarg(argv, "--");
1117*6b99b206SAugustin Cavalier argv = addarg(argv, user);
1118fdad9c93SAxel Dörfler #if defined(LOGIN_ARGS) && defined(NO_LOGIN_P)
1119fdad9c93SAxel Dörfler {
1120fdad9c93SAxel Dörfler char **cpp;
1121fdad9c93SAxel Dörfler for (cpp = environ; *cpp; cpp++)
1122fdad9c93SAxel Dörfler argv = addarg(argv, *cpp);
1123fdad9c93SAxel Dörfler }
1124fdad9c93SAxel Dörfler #endif
1125fdad9c93SAxel Dörfler }
1126fdad9c93SAxel Dörfler #ifdef AUTHENTICATION
1127fdad9c93SAxel Dörfler #if defined(NO_LOGIN_F) && defined(LOGIN_R)
1128fdad9c93SAxel Dörfler if (pty > 2)
1129fdad9c93SAxel Dörfler close(pty);
1130fdad9c93SAxel Dörfler #endif
1131fdad9c93SAxel Dörfler #endif /* AUTHENTICATION */
1132fdad9c93SAxel Dörfler closelog();
1133fdad9c93SAxel Dörfler
1134*6b99b206SAugustin Cavalier if (user != NULL)
1135*6b99b206SAugustin Cavalier free(user);
1136*6b99b206SAugustin Cavalier
1137fdad9c93SAxel Dörfler if (altlogin == NULL) {
1138fdad9c93SAxel Dörfler altlogin = _PATH_LOGIN;
1139fdad9c93SAxel Dörfler }
1140fdad9c93SAxel Dörfler execv(altlogin, argv);
1141fdad9c93SAxel Dörfler
1142fdad9c93SAxel Dörfler syslog(LOG_ERR, "%s: %m", altlogin);
1143fdad9c93SAxel Dörfler fatalperror(net, altlogin);
1144fdad9c93SAxel Dörfler /*NOTREACHED*/
1145fdad9c93SAxel Dörfler }
1146fdad9c93SAxel Dörfler
1147fdad9c93SAxel Dörfler static char **
addarg(char ** argv,const char * val)1148fdad9c93SAxel Dörfler addarg(char **argv, const char *val)
1149fdad9c93SAxel Dörfler {
1150fdad9c93SAxel Dörfler char **cpp;
1151fdad9c93SAxel Dörfler
1152fdad9c93SAxel Dörfler if (argv == NULL) {
1153fdad9c93SAxel Dörfler /*
1154fdad9c93SAxel Dörfler * 10 entries, a leading length, and a null
1155fdad9c93SAxel Dörfler */
1156fdad9c93SAxel Dörfler argv = (char **)malloc(sizeof(*argv) * 12);
1157fdad9c93SAxel Dörfler if (argv == NULL)
1158*6b99b206SAugustin Cavalier fatal(net, "failure allocating argument space");
1159fdad9c93SAxel Dörfler *argv++ = (char *)10;
1160fdad9c93SAxel Dörfler *argv = (char *)0;
1161fdad9c93SAxel Dörfler }
1162fdad9c93SAxel Dörfler for (cpp = argv; *cpp; cpp++)
1163fdad9c93SAxel Dörfler ;
1164fdad9c93SAxel Dörfler if (cpp == &argv[(long)argv[-1]]) {
1165fdad9c93SAxel Dörfler --argv;
1166fdad9c93SAxel Dörfler *argv = (char *)((long)(*argv) + 10);
1167fdad9c93SAxel Dörfler argv = (char **)realloc(argv, sizeof(*argv)*((long)(*argv) + 2));
1168fdad9c93SAxel Dörfler if (argv == NULL)
1169*6b99b206SAugustin Cavalier fatal(net, "failure allocating argument space");
1170fdad9c93SAxel Dörfler argv++;
1171fdad9c93SAxel Dörfler cpp = &argv[(long)argv[-1] - 10];
1172fdad9c93SAxel Dörfler }
1173*6b99b206SAugustin Cavalier if ((*cpp++ = strdup(val)) == NULL)
1174*6b99b206SAugustin Cavalier fatal(net, "failure allocating argument space");
1175fdad9c93SAxel Dörfler *cpp = 0;
1176fdad9c93SAxel Dörfler return(argv);
1177fdad9c93SAxel Dörfler }
1178fdad9c93SAxel Dörfler
1179fdad9c93SAxel Dörfler /*
1180fdad9c93SAxel Dörfler * scrub_env()
1181fdad9c93SAxel Dörfler *
1182fdad9c93SAxel Dörfler * We only accept the environment variables listed below.
1183fdad9c93SAxel Dörfler */
1184fdad9c93SAxel Dörfler void
scrub_env(void)1185fdad9c93SAxel Dörfler scrub_env(void)
1186fdad9c93SAxel Dörfler {
1187fdad9c93SAxel Dörfler static const char *rej[] = {
1188fdad9c93SAxel Dörfler "TERMCAP=/",
1189fdad9c93SAxel Dörfler NULL
1190fdad9c93SAxel Dörfler };
1191fdad9c93SAxel Dörfler
1192fdad9c93SAxel Dörfler static const char *acc[] = {
1193fdad9c93SAxel Dörfler "XAUTH=", "XAUTHORITY=", "DISPLAY=",
1194fdad9c93SAxel Dörfler "TERM=",
1195fdad9c93SAxel Dörfler "EDITOR=",
1196fdad9c93SAxel Dörfler "PAGER=",
1197fdad9c93SAxel Dörfler "LOGNAME=",
1198fdad9c93SAxel Dörfler "POSIXLY_CORRECT=",
1199fdad9c93SAxel Dörfler "PRINTER=",
1200fdad9c93SAxel Dörfler NULL
1201fdad9c93SAxel Dörfler };
1202fdad9c93SAxel Dörfler
1203fdad9c93SAxel Dörfler char **cpp, **cpp2;
1204fdad9c93SAxel Dörfler const char **p;
1205*6b99b206SAugustin Cavalier char ** new_environ;
1206*6b99b206SAugustin Cavalier size_t count;
1207fdad9c93SAxel Dörfler
1208*6b99b206SAugustin Cavalier /* Allocate space for scrubbed environment. */
1209*6b99b206SAugustin Cavalier for (count = 1, cpp = environ; *cpp; count++, cpp++)
1210*6b99b206SAugustin Cavalier continue;
1211*6b99b206SAugustin Cavalier if ((new_environ = malloc(count * sizeof(char *))) == NULL) {
1212*6b99b206SAugustin Cavalier environ = NULL;
1213*6b99b206SAugustin Cavalier return;
1214*6b99b206SAugustin Cavalier }
1215*6b99b206SAugustin Cavalier
1216*6b99b206SAugustin Cavalier for (cpp2 = new_environ, cpp = environ; *cpp; cpp++) {
1217fdad9c93SAxel Dörfler int reject_it = 0;
1218fdad9c93SAxel Dörfler
1219fdad9c93SAxel Dörfler for(p = rej; *p; p++)
1220fdad9c93SAxel Dörfler if(strncmp(*cpp, *p, strlen(*p)) == 0) {
1221fdad9c93SAxel Dörfler reject_it = 1;
1222fdad9c93SAxel Dörfler break;
1223fdad9c93SAxel Dörfler }
1224fdad9c93SAxel Dörfler if (reject_it)
1225fdad9c93SAxel Dörfler continue;
1226fdad9c93SAxel Dörfler
1227fdad9c93SAxel Dörfler for(p = acc; *p; p++)
1228fdad9c93SAxel Dörfler if(strncmp(*cpp, *p, strlen(*p)) == 0)
1229fdad9c93SAxel Dörfler break;
1230*6b99b206SAugustin Cavalier if(*p != NULL) {
1231*6b99b206SAugustin Cavalier if ((*cpp2++ = strdup(*cpp)) == NULL) {
1232*6b99b206SAugustin Cavalier environ = new_environ;
1233*6b99b206SAugustin Cavalier return;
1234*6b99b206SAugustin Cavalier }
1235*6b99b206SAugustin Cavalier }
1236fdad9c93SAxel Dörfler }
1237fdad9c93SAxel Dörfler *cpp2 = NULL;
1238*6b99b206SAugustin Cavalier environ = new_environ;
1239fdad9c93SAxel Dörfler }
1240fdad9c93SAxel Dörfler
1241fdad9c93SAxel Dörfler /*
1242fdad9c93SAxel Dörfler * cleanup()
1243fdad9c93SAxel Dörfler *
1244fdad9c93SAxel Dörfler * This is the routine to call when we are all through, to
1245fdad9c93SAxel Dörfler * clean up anything that needs to be cleaned up.
1246fdad9c93SAxel Dörfler */
1247fdad9c93SAxel Dörfler /* ARGSUSED */
1248fdad9c93SAxel Dörfler void
cleanup(int sig __unused)1249fdad9c93SAxel Dörfler cleanup(int sig __unused)
1250fdad9c93SAxel Dörfler {
1251fdad9c93SAxel Dörfler
1252*6b99b206SAugustin Cavalier (void) shutdown(net, SHUT_RDWR);
1253fdad9c93SAxel Dörfler _exit(1);
1254fdad9c93SAxel Dörfler }
1255