1*16362Skarels #ifndef lint 2*16362Skarels static char sccsid[] = "@(#)announce.c 1.2 (Berkeley) 04/11/84"; 3*16362Skarels #endif 416341Skarels 516341Skarels #include "ctl.h" 616341Skarels 716341Skarels #include <sys/stat.h> 816341Skarels #include <sgtty.h> 916341Skarels #include <sys/ioctl.h> 1016341Skarels #include <sys/time.h> 1116341Skarels #include <stdio.h> 1216341Skarels #include <sys/wait.h> 1316341Skarels #include <errno.h> 1416341Skarels 1516341Skarels char *sprintf(); 1616341Skarels 1716341Skarels extern int errno; 1816341Skarels extern char hostname[]; 1916341Skarels int nofork = 0; /* to be set from the debugger */ 2016341Skarels 2116341Skarels /* 2216341Skarels * Because the tty driver insists on attaching a terminal-less 2316341Skarels * process to any terminal that it writes on, we must fork a child 2416341Skarels * to protect ourselves 2516341Skarels */ 2616341Skarels 2716341Skarels announce(request, remote_machine) 28*16362Skarels CTL_MSG *request; 29*16362Skarels char *remote_machine; 3016341Skarels { 31*16362Skarels int pid, val, status; 3216341Skarels 33*16362Skarels if (nofork) 34*16362Skarels return(announce_proc(request, remote_machine)); 35*16362Skarels if (pid = fork()) { 36*16362Skarels /* we are the parent, so wait for the child */ 37*16362Skarels if (pid == -1) /* the fork failed */ 38*16362Skarels return(FAILED); 39*16362Skarels do { 40*16362Skarels val = wait(&status); 41*16362Skarels if (val == -1) { 42*16362Skarels if (errno == EINTR) 43*16362Skarels continue; 44*16362Skarels /* shouldn't happen */ 45*16362Skarels perror("wait"); 46*16362Skarels return (FAILED); 47*16362Skarels } 48*16362Skarels } while (val != pid); 49*16362Skarels if (status&0377 > 0) /* we were killed by some signal */ 50*16362Skarels return (FAILED); 51*16362Skarels /* Get the second byte, this is the exit/return code */ 52*16362Skarels return ((status >> 8) & 0377); 5316341Skarels } 54*16362Skarels /* we are the child, go and do it */ 5516341Skarels _exit(announce_proc(request, remote_machine)); 5616341Skarels } 5716341Skarels 58*16362Skarels /* 59*16362Skarels * See if the user is accepting messages. If so, announce that 60*16362Skarels * a talk is requested. 61*16362Skarels */ 6216341Skarels announce_proc(request, remote_machine) 63*16362Skarels CTL_MSG *request; 64*16362Skarels char *remote_machine; 6516341Skarels { 66*16362Skarels int pid, status; 67*16362Skarels char full_tty[32]; 68*16362Skarels FILE *tf; 69*16362Skarels struct stat stbuf; 7016341Skarels 71*16362Skarels (void) sprintf(full_tty, "/dev/%s", request->r_tty); 72*16362Skarels if (access(full_tty, 0) != 0) 73*16362Skarels return (FAILED); 74*16362Skarels if ((tf = fopen(full_tty, "w")) == NULL) 75*16362Skarels return (PERMISSION_DENIED); 76*16362Skarels /* 77*16362Skarels * Open gratuitously attaches the talkd to 78*16362Skarels * any tty it opens, so disconnect us from the 79*16362Skarels * tty before we catch a signal 80*16362Skarels */ 81*16362Skarels ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); 82*16362Skarels if (fstat(fileno(tf), &stbuf) < 0) 83*16362Skarels return (PERMISSION_DENIED); 84*16362Skarels if ((stbuf.st_mode&02) == 0) 85*16362Skarels return (PERMISSION_DENIED); 86*16362Skarels print_mesg(tf, request, remote_machine); 87*16362Skarels fclose(tf); 88*16362Skarels return (SUCCESS); 8916341Skarels } 9016341Skarels 9116341Skarels #define max(a,b) ( (a) > (b) ? (a) : (b) ) 9216341Skarels #define N_LINES 5 9316341Skarels #define N_CHARS 120 9416341Skarels 95*16362Skarels /* 96*16362Skarels * Build a block of characters containing the message. 97*16362Skarels * It is sent blank filled and in a single block to 98*16362Skarels * try to keep the message in one piece if the recipient 99*16362Skarels * in in vi at the time 100*16362Skarels */ 10116341Skarels print_mesg(tf, request, remote_machine) 102*16362Skarels FILE *tf; 103*16362Skarels CTL_MSG *request; 104*16362Skarels char *remote_machine; 10516341Skarels { 106*16362Skarels struct timeval clock; 107*16362Skarels struct timezone zone; 108*16362Skarels struct tm *localtime(); 109*16362Skarels struct tm *localclock; 110*16362Skarels char line_buf[N_LINES][N_CHARS]; 111*16362Skarels int sizes[N_LINES]; 112*16362Skarels char big_buf[N_LINES*N_CHARS]; 113*16362Skarels char *bptr, *lptr; 114*16362Skarels int i, j, max_size; 11516341Skarels 116*16362Skarels i = 0; 117*16362Skarels max_size = 0; 118*16362Skarels gettimeofday(&clock, &zone); 119*16362Skarels localclock = localtime( &clock.tv_sec ); 120*16362Skarels sprintf(line_buf[i], " "); 121*16362Skarels sizes[i] = strlen(line_buf[i]); 122*16362Skarels max_size = max(max_size, sizes[i]); 123*16362Skarels i++; 124*16362Skarels sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...", 12516341Skarels hostname, localclock->tm_hour , localclock->tm_min ); 126*16362Skarels sizes[i] = strlen(line_buf[i]); 127*16362Skarels max_size = max(max_size, sizes[i]); 128*16362Skarels i++; 129*16362Skarels sprintf(line_buf[i], "talk: connection requested by %s@%s.", 13016341Skarels request->l_name, remote_machine); 131*16362Skarels sizes[i] = strlen(line_buf[i]); 132*16362Skarels max_size = max(max_size, sizes[i]); 133*16362Skarels i++; 134*16362Skarels sprintf(line_buf[i], "talk: respond with: talk %s@%s", 13516341Skarels request->l_name, remote_machine); 136*16362Skarels sizes[i] = strlen(line_buf[i]); 137*16362Skarels max_size = max(max_size, sizes[i]); 138*16362Skarels i++; 139*16362Skarels sprintf(line_buf[i], " "); 140*16362Skarels sizes[i] = strlen(line_buf[i]); 141*16362Skarels max_size = max(max_size, sizes[i]); 142*16362Skarels i++; 143*16362Skarels bptr = big_buf; 144*16362Skarels *(bptr++) = ''; /* send something to wake them up */ 14516341Skarels *(bptr++) = '\r'; /* add a \r in case of raw mode */ 14616341Skarels *(bptr++) = '\n'; 147*16362Skarels for (i = 0; i < N_LINES; i++) { 148*16362Skarels /* copy the line into the big buffer */ 149*16362Skarels lptr = line_buf[i]; 150*16362Skarels while (*lptr != '\0') 151*16362Skarels *(bptr++) = *(lptr++); 152*16362Skarels /* pad out the rest of the lines with blanks */ 153*16362Skarels for (j = sizes[i]; j < max_size + 2; j++) 154*16362Skarels *(bptr++) = ' '; 155*16362Skarels *(bptr++) = '\r'; /* add a \r in case of raw mode */ 156*16362Skarels *(bptr++) = '\n'; 157*16362Skarels } 158*16362Skarels *bptr = '\0'; 159*16362Skarels fprintf(tf, big_buf); 160*16362Skarels fflush(tf); 161*16362Skarels ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); 16216341Skarels } 163