|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988, 1990 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: char copyright[] = ! 20: "@(#) Copyright (c) 1988 Regents of the University of California.\n\ ! 21: All rights reserved.\n"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)wall.c 5.12 (Berkeley) 6/29/90"; ! 26: #endif /* not lint */ ! 27: ! 28: /* ! 29: * This program is not related to David Wall, whose Stanford Ph.D. thesis ! 30: * is entitled "Mechanisms for Broadcast and Selective Broadcast". ! 31: */ ! 32: ! 33: #include <sys/param.h> ! 34: #include <sys/stat.h> ! 35: #include <sys/time.h> ! 36: #include <sys/uio.h> ! 37: #include <utmp.h> ! 38: #include <pwd.h> ! 39: #include <stdio.h> ! 40: #include <paths.h> ! 41: ! 42: #define IGNOREUSER "sleeper" ! 43: ! 44: int nobanner; ! 45: int mbufsize; ! 46: char *mbuf; ! 47: ! 48: /* ARGSUSED */ ! 49: main(argc, argv) ! 50: int argc; ! 51: char **argv; ! 52: { ! 53: extern int optind; ! 54: int ch; ! 55: struct iovec iov; ! 56: struct utmp utmp; ! 57: FILE *fp; ! 58: char *p, *ttymsg(); ! 59: ! 60: while ((ch = getopt(argc, argv, "n")) != EOF) ! 61: switch (ch) { ! 62: case 'n': ! 63: /* undoc option for shutdown: suppress banner */ ! 64: if (geteuid() == 0) ! 65: nobanner = 1; ! 66: break; ! 67: case '?': ! 68: default: ! 69: usage: ! 70: (void)fprintf(stderr, "usage: wall [file]\n"); ! 71: exit(1); ! 72: } ! 73: argc -= optind; ! 74: argv += optind; ! 75: if (argc > 1) ! 76: goto usage; ! 77: ! 78: makemsg(*argv); ! 79: ! 80: if (!(fp = fopen(_PATH_UTMP, "r"))) { ! 81: (void)fprintf(stderr, "wall: cannot read %s.\n", _PATH_UTMP); ! 82: exit(1); ! 83: } ! 84: iov.iov_base = mbuf; ! 85: iov.iov_len = mbufsize; ! 86: /* NOSTRICT */ ! 87: while (fread((char *)&utmp, sizeof(utmp), 1, fp) == 1) { ! 88: if (!utmp.ut_name[0] || ! 89: !strncmp(utmp.ut_name, IGNOREUSER, sizeof(utmp.ut_name))) ! 90: continue; ! 91: if (p = ttymsg(&iov, 1, utmp.ut_line)) ! 92: (void)fprintf(stderr, "wall: %s\n", p); ! 93: } ! 94: exit(0); ! 95: } ! 96: ! 97: makemsg(fname) ! 98: char *fname; ! 99: { ! 100: register int ch, cnt; ! 101: struct tm *lt; ! 102: struct passwd *pw, *getpwuid(); ! 103: struct stat sbuf; ! 104: time_t now, time(); ! 105: FILE *fp; ! 106: int fd; ! 107: char *p, *whom, hostname[MAXHOSTNAMELEN], lbuf[100], tmpname[15]; ! 108: char *getlogin(), *malloc(), *strcpy(), *ttyname(); ! 109: ! 110: (void)strcpy(tmpname, _PATH_TMP); ! 111: (void)strcat(tmpname, "/wall.XXXXXX"); ! 112: if (!(fd = mkstemp(tmpname)) || !(fp = fdopen(fd, "r+"))) { ! 113: (void)fprintf(stderr, "wall: can't open temporary file.\n"); ! 114: exit(1); ! 115: } ! 116: (void)unlink(tmpname); ! 117: ! 118: if (!nobanner) { ! 119: if (!(whom = getlogin())) ! 120: whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; ! 121: (void)gethostname(hostname, sizeof(hostname)); ! 122: (void)time(&now); ! 123: lt = localtime(&now); ! 124: ! 125: /* ! 126: * all this stuff is to blank out a square for the message; ! 127: * we wrap message lines at column 79, not 80, because some ! 128: * terminals wrap after 79, some do not, and we can't tell. ! 129: * Which means that we may leave a non-blank character ! 130: * in column 80, but that can't be helped. ! 131: */ ! 132: (void)fprintf(fp, "\r%79s\r\n", " "); ! 133: (void)sprintf(lbuf, "Broadcast Message from %s@%s", ! 134: whom, hostname); ! 135: (void)fprintf(fp, "%-79.79s\007\007\r\n", lbuf); ! 136: (void)sprintf(lbuf, " (%s) at %d:%02d ...", ttyname(2), ! 137: lt->tm_hour, lt->tm_min); ! 138: (void)fprintf(fp, "%-79.79s\r\n", lbuf); ! 139: } ! 140: (void)fprintf(fp, "%79s\r\n", " "); ! 141: ! 142: if (*fname && !(freopen(fname, "r", stdin))) { ! 143: (void)fprintf(stderr, "wall: can't read %s.\n", fname); ! 144: exit(1); ! 145: } ! 146: while (fgets(lbuf, sizeof(lbuf), stdin)) ! 147: for (cnt = 0, p = lbuf; ch = *p; ++p, ++cnt) { ! 148: if (cnt == 79 || ch == '\n') { ! 149: for (; cnt < 79; ++cnt) ! 150: putc(' ', fp); ! 151: putc('\r', fp); ! 152: putc('\n', fp); ! 153: cnt = 0; ! 154: } else ! 155: putc(ch, fp); ! 156: } ! 157: (void)fprintf(fp, "%79s\r\n", " "); ! 158: rewind(fp); ! 159: ! 160: if (fstat(fd, &sbuf)) { ! 161: (void)fprintf(stderr, "wall: can't stat temporary file.\n"); ! 162: exit(1); ! 163: } ! 164: mbufsize = sbuf.st_size; ! 165: if (!(mbuf = malloc((u_int)mbufsize))) { ! 166: (void)fprintf(stderr, "wall: out of memory.\n"); ! 167: exit(1); ! 168: } ! 169: if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) { ! 170: (void)fprintf(stderr, "wall: can't read temporary file.\n"); ! 171: exit(1); ! 172: } ! 173: (void)close(fd); ! 174: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.