122387Sdist /* 222387Sdist * Copyright (c) 1983 Regents of the University of California. 334360Sbostic * All rights reserved. 434360Sbostic * 542673Sbostic * %sccs.include.redist.c% 622387Sdist */ 722387Sdist 816362Skarels #ifndef lint 9*50743Smarc static char sccsid[] = "@(#)announce.c 5.11 (Berkeley) 08/01/91"; 1034360Sbostic #endif /* not lint */ 1116341Skarels 1226839Smckusick #include <sys/types.h> 1350742Smarc #include <sys/uio.h> 1416341Skarels #include <sys/stat.h> 1516341Skarels #include <sys/time.h> 1616341Skarels #include <sys/wait.h> 1746683Sbostic #include <sys/socket.h> 1846683Sbostic #include <protocols/talkd.h> 1946683Sbostic #include <sgtty.h> 2016341Skarels #include <errno.h> 2126839Smckusick #include <syslog.h> 2246683Sbostic #include <unistd.h> 2346683Sbostic #include <stdio.h> 2446683Sbostic #include <string.h> 2537991Sbostic #include <paths.h> 2616341Skarels 2746683Sbostic extern char hostname[]; 2816341Skarels 2916341Skarels /* 3026839Smckusick * Announce an invitation to talk. 3116341Skarels */ 3216341Skarels 3316362Skarels /* 3416362Skarels * See if the user is accepting messages. If so, announce that 3516362Skarels * a talk is requested. 3616362Skarels */ 3750742Smarc announce(request, remote_machine) 3816362Skarels CTL_MSG *request; 3916362Skarels char *remote_machine; 4016341Skarels { 4116362Skarels char full_tty[32]; 4216362Skarels FILE *tf; 4316362Skarels struct stat stbuf; 4416341Skarels 4537991Sbostic (void)sprintf(full_tty, "%s/%s", _PATH_DEV, request->r_tty); 4650742Smarc if (stat(full_tty, &stbuf) < 0 || (stbuf.st_mode&020) == 0) 4716362Skarels return (PERMISSION_DENIED); 4850742Smarc return (print_mesg(request->r_tty, tf, request, remote_machine)); 4916341Skarels } 5016341Skarels 5116341Skarels #define max(a,b) ( (a) > (b) ? (a) : (b) ) 5216341Skarels #define N_LINES 5 5316341Skarels #define N_CHARS 120 5416341Skarels 5516362Skarels /* 5616362Skarels * Build a block of characters containing the message. 5716362Skarels * It is sent blank filled and in a single block to 5816362Skarels * try to keep the message in one piece if the recipient 5916362Skarels * in in vi at the time 6016362Skarels */ 6150742Smarc print_mesg(tty, tf, request, remote_machine) 6250742Smarc char *tty; 6316362Skarels FILE *tf; 6416362Skarels CTL_MSG *request; 6516362Skarels char *remote_machine; 6616341Skarels { 6716362Skarels struct timeval clock; 6816362Skarels struct timezone zone; 6916362Skarels struct tm *localtime(); 7016362Skarels struct tm *localclock; 7150742Smarc struct iovec iovec; 7216362Skarels char line_buf[N_LINES][N_CHARS]; 7316362Skarels int sizes[N_LINES]; 7416362Skarels char big_buf[N_LINES*N_CHARS]; 7550742Smarc char *bptr, *lptr, *ttymsg(); 7616362Skarels int i, j, max_size; 7716341Skarels 7816362Skarels i = 0; 7916362Skarels max_size = 0; 8016362Skarels gettimeofday(&clock, &zone); 8116362Skarels localclock = localtime( &clock.tv_sec ); 8232465Sbostic (void)sprintf(line_buf[i], " "); 8316362Skarels sizes[i] = strlen(line_buf[i]); 8416362Skarels max_size = max(max_size, sizes[i]); 8516362Skarels i++; 8632465Sbostic (void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...", 8716341Skarels hostname, localclock->tm_hour , localclock->tm_min ); 8816362Skarels sizes[i] = strlen(line_buf[i]); 8916362Skarels max_size = max(max_size, sizes[i]); 9016362Skarels i++; 9132465Sbostic (void)sprintf(line_buf[i], "talk: connection requested by %s@%s.", 9216341Skarels request->l_name, remote_machine); 9316362Skarels sizes[i] = strlen(line_buf[i]); 9416362Skarels max_size = max(max_size, sizes[i]); 9516362Skarels i++; 9632465Sbostic (void)sprintf(line_buf[i], "talk: respond with: talk %s@%s", 9716341Skarels request->l_name, remote_machine); 9816362Skarels sizes[i] = strlen(line_buf[i]); 9916362Skarels max_size = max(max_size, sizes[i]); 10016362Skarels i++; 10132465Sbostic (void)sprintf(line_buf[i], " "); 10216362Skarels sizes[i] = strlen(line_buf[i]); 10316362Skarels max_size = max(max_size, sizes[i]); 10416362Skarels i++; 10516362Skarels bptr = big_buf; 10626839Smckusick *bptr++ = ''; /* send something to wake them up */ 10726839Smckusick *bptr++ = '\r'; /* add a \r in case of raw mode */ 10826839Smckusick *bptr++ = '\n'; 10916362Skarels for (i = 0; i < N_LINES; i++) { 11016362Skarels /* copy the line into the big buffer */ 11116362Skarels lptr = line_buf[i]; 11216362Skarels while (*lptr != '\0') 11316362Skarels *(bptr++) = *(lptr++); 11416362Skarels /* pad out the rest of the lines with blanks */ 11516362Skarels for (j = sizes[i]; j < max_size + 2; j++) 11616362Skarels *(bptr++) = ' '; 11716362Skarels *(bptr++) = '\r'; /* add a \r in case of raw mode */ 11816362Skarels *(bptr++) = '\n'; 11916362Skarels } 12016362Skarels *bptr = '\0'; 12150742Smarc iovec.iov_base = big_buf; 12250742Smarc iovec.iov_len = bptr - big_buf; 123*50743Smarc /* 124*50743Smarc * we choose a timeout of RING_WAIT-5 seconds so that we don't 125*50743Smarc * stack up processes trying to write messages to a tty 126*50743Smarc * that is permanently blocked. 127*50743Smarc */ 128*50743Smarc if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL) 12950742Smarc return (FAILED); 13050742Smarc 13150742Smarc return (SUCCESS); 13216341Skarels } 133