source: trunk/minix/commands/reboot/sh_wall.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 2.6 KB
Line 
1/* wall - write to all logged in users Author: V. Archer */
2/*
3 Edvard Tuinder v892231@si.hhs.NL
4 Modified some things to include this with my shutdown/halt
5 package
6 */
7
8#define _POSIX_SOURCE 1
9#include <sys/types.h>
10#include <fcntl.h>
11#include <pwd.h>
12#include <string.h>
13#include <stdio.h>
14#include <time.h>
15#include <utmp.h>
16#include <unistd.h>
17#include <sys/utsname.h>
18#include <sys/stat.h>
19#undef UTMP
20
21static char UTMP[] = "/etc/utmp"; /* Currently logged in users. */
22
23void wall _ARGS(( char *when, char *extra ));
24void crnlcat _ARGS(( char *message, char *more ));
25
26void
27wall(when, extra)
28char *when; /* When is shutdown */
29char *extra; /* If non-nil, why is the shutdown */
30{
31 struct utmp utmp;
32 char utmptty[5 + sizeof(utmp.ut_line) + 1];
33 char message[1024];
34 struct passwd *pw;
35 int utmpfd, ttyfd;
36 char *ourtty, *ourname;
37 time_t now;
38 struct utsname utsname;
39 struct stat con_st, tty_st;
40
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";
46
47 time(&now);
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));
51
52 crnlcat(message, when);
53 crnlcat(message, extra);
54
55/* Search the UTMP database for all logged-in users. */
56
57 if ((utmpfd = open(UTMP, O_RDONLY)) < 0) {
58 fprintf(stderr, "Cannot open utmp file\r\n");
59 return;
60 }
61
62 /* first the console */
63 strcpy(utmptty, "/dev/console");
64 if ((ttyfd = open(utmptty, O_WRONLY | O_NONBLOCK)) < 0) {
65 perror(utmptty);
66 } else {
67 fstat(ttyfd, &con_st);
68 write(ttyfd, message, strlen(message));
69 close(ttyfd);
70 }
71
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;
75
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) {
79 perror(utmptty);
80 continue;
81 }
82 fstat(ttyfd, &tty_st);
83 if (tty_st.st_rdev != con_st.st_rdev)
84 write(ttyfd, message, strlen(message));
85 close(ttyfd);
86 }
87 close(utmpfd);
88 return;
89}
90
91void
92crnlcat(message, more)
93char *message, *more;
94{
95 char *p = message;
96 char *m = more;
97 char *end = message + 1024 - 1;
98
99 while (p < end && *p != 0) *p++;
100
101 while (p < end && *m != 0) {
102 if (*m == '\n' && (p == message || p[-1] != '\n')) {
103 *p++ = '\r';
104 if (p == end) p--;
105 }
106 *p++ = *m++;
107 }
108 *p = 0;
109}
Note: See TracBrowser for help on using the repository browser.