|
|
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 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.
16: */
17:
18: #ifndef lint
19: static char sccsid[] = "@(#)announce.c 5.6 (Berkeley) 6/18/88";
20: #endif /* not lint */
21:
22: #include <sys/types.h>
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>
30: #include <syslog.h>
31:
32: #include <protocols/talkd.h>
33:
34: extern int errno;
35: extern char hostname[];
36:
37: /*
38: * Announce an invitation to talk.
39: *
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: */
44: announce(request, remote_machine)
45: CTL_MSG *request;
46: char *remote_machine;
47: {
48: int pid, val, status;
49:
50: if (pid = fork()) {
51: /* we are the parent, so wait for the child */
52: if (pid == -1) /* the fork failed */
53: return (FAILED);
54: do {
55: val = wait(&status);
56: if (val == -1) {
57: if (errno == EINTR)
58: continue;
59: /* shouldn't happen */
60: syslog(LOG_WARNING, "announce: wait: %m");
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);
68: }
69: /* we are the child, go and do it */
70: _exit(announce_proc(request, remote_machine));
71: }
72:
73: /*
74: * See if the user is accepting messages. If so, announce that
75: * a talk is requested.
76: */
77: announce_proc(request, remote_machine)
78: CTL_MSG *request;
79: char *remote_machine;
80: {
81: int pid, status;
82: char full_tty[32];
83: FILE *tf;
84: struct stat stbuf;
85:
86: (void)sprintf(full_tty, "/dev/%s", request->r_tty);
87: if (access(full_tty, 0) != 0)
88: return (FAILED);
89: if ((tf = fopen(full_tty, "w")) == NULL)
90: return (PERMISSION_DENIED);
91: /*
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.
95: */
96: ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
97: if (fstat(fileno(tf), &stbuf) < 0)
98: return (PERMISSION_DENIED);
99: if ((stbuf.st_mode&020) == 0)
100: return (PERMISSION_DENIED);
101: print_mesg(tf, request, remote_machine);
102: fclose(tf);
103: return (SUCCESS);
104: }
105:
106: #define max(a,b) ( (a) > (b) ? (a) : (b) )
107: #define N_LINES 5
108: #define N_CHARS 120
109:
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: */
116: print_mesg(tf, request, remote_machine)
117: FILE *tf;
118: CTL_MSG *request;
119: char *remote_machine;
120: {
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 );
135: (void)sprintf(line_buf[i], " ");
136: sizes[i] = strlen(line_buf[i]);
137: max_size = max(max_size, sizes[i]);
138: i++;
139: (void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...",
140: hostname, localclock->tm_hour , localclock->tm_min );
141: sizes[i] = strlen(line_buf[i]);
142: max_size = max(max_size, sizes[i]);
143: i++;
144: (void)sprintf(line_buf[i], "talk: connection requested by %s@%s.",
145: request->l_name, remote_machine);
146: sizes[i] = strlen(line_buf[i]);
147: max_size = max(max_size, sizes[i]);
148: i++;
149: (void)sprintf(line_buf[i], "talk: respond with: talk %s@%s",
150: request->l_name, remote_machine);
151: sizes[i] = strlen(line_buf[i]);
152: max_size = max(max_size, sizes[i]);
153: i++;
154: (void)sprintf(line_buf[i], " ");
155: sizes[i] = strlen(line_buf[i]);
156: max_size = max(max_size, sizes[i]);
157: i++;
158: bptr = big_buf;
159: *bptr++ = ''; /* send something to wake them up */
160: *bptr++ = '\r'; /* add a \r in case of raw mode */
161: *bptr++ = '\n';
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);
177: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.