date and time created 84/04/11 15:02:40 by karels
[unix-history] / usr / src / libexec / talkd / announce.c
CommitLineData
610b175a
MK
1/* $Header: /a/guest/moore/talk/RCS/announce.c,v 1.8 83/07/06 00:16:57 moore Exp $ */
2
3#include "ctl.h"
4
5#include <sys/stat.h>
6#include <sgtty.h>
7#include <sys/ioctl.h>
8#include <sys/time.h>
9#include <stdio.h>
10#include <sys/wait.h>
11#include <errno.h>
12
13char *sprintf();
14
15extern int errno;
16extern char hostname[];
17int nofork = 0; /* to be set from the debugger */
18
19/*
20 * Because the tty driver insists on attaching a terminal-less
21 * process to any terminal that it writes on, we must fork a child
22 * to protect ourselves
23 */
24
25announce(request, remote_machine)
26CTL_MSG *request;
27char *remote_machine;
28{
29 int pid, val, status;
30
31 if (nofork) {
32 return(announce_proc(request, remote_machine));
33 }
34
35 if ( pid = fork() ) {
36
37 /* we are the parent, so wait for the child */
38
39 if (pid == -1) {
40 /* the fork failed */
41 return(FAILED);
42 }
43
44 do {
45 val = wait(&status);
46 if (val == -1) {
47 if (errno == EINTR) {
48 continue;
49 } else {
50 /* shouldn't happen */
51 print_error("wait");
52 return(FAILED);
53 }
54 }
55 } while (val != pid);
56
57 if (status&0377 > 0) {
58 /* we were killed by some signal */
59 return(FAILED);
60 }
61
62 /* Get the second byte, this is the exit/return code */
63
64 return((status>>8)&0377);
65
66 } else {
67 /* we are the child, go and do it */
68 _exit(announce_proc(request, remote_machine));
69 }
70}
71
72
73 /* See if the user is accepting messages. If so, announce that
74 a talk is requested.
75 */
76
77announce_proc(request, remote_machine)
78CTL_MSG *request;
79char *remote_machine;
80{
81 int pid, status;
82 char full_tty[32];
83 FILE *tf;
84 struct stat stbuf;
85
86
87 (void) sprintf(full_tty, "/dev/%s", request->r_tty);
88
89 if (access(full_tty, 0) != 0) {
90 return(FAILED);
91 }
92
93 if ((tf = fopen(full_tty, "w")) == NULL) {
94 return(PERMISSION_DENIED);
95 }
96
97 /* open gratuitously attaches the talkd to
98 any tty it opens, so disconnect us from the
99 tty before we catch a signal */
100
101 ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
102
103 if (fstat(fileno(tf), &stbuf) < 0) {
104 return(PERMISSION_DENIED);
105 }
106
107 if ((stbuf.st_mode&02) == 0) {
108 return(PERMISSION_DENIED);
109 }
110
111 print_mesg(tf, request, remote_machine);
112 fclose(tf);
113 return(SUCCESS);
114}
115
116#define max(a,b) ( (a) > (b) ? (a) : (b) )
117#define N_LINES 5
118#define N_CHARS 120
119
120 /*
121 * build a block of characters containing the message.
122 * It is sent blank filled and in a single block to
123 * try to keep the message in one piece if the recipient
124 * in in vi at the time
125 */
126
127print_mesg(tf, request, remote_machine)
128FILE *tf;
129CTL_MSG *request;
130char *remote_machine;
131{
132 struct timeval clock;
133 struct timezone zone;
134 struct tm *localtime();
135 struct tm *localclock;
136 char line_buf[N_LINES][N_CHARS];
137 int sizes[N_LINES];
138 char big_buf[N_LINES*N_CHARS];
139 char *bptr, *lptr;
140 int i, j, max_size;
141
142 i = 0;
143 max_size = 0;
144
145 gettimeofday(&clock, &zone);
146 localclock = localtime( &clock.tv_sec );
147
148 sprintf(line_buf[i], " ");
149
150 sizes[i] = strlen(line_buf[i]);
151 max_size = max(max_size, sizes[i]);
152 i++;
153
154 sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...",
155 hostname, localclock->tm_hour , localclock->tm_min );
156
157 sizes[i] = strlen(line_buf[i]);
158 max_size = max(max_size, sizes[i]);
159 i++;
160
161 sprintf(line_buf[i], "talk: connection requested by %s@%s.",
162 request->l_name, remote_machine);
163
164 sizes[i] = strlen(line_buf[i]);
165 max_size = max(max_size, sizes[i]);
166 i++;
167
168 sprintf(line_buf[i], "talk: respond with: talk %s@%s",
169 request->l_name, remote_machine);
170
171 sizes[i] = strlen(line_buf[i]);
172 max_size = max(max_size, sizes[i]);
173 i++;
174
175 sprintf(line_buf[i], " ");
176
177 sizes[i] = strlen(line_buf[i]);
178 max_size = max(max_size, sizes[i]);
179 i++;
180
181 bptr = big_buf;
182 *(bptr++) = '\a'; /* send something to wake them up */
183 *(bptr++) = '\r'; /* add a \r in case of raw mode */
184 *(bptr++) = '\n';
185 for(i = 0; i < N_LINES; i++) {
186
187 /* copy the line into the big buffer */
188
189 lptr = line_buf[i];
190 while (*lptr != '\0') {
191 *(bptr++) = *(lptr++);
192 }
193
194 /* pad out the rest of the lines with blanks */
195
196 for(j = sizes[i]; j < max_size + 2; j++) {
197 *(bptr++) = ' ';
198 }
199
200 *(bptr++) = '\r'; /* add a \r in case of raw mode */
201 *(bptr++) = '\n';
202 }
203 *bptr = '\0';
204
205 fprintf(tf, big_buf);
206 fflush(tf);
207 ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
208}