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