Annotation of researchv9/cmd/write.c, revision 1.1.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.