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