Commit | Line | Data |
---|---|---|
d0aeaf5a DF |
1 | /* |
2 | * Copyright (c) 1983 Regents of the University of California. | |
9e678aa5 KB |
3 | * All rights reserved. |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
b8c620d6 KB |
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. | |
d0aeaf5a DF |
16 | */ |
17 | ||
963ce42e | 18 | #ifndef lint |
7abf8d65 | 19 | static char sccsid[] = "@(#)announce.c 5.7 (Berkeley) %G%"; |
9e678aa5 | 20 | #endif /* not lint */ |
610b175a | 21 | |
595cdd5e | 22 | #include <sys/types.h> |
610b175a MK |
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> | |
595cdd5e | 30 | #include <syslog.h> |
610b175a | 31 | |
595cdd5e | 32 | #include <protocols/talkd.h> |
7abf8d65 | 33 | #include <paths.h> |
610b175a | 34 | |
595cdd5e KM |
35 | extern int errno; |
36 | extern char hostname[]; | |
610b175a MK |
37 | |
38 | /* | |
595cdd5e KM |
39 | * Announce an invitation to talk. |
40 | * | |
610b175a MK |
41 | * Because the tty driver insists on attaching a terminal-less |
42 | * process to any terminal that it writes on, we must fork a child | |
43 | * to protect ourselves | |
44 | */ | |
610b175a | 45 | announce(request, remote_machine) |
963ce42e MK |
46 | CTL_MSG *request; |
47 | char *remote_machine; | |
610b175a | 48 | { |
963ce42e MK |
49 | int pid, val, status; |
50 | ||
963ce42e MK |
51 | if (pid = fork()) { |
52 | /* we are the parent, so wait for the child */ | |
53 | if (pid == -1) /* the fork failed */ | |
595cdd5e | 54 | return (FAILED); |
963ce42e MK |
55 | do { |
56 | val = wait(&status); | |
57 | if (val == -1) { | |
58 | if (errno == EINTR) | |
59 | continue; | |
60 | /* shouldn't happen */ | |
595cdd5e | 61 | syslog(LOG_WARNING, "announce: wait: %m"); |
963ce42e MK |
62 | return (FAILED); |
63 | } | |
64 | } while (val != pid); | |
65 | if (status&0377 > 0) /* we were killed by some signal */ | |
66 | return (FAILED); | |
67 | /* Get the second byte, this is the exit/return code */ | |
68 | return ((status >> 8) & 0377); | |
610b175a | 69 | } |
963ce42e | 70 | /* we are the child, go and do it */ |
610b175a | 71 | _exit(announce_proc(request, remote_machine)); |
610b175a MK |
72 | } |
73 | ||
963ce42e MK |
74 | /* |
75 | * See if the user is accepting messages. If so, announce that | |
76 | * a talk is requested. | |
77 | */ | |
610b175a | 78 | announce_proc(request, remote_machine) |
963ce42e MK |
79 | CTL_MSG *request; |
80 | char *remote_machine; | |
610b175a | 81 | { |
963ce42e MK |
82 | int pid, status; |
83 | char full_tty[32]; | |
84 | FILE *tf; | |
85 | struct stat stbuf; | |
86 | ||
7abf8d65 | 87 | (void)sprintf(full_tty, "%s/%s", _PATH_DEV, request->r_tty); |
963ce42e MK |
88 | if (access(full_tty, 0) != 0) |
89 | return (FAILED); | |
90 | if ((tf = fopen(full_tty, "w")) == NULL) | |
91 | return (PERMISSION_DENIED); | |
92 | /* | |
595cdd5e KM |
93 | * On first tty open, the server will have |
94 | * it's pgrp set, so disconnect us from the | |
95 | * tty before we catch a signal. | |
963ce42e MK |
96 | */ |
97 | ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); | |
98 | if (fstat(fileno(tf), &stbuf) < 0) | |
99 | return (PERMISSION_DENIED); | |
ec72c538 | 100 | if ((stbuf.st_mode&020) == 0) |
963ce42e MK |
101 | return (PERMISSION_DENIED); |
102 | print_mesg(tf, request, remote_machine); | |
103 | fclose(tf); | |
104 | return (SUCCESS); | |
610b175a MK |
105 | } |
106 | ||
107 | #define max(a,b) ( (a) > (b) ? (a) : (b) ) | |
108 | #define N_LINES 5 | |
109 | #define N_CHARS 120 | |
110 | ||
963ce42e MK |
111 | /* |
112 | * Build a block of characters containing the message. | |
113 | * It is sent blank filled and in a single block to | |
114 | * try to keep the message in one piece if the recipient | |
115 | * in in vi at the time | |
116 | */ | |
610b175a | 117 | print_mesg(tf, request, remote_machine) |
963ce42e MK |
118 | FILE *tf; |
119 | CTL_MSG *request; | |
120 | char *remote_machine; | |
610b175a | 121 | { |
963ce42e MK |
122 | struct timeval clock; |
123 | struct timezone zone; | |
124 | struct tm *localtime(); | |
125 | struct tm *localclock; | |
126 | char line_buf[N_LINES][N_CHARS]; | |
127 | int sizes[N_LINES]; | |
128 | char big_buf[N_LINES*N_CHARS]; | |
129 | char *bptr, *lptr; | |
130 | int i, j, max_size; | |
131 | ||
132 | i = 0; | |
133 | max_size = 0; | |
134 | gettimeofday(&clock, &zone); | |
135 | localclock = localtime( &clock.tv_sec ); | |
9bd38ba8 | 136 | (void)sprintf(line_buf[i], " "); |
963ce42e MK |
137 | sizes[i] = strlen(line_buf[i]); |
138 | max_size = max(max_size, sizes[i]); | |
139 | i++; | |
9bd38ba8 | 140 | (void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...", |
610b175a | 141 | hostname, localclock->tm_hour , localclock->tm_min ); |
963ce42e MK |
142 | sizes[i] = strlen(line_buf[i]); |
143 | max_size = max(max_size, sizes[i]); | |
144 | i++; | |
9bd38ba8 | 145 | (void)sprintf(line_buf[i], "talk: connection requested by %s@%s.", |
610b175a | 146 | request->l_name, remote_machine); |
963ce42e MK |
147 | sizes[i] = strlen(line_buf[i]); |
148 | max_size = max(max_size, sizes[i]); | |
149 | i++; | |
9bd38ba8 | 150 | (void)sprintf(line_buf[i], "talk: respond with: talk %s@%s", |
610b175a | 151 | request->l_name, remote_machine); |
963ce42e MK |
152 | sizes[i] = strlen(line_buf[i]); |
153 | max_size = max(max_size, sizes[i]); | |
154 | i++; | |
9bd38ba8 | 155 | (void)sprintf(line_buf[i], " "); |
963ce42e MK |
156 | sizes[i] = strlen(line_buf[i]); |
157 | max_size = max(max_size, sizes[i]); | |
158 | i++; | |
159 | bptr = big_buf; | |
595cdd5e KM |
160 | *bptr++ = '\a'; /* send something to wake them up */ |
161 | *bptr++ = '\r'; /* add a \r in case of raw mode */ | |
162 | *bptr++ = '\n'; | |
963ce42e MK |
163 | for (i = 0; i < N_LINES; i++) { |
164 | /* copy the line into the big buffer */ | |
165 | lptr = line_buf[i]; | |
166 | while (*lptr != '\0') | |
167 | *(bptr++) = *(lptr++); | |
168 | /* pad out the rest of the lines with blanks */ | |
169 | for (j = sizes[i]; j < max_size + 2; j++) | |
170 | *(bptr++) = ' '; | |
171 | *(bptr++) = '\r'; /* add a \r in case of raw mode */ | |
172 | *(bptr++) = '\n'; | |
173 | } | |
174 | *bptr = '\0'; | |
175 | fprintf(tf, big_buf); | |
176 | fflush(tf); | |
177 | ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); | |
610b175a | 178 | } |