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.1 (Berkeley) 06/04/93"; 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)sprintf(full_tty, "%s/%s", _PATH_DEV, request->r_tty); 46 if (stat(full_tty, &stbuf) < 0 || (stbuf.st_mode&020) == 0) 47 return (PERMISSION_DENIED); 48 return (print_mesg(request->r_tty, tf, request, remote_machine)); 49 } 50 51 #define max(a,b) ( (a) > (b) ? (a) : (b) ) 52 #define N_LINES 5 53 #define N_CHARS 120 54 55 /* 56 * Build a block of characters containing the message. 57 * It is sent blank filled and in a single block to 58 * try to keep the message in one piece if the recipient 59 * in in vi at the time 60 */ 61 print_mesg(tty, tf, request, remote_machine) 62 char *tty; 63 FILE *tf; 64 CTL_MSG *request; 65 char *remote_machine; 66 { 67 struct timeval clock; 68 struct timezone zone; 69 struct tm *localtime(); 70 struct tm *localclock; 71 struct iovec iovec; 72 char line_buf[N_LINES][N_CHARS]; 73 int sizes[N_LINES]; 74 char big_buf[N_LINES*N_CHARS]; 75 char *bptr, *lptr, *ttymsg(); 76 int i, j, max_size; 77 78 i = 0; 79 max_size = 0; 80 gettimeofday(&clock, &zone); 81 localclock = localtime( &clock.tv_sec ); 82 (void)sprintf(line_buf[i], " "); 83 sizes[i] = strlen(line_buf[i]); 84 max_size = max(max_size, sizes[i]); 85 i++; 86 (void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...", 87 hostname, localclock->tm_hour , localclock->tm_min ); 88 sizes[i] = strlen(line_buf[i]); 89 max_size = max(max_size, sizes[i]); 90 i++; 91 (void)sprintf(line_buf[i], "talk: connection requested by %s@%s", 92 request->l_name, remote_machine); 93 sizes[i] = strlen(line_buf[i]); 94 max_size = max(max_size, sizes[i]); 95 i++; 96 (void)sprintf(line_buf[i], "talk: respond with: talk %s@%s", 97 request->l_name, remote_machine); 98 sizes[i] = strlen(line_buf[i]); 99 max_size = max(max_size, sizes[i]); 100 i++; 101 (void)sprintf(line_buf[i], " "); 102 sizes[i] = strlen(line_buf[i]); 103 max_size = max(max_size, sizes[i]); 104 i++; 105 bptr = big_buf; 106 *bptr++ = ''; /* send something to wake them up */ 107 *bptr++ = '\r'; /* add a \r in case of raw mode */ 108 *bptr++ = '\n'; 109 for (i = 0; i < N_LINES; i++) { 110 /* copy the line into the big buffer */ 111 lptr = line_buf[i]; 112 while (*lptr != '\0') 113 *(bptr++) = *(lptr++); 114 /* pad out the rest of the lines with blanks */ 115 for (j = sizes[i]; j < max_size + 2; j++) 116 *(bptr++) = ' '; 117 *(bptr++) = '\r'; /* add a \r in case of raw mode */ 118 *(bptr++) = '\n'; 119 } 120 *bptr = '\0'; 121 iovec.iov_base = big_buf; 122 iovec.iov_len = bptr - big_buf; 123 /* 124 * we choose a timeout of RING_WAIT-5 seconds so that we don't 125 * stack up processes trying to write messages to a tty 126 * that is permanently blocked. 127 */ 128 if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL) 129 return (FAILED); 130 131 return (SUCCESS); 132 } 133