xref: /minix3/usr.bin/login/common.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /*	$NetBSD: common.c,v 1.6 2012/05/19 00:02:44 christos Exp $	*/
2a2d13726SBen Gras 
3a2d13726SBen Gras /*-
4a2d13726SBen Gras  * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994
5a2d13726SBen Gras  *	The Regents of the University of California.  All rights reserved.
6a2d13726SBen Gras  *
7a2d13726SBen Gras  * Redistribution and use in source and binary forms, with or without
8a2d13726SBen Gras  * modification, are permitted provided that the following conditions
9a2d13726SBen Gras  * are met:
10a2d13726SBen Gras  * 1. Redistributions of source code must retain the above copyright
11a2d13726SBen Gras  *    notice, this list of conditions and the following disclaimer.
12a2d13726SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
13a2d13726SBen Gras  *    notice, this list of conditions and the following disclaimer in the
14a2d13726SBen Gras  *    documentation and/or other materials provided with the distribution.
15a2d13726SBen Gras  * 3. Neither the name of the University nor the names of its contributors
16a2d13726SBen Gras  *    may be used to endorse or promote products derived from this software
17a2d13726SBen Gras  *    without specific prior written permission.
18a2d13726SBen Gras  *
19a2d13726SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20a2d13726SBen Gras  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21a2d13726SBen Gras  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22a2d13726SBen Gras  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23a2d13726SBen Gras  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24a2d13726SBen Gras  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25a2d13726SBen Gras  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26a2d13726SBen Gras  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27a2d13726SBen Gras  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28a2d13726SBen Gras  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29a2d13726SBen Gras  * SUCH DAMAGE.
30a2d13726SBen Gras  */
31a2d13726SBen Gras #include <sys/cdefs.h>
32*84d9c625SLionel Sambuc __RCSID("$NetBSD: common.c,v 1.6 2012/05/19 00:02:44 christos Exp $");
33a2d13726SBen Gras 
34a2d13726SBen Gras #include <sys/types.h>
35a2d13726SBen Gras #include <sys/param.h>
36a2d13726SBen Gras #include <sys/socket.h>
37a2d13726SBen Gras #include <stdio.h>
38a2d13726SBen Gras #include <string.h>
39a2d13726SBen Gras #include <unistd.h>
40a2d13726SBen Gras #include <stdlib.h>
41a2d13726SBen Gras #include <syslog.h>
42a2d13726SBen Gras #include <fcntl.h>
43a2d13726SBen Gras #include <ttyent.h>
44a2d13726SBen Gras #include <setjmp.h>
45a2d13726SBen Gras #include <time.h>
46a2d13726SBen Gras #include <pwd.h>
47a2d13726SBen Gras #include <err.h>
48a2d13726SBen Gras #include <vis.h>
49a2d13726SBen Gras #include <util.h>
50a2d13726SBen Gras 
51a2d13726SBen Gras #include "pathnames.h"
52a2d13726SBen Gras #include "common.h"
53a2d13726SBen Gras 
54a2d13726SBen Gras #if defined(KERBEROS5)
55a2d13726SBen Gras #define	NBUFSIZ		(MAXLOGNAME + 1 + 5)	/* .root suffix */
56a2d13726SBen Gras #else
57a2d13726SBen Gras #define	NBUFSIZ		(MAXLOGNAME + 1)
58a2d13726SBen Gras #endif
59a2d13726SBen Gras 
60a2d13726SBen Gras #ifdef SUPPORT_UTMP
61a2d13726SBen Gras #include <utmp.h>
62a2d13726SBen Gras static void	 doutmp(void);
63a2d13726SBen Gras static void	 dolastlog(int);
64a2d13726SBen Gras #endif
65a2d13726SBen Gras #ifdef SUPPORT_UTMPX
66a2d13726SBen Gras #include <utmpx.h>
67a2d13726SBen Gras static void	 doutmpx(void);
68a2d13726SBen Gras static void	 dolastlogx(int);
69a2d13726SBen Gras #endif
70a2d13726SBen Gras 
71a2d13726SBen Gras /*
72a2d13726SBen Gras  * This bounds the time given to login.  Not a define so it can
73a2d13726SBen Gras  * be patched on machines where it's too small.
74a2d13726SBen Gras  */
75a2d13726SBen Gras u_int	timeout = 300;
76a2d13726SBen Gras 
77a2d13726SBen Gras void	 decode_ss(const char *);
78a2d13726SBen Gras struct	passwd *pwd;
79a2d13726SBen Gras int	failures, have_ss;
80*84d9c625SLionel Sambuc char	term[64], *envinit[1], *hostname, *tty, *nested;
81*84d9c625SLionel Sambuc const char *username;
82a2d13726SBen Gras struct timeval now;
83a2d13726SBen Gras struct sockaddr_storage ss;
84a2d13726SBen Gras 
85*84d9c625SLionel Sambuc char *
trimloginname(char * u)86*84d9c625SLionel Sambuc trimloginname(char *u)
87*84d9c625SLionel Sambuc {
88*84d9c625SLionel Sambuc 	if (strlen(u) > MAXLOGNAME)
89*84d9c625SLionel Sambuc 		u[MAXLOGNAME] = '\0';
90*84d9c625SLionel Sambuc 	return u;
91*84d9c625SLionel Sambuc }
92*84d9c625SLionel Sambuc 
93*84d9c625SLionel Sambuc char *
getloginname(void)94a2d13726SBen Gras getloginname(void)
95a2d13726SBen Gras {
96a2d13726SBen Gras 	int ch;
97a2d13726SBen Gras 	char *p;
98a2d13726SBen Gras 	static char nbuf[NBUFSIZ];
99a2d13726SBen Gras 
100a2d13726SBen Gras 	for (;;) {
101a2d13726SBen Gras 		(void)printf("login: ");
102a2d13726SBen Gras 		for (p = nbuf; (ch = getchar()) != '\n'; ) {
103a2d13726SBen Gras 			if (ch == EOF) {
104a2d13726SBen Gras 				badlogin(username);
105a2d13726SBen Gras 				exit(EXIT_FAILURE);
106a2d13726SBen Gras 			}
107a2d13726SBen Gras 			if (p < nbuf + (NBUFSIZ - 1))
108a2d13726SBen Gras 				*p++ = ch;
109a2d13726SBen Gras 		}
110a2d13726SBen Gras 		if (p > nbuf) {
111a2d13726SBen Gras 			if (nbuf[0] == '-')
112a2d13726SBen Gras 				(void)fprintf(stderr,
113a2d13726SBen Gras 				    "login names may not start with '-'.\n");
114a2d13726SBen Gras 			else {
115a2d13726SBen Gras 				*p = '\0';
116*84d9c625SLionel Sambuc 				return nbuf;
117a2d13726SBen Gras 			}
118a2d13726SBen Gras 		}
119a2d13726SBen Gras 	}
120a2d13726SBen Gras }
121a2d13726SBen Gras 
122a2d13726SBen Gras int
rootterm(char * ttyn)123a2d13726SBen Gras rootterm(char *ttyn)
124a2d13726SBen Gras {
125a2d13726SBen Gras 	struct ttyent *t;
126a2d13726SBen Gras 
127a2d13726SBen Gras 	return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
128a2d13726SBen Gras }
129a2d13726SBen Gras 
130a2d13726SBen Gras static jmp_buf motdinterrupt;
131a2d13726SBen Gras 
132a2d13726SBen Gras void
motd(const char * fname)133*84d9c625SLionel Sambuc motd(const char *fname)
134a2d13726SBen Gras {
135a2d13726SBen Gras 	int fd, nchars;
136a2d13726SBen Gras 	sig_t oldint;
137a2d13726SBen Gras 	char tbuf[8192];
138a2d13726SBen Gras 
139a2d13726SBen Gras 	if ((fd = open(fname ? fname : _PATH_MOTDFILE, O_RDONLY, 0)) < 0)
140a2d13726SBen Gras 		return;
141a2d13726SBen Gras 	oldint = signal(SIGINT, sigint);
142a2d13726SBen Gras 	if (setjmp(motdinterrupt) == 0)
143a2d13726SBen Gras 		while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
144a2d13726SBen Gras 			(void)write(fileno(stdout), tbuf, nchars);
145a2d13726SBen Gras 	(void)signal(SIGINT, oldint);
146a2d13726SBen Gras 	(void)close(fd);
147a2d13726SBen Gras }
148a2d13726SBen Gras 
149a2d13726SBen Gras /* ARGSUSED */
150*84d9c625SLionel Sambuc void __dead
sigint(int signo)151a2d13726SBen Gras sigint(int signo)
152a2d13726SBen Gras {
153a2d13726SBen Gras 
154a2d13726SBen Gras 	longjmp(motdinterrupt, 1);
155a2d13726SBen Gras }
156a2d13726SBen Gras 
157a2d13726SBen Gras /* ARGSUSED */
158*84d9c625SLionel Sambuc void __dead
timedout(int signo)159a2d13726SBen Gras timedout(int signo)
160a2d13726SBen Gras {
161a2d13726SBen Gras 
162a2d13726SBen Gras 	(void)fprintf(stderr, "Login timed out after %d seconds\n", timeout);
163a2d13726SBen Gras 	exit(EXIT_FAILURE);
164a2d13726SBen Gras }
165a2d13726SBen Gras 
166a2d13726SBen Gras void
update_db(int quietlog,int rootlogin,int fflag)167a2d13726SBen Gras update_db(int quietlog, int rootlogin, int fflag)
168a2d13726SBen Gras {
169a2d13726SBen Gras 	struct sockaddr_storage ass;
170a2d13726SBen Gras 	char assbuf[1024];
171a2d13726SBen Gras 	socklen_t alen;
172a2d13726SBen Gras 	const char *hname;
173a2d13726SBen Gras 	int remote;
174a2d13726SBen Gras 
175a2d13726SBen Gras 	hname = (hostname == NULL) ? "?" : hostname;
176a2d13726SBen Gras 	if (getpeername(STDIN_FILENO, (struct sockaddr *)&ass, &alen) != -1) {
177a2d13726SBen Gras 		(void)sockaddr_snprintf(assbuf,
178a2d13726SBen Gras 		    sizeof(assbuf), "%A (%a)", (void *)&ass);
179a2d13726SBen Gras 		if (have_ss) {
180a2d13726SBen Gras 			char ssbuf[1024];
181a2d13726SBen Gras 			(void)sockaddr_snprintf(ssbuf,
182a2d13726SBen Gras 			    sizeof(ssbuf), "%A(%a)", (void *)&ss);
183a2d13726SBen Gras 			 if (memcmp(&ass, &ss, alen) != 0)
184a2d13726SBen Gras 				syslog(LOG_NOTICE,
185a2d13726SBen Gras 				    "login %s on tty %s address mismatch "
186a2d13726SBen Gras 				    "passed %s != actual %s", username, tty,
187a2d13726SBen Gras 				    ssbuf, assbuf);
188a2d13726SBen Gras 		} else
189a2d13726SBen Gras 			ss = ass;
190a2d13726SBen Gras 		remote = 1;
191a2d13726SBen Gras 	} else if (have_ss) {
192a2d13726SBen Gras 		(void)sockaddr_snprintf(assbuf,
193a2d13726SBen Gras 		    sizeof(assbuf), "%A(%a)", (void *)&ss);
194a2d13726SBen Gras 		remote = 1;
195a2d13726SBen Gras 	} else if (hostname) {
196a2d13726SBen Gras 		(void)snprintf(assbuf, sizeof(assbuf), "? ?");
197a2d13726SBen Gras 		remote = 1;
198a2d13726SBen Gras 	} else
199a2d13726SBen Gras 		remote = 0;
200a2d13726SBen Gras 
201a2d13726SBen Gras 	/* If fflag is on, assume caller/authenticator has logged root login. */
202a2d13726SBen Gras 	if (rootlogin && fflag == 0) {
203a2d13726SBen Gras 		if (remote)
204a2d13726SBen Gras 			syslog(LOG_NOTICE, "ROOT LOGIN (%s) on tty %s from %s /"
205a2d13726SBen Gras 			    " %s", username, tty, hname, assbuf);
206a2d13726SBen Gras 		else
207a2d13726SBen Gras 			syslog(LOG_NOTICE, "ROOT LOGIN (%s) on tty %s",
208a2d13726SBen Gras 			    username, tty);
209a2d13726SBen Gras 	} else if (nested != NULL) {
210a2d13726SBen Gras 		if (remote)
211a2d13726SBen Gras 			syslog(LOG_NOTICE, "%s to %s on tty %s from %s / "
212a2d13726SBen Gras 			    "%s", nested, pwd->pw_name, tty, hname, assbuf);
213a2d13726SBen Gras 		else
214a2d13726SBen Gras 			syslog(LOG_NOTICE, "%s to %s on tty %s", nested,
215a2d13726SBen Gras 			    pwd->pw_name, tty);
216a2d13726SBen Gras 	} else {
217a2d13726SBen Gras 		if (remote)
218a2d13726SBen Gras 			syslog(LOG_NOTICE, "%s on tty %s from %s / %s",
219a2d13726SBen Gras 			    pwd->pw_name, tty, hname, assbuf);
220a2d13726SBen Gras 		else
221a2d13726SBen Gras 			syslog(LOG_NOTICE, "%s on tty %s",
222a2d13726SBen Gras 			    pwd->pw_name, tty);
223a2d13726SBen Gras 	}
224a2d13726SBen Gras 	(void)gettimeofday(&now, NULL);
225a2d13726SBen Gras #ifdef SUPPORT_UTMPX
226a2d13726SBen Gras 	doutmpx();
227a2d13726SBen Gras 	dolastlogx(quietlog);
228a2d13726SBen Gras 	quietlog = 1;
229a2d13726SBen Gras #endif
230a2d13726SBen Gras #ifdef SUPPORT_UTMP
231a2d13726SBen Gras 	doutmp();
232a2d13726SBen Gras 	dolastlog(quietlog);
233a2d13726SBen Gras #endif
234a2d13726SBen Gras }
235a2d13726SBen Gras 
236a2d13726SBen Gras #ifdef SUPPORT_UTMPX
237a2d13726SBen Gras static void
doutmpx(void)238a2d13726SBen Gras doutmpx(void)
239a2d13726SBen Gras {
240a2d13726SBen Gras 	struct utmpx utmpx;
241a2d13726SBen Gras 	char *t;
242a2d13726SBen Gras 
243a2d13726SBen Gras 	memset((void *)&utmpx, 0, sizeof(utmpx));
244a2d13726SBen Gras 	utmpx.ut_tv = now;
245a2d13726SBen Gras 	(void)strncpy(utmpx.ut_name, username, sizeof(utmpx.ut_name));
246a2d13726SBen Gras 	if (hostname) {
247a2d13726SBen Gras 		(void)strncpy(utmpx.ut_host, hostname, sizeof(utmpx.ut_host));
248a2d13726SBen Gras 		utmpx.ut_ss = ss;
249a2d13726SBen Gras 	}
250a2d13726SBen Gras 	(void)strncpy(utmpx.ut_line, tty, sizeof(utmpx.ut_line));
251a2d13726SBen Gras 	utmpx.ut_type = USER_PROCESS;
252a2d13726SBen Gras 	utmpx.ut_pid = getpid();
253a2d13726SBen Gras 	t = tty + strlen(tty);
254*84d9c625SLionel Sambuc 	if ((size_t)(t - tty) >= sizeof(utmpx.ut_id)) {
255a2d13726SBen Gras 	    (void)strncpy(utmpx.ut_id, t - sizeof(utmpx.ut_id),
256a2d13726SBen Gras 		sizeof(utmpx.ut_id));
257a2d13726SBen Gras 	} else {
258a2d13726SBen Gras 	    (void)strncpy(utmpx.ut_id, tty, sizeof(utmpx.ut_id));
259a2d13726SBen Gras 	}
260a2d13726SBen Gras 	if (pututxline(&utmpx) == NULL)
261a2d13726SBen Gras 		syslog(LOG_NOTICE, "Cannot update utmpx: %m");
262a2d13726SBen Gras 	endutxent();
263a2d13726SBen Gras 	if (updwtmpx(_PATH_WTMPX, &utmpx) != 0)
264a2d13726SBen Gras 		syslog(LOG_NOTICE, "Cannot update wtmpx: %m");
265a2d13726SBen Gras }
266a2d13726SBen Gras 
267a2d13726SBen Gras static void
dolastlogx(int quiet)268a2d13726SBen Gras dolastlogx(int quiet)
269a2d13726SBen Gras {
270a2d13726SBen Gras 	struct lastlogx ll;
271a2d13726SBen Gras 	if (!quiet && getlastlogx(_PATH_LASTLOGX, pwd->pw_uid, &ll) != NULL) {
272a2d13726SBen Gras 		time_t t = (time_t)ll.ll_tv.tv_sec;
273a2d13726SBen Gras 		(void)printf("Last login: %.24s ", ctime(&t));
274a2d13726SBen Gras 		if (*ll.ll_host != '\0')
275a2d13726SBen Gras 			(void)printf("from %.*s ",
276a2d13726SBen Gras 			    (int)sizeof(ll.ll_host),
277a2d13726SBen Gras 			    ll.ll_host);
278a2d13726SBen Gras 		(void)printf("on %.*s\n",
279a2d13726SBen Gras 		    (int)sizeof(ll.ll_line),
280a2d13726SBen Gras 		    ll.ll_line);
281a2d13726SBen Gras 	}
282a2d13726SBen Gras 	ll.ll_tv = now;
283a2d13726SBen Gras 	(void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
284a2d13726SBen Gras 	if (hostname)
285a2d13726SBen Gras 		(void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
286a2d13726SBen Gras 	else
287a2d13726SBen Gras 		(void)memset(ll.ll_host, '\0', sizeof(ll.ll_host));
288a2d13726SBen Gras 	if (have_ss)
289a2d13726SBen Gras 		ll.ll_ss = ss;
290a2d13726SBen Gras 	else
291a2d13726SBen Gras 		(void)memset(&ll.ll_ss, 0, sizeof(ll.ll_ss));
292a2d13726SBen Gras 	if (updlastlogx(_PATH_LASTLOGX, pwd->pw_uid, &ll) != 0)
293a2d13726SBen Gras 		syslog(LOG_NOTICE, "Cannot update lastlogx: %m");
294a2d13726SBen Gras }
295a2d13726SBen Gras #endif
296a2d13726SBen Gras 
297a2d13726SBen Gras #ifdef SUPPORT_UTMP
298a2d13726SBen Gras static void
doutmp(void)299a2d13726SBen Gras doutmp(void)
300a2d13726SBen Gras {
301a2d13726SBen Gras 	struct utmp utmp;
302a2d13726SBen Gras 
303a2d13726SBen Gras 	(void)memset((void *)&utmp, 0, sizeof(utmp));
304a2d13726SBen Gras 	utmp.ut_time = now.tv_sec;
305a2d13726SBen Gras 	(void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
306a2d13726SBen Gras 	if (hostname)
307a2d13726SBen Gras 		(void)strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
308a2d13726SBen Gras 	(void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
309a2d13726SBen Gras 	login(&utmp);
310a2d13726SBen Gras }
311a2d13726SBen Gras 
312a2d13726SBen Gras static void
dolastlog(int quiet)313a2d13726SBen Gras dolastlog(int quiet)
314a2d13726SBen Gras {
315a2d13726SBen Gras 	struct lastlog ll;
316a2d13726SBen Gras 	int fd;
317a2d13726SBen Gras 
318a2d13726SBen Gras 	if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
319a2d13726SBen Gras 		(void)lseek(fd, (off_t)(pwd->pw_uid * sizeof(ll)), SEEK_SET);
320a2d13726SBen Gras 		if (!quiet) {
321a2d13726SBen Gras 			if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
322a2d13726SBen Gras 			    ll.ll_time != 0) {
323a2d13726SBen Gras 				(void)printf("Last login: %.24s ",
324a2d13726SBen Gras 				    ctime(&ll.ll_time));
325a2d13726SBen Gras 				if (*ll.ll_host != '\0')
326a2d13726SBen Gras 					(void)printf("from %.*s ",
327a2d13726SBen Gras 					    (int)sizeof(ll.ll_host),
328a2d13726SBen Gras 					    ll.ll_host);
329a2d13726SBen Gras 				(void)printf("on %.*s\n",
330a2d13726SBen Gras 				    (int)sizeof(ll.ll_line), ll.ll_line);
331a2d13726SBen Gras 			}
332a2d13726SBen Gras 			(void)lseek(fd, (off_t)(pwd->pw_uid * sizeof(ll)),
333a2d13726SBen Gras 			    SEEK_SET);
334a2d13726SBen Gras 		}
335a2d13726SBen Gras 		memset((void *)&ll, 0, sizeof(ll));
336a2d13726SBen Gras 		ll.ll_time = now.tv_sec;
337a2d13726SBen Gras 		(void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
338a2d13726SBen Gras 		if (hostname)
339a2d13726SBen Gras 			(void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
340a2d13726SBen Gras 		(void)write(fd, (char *)&ll, sizeof(ll));
341a2d13726SBen Gras 		(void)close(fd);
342a2d13726SBen Gras 	}
343a2d13726SBen Gras }
344a2d13726SBen Gras #endif
345a2d13726SBen Gras 
346a2d13726SBen Gras void
badlogin(const char * name)347a2d13726SBen Gras badlogin(const char *name)
348a2d13726SBen Gras {
349a2d13726SBen Gras 
350a2d13726SBen Gras 	if (failures == 0)
351a2d13726SBen Gras 		return;
352a2d13726SBen Gras 	if (hostname) {
353a2d13726SBen Gras 		syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s",
354a2d13726SBen Gras 		    failures, failures > 1 ? "S" : "", hostname);
355a2d13726SBen Gras 		syslog(LOG_AUTHPRIV|LOG_NOTICE,
356a2d13726SBen Gras 		    "%d LOGIN FAILURE%s FROM %s, %s",
357a2d13726SBen Gras 		    failures, failures > 1 ? "S" : "", hostname, name);
358a2d13726SBen Gras 	} else {
359a2d13726SBen Gras 		syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s",
360a2d13726SBen Gras 		    failures, failures > 1 ? "S" : "", tty);
361a2d13726SBen Gras 		syslog(LOG_AUTHPRIV|LOG_NOTICE,
362a2d13726SBen Gras 		    "%d LOGIN FAILURE%s ON %s, %s",
363a2d13726SBen Gras 		    failures, failures > 1 ? "S" : "", tty, name);
364a2d13726SBen Gras 	}
365a2d13726SBen Gras }
366a2d13726SBen Gras 
367a2d13726SBen Gras const char *
stypeof(const char * ttyid)368a2d13726SBen Gras stypeof(const char *ttyid)
369a2d13726SBen Gras {
370a2d13726SBen Gras 	struct ttyent *t;
371a2d13726SBen Gras 
372a2d13726SBen Gras 	return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : NULL);
373a2d13726SBen Gras }
374a2d13726SBen Gras 
375*84d9c625SLionel Sambuc void __dead
sleepexit(int eval)376a2d13726SBen Gras sleepexit(int eval)
377a2d13726SBen Gras {
378a2d13726SBen Gras 
379a2d13726SBen Gras 	(void)sleep(5);
380a2d13726SBen Gras 	exit(eval);
381a2d13726SBen Gras }
382a2d13726SBen Gras 
383a2d13726SBen Gras void
decode_ss(const char * arg)384a2d13726SBen Gras decode_ss(const char *arg)
385a2d13726SBen Gras {
386a2d13726SBen Gras 	struct sockaddr_storage *ssp;
387a2d13726SBen Gras 	size_t len = strlen(arg);
388a2d13726SBen Gras 
389a2d13726SBen Gras 	if (len > sizeof(*ssp) * 4 + 1 || len < sizeof(*ssp))
390a2d13726SBen Gras 		errx(EXIT_FAILURE, "Bad argument");
391a2d13726SBen Gras 
392a2d13726SBen Gras 	if ((ssp = malloc(len)) == NULL)
393a2d13726SBen Gras 		err(EXIT_FAILURE, NULL);
394a2d13726SBen Gras 
395a2d13726SBen Gras 	if (strunvis((char *)ssp, arg) != sizeof(*ssp))
396a2d13726SBen Gras 		errx(EXIT_FAILURE, "Decoding error");
397a2d13726SBen Gras 
398a2d13726SBen Gras 	(void)memcpy(&ss, ssp, sizeof(ss));
399a2d13726SBen Gras 	free(ssp);
400a2d13726SBen Gras 	have_ss = 1;
401a2d13726SBen Gras }
402