Annotation of coherent/d/bin/write.c, revision 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.