|
Lines 48-53
Link Here
|
| 48 |
#include <dbus/dbus.h> |
48 |
#include <dbus/dbus.h> |
| 49 |
#include <dbus/dbus-glib.h> |
49 |
#include <dbus/dbus-glib.h> |
| 50 |
|
50 |
|
|
|
51 |
#include <libudev.h> |
| 52 |
|
| 51 |
#include "../device_info.h" |
53 |
#include "../device_info.h" |
| 52 |
#include "../hald.h" |
54 |
#include "../hald.h" |
| 53 |
#include "../hald_dbus.h" |
55 |
#include "../hald_dbus.h" |
|
Lines 68-221
Link Here
|
| 68 |
#include "osspec_linux.h" |
70 |
#include "osspec_linux.h" |
| 69 |
|
71 |
|
| 70 |
static gboolean hald_done_synthesizing_coldplug = FALSE; |
72 |
static gboolean hald_done_synthesizing_coldplug = FALSE; |
|
|
73 |
struct udev *udev = NULL; |
| 74 |
struct udev_monitor *mon = NULL; |
| 71 |
|
75 |
|
| 72 |
static gboolean |
76 |
static gboolean |
| 73 |
hald_udev_data (GIOChannel *source, GIOCondition condition, gpointer user_data) |
77 |
hald_udev_data (GIOChannel *source, GIOCondition condition, gpointer user_data) |
| 74 |
{ |
78 |
{ |
| 75 |
int fd; |
|
|
| 76 |
int retval; |
| 77 |
struct msghdr smsg; |
| 78 |
struct cmsghdr *cmsg; |
| 79 |
struct iovec iov; |
| 80 |
struct ucred *cred; |
| 81 |
char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; |
| 82 |
|
| 83 |
char buf[4096]; |
| 84 |
size_t bufpos = 0; |
| 85 |
const char *action = NULL; |
79 |
const char *action = NULL; |
| 86 |
HotplugEvent *hotplug_event; |
80 |
HotplugEvent *hotplug_event; |
| 87 |
|
81 |
|
| 88 |
memset(buf, 0x00, sizeof (buf)); |
|
|
| 89 |
|
| 90 |
fd = g_io_channel_unix_get_fd (source); |
| 91 |
|
| 92 |
iov.iov_base = &buf; |
| 93 |
iov.iov_len = sizeof (buf); |
| 94 |
|
| 95 |
memset(&smsg, 0x00, sizeof (struct msghdr)); |
| 96 |
smsg.msg_iov = &iov; |
| 97 |
smsg.msg_iovlen = 1; |
| 98 |
smsg.msg_control = cred_msg; |
| 99 |
smsg.msg_controllen = sizeof (cred_msg); |
| 100 |
|
| 101 |
retval = recvmsg (fd, &smsg, 0); |
| 102 |
if (retval < 0) { |
| 103 |
if (errno != EINTR) |
| 104 |
HAL_INFO (("Unable to receive message, errno=%d", errno)); |
| 105 |
goto out; |
| 106 |
} |
| 107 |
cmsg = CMSG_FIRSTHDR (&smsg); |
| 108 |
cred = (struct ucred *) CMSG_DATA (cmsg); |
| 109 |
|
| 110 |
if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { |
| 111 |
HAL_INFO (("No sender credentials received, message ignored")); |
| 112 |
goto out; |
| 113 |
} |
| 114 |
|
| 115 |
if (cred->uid != 0) { |
| 116 |
HAL_INFO (("Sender uid=%i, message ignored", cred->uid)); |
| 117 |
goto out; |
| 118 |
} |
| 119 |
|
| 120 |
if (!strstr(buf, "@/")) { |
| 121 |
HAL_INFO (("invalid message format")); |
| 122 |
goto out; |
| 123 |
} |
| 124 |
|
| 125 |
hotplug_event = g_slice_new0 (HotplugEvent); |
82 |
hotplug_event = g_slice_new0 (HotplugEvent); |
| 126 |
hotplug_event->type = HOTPLUG_EVENT_SYSFS; |
83 |
hotplug_event->type = HOTPLUG_EVENT_SYSFS; |
| 127 |
|
84 |
|
| 128 |
while (bufpos < sizeof (buf)) { |
85 |
struct udev_device *dev = NULL; |
| 129 |
size_t keylen; |
86 |
if((dev=udev_monitor_receive_device(mon))) |
| 130 |
char *key; |
87 |
{ |
| 131 |
char *str, *dstr; |
88 |
char *str, *dstr; |
| 132 |
|
89 |
action = udev_device_get_action(dev); |
| 133 |
key = &buf[bufpos]; |
90 |
|
| 134 |
keylen = strlen(key); |
91 |
// md devices are handled via looking at /proc/mdstat |
| 135 |
if (keylen == 0) |
92 |
if (g_str_has_prefix (udev_device_get_devpath(dev), "/block/md")) { |
| 136 |
break; |
93 |
HAL_INFO (("skipping md event for %s", udev_device_get_devpath(dev))); |
| 137 |
bufpos += keylen + 1; |
94 |
goto invalid; |
| 138 |
|
95 |
} |
| 139 |
if (strncmp(key, "ACTION=", 7) == 0) |
96 |
g_snprintf (hotplug_event->sysfs.sysfs_path, sizeof(hotplug_event->sysfs.sysfs_path), "/sys%s", udev_device_get_devpath(dev)); |
| 140 |
action = &key[7]; |
97 |
g_strlcpy (hotplug_event->sysfs.subsystem, udev_device_get_subsystem(dev), sizeof(hotplug_event->sysfs.subsystem)); |
| 141 |
else if (strncmp(key, "DEVPATH=", 8) == 0) { |
98 |
g_strlcpy (hotplug_event->sysfs.device_file, udev_device_get_property_value(dev,"DEVNAME"), sizeof(hotplug_event->sysfs.device_file)); |
| 142 |
|
99 |
hotplug_event->sysfs.seqnum = udev_device_get_seqnum(dev); |
| 143 |
/* md devices are handled via looking at /proc/mdstat */ |
100 |
if((str=udev_device_get_property_value(dev,"IFINDEX"))) |
| 144 |
if (g_str_has_prefix (key + 8, "/block/md")) { |
101 |
hotplug_event->sysfs.net_ifindex = strtoul(str, NULL, 10); |
| 145 |
HAL_INFO (("skipping md event for %s", key + 8)); |
102 |
if((str=udev_device_get_property_value(dev,"ID_VENDOR")) && (str=hal_util_strdup_valid_utf8(str))) |
| 146 |
goto invalid; |
103 |
{ g_strlcpy (hotplug_event->sysfs.vendor, str, sizeof(hotplug_event->sysfs.vendor)); g_free (str); } |
| 147 |
} |
104 |
if((str=udev_device_get_property_value(dev,"ID_MODEL")) && (str=hal_util_strdup_valid_utf8(str))) |
| 148 |
|
105 |
{ g_strlcpy (hotplug_event->sysfs.model, str, sizeof(hotplug_event->sysfs.model)); g_free (str); } |
| 149 |
g_snprintf (hotplug_event->sysfs.sysfs_path, sizeof (hotplug_event->sysfs.sysfs_path), |
106 |
if((str=udev_device_get_property_value(dev,"ID_REVISION")) && (str=hal_util_strdup_valid_utf8(str))) |
| 150 |
"/sys%s", &key[8]); |
107 |
{ g_strlcpy (hotplug_event->sysfs.revision, str, sizeof(hotplug_event->sysfs.revision)); g_free (str); } |
| 151 |
} else if (strncmp(key, "DEVPATH_OLD=", 12) == 0) { |
108 |
if((str=udev_device_get_property_value(dev,"ID_SERIAL")) && (str=hal_util_strdup_valid_utf8(str))) |
| 152 |
|
109 |
{ g_strlcpy (hotplug_event->sysfs.serial, str, sizeof(hotplug_event->sysfs.serial)); g_free (str); } |
| 153 |
/* md devices are handled via looking at /proc/mdstat */ |
110 |
if((str=udev_device_get_property_value(dev,"ID_FS_USAGE")) && (str=hal_util_strdup_valid_utf8(str))) |
| 154 |
if (g_str_has_prefix (key + 12, "/block/md")) { |
111 |
{ g_strlcpy (hotplug_event->sysfs.fsusage, str, sizeof(hotplug_event->sysfs.fsusage)); g_free (str); } |
| 155 |
HAL_INFO (("skipping md event for %s", key + 8)); |
112 |
if((str=udev_device_get_property_value(dev,"ID_FS_TYPE")) && (str=hal_util_strdup_valid_utf8(str))) |
| 156 |
goto invalid; |
113 |
{ g_strlcpy (hotplug_event->sysfs.fstype, str, sizeof(hotplug_event->sysfs.fstype)); g_free (str); } |
| 157 |
} |
114 |
if((str=udev_device_get_property_value(dev,"ID_FS_VERSION")) && (str=hal_util_strdup_valid_utf8(str))) |
| 158 |
|
115 |
{ g_strlcpy (hotplug_event->sysfs.fsversion, str, sizeof(hotplug_event->sysfs.fsversion)); g_free (str); } |
| 159 |
g_snprintf (hotplug_event->sysfs.sysfs_path_old, sizeof (hotplug_event->sysfs.sysfs_path_old), |
116 |
if((str=udev_device_get_property_value(dev,"ID_FS_UUID")) && (str=hal_util_strdup_valid_utf8(str))) |
| 160 |
"/sys%s", &key[12]); |
117 |
{ g_strlcpy (hotplug_event->sysfs.fsuuid, str, sizeof(hotplug_event->sysfs.fsuuid)); g_free (str); } |
| 161 |
} else if (strncmp(key, "SUBSYSTEM=", 10) == 0) |
118 |
if((str=udev_device_get_property_value(dev,"ID_FS_LABEL_ENC"))) |
| 162 |
g_strlcpy (hotplug_event->sysfs.subsystem, &key[10], sizeof (hotplug_event->sysfs.subsystem)); |
119 |
{ |
| 163 |
else if (strncmp(key, "DEVNAME=", 8) == 0) |
120 |
dstr = g_malloc0(strlen(str)+1); |
| 164 |
g_strlcpy (hotplug_event->sysfs.device_file, &key[8], sizeof (hotplug_event->sysfs.device_file)); |
121 |
hal_util_decode_escape(str, dstr, sizeof(hotplug_event->sysfs.fslabel)); |
| 165 |
else if (strncmp(key, "SEQNUM=", 7) == 0) |
122 |
if((str=hal_util_strdup_valid_utf8(dstr))) |
| 166 |
hotplug_event->sysfs.seqnum = strtoull(&key[7], NULL, 10); |
123 |
{ g_strlcpy (hotplug_event->sysfs.fslabel, str, sizeof(hotplug_event->sysfs.fslabel)); g_free (str); } |
| 167 |
else if (strncmp(key, "IFINDEX=", 8) == 0) |
124 |
g_free(dstr); |
| 168 |
hotplug_event->sysfs.net_ifindex = strtoul(&key[8], NULL, 10); |
125 |
} |
| 169 |
else if (strncmp(key, "ID_VENDOR=", 10) == 0) { |
|
|
| 170 |
if ((str = hal_util_strdup_valid_utf8(&key[10])) != NULL ) { |
| 171 |
g_strlcpy (hotplug_event->sysfs.vendor, str, sizeof(hotplug_event->sysfs.vendor)); |
| 172 |
g_free (str); |
| 173 |
} |
| 174 |
} else if (strncmp(key, "ID_MODEL=", 9) == 0) { |
| 175 |
if ((str = hal_util_strdup_valid_utf8(&key[9])) != NULL ) { |
| 176 |
g_strlcpy (hotplug_event->sysfs.model, str, sizeof(hotplug_event->sysfs.model)); |
| 177 |
g_free (str); |
| 178 |
} |
| 179 |
} else if (strncmp(key, "ID_REVISION=", 12) == 0) { |
| 180 |
if ((str = hal_util_strdup_valid_utf8(&key[12])) != NULL ) { |
| 181 |
g_strlcpy (hotplug_event->sysfs.revision, str, sizeof(hotplug_event->sysfs.revision)); |
| 182 |
g_free (str); |
| 183 |
} |
| 184 |
} else if (strncmp(key, "ID_SERIAL=", 10) == 0) { |
| 185 |
if ((str = hal_util_strdup_valid_utf8(&key[10])) != NULL ) { |
| 186 |
g_strlcpy (hotplug_event->sysfs.serial, str, sizeof(hotplug_event->sysfs.serial)); |
| 187 |
g_free (str); |
| 188 |
} |
| 189 |
} else if (strncmp(key, "ID_FS_USAGE=", 12) == 0) { |
| 190 |
if ((str = hal_util_strdup_valid_utf8(&key[12])) != NULL ) { |
| 191 |
g_strlcpy (hotplug_event->sysfs.fsusage, str, sizeof(hotplug_event->sysfs.fsusage)); |
| 192 |
g_free (str); |
| 193 |
} |
| 194 |
} else if (strncmp(key, "ID_FS_TYPE=", 11) == 0) { |
| 195 |
if ((str = hal_util_strdup_valid_utf8(&key[11])) != NULL ) { |
| 196 |
g_strlcpy (hotplug_event->sysfs.fstype, str, sizeof(hotplug_event->sysfs.fstype)); |
| 197 |
g_free (str); |
| 198 |
} |
| 199 |
} else if (strncmp(key, "ID_FS_VERSION=", 14) == 0) { |
| 200 |
if ((str = hal_util_strdup_valid_utf8(&key[14])) != NULL ) { |
| 201 |
g_strlcpy (hotplug_event->sysfs.fsversion, str, sizeof(hotplug_event->sysfs.fsversion)); |
| 202 |
g_free (str); |
| 203 |
} |
| 204 |
} else if (strncmp(key, "ID_FS_UUID=", 11) == 0) { |
| 205 |
if ((str = hal_util_strdup_valid_utf8(&key[11])) != NULL ) { |
| 206 |
g_strlcpy (hotplug_event->sysfs.fsuuid, str, sizeof(hotplug_event->sysfs.fsuuid)); |
| 207 |
g_free (str); |
| 208 |
} |
| 209 |
} else if (strncmp(key, "ID_FS_LABEL_ENC=", 16) == 0) { |
| 210 |
dstr = g_malloc0 (keylen - 15); |
| 211 |
hal_util_decode_escape (&key[16], dstr, sizeof(hotplug_event->sysfs.fslabel)); |
| 212 |
|
| 213 |
if ((str = hal_util_strdup_valid_utf8(dstr)) != NULL ) { |
| 214 |
g_strlcpy (hotplug_event->sysfs.fslabel, str, sizeof(hotplug_event->sysfs.fslabel)); |
| 215 |
g_free (str); |
| 216 |
} |
| 217 |
g_free (dstr); |
| 218 |
} |
| 219 |
} |
126 |
} |
| 220 |
|
127 |
|
| 221 |
if (!action) { |
128 |
if (!action) { |
|
Lines 284-290
Link Here
|
| 284 |
|
191 |
|
| 285 |
invalid: |
192 |
invalid: |
| 286 |
g_slice_free (HotplugEvent, hotplug_event); |
193 |
g_slice_free (HotplugEvent, hotplug_event); |
| 287 |
|
194 |
if(dev) udev_device_unref(dev); |
| 288 |
out: |
195 |
out: |
| 289 |
return TRUE; |
196 |
return TRUE; |
| 290 |
} |
197 |
} |
|
Lines 430-438
Link Here
|
| 430 |
exit (1); |
337 |
exit (1); |
| 431 |
} |
338 |
} |
| 432 |
/* enable receiving of the sender credentials */ |
339 |
/* enable receiving of the sender credentials */ |
| 433 |
setsockopt(udev_socket, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); |
340 |
udev = udev_new(); |
|
|
341 |
mon = udev_monitor_new_from_netlink(udev, "udev"); |
| 342 |
udev_monitor_enable_receiving(mon); |
| 434 |
|
343 |
|
| 435 |
udev_channel = g_io_channel_unix_new (udev_socket); |
344 |
udev_channel = g_io_channel_unix_new (udev_monitor_get_fd(mon)); |
| 436 |
g_io_add_watch (udev_channel, G_IO_IN, hald_udev_data, NULL); |
345 |
g_io_add_watch (udev_channel, G_IO_IN, hald_udev_data, NULL); |
| 437 |
g_io_channel_unref (udev_channel); |
346 |
g_io_channel_unref (udev_channel); |
| 438 |
|
347 |
|