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