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