xref: /csrg-svn/usr.bin/wall/ttymsg.c (revision 39422)
1*39422Sbostic /*
2*39422Sbostic  * Copyright (c) 1989 The Regents of the University of California.
3*39422Sbostic  * All rights reserved.
4*39422Sbostic  *
5*39422Sbostic  * Redistribution and use in source and binary forms are permitted
6*39422Sbostic  * provided that the above copyright notice and this paragraph are
7*39422Sbostic  * duplicated in all such forms and that any documentation,
8*39422Sbostic  * advertising materials, and other materials related to such
9*39422Sbostic  * distribution and use acknowledge that the software was developed
10*39422Sbostic  * by the University of California, Berkeley.  The name of the
11*39422Sbostic  * University may not be used to endorse or promote products derived
12*39422Sbostic  * from this software without specific prior written permission.
13*39422Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*39422Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*39422Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16*39422Sbostic  */
17*39422Sbostic 
18*39422Sbostic #ifndef lint
19*39422Sbostic static char sccsid[] = "@(#)ttymsg.c	5.1 (Berkeley) 10/28/89";
20*39422Sbostic #endif /* not lint */
21*39422Sbostic 
22*39422Sbostic #include <sys/types.h>
23*39422Sbostic #include <sys/uio.h>
24*39422Sbostic #include <sys/file.h>
25*39422Sbostic #include <dirent.h>
26*39422Sbostic #include <errno.h>
27*39422Sbostic #include <paths.h>
28*39422Sbostic 
29*39422Sbostic /*
30*39422Sbostic  * display the contents of a uio structure on a terminal.  Used by
31*39422Sbostic  * wall(1) and syslogd(8).
32*39422Sbostic  */
33*39422Sbostic char *
34*39422Sbostic ttymsg(iov, iovcnt, line, nonblock)
35*39422Sbostic 	struct iovec *iov;
36*39422Sbostic 	int iovcnt;
37*39422Sbostic 	char *line;
38*39422Sbostic 	int nonblock;
39*39422Sbostic {
40*39422Sbostic 	extern int errno;
41*39422Sbostic 	static char device[MAXNAMLEN] = _PATH_DEV;
42*39422Sbostic 	static char errbuf[1024];
43*39422Sbostic 	register int cnt, fd, total, wret;
44*39422Sbostic 	char *strcpy(), *strerror();
45*39422Sbostic 
46*39422Sbostic 	/*
47*39422Sbostic 	 * open will fail on slip lines or exclusive-use lines
48*39422Sbostic 	 * if not running as root; not an error.
49*39422Sbostic 	 */
50*39422Sbostic 	(void)strcpy(device + sizeof(_PATH_DEV) - 1, line);
51*39422Sbostic 	if ((fd = open(device, O_WRONLY|(nonblock ? O_NONBLOCK : 0), 0)) < 0)
52*39422Sbostic 		if (errno != EBUSY && errno != EPERM)
53*39422Sbostic 			goto bad;
54*39422Sbostic 		else
55*39422Sbostic 			return(NULL);
56*39422Sbostic 
57*39422Sbostic 	for (cnt = total = 0; cnt < iovcnt; ++cnt)
58*39422Sbostic 		total += iov[cnt].iov_len;
59*39422Sbostic 
60*39422Sbostic 	for (;;)
61*39422Sbostic 		if ((wret = writev(fd, iov, iovcnt)) < 0)
62*39422Sbostic 			if (errno == EWOULDBLOCK) {
63*39422Sbostic 				if (fork())
64*39422Sbostic 					goto bad;
65*39422Sbostic 				/* wait at most 5 minutes */
66*39422Sbostic 				(void)alarm((u_int)(60 * 5));
67*39422Sbostic 				(void)ttymsg(iov, iovcnt, line, 0);
68*39422Sbostic 				exit(0);
69*39422Sbostic 			} else {
70*39422Sbostic 				/*
71*39422Sbostic 				 * we get ENODEV on a slip line if we're
72*39422Sbostic 				 * running as root
73*39422Sbostic 				 */
74*39422Sbostic 				if (errno == ENODEV)
75*39422Sbostic 					break;
76*39422Sbostic bad:				(void)sprintf(errbuf, "%s: %s\n", device,
77*39422Sbostic 				    strerror(errno));
78*39422Sbostic 				(void)close(fd);
79*39422Sbostic 				return(errbuf);
80*39422Sbostic 			}
81*39422Sbostic 		else if (wret) {
82*39422Sbostic 			if (wret == total)
83*39422Sbostic 				break;
84*39422Sbostic 			for (cnt = 0; wret >= iov->iov_len; ++cnt) {
85*39422Sbostic 				wret -= iov->iov_len;
86*39422Sbostic 				++iov;
87*39422Sbostic 				--iovcnt;
88*39422Sbostic 			}
89*39422Sbostic 			if (wret) {
90*39422Sbostic 				iov->iov_base += wret;
91*39422Sbostic 				iov->iov_len -= wret;
92*39422Sbostic 			}
93*39422Sbostic 		}
94*39422Sbostic 	(void)close(fd);
95*39422Sbostic 	return(NULL);
96*39422Sbostic }
97