]>
git.ipfire.org Git - thirdparty/systemd.git/blob - udevmonitor.c
4 * Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation version 2 of the License.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <sys/socket.h>
31 #include <sys/select.h>
32 #include <linux/types.h>
33 #include <linux/netlink.h>
37 #include "udev_utils.h"
38 #include "udev_libc_wrapper.h"
40 static int uevent_netlink_sock
;
41 static int udev_monitor_sock
;
42 static volatile int udev_exit
;
44 static int init_udev_monitor_socket(void)
46 struct sockaddr_un saddr
;
48 const int feature_on
= 1;
51 memset(&saddr
, 0x00, sizeof(saddr
));
52 saddr
.sun_family
= AF_LOCAL
;
53 /* use abstract namespace for socket path */
54 strcpy(&saddr
.sun_path
[1], "/org/kernel/udev/monitor");
55 addrlen
= offsetof(struct sockaddr_un
, sun_path
) + strlen(saddr
.sun_path
+1) + 1;
57 udev_monitor_sock
= socket(AF_LOCAL
, SOCK_DGRAM
, 0);
58 if (udev_monitor_sock
== -1) {
59 fprintf(stderr
, "error getting socket: %s\n", strerror(errno
));
63 /* the bind takes care of ensuring only one copy running */
64 retval
= bind(udev_monitor_sock
, (struct sockaddr
*) &saddr
, addrlen
);
66 fprintf(stderr
, "bind failed: %s\n", strerror(errno
));
67 close(udev_monitor_sock
);
68 udev_monitor_sock
= -1;
72 /* enable receiving of the sender credentials */
73 setsockopt(udev_monitor_sock
, SOL_SOCKET
, SO_PASSCRED
, &feature_on
, sizeof(feature_on
));
78 static int init_uevent_netlink_sock(void)
80 struct sockaddr_nl snl
;
83 memset(&snl
, 0x00, sizeof(struct sockaddr_nl
));
84 snl
.nl_family
= AF_NETLINK
;
85 snl
.nl_pid
= getpid();
86 snl
.nl_groups
= 0xffffffff;
88 uevent_netlink_sock
= socket(PF_NETLINK
, SOCK_DGRAM
, NETLINK_KOBJECT_UEVENT
);
89 if (uevent_netlink_sock
== -1) {
90 fprintf(stderr
, "error getting socket: %s\n", strerror(errno
));
94 retval
= bind(uevent_netlink_sock
, (struct sockaddr
*) &snl
,
95 sizeof(struct sockaddr_nl
));
97 fprintf(stderr
, "bind failed: %s\n", strerror(errno
));
98 close(uevent_netlink_sock
);
99 uevent_netlink_sock
= -1;
106 static void asmlinkage
sig_handler(int signum
)
108 if (signum
== SIGINT
|| signum
== SIGTERM
)
112 int main(int argc
, char *argv
[])
114 struct sigaction act
;
120 for (i
= 1 ; i
< argc
; i
++) {
122 if (strcmp(arg
, "--env") == 0 || strcmp(arg
, "-e") == 0) {
125 else if (strcmp(arg
, "--help") == 0 || strcmp(arg
, "-h") == 0){
126 printf("Usage: udevmonitor [--env]\n"
127 " --env print the whole event environment\n"
128 " --help print this help text\n\n");
131 fprintf(stderr
, "unknown option\n\n");
137 fprintf(stderr
, "need to be root, exit\n\n");
141 /* set signal handlers */
142 memset(&act
, 0x00, sizeof(struct sigaction
));
143 act
.sa_handler
= (void (*)(int)) sig_handler
;
144 sigemptyset(&act
.sa_mask
);
145 act
.sa_flags
= SA_RESTART
;
146 sigaction(SIGINT
, &act
, NULL
);
147 sigaction(SIGTERM
, &act
, NULL
);
149 retval
= init_udev_monitor_socket();
152 retval
= init_uevent_netlink_sock();
156 printf("udevmonitor prints the received event from the kernel [UEVENT]\n"
157 "and the event which udev sends out after rule processing [UDEV]\n\n");
160 static char buf
[UEVENT_BUFFER_SIZE
*2];
169 if (uevent_netlink_sock
> 0)
170 FD_SET(uevent_netlink_sock
, &readfds
);
171 if (udev_monitor_sock
> 0)
172 FD_SET(udev_monitor_sock
, &readfds
);
174 fdcount
= select(UDEV_MAX(uevent_netlink_sock
, udev_monitor_sock
)+1, &readfds
, NULL
, NULL
, NULL
);
177 fprintf(stderr
, "error receiving uevent message: %s\n", strerror(errno
));
181 if (gettimeofday(&tv
, &tz
) == 0) {
182 snprintf(timestr
, sizeof(timestr
), "%llu.%06u",
183 (unsigned long long) tv
.tv_sec
, (unsigned int) tv
.tv_usec
);
187 if ((uevent_netlink_sock
> 0) && FD_ISSET(uevent_netlink_sock
, &readfds
)) {
188 buflen
= recv(uevent_netlink_sock
, &buf
, sizeof(buf
), 0);
190 fprintf(stderr
, "error receiving uevent message: %s\n", strerror(errno
));
193 printf("UEVENT[%s] %s\n", timestr
, buf
);
196 if ((udev_monitor_sock
> 0) && FD_ISSET(udev_monitor_sock
, &readfds
)) {
197 buflen
= recv(udev_monitor_sock
, &buf
, sizeof(buf
), 0);
199 fprintf(stderr
, "error receiving udev message: %s\n", strerror(errno
));
202 printf("UDEV [%s] %s\n", timestr
, buf
);
208 /* print environment */
212 /* start of payload */
213 bufpos
= strlen(buf
) + 1;
215 while (bufpos
< (size_t)buflen
) {
220 keylen
= strlen(key
);
224 bufpos
+= keylen
+ 1;
231 if (uevent_netlink_sock
> 0)
232 close(uevent_netlink_sock
);
233 if (udev_monitor_sock
> 0)
234 close(udev_monitor_sock
);