]>
git.ipfire.org Git - thirdparty/systemd.git/blob - udevmonitor.c
6f2844ff150b46265cd506184a4c06a64ed47d61
4 * Copyright (C) 2004-2006 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.
30 #include <sys/socket.h>
32 #include <sys/select.h>
33 #include <linux/types.h>
34 #include <linux/netlink.h>
39 static int uevent_netlink_sock
= -1;
40 static int udev_monitor_sock
= -1;
41 static volatile int udev_exit
;
43 static int init_udev_monitor_socket(void)
45 struct sockaddr_un saddr
;
47 const int feature_on
= 1;
50 memset(&saddr
, 0x00, sizeof(saddr
));
51 saddr
.sun_family
= AF_LOCAL
;
52 /* use abstract namespace for socket path */
53 strcpy(&saddr
.sun_path
[1], "/org/kernel/udev/monitor");
54 addrlen
= offsetof(struct sockaddr_un
, sun_path
) + strlen(saddr
.sun_path
+1) + 1;
56 udev_monitor_sock
= socket(AF_LOCAL
, SOCK_DGRAM
, 0);
57 if (udev_monitor_sock
== -1) {
58 fprintf(stderr
, "error getting socket: %s\n", strerror(errno
));
62 /* the bind takes care of ensuring only one copy running */
63 retval
= bind(udev_monitor_sock
, (struct sockaddr
*) &saddr
, addrlen
);
65 fprintf(stderr
, "bind failed: %s\n", strerror(errno
));
66 close(udev_monitor_sock
);
67 udev_monitor_sock
= -1;
71 /* enable receiving of the sender credentials */
72 setsockopt(udev_monitor_sock
, SOL_SOCKET
, SO_PASSCRED
, &feature_on
, sizeof(feature_on
));
77 static int init_uevent_netlink_sock(void)
79 struct sockaddr_nl snl
;
82 memset(&snl
, 0x00, sizeof(struct sockaddr_nl
));
83 snl
.nl_family
= AF_NETLINK
;
84 snl
.nl_pid
= getpid();
87 uevent_netlink_sock
= socket(PF_NETLINK
, SOCK_DGRAM
, NETLINK_KOBJECT_UEVENT
);
88 if (uevent_netlink_sock
== -1) {
89 fprintf(stderr
, "error getting socket: %s\n", strerror(errno
));
93 retval
= bind(uevent_netlink_sock
, (struct sockaddr
*) &snl
,
94 sizeof(struct sockaddr_nl
));
96 fprintf(stderr
, "bind failed: %s\n", strerror(errno
));
97 close(uevent_netlink_sock
);
98 uevent_netlink_sock
= -1;
105 static void asmlinkage
sig_handler(int signum
)
107 if (signum
== SIGINT
|| signum
== SIGTERM
)
111 int main(int argc
, char *argv
[])
113 struct sigaction act
;
119 for (i
= 1 ; i
< argc
; i
++) {
121 if (strcmp(arg
, "--env") == 0 || strcmp(arg
, "-e") == 0)
123 else if (strcmp(arg
, "--help") == 0 || strcmp(arg
, "-h") == 0){
124 printf("Usage: udevmonitor [--help] [--env]\n"
125 " --env print the whole event environment\n"
126 " --help print this help text\n\n");
129 fprintf(stderr
, "unrecognized option '%s'\n", arg
);
135 fprintf(stderr
, "root privileges required\n");
139 /* set signal handlers */
140 memset(&act
, 0x00, sizeof(struct sigaction
));
141 act
.sa_handler
= (void (*)(int)) sig_handler
;
142 sigemptyset(&act
.sa_mask
);
143 act
.sa_flags
= SA_RESTART
;
144 sigaction(SIGINT
, &act
, NULL
);
145 sigaction(SIGTERM
, &act
, NULL
);
147 retval
= init_udev_monitor_socket();
151 retval
= init_uevent_netlink_sock();
155 printf("udevmonitor prints the received event from the kernel [UEVENT]\n"
156 "and the event which udev sends out after rule processing [UDEV]\n\n");
159 char buf
[UEVENT_BUFFER_SIZE
*2];
168 if (uevent_netlink_sock
>= 0)
169 FD_SET(uevent_netlink_sock
, &readfds
);
170 if (udev_monitor_sock
>= 0)
171 FD_SET(udev_monitor_sock
, &readfds
);
173 fdcount
= select(UDEV_MAX(uevent_netlink_sock
, udev_monitor_sock
)+1, &readfds
, NULL
, NULL
, NULL
);
176 fprintf(stderr
, "error receiving uevent message: %s\n", strerror(errno
));
180 if (gettimeofday(&tv
, &tz
) == 0) {
181 snprintf(timestr
, sizeof(timestr
), "%llu.%06u",
182 (unsigned long long) tv
.tv_sec
, (unsigned int) tv
.tv_usec
);
186 if ((uevent_netlink_sock
>= 0) && FD_ISSET(uevent_netlink_sock
, &readfds
)) {
187 buflen
= recv(uevent_netlink_sock
, &buf
, sizeof(buf
), 0);
189 fprintf(stderr
, "error receiving uevent message: %s\n", strerror(errno
));
192 printf("UEVENT[%s] %s\n", timestr
, buf
);
195 if ((udev_monitor_sock
>= 0) && FD_ISSET(udev_monitor_sock
, &readfds
)) {
196 buflen
= recv(udev_monitor_sock
, &buf
, sizeof(buf
), 0);
198 fprintf(stderr
, "error receiving udev message: %s\n", strerror(errno
));
201 printf("UDEV [%s] %s\n", timestr
, buf
);
207 /* print environment */
211 /* start of payload */
212 bufpos
= strlen(buf
) + 1;
214 while (bufpos
< (size_t)buflen
) {
219 keylen
= strlen(key
);
223 bufpos
+= keylen
+ 1;
230 if (uevent_netlink_sock
>= 0)
231 close(uevent_netlink_sock
);
232 if (udev_monitor_sock
>= 0)
233 close(udev_monitor_sock
);