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