|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)announce.c 5.8 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include <sys/types.h> ! 25: #include <sys/stat.h> ! 26: #include <sgtty.h> ! 27: #include <sys/ioctl.h> ! 28: #include <sys/time.h> ! 29: #include <stdio.h> ! 30: #include <sys/wait.h> ! 31: #include <errno.h> ! 32: #include <syslog.h> ! 33: ! 34: #include <protocols/talkd.h> ! 35: #include <paths.h> ! 36: ! 37: extern int errno; ! 38: extern char hostname[]; ! 39: ! 40: /* ! 41: * Announce an invitation to talk. ! 42: * ! 43: * Because the tty driver insists on attaching a terminal-less ! 44: * process to any terminal that it writes on, we must fork a child ! 45: * to protect ourselves ! 46: */ ! 47: announce(request, remote_machine) ! 48: CTL_MSG *request; ! 49: char *remote_machine; ! 50: { ! 51: int pid, val, status; ! 52: ! 53: if (pid = fork()) { ! 54: /* we are the parent, so wait for the child */ ! 55: if (pid == -1) /* the fork failed */ ! 56: return (FAILED); ! 57: do { ! 58: val = wait(&status); ! 59: if (val == -1) { ! 60: if (errno == EINTR) ! 61: continue; ! 62: /* shouldn't happen */ ! 63: syslog(LOG_WARNING, "announce: wait: %m"); ! 64: return (FAILED); ! 65: } ! 66: } while (val != pid); ! 67: if (status&0377 > 0) /* we were killed by some signal */ ! 68: return (FAILED); ! 69: /* Get the second byte, this is the exit/return code */ ! 70: return ((status >> 8) & 0377); ! 71: } ! 72: /* we are the child, go and do it */ ! 73: _exit(announce_proc(request, remote_machine)); ! 74: } ! 75: ! 76: /* ! 77: * See if the user is accepting messages. If so, announce that ! 78: * a talk is requested. ! 79: */ ! 80: announce_proc(request, remote_machine) ! 81: CTL_MSG *request; ! 82: char *remote_machine; ! 83: { ! 84: int pid, status; ! 85: char full_tty[32]; ! 86: FILE *tf; ! 87: struct stat stbuf; ! 88: ! 89: (void)sprintf(full_tty, "%s/%s", _PATH_DEV, request->r_tty); ! 90: if (access(full_tty, 0) != 0) ! 91: return (FAILED); ! 92: if ((tf = fopen(full_tty, "w")) == NULL) ! 93: return (PERMISSION_DENIED); ! 94: /* ! 95: * On first tty open, the server will have ! 96: * it's pgrp set, so disconnect us from the ! 97: * tty before we catch a signal. ! 98: */ ! 99: ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); ! 100: if (fstat(fileno(tf), &stbuf) < 0) ! 101: return (PERMISSION_DENIED); ! 102: if ((stbuf.st_mode&020) == 0) ! 103: return (PERMISSION_DENIED); ! 104: print_mesg(tf, request, remote_machine); ! 105: fclose(tf); ! 106: return (SUCCESS); ! 107: } ! 108: ! 109: #define max(a,b) ( (a) > (b) ? (a) : (b) ) ! 110: #define N_LINES 5 ! 111: #define N_CHARS 120 ! 112: ! 113: /* ! 114: * Build a block of characters containing the message. ! 115: * It is sent blank filled and in a single block to ! 116: * try to keep the message in one piece if the recipient ! 117: * in in vi at the time ! 118: */ ! 119: print_mesg(tf, request, remote_machine) ! 120: FILE *tf; ! 121: CTL_MSG *request; ! 122: char *remote_machine; ! 123: { ! 124: struct timeval clock; ! 125: struct timezone zone; ! 126: struct tm *localtime(); ! 127: struct tm *localclock; ! 128: char line_buf[N_LINES][N_CHARS]; ! 129: int sizes[N_LINES]; ! 130: char big_buf[N_LINES*N_CHARS]; ! 131: char *bptr, *lptr; ! 132: int i, j, max_size; ! 133: ! 134: i = 0; ! 135: max_size = 0; ! 136: gettimeofday(&clock, &zone); ! 137: localclock = localtime( &clock.tv_sec ); ! 138: (void)sprintf(line_buf[i], " "); ! 139: sizes[i] = strlen(line_buf[i]); ! 140: max_size = max(max_size, sizes[i]); ! 141: i++; ! 142: (void)sprintf(line_buf[i], "Message from Talk_Daemon@%s at %d:%02d ...", ! 143: hostname, localclock->tm_hour , localclock->tm_min ); ! 144: sizes[i] = strlen(line_buf[i]); ! 145: max_size = max(max_size, sizes[i]); ! 146: i++; ! 147: (void)sprintf(line_buf[i], "talk: connection requested by %s@%s.", ! 148: request->l_name, remote_machine); ! 149: sizes[i] = strlen(line_buf[i]); ! 150: max_size = max(max_size, sizes[i]); ! 151: i++; ! 152: (void)sprintf(line_buf[i], "talk: respond with: talk %s@%s", ! 153: request->l_name, remote_machine); ! 154: sizes[i] = strlen(line_buf[i]); ! 155: max_size = max(max_size, sizes[i]); ! 156: i++; ! 157: (void)sprintf(line_buf[i], " "); ! 158: sizes[i] = strlen(line_buf[i]); ! 159: max_size = max(max_size, sizes[i]); ! 160: i++; ! 161: bptr = big_buf; ! 162: *bptr++ = ''; /* send something to wake them up */ ! 163: *bptr++ = '\r'; /* add a \r in case of raw mode */ ! 164: *bptr++ = '\n'; ! 165: for (i = 0; i < N_LINES; i++) { ! 166: /* copy the line into the big buffer */ ! 167: lptr = line_buf[i]; ! 168: while (*lptr != '\0') ! 169: *(bptr++) = *(lptr++); ! 170: /* pad out the rest of the lines with blanks */ ! 171: for (j = sizes[i]; j < max_size + 2; j++) ! 172: *(bptr++) = ' '; ! 173: *(bptr++) = '\r'; /* add a \r in case of raw mode */ ! 174: *(bptr++) = '\n'; ! 175: } ! 176: *bptr = '\0'; ! 177: fprintf(tf, big_buf); ! 178: fflush(tf); ! 179: ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); ! 180: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.