1 /* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)announce.c 8.2 (Berkeley) 01/07/94"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 #include <sys/uio.h> 14 #include <sys/stat.h> 15 #include <sys/time.h> 16 #include <sys/wait.h> 17 #include <sys/socket.h> 18 #include <protocols/talkd.h> 19 #include <sgtty.h> 20 #include <errno.h> 21 #include <syslog.h> 22 #include <unistd.h> 23 #include <stdio.h> 24 #include <string.h> 25 #include <paths.h> 26 27 extern char hostname[]; 28 29 /* 30 * Announce an invitation to talk. 31 */ 32 33 /* 34 * See if the user is accepting messages. If so, announce that 35 * a talk is requested. 36 */ 37 announce(request, remote_machine) 38 CTL_MSG *request; 39 char *remote_machine; 40 { 41 char full_tty[32]; 42 FILE *tf; 43 struct stat stbuf; 44 45 (void)snprintf(full_tty, sizeof(full_tty), 46 "%s%s", _PATH_DEV, request->r_tty); 47 if (stat(full_tty, &stbuf) < 0 || (stbuf.st_mode&020) == 0) 48 return (PERMISSION_DENIED); 49 return (print_mesg(request->r_tty, tf, request, remote_machine)); 50 } 51 52 #define max(a,b) ( (a) > (b) ? (a) : (b) ) 53 #define N_LINES 5 54 #define N_CHARS 120 55 56 /* 57 * Build a block of characters containing the message. 58 * It is sent blank filled and in a single block to 59 * try to keep the message in one piece if the recipient 60 * in in vi at the time 61 */ 62 print_mesg(tty, tf, request, remote_machine) 63 char *tty; 64 FILE *tf; 65 CTL_MSG *request; 66 char *remote_machine; 67 { 68 struct timeval clock; 69 struct timezone zone; 70 struct tm *localtime(); 71 struct tm *localclock; 72 struct iovec iovec; 73 char line_buf[N_LINES][N_CHARS]; 74 int sizes[N_LINES]; 75 char big_buf[N_LINES*N_CHARS]; 76 char *bptr, *lptr, *ttymsg(); 77 int i, j, max_size; 78 79 i = 0; 80 max_size = 0; 81 gettimeofday(&clock, &zone); 82 localclock = localtime( &clock.tv_sec ); 83 (void)sprintf(line_buf[i], " "); 84 sizes[i] = strlen(line_buf[i]); 85 max_size = max(max_size, sizes[i]); 86 i++; 87 (void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...", 88 hostname, localclock->tm_hour , localclock->tm_min ); 89 sizes[i] = strlen(line_buf[i]); 90 max_size = max(max_size, sizes[i]); 91 i++; 92 (void)sprintf(line_buf[i], "talk: connection requested by %s@%s", 93 request->l_name, remote_machine); 94 sizes[i] = strlen(line_buf[i]); 95 max_size = max(max_size, sizes[i]); 96 i++; 97 (void)sprintf(line_buf[i], "talk: respond with: talk %s@%s", 98 request->l_name, remote_machine); 99 sizes[i] = strlen(line_buf[i]); 100 max_size = max(max_size, sizes[i]); 101 i++; 102 (void)sprintf(line_buf[i], " "); 103 sizes[i] = strlen(line_buf[i]); 104 max_size = max(max_size, sizes[i]); 105 i++; 106 bptr = big_buf; 107 *bptr++ = ''; /* send something to wake them up */ 108 *bptr++ = '\r'; /* add a \r in case of raw mode */ 109 *bptr++ = '\n'; 110 for (i = 0; i < N_LINES; i++) { 111 /* copy the line into the big buffer */ 112 lptr = line_buf[i]; 113 while (*lptr != '\0') 114 *(bptr++) = *(lptr++); 115 /* pad out the rest of the lines with blanks */ 116 for (j = sizes[i]; j < max_size + 2; j++) 117 *(bptr++) = ' '; 118 *(bptr++) = '\r'; /* add a \r in case of raw mode */ 119 *(bptr++) = '\n'; 120 } 121 *bptr = '\0'; 122 iovec.iov_base = big_buf; 123 iovec.iov_len = bptr - big_buf; 124 /* 125 * we choose a timeout of RING_WAIT-5 seconds so that we don't 126 * stack up processes trying to write messages to a tty 127 * that is permanently blocked. 128 */ 129 if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL) 130 return (FAILED); 131 132 return (SUCCESS); 133 } 134