Annotation of researchv9/cmd/write.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <signal.h>
        !             3: #include <utmp.h>
        !             4: #include <sys/types.h>
        !             5: #include <sys/stat.h>
        !             6: #include <sys/utsname.h>
        !             7: 
        !             8: #define        MAXPPL  15      /* maximum number of people to whom we can write */
        !             9: #define        TTYSIZ  16      /* path-name size for ttys */
        !            10: #define        PT      "pt/pt" /* we can also write directly to Jerq layers */
        !            11: #define UDIRSIZ        8       /* size of fields in utmp */
        !            12: 
        !            13: int num;
        !            14: int fd[MAXPPL + 1];
        !            15: char *logname, *mytty, *sysname;
        !            16: struct utmp ut[MAXPPL + 1];
        !            17: 
        !            18: main(argc, argv)
        !            19: int argc;
        !            20: char **argv;
        !            21: {
        !            22:        int x;
        !            23:        int cleanup();
        !            24:        char inp[BUFSIZ], mesg[BUFSIZ], strm[MAXPPL + 1][TTYSIZ];
        !            25:        char *getlogin(), *cttyname();
        !            26:        struct utsname ourname;
        !            27: 
        !            28:        signal(SIGHUP, cleanup);
        !            29:        signal(SIGINT, cleanup);
        !            30:        signal(SIGQUIT, cleanup);
        !            31: 
        !            32:        logname = getlogin();
        !            33:        if ((mytty = cttyname()) == 0)
        !            34:                error("write: Cannot find your tty.\n");
        !            35:        mytty += 5;             /* strip "/dev/" off of tty */
        !            36:        cktty(logname, mytty, 0);
        !            37:        uname(&ourname);
        !            38:        sysname = ourname.nodename;
        !            39: 
        !            40:        if (argc > MAXPPL + 1 || argc < 2) {
        !            41:                sprintf(mesg, "usage: write person1 [... person%d]\n", MAXPPL);
        !            42:                error(mesg);
        !            43:        }
        !            44:        num = argc - 1;
        !            45:        if ((fd[0] = open("/etc/utmp", 0)) < 0)
        !            46:                error("write: Cannot open /etc/utmp.\n");
        !            47:        while (read(fd[0], &ut[0], sizeof(struct utmp)) == sizeof(struct utmp))
        !            48:                for (x = 1; x <= num; x++)
        !            49:                        if (strncmp(ut[0].ut_name, argv[x], UDIRSIZ) == 0 ||
        !            50:                            strncmp(ut[0].ut_line, argv[x], UDIRSIZ) == 0)
        !            51:                                ut[x] = ut[0];
        !            52:                        else if (strncmp(argv[x], PT, strlen(PT)) == 0) {
        !            53:                                strcpy(ut[x].ut_name, argv[x]);
        !            54:                                strcpy(ut[x].ut_line, argv[x]);
        !            55:                        }
        !            56: 
        !            57:        for (x = 1; x <= num; x++) {
        !            58:                if (strcmp(ut[x].ut_name, "\0") == 0) {
        !            59:                        sprintf(mesg, "write: %s is not on.\n", argv[x]);
        !            60:                        error(mesg);
        !            61:                }
        !            62: 
        !            63:                if (strcmp(ut[x].ut_line, argv[x]) == 0)
        !            64:                        strcpy(ut[x].ut_name, ut[x].ut_line);
        !            65: 
        !            66:                cktty(ut[x].ut_name, ut[x].ut_line, 0);
        !            67:                strcpy(strm[x], "/dev/");
        !            68:                strcat(strm[x], ut[x].ut_line);
        !            69:                if ((fd[x] = open(strm[x], 1)) < 0) {
        !            70:                        sprintf(mesg, "write: Cannot open %s's tty.\n", argv[x]);
        !            71:                        error(mesg);
        !            72:                }
        !            73:        }
        !            74: 
        !            75:        people(mesg);
        !            76:        for (x = 1; x <= num; x++) {
        !            77:                write(fd[x], "\007\007\007write: ", 10);
        !            78:                write(fd[x], sysname, strlen(sysname));
        !            79:                write(fd[x], "!", 1);
        !            80:                write(fd[x], logname, strlen(logname));
        !            81:                write(fd[x], " on ", 4);
        !            82:                write(fd[x], mytty, strlen(mytty));
        !            83:                write(fd[x], " to ", 4);
        !            84:                write(fd[x], mesg, strlen(mesg));
        !            85:                write(fd[x], ".\n", 2);
        !            86:        }
        !            87:        while (fgets(inp, 512, stdin) != NULL)
        !            88:                if (inp[0] == '!')
        !            89:                        shell(inp);
        !            90:                else if (inp[0] == ':')
        !            91:                        colon(inp);
        !            92:                else
        !            93:                        for (x = 1; x <= num; x++) {
        !            94:                                if (num != 1) {
        !            95:                                        write(fd[x], logname, strlen(logname));
        !            96:                                        write(fd[x], ": ", 2);
        !            97:                                }
        !            98:                                write(fd[x], inp, strlen(inp));
        !            99:                        }
        !           100:        cleanup();
        !           101: }
        !           102: 
        !           103: cleanup()
        !           104: {
        !           105:        int x;
        !           106: 
        !           107:        for (x = 1; x <= num; x++) {
        !           108:                write(fd[x], "write: ", 7);
        !           109:                write(fd[x], logname, strlen(logname));
        !           110:                write(fd[x], ": EOF\n", 6);
        !           111:                close(fd[x]);
        !           112:        }
        !           113:        close(fd[0]);
        !           114:        exit(0);
        !           115: }
        !           116: 
        !           117: people(list)
        !           118: char *list;
        !           119: {
        !           120:        int x;
        !           121: 
        !           122:        strncpy(list, ut[1].ut_name, UDIRSIZ);
        !           123:        list[UDIRSIZ] = '\0';
        !           124:        if (num > 2) {
        !           125:                for (x = 2; x < num; x++) {
        !           126:                        strcat(list, ", ");
        !           127:                        strncat(list, ut[x].ut_name, UDIRSIZ);
        !           128:                }
        !           129:                strcat(list, ",");
        !           130:        }
        !           131:        if (num > 1) {
        !           132:                strcat(list, " and ");
        !           133:                strncat(list, ut[num].ut_name, UDIRSIZ);
        !           134:        }
        !           135: }
        !           136: 
        !           137: shell(str)
        !           138: char *str;
        !           139: {
        !           140:        int frkd;
        !           141:        int cleanup();
        !           142: 
        !           143:        signal(SIGINT, SIG_IGN);
        !           144:        signal(SIGQUIT, SIG_IGN);
        !           145:        if ((frkd = fork()) < 0)
        !           146:                printf("write: Cannot fork.\n");
        !           147:        if (frkd == 0) {
        !           148:                signal(SIGINT, SIG_DFL);
        !           149:                signal(SIGQUIT, SIG_DFL);
        !           150:                execl("/bin/sh", "sh", "-c", str + 1, 0);
        !           151:                exit(0);
        !           152:        }
        !           153:        if (frkd > 0)
        !           154:                wait(0);
        !           155:        signal(SIGINT, cleanup);
        !           156:        signal(SIGQUIT, cleanup);
        !           157:        printf("!\n");
        !           158: }
        !           159: 
        !           160: colon(arg)
        !           161: char *arg;
        !           162: {
        !           163:        char arg1[BUFSIZ], arg2[BUFSIZ];
        !           164: 
        !           165:        strcpy(arg1, "\0");
        !           166:        strcpy(arg2, "\0");
        !           167:        sscanf(arg, ":%s %s\n", arg1, arg2);
        !           168:        if (strlen(arg1) <= 1) {
        !           169:                if (strcmp(arg2, "\0") == 0 && (strcmp(arg1, "a") == 0 ||
        !           170:                    strcmp(arg1, "d") == 0))
        !           171:                        printf("write: missing argument to colon escape.\n");
        !           172:                else
        !           173:                        switch(arg1[0]) {
        !           174:                        case 'a':
        !           175:                                add(arg2);
        !           176:                                break;
        !           177:                        case 'd':
        !           178:                                drop(arg2);
        !           179:                                break;
        !           180:                        case 'l':
        !           181:                                plist();
        !           182:                                break;
        !           183:                        default:
        !           184:                                printf("write: unknown colon escape.\n");
        !           185:                        }
        !           186:        }
        !           187:        else
        !           188:                printf("write: unknown colon escape.\n");
        !           189: }
        !           190: 
        !           191: add(name)
        !           192: char *name;
        !           193: {
        !           194:        int x;
        !           195:        char dev[TTYSIZ], list[BUFSIZ];
        !           196: 
        !           197:        if (num + 1 > MAXPPL) {
        !           198:                printf("write: too many people.\n");
        !           199:                return;
        !           200:        }
        !           201: 
        !           202:        lseek(fd[0], 0L, 0);
        !           203:        while (read(fd[0], &ut[0], sizeof(struct utmp)) == sizeof(struct utmp))
        !           204:                if (strcmp(ut[0].ut_name, name) == 0 ||
        !           205:                    strcmp(ut[0].ut_line, name) == 0)
        !           206:                        ut[num + 1] = ut[0];
        !           207:                else if (strncmp(name, PT, strlen(PT)) == 0) {
        !           208:                        strcpy(ut[num + 1].ut_name, name);
        !           209:                        strcpy(ut[num + 1].ut_line, name);
        !           210:                }
        !           211: 
        !           212:        if (strcmp(ut[num + 1].ut_name, "\0") == 0) {
        !           213:                printf("write: %s is not on.\n", name);
        !           214:                return;
        !           215:        }
        !           216: 
        !           217:        if (strcmp(ut[num + 1].ut_line, name) == 0)
        !           218:                strcpy(ut[num + 1].ut_name, ut[num + 1].ut_line);
        !           219: 
        !           220:        if (cktty(name, ut[num + 1].ut_line, 1))
        !           221:                return;
        !           222:        strcpy(dev, "/dev/");
        !           223:        strcat(dev, ut[num + 1].ut_line);
        !           224:        if ((fd[num + 1] = open(dev, 1)) < 0) {
        !           225:                printf("write: Cannot open %s's tty.\n", name);
        !           226:                return;
        !           227:        }
        !           228: 
        !           229:        num++;
        !           230:        people(list);
        !           231:        write(fd[num], "\007\007\007write: ", 10);
        !           232:        write(fd[num], sysname, strlen(sysname));
        !           233:        write(fd[num], "!", 1);
        !           234:        write(fd[num], logname, strlen(logname));
        !           235:        write(fd[num], " on ", 4);
        !           236:        write(fd[num], mytty, strlen(mytty));
        !           237:        write(fd[num], " to ", 4);
        !           238:        write(fd[num], list, strlen(list));
        !           239:        write(fd[num], ".\n", 2);
        !           240:        for (x = 1; x < num; x++) {
        !           241:                write(fd[x], "\007\007\007write: ", 10);
        !           242:                write(fd[x], logname, strlen(logname));
        !           243:                write(fd[x], " on ", 4);
        !           244:                write(fd[x], mytty, strlen(mytty));
        !           245:                write(fd[x], " added ", 7);
        !           246:                write(fd[x], name, strlen(name));
        !           247:                write(fd[x], ".\n", 2);
        !           248:        }
        !           249: }
        !           250: 
        !           251: drop(name)
        !           252: char *name;
        !           253: {
        !           254:        int x;
        !           255:        int place = 0;
        !           256: 
        !           257:        for (x = 1; x <= num; x++)
        !           258:                if (strcmp(ut[x].ut_name, name) == 0)
        !           259:                        place = x;
        !           260:        if (place == 0)
        !           261:                printf("write: %s is not in the conversation.\n", name);
        !           262:        else {
        !           263:                write(fd[place], "\007\007\007write: ", 10);
        !           264:                write(fd[place], logname, strlen(logname));
        !           265:                write(fd[place], " on ", 4);
        !           266:                write(fd[place], mytty, strlen(mytty));
        !           267:                write(fd[place], " dropped you.\n", 14);
        !           268:                close(fd[place]);
        !           269:                for (x = place; x <= num; x++) {
        !           270:                        fd[x] = fd[x + 1];
        !           271:                        ut[x] = ut[x + 1];
        !           272:                }
        !           273:                num--;
        !           274: 
        !           275:                for (x = 1; x <= num; x++) {
        !           276:                        write(fd[x], "\007\007\007write: ", 10);
        !           277:                        write(fd[x], logname, strlen(logname));
        !           278:                        write(fd[x], " on ", 4);
        !           279:                        write(fd[x], mytty, strlen(mytty));
        !           280:                        write(fd[x], " dropped ", 9);
        !           281:                        write(fd[x], name, strlen(name));
        !           282:                        write(fd[x], ".\n", 2);
        !           283:                }
        !           284:        }
        !           285: }
        !           286: 
        !           287: plist()
        !           288: {
        !           289:        char list[BUFSIZ];
        !           290: 
        !           291:        people(list);
        !           292:        if (strlen(list) < 1)
        !           293:                printf("write: You're not talking to anyone.\n");
        !           294:        else
        !           295:                printf("write: You're talking to %s.\n", list);
        !           296: }
        !           297: 
        !           298: cktty(user, tty, flag)
        !           299: int flag;
        !           300: char *user, *tty;
        !           301: {
        !           302:        char bfr[TTYSIZ], msg[BUFSIZ];
        !           303:        struct stat sbuf;
        !           304: 
        !           305:        sprintf(bfr, "/dev/%s", tty);
        !           306:        if (stat(bfr, &sbuf) < 0) {
        !           307:                sprintf(msg, "write: Cannot stat %s's tty.\n", user);
        !           308:                if (flag) {
        !           309:                        fprintf(stderr, msg);
        !           310:                        return(1);
        !           311:                }
        !           312:                error(msg);
        !           313:        }
        !           314:        if (!(sbuf.st_mode & 02)) {
        !           315:                sprintf(msg, "write: %s's tty is protected.\n", user);
        !           316:                if (flag) {
        !           317:                        fprintf(stderr, msg);
        !           318:                        return(1);
        !           319:                }
        !           320:                error(msg);
        !           321:        }
        !           322: }
        !           323: 
        !           324: error(s)
        !           325: char *s;
        !           326: {
        !           327:        fprintf(stderr, s);
        !           328:        exit(0);
        !           329: }

unix.superglobalmegacorp.com

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