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