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 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 #include "libmail.h" 31 #include <sys/types.h> 32 #include <sys/stat.h> 33 #include <fcntl.h> 34 #include <utmpx.h> 35 #include <syslog.h> 36 #if !defined(__cplusplus) && !defined(c_plusplus) 37 typedef void (*SIG_PF) (int); 38 #endif 39 #include <unistd.h> 40 #include <signal.h> 41 42 static void 43 catcher(int arg __unused) 44 { 45 /* do nothing, but allow the write() to break */ 46 } 47 48 void 49 notify(char *user, char *msg, int check_mesg_y, char *etcdir) 50 { 51 /* search the utmp file for this user */ 52 SIG_PF old; 53 unsigned int oldalarm; 54 struct utmpx utmpx, *putmpx = &utmpx; 55 56 setutxent(); 57 58 /* grab the tty name */ 59 while ((putmpx = getutxent()) != NULL) { 60 if (strncmp(user, utmpx.ut_name, 61 sizeof (utmpx.ut_name)) == 0) { 62 char tty[sizeof (utmpx.ut_line)+1]; 63 char dev[MAXFILENAME]; 64 FILE *port; 65 size_t i; 66 int fd; 67 68 for (i = 0; i < sizeof (utmpx.ut_line); i++) 69 tty[i] = utmpx.ut_line[i]; 70 tty[i] = '\0'; 71 72 /* stick /dev/ in front */ 73 (void) sprintf(dev, "%s/dev/%s", etcdir, tty); 74 75 /* break out if write() to the tty hangs */ 76 old = (SIG_PF)signal(SIGALRM, catcher); 77 oldalarm = alarm(300); 78 79 /* check if device is really a tty */ 80 if ((fd = open(dev, O_WRONLY|O_NOCTTY)) == -1) { 81 (void) fprintf(stderr, 82 "Cannot open %s.\n", dev); 83 continue; 84 } else { 85 if (!isatty(fd)) { 86 (void) fprintf(stderr, "%s in utmpx is " 87 "not a tty\n", tty); 88 openlog("mail", 0, LOG_AUTH); 89 syslog(LOG_CRIT, "%s in utmp is " 90 "not a tty\n", tty); 91 closelog(); 92 (void) close(fd); 93 continue; 94 } 95 } 96 (void) close(fd); 97 98 /* write to the tty */ 99 port = fopen(dev, "w"); 100 if (port != 0) { 101 (void) fprintf(port, "\r\n%s\r\n", msg); 102 (void) fclose(port); 103 } 104 105 /* clean up our alarm */ 106 (void) alarm(0); 107 (void) signal(SIGALRM, old); 108 (void) alarm(oldalarm); 109 } 110 } 111 endutxent(); 112 } 113