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 #include <ctype.h> 27 #include <string.h> 28 #include <stdio.h> 29 #include <signal.h> 30 #include <sys/wait.h> 31 #include <sys/types.h> 32 #include <sys/stat.h> 33 #include <stdlib.h> 34 #include <unistd.h> 35 #include <time.h> 36 #include <utmpx.h> 37 #include <pwd.h> 38 #include <fcntl.h> 39 #include <stdarg.h> 40 #include <locale.h> 41 #include <stdlib.h> 42 #include <limits.h> 43 #include <wctype.h> 44 #include <errno.h> 45 #include <syslog.h> 46 47 #define TRUE 1 48 #define FALSE 0 49 #define FAILURE -1 50 /* 51 * DATE-TIME format 52 * %a abbreviated weekday name 53 * %b abbreviated month name 54 * %e day of month 55 * %H hour - 24 hour clock 56 * %M minute 57 * %S second 58 * 59 */ 60 61 extern char myhostname[]; 62 extern char progname[]; 63 64 65 static void openfail(int); 66 static void eof(void); 67 static void setsignals(void (*)()); 68 69 static FILE *fp; /* File pointer for receipient's terminal */ 70 static char *rterm; /* Pointer to receipient's terminal */ 71 72 int 73 warn_send(char *receipient, char *msg) 74 { 75 register struct utmpx *ubuf; 76 static char rterminal[] = "/dev/\0 2345678901"; 77 extern FILE *fp; 78 time_t tod; 79 char time_buf[40]; 80 register int bad = 0; 81 char *rcp1, *rcp2, *rcp3; 82 83 (void) setlocale(LC_ALL, ""); 84 #if !defined(TEXT_DOMAIN) 85 #define TEXT_DOMAIN "SYS_TEST" 86 #endif 87 (void) textdomain(TEXT_DOMAIN); 88 89 90 /* Set "rterm" to location where receipient's terminal will go. */ 91 92 rterm = &rterminal[sizeof ("/dev/") - 1]; 93 94 /* 95 * strip any realm or instance from principal so we can match against unix 96 * userid. 97 */ 98 rcp1 = strdup(receipient); 99 rcp2 = strtok(rcp1, "@"); 100 rcp3 = strtok(rcp2, "/"); 101 102 /* 103 * Scan through the "utmpx" file for the 104 * entry for the person we want to send to. 105 */ 106 107 setutxent(); 108 while ((ubuf = getutxent()) != NULL) { 109 if (ubuf->ut_type == USER_PROCESS) { 110 if (strncmp(rcp3, ubuf->ut_user, 111 sizeof (ubuf->ut_user)) == 0) { 112 strncpy(rterm, &ubuf->ut_line[0], 113 sizeof (ubuf->ut_line)+1); 114 115 /* Try to open up the line to the receipient's terminal. */ 116 117 signal(SIGALRM, openfail); 118 alarm(5); 119 fp = fopen(&rterminal[0], "w"); 120 alarm(0); 121 122 /* Catch signals SIGHUP, SIGINT, SIGQUIT, and SIGTERM, and send */ 123 /* <EOT> message to receipient. */ 124 125 setsignals(eof); 126 127 /* Get the time of day, convert it to a string and throw away the */ 128 /* year information at the end of the string. */ 129 130 time(&tod); 131 cftime(time_buf, "%c", &tod); 132 (void) fprintf(fp, gettext( 133 "\r\n\007\007\007\tMessage from %s@%s [ %s ] ...\r\n"), 134 progname, myhostname, time_buf); 135 sleep(1); 136 fprintf(fp, gettext("\r\nMessage to %s"), msg); 137 fflush(fp); 138 139 /* Since "end of file" received, send <EOT> message to receipient. */ 140 141 eof(); 142 fclose(fp); 143 } 144 } 145 } 146 free(rcp1); 147 148 149 /* Did we find a place to talk to? If we were looking for a */ 150 /* specific spot and didn't find it, complain and log it. */ 151 152 if (*rterm == '\0') 153 if (bad > 0) { 154 (void) syslog(LOG_ERR, gettext("no place to send.\n")); 155 return (1); 156 } 157 158 endutxent(); 159 return (0); 160 } 161 162 static void 163 setsignals(catch) 164 void (*catch)(); 165 { 166 signal(SIGHUP, catch); 167 signal(SIGINT, catch); 168 signal(SIGQUIT, catch); 169 signal(SIGTERM, catch); 170 } 171 static void 172 openfail(int i) 173 { 174 extern char *rterm; 175 #if 0 176 (void) fprintf(stderr, 177 gettext("Timeout trying to open line(%s).\n"), 178 rterm); 179 #endif 180 syslog(LOG_ERR, gettext("Timeout trying to open line(%s).\n"), 181 rterm ? rterm : ""); 182 exit(1); 183 } 184 185 static void 186 eof(void) 187 { 188 extern FILE *fp; 189 190 (void) fprintf(fp, "%s\r\n", gettext("<EOT>")); 191 } 192