|
|
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.3 (Berkeley) 3/13/86"; ! 9: #endif not lint ! 10: ! 11: #include <sys/types.h> ! 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> ! 19: #include <syslog.h> ! 20: ! 21: #include <protocols/talkd.h> ! 22: ! 23: extern int errno; ! 24: extern char hostname[]; ! 25: ! 26: /* ! 27: * Announce an invitation to talk. ! 28: * ! 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: */ ! 33: announce(request, remote_machine) ! 34: CTL_MSG *request; ! 35: char *remote_machine; ! 36: { ! 37: int pid, val, status; ! 38: ! 39: if (pid = fork()) { ! 40: /* we are the parent, so wait for the child */ ! 41: if (pid == -1) /* the fork failed */ ! 42: return (FAILED); ! 43: do { ! 44: val = wait(&status); ! 45: if (val == -1) { ! 46: if (errno == EINTR) ! 47: continue; ! 48: /* shouldn't happen */ ! 49: syslog(LOG_WARNING, "announce: wait: %m"); ! 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); ! 57: } ! 58: /* we are the child, go and do it */ ! 59: _exit(announce_proc(request, remote_machine)); ! 60: } ! 61: ! 62: /* ! 63: * See if the user is accepting messages. If so, announce that ! 64: * a talk is requested. ! 65: */ ! 66: announce_proc(request, remote_machine) ! 67: CTL_MSG *request; ! 68: char *remote_machine; ! 69: { ! 70: int pid, status; ! 71: char full_tty[32]; ! 72: FILE *tf; ! 73: struct stat stbuf; ! 74: ! 75: sprintf(full_tty, "/dev/%s", request->r_tty); ! 76: if (access(full_tty, 0) != 0) ! 77: return (FAILED); ! 78: if ((tf = fopen(full_tty, "w")) == NULL) ! 79: return (PERMISSION_DENIED); ! 80: /* ! 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. ! 84: */ ! 85: ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); ! 86: if (fstat(fileno(tf), &stbuf) < 0) ! 87: return (PERMISSION_DENIED); ! 88: if ((stbuf.st_mode&020) == 0) ! 89: return (PERMISSION_DENIED); ! 90: print_mesg(tf, request, remote_machine); ! 91: fclose(tf); ! 92: return (SUCCESS); ! 93: } ! 94: ! 95: #define max(a,b) ( (a) > (b) ? (a) : (b) ) ! 96: #define N_LINES 5 ! 97: #define N_CHARS 120 ! 98: ! 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: */ ! 105: print_mesg(tf, request, remote_machine) ! 106: FILE *tf; ! 107: CTL_MSG *request; ! 108: char *remote_machine; ! 109: { ! 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 ...", ! 129: hostname, localclock->tm_hour , localclock->tm_min ); ! 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.", ! 134: request->l_name, remote_machine); ! 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", ! 139: request->l_name, remote_machine); ! 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; ! 148: *bptr++ = ''; /* send something to wake them up */ ! 149: *bptr++ = '\r'; /* add a \r in case of raw mode */ ! 150: *bptr++ = '\n'; ! 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); ! 166: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.