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