Annotation of cci/usr/src/ucb/talk/announce.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.