diff options
| author | Michael Biebl <biebl@debian.org> | 2019-04-21 21:09:51 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-04-21 21:09:51 +0200 |
| commit | 85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (patch) | |
| tree | cce7b0b02d28fae2df9fdf2c1804cacd1500f2d7 /shared/nm-utils/nm-udev-utils.c | |
| parent | 9a6dcbf895f9da01768e64b73cec88c16157d91e (diff) | |
New upstream version 1.18.0 upstream/1.18.0
Diffstat (limited to 'shared/nm-utils/nm-udev-utils.c')
| -rw-r--r-- | shared/nm-utils/nm-udev-utils.c | 291 |
1 files changed, 0 insertions, 291 deletions
diff --git a/shared/nm-utils/nm-udev-utils.c b/shared/nm-utils/nm-udev-utils.c deleted file mode 100644 index 5d0919b3..00000000 --- a/shared/nm-utils/nm-udev-utils.c +++ /dev/null @@ -1,291 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-udev-utils.c - udev utils functions - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2017 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-udev-utils.h" - -#include <libudev.h> - -struct _NMPUdevClient { - char **subsystems; - GSource *watch_source; - struct udev *udev; - struct udev_monitor *monitor; - NMUdevClientEvent event_handler; - gpointer event_user_data; -}; - -/*****************************************************************************/ - -gboolean -nm_udev_utils_property_as_boolean (const char *uproperty) -{ - /* taken from g_udev_device_get_property_as_boolean() */ - - if (uproperty) { - if ( strcmp (uproperty, "1") == 0 - || g_ascii_strcasecmp (uproperty, "true") == 0) - return TRUE; - } - return FALSE; -} - -const char * -nm_udev_utils_property_decode (const char *uproperty, char **to_free) -{ - const char *p; - char *unescaped = NULL; - char *n = NULL; - - if (!uproperty) { - *to_free = NULL; - return NULL; - } - - p = uproperty; - while (*p) { - int a, b; - - if ( p[0] == '\\' - && p[1] == 'x' - && (a = g_ascii_xdigit_value (p[2])) >= 0 - && (b = g_ascii_xdigit_value (p[3])) >= 0 - && (a || b)) { - if (!n) { - gssize l = p - uproperty; - - unescaped = g_malloc (l + strlen (p) + 1 - 3); - memcpy (unescaped, uproperty, l); - n = &unescaped[l]; - } - *n++ = (a << 4) | b; - p += 4; - } else { - if (n) - *n++ = *p; - p++; - } - } - - if (!n) { - *to_free = NULL; - return uproperty; - } - - *n++ = '\0'; - return (*to_free = unescaped); -} - -char * -nm_udev_utils_property_decode_cp (const char *uproperty) -{ - char *cpy; - - uproperty = nm_udev_utils_property_decode (uproperty, &cpy); - return cpy ?: g_strdup (uproperty); -} - -/*****************************************************************************/ - -static void -_subsystem_split (const char *subsystem_full, - const char **out_subsystem, - const char **out_devtype, - char **to_free) -{ - char *tmp, *s; - - nm_assert (subsystem_full); - nm_assert (out_subsystem); - nm_assert (out_devtype); - nm_assert (to_free); - - s = strstr (subsystem_full, "/"); - if (s) { - tmp = g_strdup (subsystem_full); - s = &tmp[s - subsystem_full]; - *s = '\0'; - *out_subsystem = tmp; - *out_devtype = &s[1]; - *to_free = tmp; - } else { - *out_subsystem = subsystem_full; - *out_devtype = NULL; - *to_free = NULL; - } -} - -static struct udev_enumerate * -nm_udev_utils_enumerate (struct udev *uclient, - const char *const*subsystems) -{ - struct udev_enumerate *enumerate; - guint n; - - enumerate = udev_enumerate_new (uclient); - - if (subsystems) { - for (n = 0; subsystems[n]; n++) { - const char *subsystem; - const char *devtype; - gs_free char *to_free = NULL; - - _subsystem_split (subsystems[n], &subsystem, &devtype, &to_free); - - udev_enumerate_add_match_subsystem (enumerate, subsystem); - - if (devtype != NULL) - udev_enumerate_add_match_property (enumerate, "DEVTYPE", devtype); - } - } - - return enumerate; -} - -struct udev * -nm_udev_client_get_udev (NMUdevClient *self) -{ - g_return_val_if_fail (self, NULL); - - return self->udev; -} - -struct udev_enumerate * -nm_udev_client_enumerate_new (NMUdevClient *self) -{ - g_return_val_if_fail (self, NULL); - - return nm_udev_utils_enumerate (self->udev, (const char *const*) self->subsystems); -} - -/*****************************************************************************/ - -static gboolean -monitor_event (GIOChannel *source, - GIOCondition condition, - gpointer user_data) -{ - NMUdevClient *self = user_data; - struct udev_device *udevice; - - if (!self->monitor) - goto out; - - udevice = udev_monitor_receive_device (self->monitor); - if (udevice == NULL) - goto out; - - self->event_handler (self, - udevice, - self->event_user_data); - udev_device_unref (udevice); - -out: - return TRUE; -} - -/** - * nm_udev_client_new: - * @subsystems: the subsystems - * @event_handler: callback for events - * @event_user_data: user-data for @event_handler - * - * Basically, it is g_udev_client_new(), and most notably - * g_udev_client_constructed(). - * - * Returns: a new NMUdevClient instance. - */ -NMUdevClient * -nm_udev_client_new (const char *const*subsystems, - NMUdevClientEvent event_handler, - gpointer event_user_data) -{ - NMUdevClient *self; - GIOChannel *channel; - guint n; - - self = g_slice_new0 (NMUdevClient); - - self->event_handler = event_handler; - self->event_user_data = event_user_data; - self->subsystems = subsystems && subsystems[0] ? g_strdupv ((char **) subsystems) : NULL; - - self->udev = udev_new (); - if (!self->udev) - goto fail; - - /* connect to event source */ - if (self->event_handler) { - self->monitor = udev_monitor_new_from_netlink (self->udev, "udev"); - if (!self->monitor) - goto fail; - - if (self->subsystems) { - /* install subsystem filters to only wake up for certain events */ - for (n = 0; self->subsystems[n]; n++) { - gs_free char *to_free = NULL; - const char *subsystem; - const char *devtype; - - _subsystem_split (self->subsystems[n], &subsystem, &devtype, &to_free); - udev_monitor_filter_add_match_subsystem_devtype (self->monitor, subsystem, devtype); - } - - /* listen to events, and buffer them */ - udev_monitor_set_receive_buffer_size (self->monitor, 4*1024*1024); - udev_monitor_enable_receiving (self->monitor); - channel = g_io_channel_unix_new (udev_monitor_get_fd (self->monitor)); - self->watch_source = g_io_create_watch (channel, G_IO_IN); - g_io_channel_unref (channel); - g_source_set_callback (self->watch_source, (GSourceFunc)(void (*) (void)) monitor_event, self, NULL); - g_source_attach (self->watch_source, g_main_context_get_thread_default ()); - g_source_unref (self->watch_source); - } - } - - return self; - -fail: - return nm_udev_client_unref (self); -} - -NMUdevClient * -nm_udev_client_unref (NMUdevClient *self) -{ - if (!self) - return NULL; - - if (self->watch_source) { - g_source_destroy (self->watch_source); - self->watch_source = NULL; - } - - udev_monitor_unref (self->monitor); - self->monitor = NULL; - udev_unref (self->udev); - self->udev = NULL; - - g_strfreev (self->subsystems); - - g_slice_free (NMUdevClient, self); - - return NULL; -} |