|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.