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