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