smgl/simpleinit-msb: initial commit
[grimoire-witchcraft.git] / smgl / simpleinit-msb / patches / dowall.c.diff
blob64169a5c96773ecdcb828c172d895016dbb980fd
1 --- dowall.c 2001-09-26 12:59:46.000000000 +0200
2 +++ ../../sysvinit-2.86.ds1/src/dowall.c 2004-06-09 14:47:45.000000000 +0200
3 @@ -3,10 +3,10 @@
5 * Author: Miquel van Smoorenburg, miquels@cistron.nl
6 *
7 - * Version: @(#)dowall.c 2.79 11-Sep-2000 miquels@cistron.nl
8 + * Version: @(#)dowall.c 2.85-5 02-Jul-2003 miquels@cistron.nl
10 * This file is part of the sysvinit suite,
11 - * Copyright 1991-2000 Miquel van Smoorenburg.
12 + * Copyright 1991-2003 Miquel van Smoorenburg.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 @@ -15,6 +15,8 @@
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 +#include <sys/sysmacros.h>
21 +#include <limits.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25 @@ -26,29 +28,24 @@
26 #include <signal.h>
27 #include <setjmp.h>
29 -static jmp_buf jbuf;
31 -/* display pid of rpc.rwalld if wall() is called with 'remote' non-zero */
32 -#define RWALLDPID
33 +static sigjmp_buf jbuf;
36 * Alarm handler
38 /*ARGSUSED*/
39 -static void handler(arg)
40 -int arg;
41 +static void handler(int arg)
43 - signal(SIGALRM, handler);
44 - longjmp(jbuf, 1);
45 + siglongjmp(jbuf, 1);
50 * Print a text, escape all characters not in Latin-1.
52 -void feputs(char *line, FILE *fp)
53 +static void feputs(char *line, FILE *fp)
55 - unsigned char *p;
56 + unsigned char *p;
58 for (p = (unsigned char *)line; *p; p++) {
59 if (strchr("\t\r\n", *p) ||
60 @@ -62,35 +59,25 @@
64 -/*
65 - * Wall function.
66 - */
67 -void wall(char *text, int fromshutdown, int remote)
68 +static void getuidtty(char **userp, char **ttyp)
70 - FILE *tp;
71 - char line[81];
72 - char term[UT_LINESIZE+6];
73 - static char *user, ttynm[32], *date;
74 - char uidbuf[32];
75 - static int fd, init = 0;
76 - struct passwd *pwd;
77 - char *tty, *p;
78 - time_t t;
79 - struct utmp *utmp;
80 - uid_t uid;
81 + struct passwd *pwd;
82 + uid_t uid;
83 + char *tty;
84 + static char uidbuf[32];
85 + static char ttynm[32];
86 + static int init = 0;
88 - setutent();
89 + if (!init) {
91 - if (init == 0) {
92 uid = getuid();
93 - pwd = getpwuid(uid);
94 - sprintf (uidbuf, "uid %d", (int)uid);
95 - /*
96 - * display uid if no corresponding username found in
97 - * password file. superuser (uid 0) is always "root",
98 - * not "uid 0".
99 - */
100 - user = pwd ? pwd->pw_name : (uid == 0 ? "root" : uidbuf);
101 + if ((pwd = getpwuid(uid)) != NULL) {
102 + uidbuf[0] = 0;
103 + strncat(uidbuf, pwd->pw_name, sizeof(uidbuf) - 1);
104 + } else {
105 + sprintf(uidbuf, uid ? "uid %d" : "root", (int)uid);
108 if ((tty = ttyname(0)) != NULL) {
109 if (strncmp(tty, "/dev/", 5) == 0)
110 tty += 5;
111 @@ -98,9 +85,65 @@
112 } else
113 ttynm[0] = 0;
114 init++;
115 - signal(SIGALRM, handler);
119 + *userp = uidbuf;
120 + *ttyp = ttynm;
124 + * Check whether given filename looks like tty device.
125 + */
126 +static int file_isatty(const char *fname)
128 + struct stat st;
129 + int major;
131 + if (stat(fname, &st) < 0)
132 + return 0;
134 + if (st.st_nlink != 1 || !S_ISCHR(st.st_mode))
135 + return 0;
137 + /*
138 + * It would be an impossible task to list all major/minors
139 + * of tty devices here, so we just exclude the obvious
140 + * majors of which just opening has side-effects:
141 + * printers and tapes.
142 + */
143 + major = major(st.st_dev);
144 + if (major == 1 || major == 2 || major == 6 || major == 9 ||
145 + major == 12 || major == 16 || major == 21 || major == 27 ||
146 + major == 37 || major == 96 || major == 97 || major == 206 ||
147 + major == 230) return 0;
149 + return 1;
153 + * Wall function.
154 + */
155 +void wall(char *text, int fromshutdown, int remote)
157 + FILE *tp;
158 + struct sigaction sa;
159 + struct utmp *utmp;
160 + time_t t;
161 + char term[UT_LINESIZE+6];
162 + char line[81];
163 + char *date, *p;
164 + char *user, *tty;
165 + int fd, flags;
167 + /*
168 + * Make sure tp and fd aren't in a register. Some versions
169 + * of gcc clobber those after longjmp (or so I understand).
170 + */
171 + (void) &tp;
172 + (void) &fd;
174 + getuidtty(&user, &tty);
176 /* Get the time */
177 time(&t);
178 date = ctime(&t);
179 @@ -115,7 +158,7 @@
180 } else {
181 snprintf(line, sizeof(line),
182 "\007\r\nBroadcast message from %s %s(%s):\r\n\r\n",
183 - user, ttynm, date);
184 + user, tty, date);
188 @@ -124,50 +167,50 @@
189 if (fork() != 0)
190 return;
192 - siginterrupt (SIGALRM, 1);
193 + memset(&sa, 0, sizeof(sa));
194 + sa.sa_handler = handler;
195 + sa.sa_flags = 0;
196 + sigemptyset(&sa.sa_mask);
197 + sigaction(SIGALRM, &sa, NULL);
199 + setutent();
201 while ((utmp = getutent()) != NULL) {
202 if(utmp->ut_type != USER_PROCESS ||
203 utmp->ut_user[0] == 0) continue;
204 - term[sizeof(term) - 1] = 0;
205 - if (strncmp(utmp->ut_line, "/dev/", 5) == 0)
206 - strncpy(term, utmp->ut_line, sizeof(term)-1);
207 - else
208 - snprintf(term, sizeof(term), "/dev/%s",
209 - utmp->ut_line);
211 - /*
212 - * Sometimes the open/write hangs in spite of the O_NDELAY
213 - */
214 - alarm(2);
215 -#ifdef O_NDELAY
216 + if (strncmp(utmp->ut_line, "/dev/", 5) == 0) {
217 + term[0] = 0;
218 + strncat(term, utmp->ut_line, UT_LINESIZE);
219 + } else
220 + snprintf(term, sizeof(term), "/dev/%.*s",
221 + UT_LINESIZE, utmp->ut_line);
222 + if (strstr(term, "/../")) continue;
224 + fd = -1;
225 + tp = NULL;
228 * Open it non-delay
230 - if (setjmp(jbuf) == 0 &&
231 - (fd = open(term, O_WRONLY | O_NDELAY )) > 0) {
232 - if ((tp = fdopen(fd, "w")) != NULL) {
233 - fputs(line, tp);
234 - feputs(text, tp);
235 - fclose(tp);
236 - } else
237 - close(fd);
238 - fd = -1;
239 - alarm(0);
240 + if (sigsetjmp(jbuf, 1) == 0) {
241 + alarm(2);
242 + flags = O_WRONLY|O_NDELAY|O_NOCTTY;
243 + if (file_isatty(term) &&
244 + (fd = open(term, flags)) >= 0) {
245 + if (isatty(fd) &&
246 + (tp = fdopen(fd, "w")) != NULL) {
247 + fputs(line, tp);
248 + feputs(text, tp);
249 + fflush(tp);
253 + alarm(0);
254 if (fd >= 0) close(fd);
255 -#else
256 - if (setjmp(jbuf) == 0 && (tp = fopen(term, "w")) != NULL) {
257 - fputs(line, tp);
258 - feputs(text, tp);
259 - alarm(0);
260 - fclose(tp);
261 - tp = NULL;
263 if (tp != NULL) fclose(tp);
264 -#endif
265 - alarm(0);
267 endutent();
269 exit(0);