Annotation of coherent/d/bin/write.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Rec'd from Lauren Weinstein, 7-16-84.
                      3:  * Write to another user
                      4:  * on the system.
                      5:  * This is setuid in order to
                      6:  * use execute permission on the
                      7:  * terminal to allow/disallow writes.
                      8:  *
                      9:  * Compile -s -n -i
                     10:  */
                     11: 
                     12: #include <stdio.h>
                     13: #include <utmp.h>
                     14: #include <signal.h>
                     15: #include <sys/stat.h>
                     16: #include <sgtty.h>
                     17: 
                     18: #define FALSE  0
                     19: #define TRUE   1
                     20: 
                     21: #define        NSYSC   150             /* Maximum system call line */
                     22: FILE   *tf;
                     23: struct stat    sb;
                     24: struct sgttyb sgttyb, sgttys;  /* for user tty modes */
                     25: struct  sgttyb sgttyd;         /* for dest tty modes */
                     26: struct  tchars tchars;         /* for determining EOF char */
                     27: char sighup, sigquit, sigint;   /* signal change flags */
                     28: int     eofmark;               /* EOF marker */                
                     29: char   dtty[40] = "/dev/";
                     30: int    conopen;                /* TRUE if connection open */
                     31: int    status;                 /* exit status */       
                     32: int     dcrtmode;              /* non-zero for dest tty crt mode */
                     33: int     ucrtmode;              /* non-zero for user tty crt mode */
                     34: int    istty;                  /* TRUE if input is a tty */
                     35: int    quit();
                     36: char   *getutmp();
                     37: char   *getlogin();
                     38: char   *ttyname();
                     39: char   crtwarn[] = 
                     40: "Warning: One or both ttys is not a screen-oriented device.\n\
                     41:          Backspacing/character erase will not function properly...\n";
                     42: 
                     43: main(argc, argv)
                     44: char **argv;
                     45: {
                     46:        char *totty, *touname;
                     47:        char *fromtty, *fromuname;
                     48:        char crtmode = 0;       /* TRUE if both ttys are crt's */
                     49:        register int c;
                     50:        register int nlf = 1;
                     51: 
                     52:        if (argc == 3)
                     53:                totty = argv[2];
                     54:        else {
                     55:                if (argc != 2)
                     56:                        usage();
                     57:                totty = NULL;
                     58:        }
                     59:        touname = argv[1];
                     60: 
                     61:        gtty(0, &sgttyb);             /* get tty modes into buffer */
                     62:        if (sgttyb.sg_flags & CRT)    /* crt mode on user tty? */
                     63:           ucrtmode++;                /* yes */ 
                     64:        gtty(0, &sgttys);             /* save copy of original modes */
                     65: 
                     66:        fromuname = getlogin();          
                     67:        totty = getutmp(totty, touname);  
                     68:        strcat(dtty, totty);          /* build full ttyname */
                     69: 
                     70:        if ((fromtty = ttyname(fileno(stderr))) != NULL) {
                     71:                stat(fromtty, &sb);
                     72:                if ((sb.st_mode & S_IEXEC) == 0)
                     73:                        fprintf(stderr, "Warning: no reply possible\n");
                     74:                fromtty += 5;           /* Skip over `/dev/' */
                     75:        }
                     76:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                     77:        {   signal(SIGINT, &quit);         /* catch ints */
                     78:            sigint++;  /* flag we're catching ints */
                     79:        }
                     80:        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                     81:        {   signal(SIGHUP, &quit);       /* catch hangups */
                     82:            sighup++;  /* flag */
                     83:        }
                     84:        if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
                     85:        {  signal(SIGQUIT, &quit);       /* catch quits */
                     86:           sigquit++;
                     87:        }
                     88:        ioctl(0, TIOCGETC, &tchars);  /* get char settings */
                     89:        setup(touname, dtty);
                     90: 
                     91:        if (isatty(0))   /* input a tty? */
                     92:        {  istty = TRUE;  /* yes */
                     93:           eofmark = tchars.t_eofc;  /* set EOF marker */
                     94:        }
                     95:        else
                     96:           eofmark = EOF;  /* set EOF marker */
                     97: 
                     98:        if (!(crtmode = dcrtmode&ucrtmode))  /* check for both crt's */
                     99:           if (!ucrtmode && istty)           /* input not crt and not tty? */
                    100:              fprintf(stderr, crtwarn);      /* yes, warn user */
                    101:           
                    102:        conopen = TRUE;               /* flag connection open */
                    103:        sgttyb.sg_flags |= CBREAK;    /* want cbreak mode */
                    104:        stty(0, &sgttyb);             /* set new mode (no flush) */     
                    105:        
                    106:        /*
                    107:         * Turn off setuid privileges.
                    108:         */
                    109:        setuid(getuid());
                    110:        fprintf(tf, "\r\n\7Message from %s (%s) ...\r\n", fromuname, fromtty);
                    111:        printf("\r\nUser %s has been notified ...\r\n", touname);
                    112:        while ((c = getchar()) != eofmark) {  /* continue until end of file */
                    113:                if (nlf && c=='!') {
                    114:                   callsys();
                    115:                   continue;
                    116:                }
                    117:                if (c == '\n')
                    118:                   nlf = 1;
                    119:                else
                    120:                   nlf = 0;
                    121:                putc(c, tf);
                    122:                if (c == '\b' && crtmode)    /* backspace and crt's? */
                    123:                {  putc(' ', stdout);  /* erase local char */ 
                    124:                   putc('\b', stdout);                     
                    125:                   putc(' ', tf);      /* erase dest char */
                    126:                   putc('\b', tf);
                    127:                }
                    128:        }
                    129:        quit();
                    130: }
                    131: 
                    132: callsys()
                    133: {
                    134:        char sysline[NSYSC];
                    135:        register char *cp;
                    136:        register int c;
                    137: 
                    138:        cp = sysline;
                    139:        while ((c = getchar()) != '\n')
                    140:                if (cp < &sysline[NSYSC-1])
                    141:                        *cp++ = c;
                    142:        *cp = '\0';
                    143:        signal(SIGINT, SIG_IGN);   /* ignore ints */    
                    144:        signal(SIGHUP, SIG_IGN);   /* hups */
                    145:        signal(SIGQUIT, SIG_IGN);  /* and quits */
                    146:        stty(0, &sgttys);          /* restore original modes */
                    147:        system(sysline);           /* fork child command */
                    148:        stty(0, &sgttyb);          /* back to special modes */
                    149:        if (sigint)                /* restore int status */
                    150:           signal(SIGINT, &quit);
                    151:        if (sighup)                /* hup */
                    152:           signal(SIGHUP, &quit);
                    153:        if (sigquit)               /* quit */
                    154:           signal(SIGQUIT, &quit);
                    155:        printf("!\n");
                    156: }
                    157: 
                    158: /*
                    159:  * Check whether or not writes are
                    160:  * allowed to this terminal.
                    161:  */
                    162: setup(u, t)
                    163: char *u, *t;
                    164: {                                
                    165:        register char abortf = 0;
                    166:        register char c;
                    167:        
                    168:        if ((tf = fopen(t, "w")) == NULL)
                    169:                fprintf(stderr, "write: cannot open %s\n", t);
                    170:        if (gtty(fileno(tf), &sgttyd) >= 0)  /* stat dest tty */
                    171:           if (sgttyd.sg_flags & CRT)        /* crt mode on dest tty? */
                    172:              dcrtmode++;
                    173:        if (fstat(fileno(tf), &sb) < 0) {
                    174:                fprintf(stderr, "write: can't write to %s\n", u);       
                    175:                quiterr();      
                    176:        }
                    177:        if ((sb.st_mode&S_IEXEC) == 0) {
                    178:                if (getuid() == 0)  /* is our real uid su? */
                    179:                {  fprintf(stderr, 
                    180:                      "User \"%s\" is denying messages.  Override? ", u);
                    181:                   if ((c = getchar()) != 'y')
                    182:                      abortf++;  /* flag abort */  
                    183:                   while (c != EOF && c != '\n')  /* flush remaining input */
                    184:                      c = getchar();
                    185:                   if ( ! abortf)  /* override requested? */
                    186:                      return;  /* allow write */
                    187:                   else
                    188:                      quit();
                    189:                }
                    190:                fprintf(stderr, "write: no permission to write to %s\n", u);
                    191:                quiterr();
                    192:        }
                    193: }
                    194: 
                    195: /*
                    196:  * Return the tty for the specified
                    197:  * username and possibly tty
                    198:  * from the utmp file.
                    199:  */
                    200: char *
                    201: getutmp(t, u)
                    202: char *t, *u;
                    203: {
                    204:        register FILE *fp;
                    205:        static struct utmp ut;
                    206: 
                    207: 
                    208:        if ((fp = fopen("/etc/utmp", "r")) == NULL) {
                    209:                fprintf(stderr, "write: /etc/utmp not accessible\n");
                    210:                quiterr();
                    211:        }
                    212:        
                    213:        while (fread(&ut, sizeof ut, 1, fp) == 1) {
                    214:                if (strncmp(ut.ut_name, u, DIRSIZ) != 0)
                    215:                        continue;
                    216:                if (t != NULL)
                    217:                        if (strncmp(ut.ut_line, t, 8) == 0) {
                    218:                                fclose(fp);
                    219:                                return (t);
                    220:                        } else
                    221:                                continue;
                    222:                ut.ut_line[8] == '\0';
                    223:                fclose(fp);
                    224:                return (ut.ut_line);
                    225:        }
                    226:        if (t == NULL)
                    227:                fprintf(stderr, "write: %s not logged in\n", u);
                    228:        else
                    229:                fprintf(stderr, "write: %s not logged onto %s\n", u, t);
                    230:        quiterr();
                    231: }
                    232: 
                    233: quit()
                    234: {
                    235:        if (conopen)          /* if connection open */
                    236:        {  stty(0, &sgttys);  /* normal mode */
                    237:           fprintf(tf, "EOT\n");
                    238:           fclose(tf);        /* close connection */
                    239:        }
                    240:        exit(status);  
                    241: }
                    242: 
                    243: quiterr()
                    244: {
                    245:        status = 1;  /* exit with error status */
                    246:        quit();
                    247: }
                    248: 
                    249: usage()
                    250: {
                    251:        fprintf(stderr, "Usage: write username [ttyname]\n");
                    252:        quit(1);
                    253: }
                    254: 
                    255: 

unix.superglobalmegacorp.com

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