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