|
|
1.1 root 1: /* $Header: announce.c,v 1.2 85/01/09 13:04:28 rcs Exp $ */
2:
3: #include "ctl.h"
4:
5: #include <sys/stat.h>
6: #include <sgtty.h>
7: #include <sys/ioctl.h>
8: #include <sys/time.h>
9: #include <sys/signal.h>
10: #include <stdio.h>
11: #include <sys/wait.h>
12: #include <errno.h>
13:
14: char *sprintf();
15:
16: extern int errno;
17: extern char hostname[];
18: extern int debug;
19: int trapit();
20: int nofork = 0; /* to be set from the debugger */
21:
22: /*
23: * Changes
24: * . fix fprintf() in print_msg() to include a format statement.
25: *
26: * . fix announce() and announce_proc() to output weird cases
27: * to console.
28: */
29: /*
30: * Because the tty driver insists on attaching a terminal-less
31: * process to any terminal that it writes on, we must fork a child
32: * to protect ourselves
33: */
34:
35: announce(request, remote_machine)
36: CTL_MSG *request;
37: char *remote_machine;
38: {
39: int pid, val, status;
40: int i;
41:
42: if (debug)
43: setbuf(stdout, (char *)0);
44:
45: if (nofork) {
46: int stat;
47: stat = (announce_proc(request, remote_machine));
48: }
49:
50: if ( pid = fork() ) {
51:
52: /* we are the parent, so wait for the child */
53:
54: if (pid == -1) {
55: /* the fork failed */
56: return(FAILED);
57: }
58:
59: do {
60: val = wait(&status);
61: if (val == -1) {
62: if (errno == EINTR) {
63: continue;
64: } else {
65: /* shouldn't happen */
66: print_error("wait");
67: return(FAILED);
68: }
69: }
70: } while (val != pid);
71:
72: if (status&0377 > 0) {
73: char buf[200];
74: /* we were killed by some signal */
75: sprintf(buf,"child killed by signal %d",status&0377);
76: print_error(buf);
77: return(FAILED);
78: }
79:
80: /* Get the second byte, this is the exit/return code */
81:
82: return((status>>8)&0377);
83:
84: } else {
85: int stat;
86:
87: /* we are the child, go and do it */
88: stat = announce_proc(request, remote_machine);
89: _exit(stat);
90: }
91: }
92:
93:
94: /* See if the user is accepting messages. If so, announce that
95: a talk is requested.
96: */
97:
98: announce_proc(request, remote_machine)
99: CTL_MSG *request;
100: char *remote_machine;
101: {
102: int pid, status;
103: char full_tty[32];
104: FILE *tf;
105: struct stat stbuf;
106:
107:
108: if (debug)
109: setbuf(stdout, (char *)0);
110:
111: (void) sprintf(full_tty, "/dev/%s", request->ctlm_r_tty);
112:
113: if (access(full_tty, 0) != 0) {
114: char buf[200];
115: sprintf(buf,"cannot access /dev/%s",request->ctlm_r_tty);
116: print_error(buf);
117: return(FAILED);
118: }
119:
120: if ((tf = fopen(full_tty, "w")) == NULL) {
121: return(PERMISSION_DENIED);
122: }
123:
124: /* open gratuitously attaches the talkd to
125: any tty it opens, so disconnect us from the
126: tty before we catch a signal */
127:
128: ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
129:
130: if (fstat(fileno(tf), &stbuf) < 0) {
131: return(PERMISSION_DENIED);
132: }
133:
134: if ((stbuf.st_mode&02) == 0) {
135: return(PERMISSION_DENIED);
136: }
137:
138: print_mesg(tf, request, remote_machine);
139: fclose(tf);
140: return(SUCCESS);
141: }
142:
143: #define max(a,b) ( (a) > (b) ? (a) : (b) )
144: #define N_LINES 5
145: #define N_CHARS 120
146:
147: /*
148: * build a block of characters containing the message.
149: * It is sent blank filled and in a single block to
150: * try to keep the message in one piece if the recipient
151: * in in vi at the time
152: */
153:
154: print_mesg(tf, request, remote_machine)
155: FILE *tf;
156: CTL_MSG *request;
157: char *remote_machine;
158: {
159: struct timeval clock;
160: struct timezone zone;
161: struct tm *localtime();
162: struct tm *localclock;
163: char line_buf[N_LINES][N_CHARS];
164: int sizes[N_LINES];
165: char big_buf[N_LINES*N_CHARS];
166: char *bptr, *lptr;
167: int i, j, max_size;
168:
169: i = 0;
170: max_size = 0;
171:
172: gettimeofday(&clock, &zone);
173: localclock = localtime( &clock.tv_sec );
174:
175: sprintf(line_buf[i], " ");
176:
177: sizes[i] = strlen(line_buf[i]);
178: max_size = max(max_size, sizes[i]);
179: i++;
180:
181: sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...",
182: hostname, localclock->tm_hour , localclock->tm_min );
183:
184: sizes[i] = strlen(line_buf[i]);
185: max_size = max(max_size, sizes[i]);
186: i++;
187:
188: sprintf(line_buf[i], "talk: connection requested by %s@%s.",
189: request->ctlm_l_name, remote_machine);
190:
191: sizes[i] = strlen(line_buf[i]);
192: max_size = max(max_size, sizes[i]);
193: i++;
194:
195: sprintf(line_buf[i], "talk: respond with: talk %s@%s",
196: request->ctlm_l_name, remote_machine);
197:
198: sizes[i] = strlen(line_buf[i]);
199: max_size = max(max_size, sizes[i]);
200: i++;
201:
202: sprintf(line_buf[i], " ");
203:
204: sizes[i] = strlen(line_buf[i]);
205: max_size = max(max_size, sizes[i]);
206: i++;
207:
208: bptr = big_buf;
209: *(bptr++) = ''; /* send something to wake them up */
210: *(bptr++) = '\r'; /* add a \r in case of raw mode */
211: *(bptr++) = '\n';
212: for(i = 0; i < N_LINES; i++) {
213:
214: /* copy the line into the big buffer */
215:
216: lptr = line_buf[i];
217: while (*lptr != '\0') {
218: *(bptr++) = *(lptr++);
219: }
220:
221: /* pad out the rest of the lines with blanks */
222:
223: for(j = sizes[i]; j < max_size + 2; j++) {
224: *(bptr++) = ' ';
225: }
226:
227: *(bptr++) = '\r'; /* add a \r in case of raw mode */
228: *(bptr++) = '\n';
229: }
230: *bptr = '\0';
231:
232: fprintf(tf, "%s", big_buf);
233: fflush(tf);
234: ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
235: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.