Annotation of src/libexec/talkd/announce.c, Revision 1.1.1.1
1.1 cgd 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #ifndef lint
35: static char sccsid[] = "@(#)announce.c 5.9 (Berkeley) 2/26/91";
36: #endif /* not lint */
37:
38: #include <sys/types.h>
39: #include <sys/stat.h>
40: #include <sys/time.h>
41: #include <sys/wait.h>
42: #include <sys/socket.h>
43: #include <protocols/talkd.h>
44: #include <sgtty.h>
45: #include <errno.h>
46: #include <syslog.h>
47: #include <unistd.h>
48: #include <stdio.h>
49: #include <string.h>
50: #include <paths.h>
51:
52: extern char hostname[];
53:
54: /*
55: * Announce an invitation to talk.
56: *
57: * Because the tty driver insists on attaching a terminal-less
58: * process to any terminal that it writes on, we must fork a child
59: * to protect ourselves
60: */
61: announce(request, remote_machine)
62: CTL_MSG *request;
63: char *remote_machine;
64: {
65: int pid, val, status;
66:
67: if (pid = fork()) {
68: /* we are the parent, so wait for the child */
69: if (pid == -1) /* the fork failed */
70: return (FAILED);
71: do {
72: val = wait(&status);
73: if (val == -1) {
74: if (errno == EINTR)
75: continue;
76: /* shouldn't happen */
77: syslog(LOG_WARNING, "announce: wait: %m");
78: return (FAILED);
79: }
80: } while (val != pid);
81: if (status&0377 > 0) /* we were killed by some signal */
82: return (FAILED);
83: /* Get the second byte, this is the exit/return code */
84: return ((status >> 8) & 0377);
85: }
86: /* we are the child, go and do it */
87: _exit(announce_proc(request, remote_machine));
88: }
89:
90: /*
91: * See if the user is accepting messages. If so, announce that
92: * a talk is requested.
93: */
94: announce_proc(request, remote_machine)
95: CTL_MSG *request;
96: char *remote_machine;
97: {
98: int pid, status;
99: char full_tty[32];
100: FILE *tf;
101: struct stat stbuf;
102:
103: (void)sprintf(full_tty, "%s/%s", _PATH_DEV, request->r_tty);
104: if (access(full_tty, 0) != 0)
105: return (FAILED);
106: if ((tf = fopen(full_tty, "w")) == NULL)
107: return (PERMISSION_DENIED);
108: /*
109: * On first tty open, the server will have
110: * it's pgrp set, so disconnect us from the
111: * tty before we catch a signal.
112: */
113: ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
114: if (fstat(fileno(tf), &stbuf) < 0)
115: return (PERMISSION_DENIED);
116: if ((stbuf.st_mode&020) == 0)
117: return (PERMISSION_DENIED);
118: print_mesg(tf, request, remote_machine);
119: fclose(tf);
120: return (SUCCESS);
121: }
122:
123: #define max(a,b) ( (a) > (b) ? (a) : (b) )
124: #define N_LINES 5
125: #define N_CHARS 120
126:
127: /*
128: * Build a block of characters containing the message.
129: * It is sent blank filled and in a single block to
130: * try to keep the message in one piece if the recipient
131: * in in vi at the time
132: */
133: print_mesg(tf, request, remote_machine)
134: FILE *tf;
135: CTL_MSG *request;
136: char *remote_machine;
137: {
138: struct timeval clock;
139: struct timezone zone;
140: struct tm *localtime();
141: struct tm *localclock;
142: char line_buf[N_LINES][N_CHARS];
143: int sizes[N_LINES];
144: char big_buf[N_LINES*N_CHARS];
145: char *bptr, *lptr;
146: int i, j, max_size;
147:
148: i = 0;
149: max_size = 0;
150: gettimeofday(&clock, &zone);
151: localclock = localtime( &clock.tv_sec );
152: (void)sprintf(line_buf[i], " ");
153: sizes[i] = strlen(line_buf[i]);
154: max_size = max(max_size, sizes[i]);
155: i++;
156: (void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...",
157: hostname, localclock->tm_hour , localclock->tm_min );
158: sizes[i] = strlen(line_buf[i]);
159: max_size = max(max_size, sizes[i]);
160: i++;
161: (void)sprintf(line_buf[i], "talk: connection requested by %s@%s.",
162: request->l_name, remote_machine);
163: sizes[i] = strlen(line_buf[i]);
164: max_size = max(max_size, sizes[i]);
165: i++;
166: (void)sprintf(line_buf[i], "talk: respond with: talk %s@%s",
167: request->l_name, remote_machine);
168: sizes[i] = strlen(line_buf[i]);
169: max_size = max(max_size, sizes[i]);
170: i++;
171: (void)sprintf(line_buf[i], " ");
172: sizes[i] = strlen(line_buf[i]);
173: max_size = max(max_size, sizes[i]);
174: i++;
175: bptr = big_buf;
176: *bptr++ = ''; /* send something to wake them up */
177: *bptr++ = '\r'; /* add a \r in case of raw mode */
178: *bptr++ = '\n';
179: for (i = 0; i < N_LINES; i++) {
180: /* copy the line into the big buffer */
181: lptr = line_buf[i];
182: while (*lptr != '\0')
183: *(bptr++) = *(lptr++);
184: /* pad out the rest of the lines with blanks */
185: for (j = sizes[i]; j < max_size + 2; j++)
186: *(bptr++) = ' ';
187: *(bptr++) = '\r'; /* add a \r in case of raw mode */
188: *(bptr++) = '\n';
189: }
190: *bptr = '\0';
191: fprintf(tf, big_buf);
192: fflush(tf);
193: ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
194: }
CVSweb <webmaster@jp.NetBSD.org>