|
|
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.