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 63 extern char myhostname[]; 64 extern char progname[]; 65 66 67 static void openfail(int); 68 static void eof(void); 69 static void setsignals(void (*)()); 70 71 static FILE *fp; /* File pointer for receipient's terminal */ 72 static char *rterm; /* Pointer to receipient's terminal */ 73 74 int 75 warn_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 164 static void 165 setsignals(catch) 166 void (*catch)(); 167 { 168 signal(SIGHUP, catch); 169 signal(SIGINT, catch); 170 signal(SIGQUIT, catch); 171 signal(SIGTERM, catch); 172 } 173 static void 174 openfail(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 187 static void 188 eof(void) 189 { 190 extern FILE *fp; 191 192 (void) fprintf(fp, "%s\r\n", gettext("<EOT>")); 193 } 194