xref: /illumos-gate/usr/src/lib/libmail/common/notifyu.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 /*
27  * Copyright (c) 1998-1999 by Sun Microsystems, Inc.
28  * All rights reserved.
29  */
30 #pragma ident	"%Z%%M%	%I%	%E% SMI" 	/* SVr4.0 1.4	*/
31 /*LINTLIBRARY*/
32 
33 #include "synonyms.h"
34 #include "libmail.h"
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <utmpx.h>
39 #include <syslog.h>
40 #if !defined(__cplusplus) && !defined(c_plusplus)
41 typedef void (*SIG_PF) (int);
42 #endif
43 #include <unistd.h>
44 #include <signal.h>
45 
46 static SIG_PF catcher(void);
47 
48 static SIG_PF catcher(void)
49 {
50 	/* do nothing, but allow the write() to break */
51 	return (0);
52 }
53 
54 void
55 notify(char *user, char *msg, int check_mesg_y, char *etcdir)
56 {
57 	/* search the utmp file for this user */
58 	SIG_PF old;
59 	unsigned int oldalarm;
60 	struct utmpx utmpx, *putmpx = &utmpx;
61 
62 	setutxent();
63 
64 	/* grab the tty name */
65 	while ((putmpx = getutxent()) != NULL) {
66 		if (strncmp(user, utmpx.ut_name,
67 		    sizeof (utmpx.ut_name)) == 0) {
68 			char tty[sizeof (utmpx.ut_line)+1];
69 			char dev[MAXFILENAME];
70 			FILE *port;
71 			size_t i;
72 			int fd;
73 
74 			for (i = 0; i < sizeof (utmpx.ut_line); i++)
75 				tty[i] = utmpx.ut_line[i];
76 			tty[i] = '\0';
77 
78 			/* stick /dev/ in front */
79 			(void) sprintf(dev, "%s/dev/%s", etcdir, tty);
80 
81 			/* break out if write() to the tty hangs */
82 			old = (SIG_PF)signal(SIGALRM, (SIG_PF)catcher);
83 			oldalarm = alarm(300);
84 
85 			/* check if device is really a tty */
86 			if ((fd = open(dev, O_WRONLY|O_NOCTTY)) == -1) {
87 				(void) fprintf(stderr,
88 				    "Cannot open %s.\n", dev);
89 				continue;
90 			} else {
91 				if (!isatty(fd)) {
92 					(void) fprintf(stderr, "%s in utmpx is "
93 					    "not a tty\n", tty);
94 					openlog("mail", 0, LOG_AUTH);
95 					syslog(LOG_CRIT, "%s in utmp is "
96 					    "not a tty\n", tty);
97 					closelog();
98 					(void) close(fd);
99 					continue;
100 				}
101 			}
102 			(void) close(fd);
103 
104 			/* write to the tty */
105 			port = fopen(dev, "w");
106 			if (port != 0) {
107 				(void) fprintf(port, "\r\n%s\r\n", msg);
108 				(void) fclose(port);
109 			}
110 
111 			/* clean up our alarm */
112 			(void) alarm(0);
113 			(void) signal(SIGALRM, old);
114 			(void) alarm(oldalarm);
115 		}
116 	}
117 	endutxent();
118 }
119