1 /* wall - write to all logged in users Author: V. Archer */
3 Edvard Tuinder v892231@si.hhs.NL
4 Modified some things to include this with my shutdown/halt
8 #define _POSIX_SOURCE 1
17 #include <sys/utsname.h>
21 static char UTMP
[] = "/etc/utmp"; /* Currently logged in users. */
23 void wall( char *when
, char *extra
);
24 void crnlcat( char *message
, char *more
);
28 char *when
; /* When is shutdown */
29 char *extra
; /* If non-nil, why is the shutdown */
32 char utmptty
[5 + sizeof(utmp
.ut_line
) + 1];
36 char *ourtty
, *ourname
;
38 struct utsname utsname
;
39 struct stat con_st
, tty_st
;
41 if ((ourtty
= ttyname(1))) {
42 if ((ourname
= strrchr(ourtty
, '/'))) ourtty
= ourname
+1;
43 } else ourtty
= "system task";
44 if ((pw
= getpwuid(getuid()))) ourname
= pw
->pw_name
;
45 else ourname
= "unknown";
48 if (uname(&utsname
) != 0) strcpy(utsname
.nodename
, "?");
49 sprintf(message
, "\r\nBroadcast message from %s@%s (%s)\r\n%.24s...\r\n",
50 ourname
, utsname
.nodename
, ourtty
, ctime(&now
));
52 crnlcat(message
, when
);
53 crnlcat(message
, extra
);
55 /* Search the UTMP database for all logged-in users. */
57 if ((utmpfd
= open(UTMP
, O_RDONLY
)) < 0) {
58 fprintf(stderr
, "Cannot open utmp file\r\n");
62 /* first the console */
63 strcpy(utmptty
, "/dev/console");
64 if ((ttyfd
= open(utmptty
, O_WRONLY
| O_NONBLOCK
)) < 0) {
67 fstat(ttyfd
, &con_st
);
68 write(ttyfd
, message
, strlen(message
));
72 while (read(utmpfd
, (char *) &utmp
, sizeof(utmp
)) == sizeof(utmp
)) {
73 /* is this the user we are looking for? */
74 if (utmp
.ut_type
!= USER_PROCESS
) continue;
76 strncpy(utmptty
+5, utmp
.ut_line
, sizeof(utmp
.ut_line
));
77 utmptty
[5 + sizeof(utmp
.ut_line
) + 1] = 0;
78 if ((ttyfd
= open(utmptty
, O_WRONLY
| O_NONBLOCK
)) < 0) {
82 fstat(ttyfd
, &tty_st
);
83 if (tty_st
.st_rdev
!= con_st
.st_rdev
)
84 write(ttyfd
, message
, strlen(message
));
92 crnlcat(message
, more
)
97 char *end
= message
+ 1024 - 1;
99 while (p
< end
&& *p
!= 0) p
++;
101 while (p
< end
&& *m
!= 0) {
102 if (*m
== '\n' && (p
== message
|| p
[-1] != '\n')) {