Annotation of coherent/d/bin/msg.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Rec'd from Lauren Weinstein, 7-16-84.
        !             3:  * Send a one-line message to
        !             4:  * another user or a number of users.
        !             5:  * This is setuid in order to
        !             6:  * use execute permission on the
        !             7:  * terminal to allow/disallow msgs.
        !             8:  *
        !             9:  * The super user may use the "-s" flag to suppress the user id
        !            10:  * prefix on messages, which also suppresses any error messages,
        !            11:  * and forces an exit code of 0 unless an error condition occurs.
        !            12:  * This is mainly for use by other programs (e.g. "rmail").
        !            13:  */
        !            14: 
        !            15: #include <stdio.h>
        !            16: #include <utmp.h>
        !            17: #include <sys/stat.h>
        !            18: #include <signal.h>
        !            19: 
        !            20: #define        MAXMSG  256             /* Longest message allowable */
        !            21: #define        NUSER   100             /* Maximum number of users to send to */
        !            22: #define ALARMT  10             /* Message send timeout in seconds */
        !            23: 
        !            24: char   msgbuf[MAXMSG];
        !            25: struct users {
        !            26:        char    *u_name;
        !            27:        int     u_flag;
        !            28: }      users[NUSER];
        !            29: 
        !            30: int    wtimeout;   /* non-zero for timeout on tty write */
        !            31: int     suppress;   /* non-zero to suppress id headers, etc. */
        !            32: 
        !            33: char   usemsg[] = "\
        !            34: Usage: msg user\n\
        !            35:        msg user ... message\n\
        !            36: ";
        !            37: 
        !            38: char   *getlogin();
        !            39: char   *ttyname();
        !            40: int    catch();
        !            41: 
        !            42: main(argc, argv)
        !            43: char *argv[];
        !            44: {
        !            45:        char *fromuname;
        !            46:        register int i;
        !            47:        register struct users *ulp = users;
        !            48: 
        !            49: 
        !            50:        /* are we the superuser and was the "-s" flag given? */
        !            51:        if (!geteuid() && argc > 1 && !strcmp(argv[1], "-s"))
        !            52:        {  suppress++;  /* set "suppress user id" prefix flag */
        !            53:           close(2);    /* close error output */
        !            54:           open("/dev/null", 1);  /* reopen fd 2 on /dev/null */ 
        !            55:           argc--;      /* adjust args */       
        !            56:           argv++;
        !            57:        }
        !            58: 
        !            59:        if (argc < 2)
        !            60:                usage();
        !            61:        if ((fromuname = getlogin()) == NULL)
        !            62:                fromuname = "daemon";
        !            63:        if (argc==2 || strcmp(argv[argc-1], "-")==0)
        !            64:                fgets(msgbuf, MAXMSG, stdin);
        !            65:        else {
        !            66:                strcpy(msgbuf, argv[argc-1]);
        !            67:                strcat(msgbuf, "\r\n");
        !            68:        }
        !            69:        if (argc == 2)
        !            70:                (ulp++)->u_name = argv[1];
        !            71:        else
        !            72:                for (i=1; i<argc-1; i++)
        !            73:                        (ulp++)->u_name = argv[i];
        !            74:        exit(msg(suppress ? 0 : fromuname));
        !            75: }
        !            76: 
        !            77: /*
        !            78:  * Find out terminal names for the
        !            79:  * given user-list and complain about
        !            80:  * those not logged in.
        !            81:  */
        !            82: msg(f)
        !            83: char *f;
        !            84: {
        !            85:        register struct users *up;
        !            86:        register FILE *fp;
        !            87:        register int st = 0;
        !            88:        static struct utmp ut;
        !            89: 
        !            90:        if ((fp = fopen("/etc/utmp", "r")) == NULL) {
        !            91:                fprintf(stderr, "msg: /etc/utmp not accessible\n");
        !            92:                exit(2);
        !            93:        }
        !            94:        while (fread(&ut, sizeof ut, 1, fp) == 1) {
        !            95:                if (ut.ut_name[0] == '\0')
        !            96:                        continue;
        !            97:                for (up = users; up->u_name != NULL; up++)
        !            98:                        if (strncmp(ut.ut_name, up->u_name, DIRSIZ) == 0)
        !            99:                                break;
        !           100:                if (up->u_name == NULL)
        !           101:                        continue;
        !           102:                send(f, &ut);
        !           103:                up->u_flag = 1;
        !           104:        }
        !           105:        for (up = users; up->u_name != NULL; up++)
        !           106:                if (up->u_flag == 0) {
        !           107:                        fprintf(stderr, "%s: not logged in\n", up->u_name);
        !           108:                        if (!suppress)
        !           109:                           st = 1;  /* indicate user not logged in */
        !           110:                }
        !           111:        return(st);
        !           112: }
        !           113: 
        !           114: /*
        !           115:  * Send the message.  Return non-zero if
        !           116:  * it does not work or is not allowed.
        !           117:  */
        !           118: send(f, up)
        !           119: char *f;
        !           120: register struct utmp *up;
        !           121: {
        !           122:        FILE *tf;
        !           123:        register struct stat sb;
        !           124:        char tty[40], c;
        !           125:        register char abortf = 0;
        !           126: 
        !           127:        sprintf(tty, "/dev/%.*s", sizeof up->ut_line, up->ut_line);
        !           128:        if ((tf = fopen(tty, "w")) == NULL) {
        !           129:                fprintf(stderr, "msg: cannot open %.*s\n",
        !           130:                    sizeof up->ut_line, up->ut_line);
        !           131:                return;
        !           132:        }
        !           133:        if (fstat(fileno(tf), &sb) < 0) 
        !           134:        {       fprintf(stderr, "msg: can't send to %.*s\n",
        !           135:                    sizeof up->ut_name, up->ut_name);
        !           136:                fclose(tf);
        !           137:                return;
        !           138:        }
        !           139:        if ((sb.st_mode&S_IEXEC) == 0) {
        !           140:                if (!getuid())  /* is our real uid su? */
        !           141:                {  fprintf(stderr, 
        !           142:                      "User \"%.*s\" is denying messages.  Override? ",
        !           143:                      sizeof up->ut_name, up->ut_name);
        !           144:                   if ((c = getchar()) != 'y')
        !           145:                      abortf++;  /* flag abort */  
        !           146:                   while (c != EOF && c != '\n')  /* flush remaining input */
        !           147:                      c = getchar();
        !           148:                   if (abortf)  /* don't want override? */
        !           149:                   {  fclose(tf);  
        !           150:                      return;
        !           151:                   }
        !           152:                }
        !           153:                else
        !           154:                {  fprintf(stderr, "write: no permission to write to %.*s\n",
        !           155:                      sizeof up->ut_name, up->ut_name);
        !           156:                   fclose(tf);
        !           157:                   return;      
        !           158:                }
        !           159:        }       
        !           160:        signal(SIGALRM, &catch);  /* catch alarms */
        !           161:        alarm(ALARMT);            /* set timeout */
        !           162:        if (f == NULL)
        !           163:                fprintf(tf, "\r\n\007%s", msgbuf);  /* send the msg */
        !           164:        else
        !           165:                fprintf(tf, "\r\n\007%s: %s", f, msgbuf);
        !           166:        alarm(0);                 /* turn off timeout */
        !           167:        if (wtimeout)             /* timeout on write? */
        !           168:        {  wtimeout = 0;          /* clear timeout flag */
        !           169:           fprintf(stderr, "msg: can't send to %.*s\n",
        !           170:              sizeof up->ut_name, up->ut_name);
        !           171:        }
        !           172:         fclose(tf);
        !           173: }
        !           174: 
        !           175: /* for alarm timeout */
        !           176: catch()
        !           177: {
        !           178:        wtimeout++;  /* set write timeout flag */
        !           179: }
        !           180: 
        !           181: usage()
        !           182: {
        !           183:        fprintf(stderr, usemsg);
        !           184:        exit(2);
        !           185: }
        !           186: 
        !           187: 

unix.superglobalmegacorp.com

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