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