e480eee651daaf44b8b905366b3064cb5b657e79
[sysvinit.git] / src / wall.c
1 /*
2 * wall.c Write to all users logged in.
3 *
4 * Usage: wall [text]
5 *
6 * Version: @(#)wall 2.79 12-Sep-2000 miquels@cistron.nl
7 *
8 * This file is part of the sysvinit suite,
9 * Copyright (C) 1991-2000 Miquel van Smoorenburg.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <pwd.h>
31 #include <syslog.h>
32 #include "init.h"
33
34
35 char *Version = "@(#) wall 2.79 12-Sep-2000 miquels@cistron.nl";
36 #define MAXLEN 4096
37 #define MAXLINES 20
38
39 int main(int argc, char **argv)
40 {
41 char buf[MAXLEN];
42 char line[83];
43 int i, f, ch;
44 int len = 0;
45 int remote = 0;
46 char *p;
47 char *whoami;
48 struct passwd *pwd;
49
50 buf[0] = 0;
51 if ((pwd = getpwuid(getuid())) == NULL) {
52 if (getuid() == 0)
53 whoami = "root";
54 else {
55 fprintf(stderr, "You don't exist. Go away.\n");
56 exit(1);
57 }
58 } else
59 whoami = pwd->pw_name;
60
61 while((ch = getopt(argc, argv, "n")) != EOF)
62 switch(ch) {
63 case 'n':
64 /*
65 * Undocumented option for suppressing
66 * banner from rpc.rwalld. Only works if
67 * we are root or if we're NOT setgid.
68 */
69 if (geteuid() != 0 && getgid() != getegid()) {
70 fprintf(stderr, "wall -n: not priviliged\n");
71 exit(1);
72 }
73 remote = 1;
74 break;
75 default:
76 fprintf(stderr, "usage: wall [message]\n");
77 return 1;
78 break;
79 }
80
81 if ((argc - optind) > 0) {
82 for(f = optind; f < argc; f++) {
83 len += strlen(argv[f]) + 1;
84 if (len >= MAXLEN-2) break;
85 strcat(buf, argv[f]);
86 if (f < argc-1) strcat(buf, " ");
87 }
88 strcat(buf, "\r\n");
89 } else {
90 while(fgets(line, 80, stdin)) {
91 /*
92 * Make sure that line ends in \r\n
93 */
94 for(p = line; *p && *p != '\r' && *p != '\n'; p++)
95 ;
96 strcpy(p, "\r\n");
97 len += strlen(line);
98 if (len >= MAXLEN) break;
99 strcat(buf, line);
100 }
101 }
102
103 i = 0;
104 for (p = buf; *p; p++) {
105 if (*p == '\n' && ++i >= MAXLINES) {
106 *++p = 0;
107 break;
108 }
109 }
110
111 openlog("wall", LOG_PID, LOG_USER);
112 syslog(LOG_INFO, "wall: user %s broadcasted %d lines (%zu chars)",
113 whoami, i, strlen(buf));
114 closelog();
115
116 unsetenv("TZ");
117 wall(buf, remote);
118
119 /*NOTREACHED*/
120 return 0;
121 }
122