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