updates
[unix-history] / usr / src / libexec / talkd / announce.c
CommitLineData
d0aeaf5a
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
963ce42e 7#ifndef lint
ec72c538 8static char sccsid[] = "@(#)announce.c 5.3 (Berkeley) %G%";
d0aeaf5a 9#endif not lint
610b175a 10
595cdd5e 11#include <sys/types.h>
610b175a
MK
12#include <sys/stat.h>
13#include <sgtty.h>
14#include <sys/ioctl.h>
15#include <sys/time.h>
16#include <stdio.h>
17#include <sys/wait.h>
18#include <errno.h>
595cdd5e 19#include <syslog.h>
610b175a 20
595cdd5e 21#include <protocols/talkd.h>
610b175a 22
595cdd5e
KM
23extern int errno;
24extern char hostname[];
610b175a
MK
25
26/*
595cdd5e
KM
27 * Announce an invitation to talk.
28 *
610b175a
MK
29 * Because the tty driver insists on attaching a terminal-less
30 * process to any terminal that it writes on, we must fork a child
31 * to protect ourselves
32 */
610b175a 33announce(request, remote_machine)
963ce42e
MK
34 CTL_MSG *request;
35 char *remote_machine;
610b175a 36{
963ce42e
MK
37 int pid, val, status;
38
963ce42e
MK
39 if (pid = fork()) {
40 /* we are the parent, so wait for the child */
41 if (pid == -1) /* the fork failed */
595cdd5e 42 return (FAILED);
963ce42e
MK
43 do {
44 val = wait(&status);
45 if (val == -1) {
46 if (errno == EINTR)
47 continue;
48 /* shouldn't happen */
595cdd5e 49 syslog(LOG_WARNING, "announce: wait: %m");
963ce42e
MK
50 return (FAILED);
51 }
52 } while (val != pid);
53 if (status&0377 > 0) /* we were killed by some signal */
54 return (FAILED);
55 /* Get the second byte, this is the exit/return code */
56 return ((status >> 8) & 0377);
610b175a 57 }
963ce42e 58 /* we are the child, go and do it */
610b175a 59 _exit(announce_proc(request, remote_machine));
610b175a
MK
60}
61
963ce42e
MK
62/*
63 * See if the user is accepting messages. If so, announce that
64 * a talk is requested.
65 */
610b175a 66announce_proc(request, remote_machine)
963ce42e
MK
67 CTL_MSG *request;
68 char *remote_machine;
610b175a 69{
963ce42e
MK
70 int pid, status;
71 char full_tty[32];
72 FILE *tf;
73 struct stat stbuf;
74
595cdd5e 75 sprintf(full_tty, "/dev/%s", request->r_tty);
963ce42e
MK
76 if (access(full_tty, 0) != 0)
77 return (FAILED);
78 if ((tf = fopen(full_tty, "w")) == NULL)
79 return (PERMISSION_DENIED);
80 /*
595cdd5e
KM
81 * On first tty open, the server will have
82 * it's pgrp set, so disconnect us from the
83 * tty before we catch a signal.
963ce42e
MK
84 */
85 ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
86 if (fstat(fileno(tf), &stbuf) < 0)
87 return (PERMISSION_DENIED);
ec72c538 88 if ((stbuf.st_mode&020) == 0)
963ce42e
MK
89 return (PERMISSION_DENIED);
90 print_mesg(tf, request, remote_machine);
91 fclose(tf);
92 return (SUCCESS);
610b175a
MK
93}
94
95#define max(a,b) ( (a) > (b) ? (a) : (b) )
96#define N_LINES 5
97#define N_CHARS 120
98
963ce42e
MK
99/*
100 * Build a block of characters containing the message.
101 * It is sent blank filled and in a single block to
102 * try to keep the message in one piece if the recipient
103 * in in vi at the time
104 */
610b175a 105print_mesg(tf, request, remote_machine)
963ce42e
MK
106 FILE *tf;
107 CTL_MSG *request;
108 char *remote_machine;
610b175a 109{
963ce42e
MK
110 struct timeval clock;
111 struct timezone zone;
112 struct tm *localtime();
113 struct tm *localclock;
114 char line_buf[N_LINES][N_CHARS];
115 int sizes[N_LINES];
116 char big_buf[N_LINES*N_CHARS];
117 char *bptr, *lptr;
118 int i, j, max_size;
119
120 i = 0;
121 max_size = 0;
122 gettimeofday(&clock, &zone);
123 localclock = localtime( &clock.tv_sec );
124 sprintf(line_buf[i], " ");
125 sizes[i] = strlen(line_buf[i]);
126 max_size = max(max_size, sizes[i]);
127 i++;
128 sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...",
610b175a 129 hostname, localclock->tm_hour , localclock->tm_min );
963ce42e
MK
130 sizes[i] = strlen(line_buf[i]);
131 max_size = max(max_size, sizes[i]);
132 i++;
133 sprintf(line_buf[i], "talk: connection requested by %s@%s.",
610b175a 134 request->l_name, remote_machine);
963ce42e
MK
135 sizes[i] = strlen(line_buf[i]);
136 max_size = max(max_size, sizes[i]);
137 i++;
138 sprintf(line_buf[i], "talk: respond with: talk %s@%s",
610b175a 139 request->l_name, remote_machine);
963ce42e
MK
140 sizes[i] = strlen(line_buf[i]);
141 max_size = max(max_size, sizes[i]);
142 i++;
143 sprintf(line_buf[i], " ");
144 sizes[i] = strlen(line_buf[i]);
145 max_size = max(max_size, sizes[i]);
146 i++;
147 bptr = big_buf;
595cdd5e
KM
148 *bptr++ = '\a'; /* send something to wake them up */
149 *bptr++ = '\r'; /* add a \r in case of raw mode */
150 *bptr++ = '\n';
963ce42e
MK
151 for (i = 0; i < N_LINES; i++) {
152 /* copy the line into the big buffer */
153 lptr = line_buf[i];
154 while (*lptr != '\0')
155 *(bptr++) = *(lptr++);
156 /* pad out the rest of the lines with blanks */
157 for (j = sizes[i]; j < max_size + 2; j++)
158 *(bptr++) = ' ';
159 *(bptr++) = '\r'; /* add a \r in case of raw mode */
160 *(bptr++) = '\n';
161 }
162 *bptr = '\0';
163 fprintf(tf, big_buf);
164 fflush(tf);
165 ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
610b175a 166}