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