kwarnd_send.c revision faebf79429f1b4c0f9334ac0f880806edf891f1f
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28#include	<ctype.h>
29#include	<string.h>
30#include	<stdio.h>
31#include	<signal.h>
32#include	<sys/wait.h>
33#include	<sys/types.h>
34#include	<sys/stat.h>
35#include	<stdlib.h>
36#include	<unistd.h>
37#include	<time.h>
38#include	<utmpx.h>
39#include	<pwd.h>
40#include	<fcntl.h>
41#include	<stdarg.h>
42#include	<locale.h>
43#include	<stdlib.h>
44#include	<limits.h>
45#include	<wctype.h>
46#include	<errno.h>
47#include	<syslog.h>
48
49#define		TRUE	1
50#define		FALSE	0
51#define		FAILURE	-1
52/*
53 *	DATE-TIME format
54 *  %a	abbreviated weekday name
55 *  %b  abbreviated month name
56 *  %e  day of month
57 *  %H  hour - 24 hour clock
58 *  %M  minute
59 *  %S  second
60 *
61 */
62
63extern char myhostname[];
64extern char progname[];
65
66
67static void openfail(int);
68static void eof(void);
69static void setsignals(void (*)());
70
71static FILE	*fp;	/* File pointer for receipient's terminal */
72static char *rterm; /* Pointer to receipient's terminal */
73
74int
75warn_send(char *receipient, char *msg)
76{
77	register struct utmpx *ubuf;
78	static char rterminal[] = "/dev/\0 2345678901";
79	extern FILE *fp;
80	time_t tod;
81	char time_buf[40];
82	register int bad = 0;
83	char	*rcp1, *rcp2, *rcp3;
84
85	(void) setlocale(LC_ALL, "");
86#if !defined(TEXT_DOMAIN)
87#define	TEXT_DOMAIN "SYS_TEST"
88#endif
89	(void) textdomain(TEXT_DOMAIN);
90
91
92/*	Set "rterm" to location where receipient's terminal will go.	*/
93
94	rterm = &rterminal[sizeof ("/dev/") - 1];
95
96/*
97 * strip any realm or instance from principal so we can match against unix
98 * userid.
99 */
100	rcp1 = strdup(receipient);
101	rcp2 = strtok(rcp1, "@");
102	rcp3 = strtok(rcp2, "/");
103
104/*
105 *	Scan through the "utmpx" file for the
106 *	entry for the person we want to send to.
107 */
108
109	setutxent();
110	while ((ubuf = getutxent()) != NULL) {
111		if (ubuf->ut_type == USER_PROCESS) {
112			if (strncmp(rcp3, ubuf->ut_user,
113				sizeof (ubuf->ut_user)) == 0) {
114				strncpy(rterm, &ubuf->ut_line[0],
115					sizeof (ubuf->ut_line)+1);
116
117/*	Try to open up the line to the receipient's terminal.		*/
118
119				signal(SIGALRM, openfail);
120				alarm(5);
121				fp = fopen(&rterminal[0], "w");
122				alarm(0);
123
124/*	Catch signals SIGHUP, SIGINT, SIGQUIT, and SIGTERM, and send	*/
125/*	<EOT> message to receipient.			*/
126
127				setsignals(eof);
128
129/*	Get the time of day, convert it to a string and throw away the	*/
130/*	year information at the end of the string.			*/
131
132				time(&tod);
133				cftime(time_buf, "%c", &tod);
134				(void) fprintf(fp, gettext(
135	    "\r\n\007\007\007\tMessage from %s@%s [ %s ] ...\r\n"),
136					    progname, myhostname, time_buf);
137				sleep(1);
138				fprintf(fp, gettext("\r\nMessage to %s"), msg);
139				fflush(fp);
140
141/*	Since "end of file" received, send <EOT> message to receipient.	*/
142
143				eof();
144				fclose(fp);
145			}
146		}
147	}
148	free(rcp1);
149
150
151/*	Did we find a place to talk to?  If we were looking for a */
152/*	specific spot and didn't find it, complain and log it. */
153
154	if (*rterm == '\0')
155		if (bad > 0) {
156			(void) syslog(LOG_ERR, gettext("no place to send.\n"));
157			return (1);
158		}
159
160	endutxent();
161	return (0);
162}
163
164static void
165setsignals(catch)
166void (*catch)();
167{
168	signal(SIGHUP, catch);
169	signal(SIGINT, catch);
170	signal(SIGQUIT, catch);
171	signal(SIGTERM, catch);
172}
173static void
174openfail(int i)
175{
176	extern char *rterm;
177#if 0
178	(void) fprintf(stderr,
179		gettext("Timeout trying to open line(%s).\n"),
180			rterm);
181#endif
182	syslog(LOG_ERR, gettext("Timeout trying to open line(%s).\n"),
183			rterm ? rterm : "");
184	exit(1);
185}
186
187static void
188eof(void)
189{
190	extern FILE *fp;
191
192	(void) fprintf(fp, "%s\r\n", gettext("<EOT>"));
193}
194