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