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

unix.superglobalmegacorp.com

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