xref: /csrg-svn/libexec/talkd/announce.c (revision 69071)
122387Sdist /*
261449Sbostic  * Copyright (c) 1983, 1993
361449Sbostic  *	The Regents of the University of California.  All rights reserved.
434360Sbostic  *
542673Sbostic  * %sccs.include.redist.c%
622387Sdist  */
722387Sdist 
816362Skarels #ifndef lint
9*69071Sbostic static char sccsid[] = "@(#)announce.c	8.3 (Berkeley) 04/28/95";
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>
25*69071Sbostic #include <vis.h>
2637991Sbostic #include <paths.h>
2716341Skarels 
2846683Sbostic extern char hostname[];
2916341Skarels 
3016341Skarels /*
3126839Smckusick  * Announce an invitation to talk.
3216341Skarels  */
3316341Skarels 
3416362Skarels /*
3516362Skarels  * See if the user is accepting messages. If so, announce that
3616362Skarels  * a talk is requested.
3716362Skarels  */
announce(request,remote_machine)3850742Smarc announce(request, remote_machine)
3916362Skarels 	CTL_MSG *request;
4016362Skarels 	char *remote_machine;
4116341Skarels {
4216362Skarels 	char full_tty[32];
4316362Skarels 	FILE *tf;
4416362Skarels 	struct stat stbuf;
4516341Skarels 
4665572Sbostic 	(void)snprintf(full_tty, sizeof(full_tty),
4765572Sbostic 	    "%s%s", _PATH_DEV, request->r_tty);
4850742Smarc 	if (stat(full_tty, &stbuf) < 0 || (stbuf.st_mode&020) == 0)
4916362Skarels 		return (PERMISSION_DENIED);
5050742Smarc 	return (print_mesg(request->r_tty, tf, request, remote_machine));
5116341Skarels }
5216341Skarels 
5316341Skarels #define max(a,b) ( (a) > (b) ? (a) : (b) )
5416341Skarels #define N_LINES 5
55*69071Sbostic #define N_CHARS 256
5616341Skarels 
5716362Skarels /*
5816362Skarels  * Build a block of characters containing the message.
5916362Skarels  * It is sent blank filled and in a single block to
6016362Skarels  * try to keep the message in one piece if the recipient
6116362Skarels  * in in vi at the time
6216362Skarels  */
print_mesg(tty,tf,request,remote_machine)6350742Smarc print_mesg(tty, tf, request, remote_machine)
6450742Smarc 	char *tty;
6516362Skarels 	FILE *tf;
6616362Skarels 	CTL_MSG *request;
6716362Skarels 	char *remote_machine;
6816341Skarels {
6916362Skarels 	struct timeval clock;
7016362Skarels 	struct timezone zone;
7116362Skarels 	struct tm *localtime();
7216362Skarels 	struct tm *localclock;
7350742Smarc 	struct iovec iovec;
7416362Skarels 	char line_buf[N_LINES][N_CHARS];
7516362Skarels 	int sizes[N_LINES];
7616362Skarels 	char big_buf[N_LINES*N_CHARS];
77*69071Sbostic 	char *bptr, *lptr, *vis_user;
7816362Skarels 	int i, j, max_size;
7916341Skarels 
8016362Skarels 	i = 0;
8116362Skarels 	max_size = 0;
8216362Skarels 	gettimeofday(&clock, &zone);
8316362Skarels 	localclock = localtime( &clock.tv_sec );
8432465Sbostic 	(void)sprintf(line_buf[i], " ");
8516362Skarels 	sizes[i] = strlen(line_buf[i]);
8616362Skarels 	max_size = max(max_size, sizes[i]);
8716362Skarels 	i++;
8832465Sbostic 	(void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...",
8916341Skarels 	hostname, localclock->tm_hour , localclock->tm_min );
9016362Skarels 	sizes[i] = strlen(line_buf[i]);
9116362Skarels 	max_size = max(max_size, sizes[i]);
9216362Skarels 	i++;
93*69071Sbostic 	vis_user = (char *) malloc(strlen(request->l_name) * 4 + 1);
94*69071Sbostic 	strvis(vis_user, request->l_name, VIS_CSTYLE);
9551581Sbostic 	(void)sprintf(line_buf[i], "talk: connection requested by %s@%s",
96*69071Sbostic 		vis_user, remote_machine);
9716362Skarels 	sizes[i] = strlen(line_buf[i]);
9816362Skarels 	max_size = max(max_size, sizes[i]);
9916362Skarels 	i++;
10032465Sbostic 	(void)sprintf(line_buf[i], "talk: respond with:  talk %s@%s",
101*69071Sbostic 		vis_user, remote_machine);
10216362Skarels 	sizes[i] = strlen(line_buf[i]);
10316362Skarels 	max_size = max(max_size, sizes[i]);
10416362Skarels 	i++;
10532465Sbostic 	(void)sprintf(line_buf[i], " ");
10616362Skarels 	sizes[i] = strlen(line_buf[i]);
10716362Skarels 	max_size = max(max_size, sizes[i]);
10816362Skarels 	i++;
10916362Skarels 	bptr = big_buf;
11026839Smckusick 	*bptr++ = ''; /* send something to wake them up */
11126839Smckusick 	*bptr++ = '\r';	/* add a \r in case of raw mode */
11226839Smckusick 	*bptr++ = '\n';
11316362Skarels 	for (i = 0; i < N_LINES; i++) {
11416362Skarels 		/* copy the line into the big buffer */
11516362Skarels 		lptr = line_buf[i];
11616362Skarels 		while (*lptr != '\0')
11716362Skarels 			*(bptr++) = *(lptr++);
11816362Skarels 		/* pad out the rest of the lines with blanks */
11916362Skarels 		for (j = sizes[i]; j < max_size + 2; j++)
12016362Skarels 			*(bptr++) = ' ';
12116362Skarels 		*(bptr++) = '\r';	/* add a \r in case of raw mode */
12216362Skarels 		*(bptr++) = '\n';
12316362Skarels 	}
12416362Skarels 	*bptr = '\0';
12550742Smarc 	iovec.iov_base = big_buf;
12650742Smarc 	iovec.iov_len = bptr - big_buf;
12750743Smarc 	/*
12850743Smarc 	 * we choose a timeout of RING_WAIT-5 seconds so that we don't
12950743Smarc 	 * stack up processes trying to write messages to a tty
13050743Smarc 	 * that is permanently blocked.
13150743Smarc 	 */
13250743Smarc 	if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL)
13350742Smarc 		return (FAILED);
13450742Smarc 
13550742Smarc 	return (SUCCESS);
13616341Skarels }
137