chiark / gitweb /
Remove src/udev
authorAndy Wingo <wingo@pobox.com>
Sun, 19 Apr 2015 11:28:47 +0000 (13:28 +0200)
committerAndy Wingo <wingo@pobox.com>
Sun, 19 Apr 2015 11:32:26 +0000 (13:32 +0200)
63 files changed:
src/udev/.gitignore [deleted file]
src/udev/.vimrc [deleted file]
src/udev/Makefile [deleted symlink]
src/udev/accelerometer/Makefile [deleted symlink]
src/udev/accelerometer/accelerometer.c [deleted file]
src/udev/ata_id/Makefile [deleted symlink]
src/udev/ata_id/ata_id.c [deleted file]
src/udev/cdrom_id/Makefile [deleted symlink]
src/udev/cdrom_id/cdrom_id.c [deleted file]
src/udev/collect/Makefile [deleted symlink]
src/udev/collect/collect.c [deleted file]
src/udev/mtd_probe/Makefile [deleted symlink]
src/udev/mtd_probe/mtd_probe.c [deleted file]
src/udev/mtd_probe/mtd_probe.h [deleted file]
src/udev/mtd_probe/probe_smartmedia.c [deleted file]
src/udev/net/.gitignore [deleted file]
src/udev/net/Makefile [deleted symlink]
src/udev/net/ethtool-util.c [deleted file]
src/udev/net/ethtool-util.h [deleted file]
src/udev/net/link-config-gperf.gperf [deleted file]
src/udev/net/link-config.c [deleted file]
src/udev/net/link-config.h [deleted file]
src/udev/scsi_id/.gitignore [deleted file]
src/udev/scsi_id/Makefile [deleted symlink]
src/udev/scsi_id/README [deleted file]
src/udev/scsi_id/scsi.h [deleted file]
src/udev/scsi_id/scsi_id.c [deleted file]
src/udev/scsi_id/scsi_id.h [deleted file]
src/udev/scsi_id/scsi_serial.c [deleted file]
src/udev/udev-builtin-blkid.c [deleted file]
src/udev/udev-builtin-btrfs.c [deleted file]
src/udev/udev-builtin-hwdb.c [deleted file]
src/udev/udev-builtin-input_id.c [deleted file]
src/udev/udev-builtin-keyboard.c [deleted file]
src/udev/udev-builtin-kmod.c [deleted file]
src/udev/udev-builtin-net_id.c [deleted file]
src/udev/udev-builtin-net_setup_link.c [deleted file]
src/udev/udev-builtin-path_id.c [deleted file]
src/udev/udev-builtin-uaccess.c [deleted file]
src/udev/udev-builtin-usb_id.c [deleted file]
src/udev/udev-builtin.c [deleted file]
src/udev/udev-ctrl.c [deleted file]
src/udev/udev-event.c [deleted file]
src/udev/udev-node.c [deleted file]
src/udev/udev-rules.c [deleted file]
src/udev/udev-watch.c [deleted file]
src/udev/udev.conf [deleted file]
src/udev/udev.h [deleted file]
src/udev/udev.pc.in [deleted file]
src/udev/udevadm-control.c [deleted file]
src/udev/udevadm-hwdb.c [deleted file]
src/udev/udevadm-info.c [deleted file]
src/udev/udevadm-monitor.c [deleted file]
src/udev/udevadm-settle.c [deleted file]
src/udev/udevadm-test-builtin.c [deleted file]
src/udev/udevadm-test.c [deleted file]
src/udev/udevadm-trigger.c [deleted file]
src/udev/udevadm-util.c [deleted file]
src/udev/udevadm-util.h [deleted file]
src/udev/udevadm.c [deleted file]
src/udev/udevd.c [deleted file]
src/udev/v4l_id/Makefile [deleted symlink]
src/udev/v4l_id/v4l_id.c [deleted file]

diff --git a/src/udev/.gitignore b/src/udev/.gitignore
deleted file mode 100644 (file)
index ba112ce..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/udev.pc
-/keyboard-keys-from-name.gperf
-/keyboard-keys-from-name.h
-/keyboard-keys-to-name.h
-/keyboard-keys-list.txt
diff --git a/src/udev/.vimrc b/src/udev/.vimrc
deleted file mode 100644 (file)
index 366fbdc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-" 'set exrc' in ~/.vimrc will read .vimrc from the current directory
-set tabstop=8
-set shiftwidth=8
-set expandtab
diff --git a/src/udev/Makefile b/src/udev/Makefile
deleted file mode 120000 (symlink)
index d0b0e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/src/udev/accelerometer/Makefile b/src/udev/accelerometer/Makefile
deleted file mode 120000 (symlink)
index d0b0e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/src/udev/accelerometer/accelerometer.c b/src/udev/accelerometer/accelerometer.c
deleted file mode 100644 (file)
index 9e2c590..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * accelerometer - exports device orientation through property
- *
- * When an "change" event is received on an accelerometer,
- * open its device node, and from the value, as well as the previous
- * value of the property, calculate the device's new orientation,
- * and export it as ID_INPUT_ACCELEROMETER_ORIENTATION.
- *
- * Possible values are:
- * undefined
- * * normal
- * * bottom-up
- * * left-up
- * * right-up
- *
- * The property will be persistent across sessions, and the new
- * orientations can be deducted from the previous one (it allows
- * for a threshold for switching between opposite ends of the
- * orientation).
- *
- * Copyright (C) 2011 Red Hat, Inc.
- * Author:
- *   Bastien Nocera <hadess@hadess.net>
- *
- * orientation_calc() from the sensorfw package
- * Copyright (C) 2009-2010 Nokia Corporation
- * Authors:
- *   Üstün Ergenoglu <ext-ustun.ergenoglu@nokia.com>
- *   Timo Rongas <ext-timo.2.rongas@nokia.com>
- *   Lihan Guo <lihan.guo@digia.com>
- *
- * 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 of the License, 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.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <limits.h>
-#include <linux/input.h>
-
-#include "libudev.h"
-#include "libudev-private.h"
-
-/* we must use this kernel-compatible implementation */
-#define BITS_PER_LONG (sizeof(unsigned long) * 8)
-#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
-#define OFF(x)  ((x)%BITS_PER_LONG)
-#define BIT(x)  (1UL<<OFF(x))
-#define LONG(x) ((x)/BITS_PER_LONG)
-#define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
-
-typedef enum {
-        ORIENTATION_UNDEFINED,
-        ORIENTATION_NORMAL,
-        ORIENTATION_BOTTOM_UP,
-        ORIENTATION_LEFT_UP,
-        ORIENTATION_RIGHT_UP
-} OrientationUp;
-
-static const char *orientations[] = {
-        "undefined",
-        "normal",
-        "bottom-up",
-        "left-up",
-        "right-up",
-        NULL
-};
-
-#define ORIENTATION_UP_UP ORIENTATION_NORMAL
-
-#define DEFAULT_THRESHOLD 250
-#define RADIANS_TO_DEGREES 180.0/M_PI
-#define SAME_AXIS_LIMIT 5
-
-#define THRESHOLD_LANDSCAPE  25
-#define THRESHOLD_PORTRAIT  20
-
-static const char *
-orientation_to_string (OrientationUp o)
-{
-        return orientations[o];
-}
-
-static OrientationUp
-string_to_orientation (const char *orientation)
-{
-        int i;
-
-        if (orientation == NULL)
-                return ORIENTATION_UNDEFINED;
-        for (i = 0; orientations[i] != NULL; i++) {
-                if (streq (orientation, orientations[i]))
-                        return i;
-        }
-        return ORIENTATION_UNDEFINED;
-}
-
-static OrientationUp
-orientation_calc (OrientationUp prev,
-                  int x, int y, int z)
-{
-        int rotation;
-        OrientationUp ret = prev;
-
-        /* Portrait check */
-        rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES);
-
-        if (abs(rotation) > THRESHOLD_PORTRAIT) {
-                ret = (rotation < 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;
-
-                /* Some threshold to switching between portrait modes */
-                if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) {
-                        if (abs(rotation) < SAME_AXIS_LIMIT) {
-                                ret = prev;
-                        }
-                }
-
-        } else {
-                /* Landscape check */
-                rotation = round(atan((double) y / sqrt(x * x + z * z)) * RADIANS_TO_DEGREES);
-
-                if (abs(rotation) > THRESHOLD_LANDSCAPE) {
-                        ret = (rotation < 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;
-
-                        /* Some threshold to switching between landscape modes */
-                        if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) {
-                                if (abs(rotation) < SAME_AXIS_LIMIT) {
-                                        ret = prev;
-                                }
-                        }
-                }
-        }
-
-        return ret;
-}
-
-static OrientationUp
-get_prev_orientation(struct udev_device *dev)
-{
-        const char *value;
-
-        value = udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER_ORIENTATION");
-        if (value == NULL)
-                return ORIENTATION_UNDEFINED;
-        return string_to_orientation(value);
-}
-
-#define READ_AXIS(axis, var) { memzero(&abs_info, sizeof(abs_info)); r = ioctl(fd, EVIOCGABS(axis), &abs_info); if (r < 0) return; var = abs_info.value; }
-
-/* accelerometers */
-static void test_orientation(struct udev *udev,
-                             struct udev_device *dev,
-                             const char *devpath)
-{
-        OrientationUp old, new;
-        _cleanup_close_ int fd = -1;
-        struct input_absinfo abs_info;
-        int x = 0, y = 0, z = 0;
-        int r;
-        char text[64];
-
-        old = get_prev_orientation(dev);
-
-        fd = open(devpath, O_RDONLY|O_CLOEXEC);
-        if (fd < 0)
-                return;
-
-        READ_AXIS(ABS_X, x);
-        READ_AXIS(ABS_Y, y);
-        READ_AXIS(ABS_Z, z);
-
-        new = orientation_calc(old, x, y, z);
-        snprintf(text, sizeof(text),
-                 "ID_INPUT_ACCELEROMETER_ORIENTATION=%s", orientation_to_string(new));
-        puts(text);
-}
-
-static void help(void) {
-
-        printf("%s [options] <device path>\n\n"
-               "Accelerometer device identification.\n\n"
-               "  -h --help  Print this message\n"
-               "  -d --debug Debug to stderr\n"
-               , program_invocation_short_name);
-}
-
-int main (int argc, char** argv)
-{
-        struct udev *udev;
-        struct udev_device *dev;
-
-        static const struct option options[] = {
-                { "debug", no_argument, NULL, 'd' },
-                { "help", no_argument, NULL, 'h' },
-                {}
-        };
-
-        char devpath[PATH_MAX];
-        char *devnode;
-        struct udev_enumerate *enumerate;
-        struct udev_list_entry *list_entry;
-
-        log_parse_environment();
-        log_open();
-
-        udev = udev_new();
-        if (udev == NULL)
-                return 1;
-
-        /* CLI argument parsing */
-        while (1) {
-                int option;
-
-                option = getopt_long(argc, argv, "dh", options, NULL);
-                if (option == -1)
-                        break;
-
-                switch (option) {
-                case 'd':
-                        log_set_target(LOG_TARGET_CONSOLE);
-                        log_set_max_level(LOG_DEBUG);
-                        log_open();
-                        break;
-                case 'h':
-                        help();
-                        exit(0);
-                default:
-                        exit(1);
-                }
-        }
-
-        if (argv[optind] == NULL) {
-                help();
-                exit(1);
-        }
-
-        /* get the device */
-        snprintf(devpath, sizeof(devpath), "/sys/%s", argv[optind]);
-        dev = udev_device_new_from_syspath(udev, devpath);
-        if (dev == NULL) {
-                fprintf(stderr, "unable to access '%s'\n", devpath);
-                return 1;
-        }
-
-        /* Get the children devices and find the devnode */
-        devnode = NULL;
-        enumerate = udev_enumerate_new(udev);
-        udev_enumerate_add_match_parent(enumerate, dev);
-        udev_enumerate_scan_devices(enumerate);
-        udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
-                struct udev_device *device;
-                const char *node;
-
-                device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
-                                                      udev_list_entry_get_name(list_entry));
-                if (device == NULL)
-                        continue;
-                /* Already found it */
-                if (devnode != NULL) {
-                        udev_device_unref(device);
-                        continue;
-                }
-
-                node = udev_device_get_devnode(device);
-                if (node == NULL) {
-                        udev_device_unref(device);
-                        continue;
-                }
-                /* Use the event sub-device */
-                if (strstr(node, "/event") == NULL) {
-                        udev_device_unref(device);
-                        continue;
-                }
-
-                devnode = strdup(node);
-                udev_device_unref(device);
-        }
-
-        if (devnode == NULL) {
-                fprintf(stderr, "unable to get device node for '%s'\n", devpath);
-                return 0;
-        }
-
-        log_debug("opening accelerometer device %s", devnode);
-        test_orientation(udev, dev, devnode);
-        free(devnode);
-        log_close();
-        return 0;
-}
diff --git a/src/udev/ata_id/Makefile b/src/udev/ata_id/Makefile
deleted file mode 120000 (symlink)
index d0b0e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c
deleted file mode 100644 (file)
index 9e4f674..0000000
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * ata_id - reads product/serial number from ATA drives
- *
- * Copyright (C) 2005-2008 Kay Sievers <kay@vrfy.org>
- * Copyright (C) 2009 Lennart Poettering <lennart@poettering.net>
- * Copyright (C) 2009-2010 David Zeuthen <zeuthen@gmail.com>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <getopt.h>
-#include <scsi/scsi.h>
-#include <scsi/sg.h>
-#include <scsi/scsi_ioctl.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <linux/hdreg.h>
-#include <linux/bsg.h>
-
-#include "libudev.h"
-#include "libudev-private.h"
-#include "udev-util.h"
-#include "log.h"
-
-#define COMMAND_TIMEOUT_MSEC (30 * 1000)
-
-static int disk_scsi_inquiry_command(int      fd,
-                                     void    *buf,
-                                     size_t   buf_len)
-{
-        uint8_t cdb[6] = {
-                /*
-                 * INQUIRY, see SPC-4 section 6.4
-                 */
-                [0] = 0x12,                /* OPERATION CODE: INQUIRY */
-                [3] = (buf_len >> 8),      /* ALLOCATION LENGTH */
-                [4] = (buf_len & 0xff),
-        };
-        uint8_t sense[32] = {};
-        struct sg_io_v4 io_v4 = {
-                .guard = 'Q',
-                .protocol = BSG_PROTOCOL_SCSI,
-                .subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD,
-                .request_len = sizeof(cdb),
-                .request = (uintptr_t) cdb,
-                .max_response_len = sizeof(sense),
-                .response = (uintptr_t) sense,
-                .din_xfer_len = buf_len,
-                .din_xferp = (uintptr_t) buf,
-                .timeout = COMMAND_TIMEOUT_MSEC,
-        };
-        int ret;
-
-        ret = ioctl(fd, SG_IO, &io_v4);
-        if (ret != 0) {
-                /* could be that the driver doesn't do version 4, try version 3 */
-                if (errno == EINVAL) {
-                        struct sg_io_hdr io_hdr = {
-                                .interface_id = 'S',
-                                .cmdp = (unsigned char*) cdb,
-                                .cmd_len = sizeof (cdb),
-                                .dxferp = buf,
-                                .dxfer_len = buf_len,
-                                .sbp = sense,
-                                .mx_sb_len = sizeof(sense),
-                                .dxfer_direction = SG_DXFER_FROM_DEV,
-                                .timeout = COMMAND_TIMEOUT_MSEC,
-                        };
-
-                        ret = ioctl(fd, SG_IO, &io_hdr);
-                        if (ret != 0)
-                                return ret;
-
-                        /* even if the ioctl succeeds, we need to check the return value */
-                        if (!(io_hdr.status == 0 &&
-                              io_hdr.host_status == 0 &&
-                              io_hdr.driver_status == 0)) {
-                                errno = EIO;
-                                return -1;
-                        }
-                } else
-                        return ret;
-        }
-
-        /* even if the ioctl succeeds, we need to check the return value */
-        if (!(io_v4.device_status == 0 &&
-              io_v4.transport_status == 0 &&
-              io_v4.driver_status == 0)) {
-                errno = EIO;
-                return -1;
-        }
-
-        return 0;
-}
-
-static int disk_identify_command(int          fd,
-                                 void         *buf,
-                                 size_t          buf_len)
-{
-        uint8_t cdb[12] = {
-                /*
-                 * ATA Pass-Through 12 byte command, as described in
-                 *
-                 *  T10 04-262r8 ATA Command Pass-Through
-                 *
-                 * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
-                 */
-                [0] = 0xa1,     /* OPERATION CODE: 12 byte pass through */
-                [1] = 4 << 1,   /* PROTOCOL: PIO Data-in */
-                [2] = 0x2e,     /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
-                [3] = 0,        /* FEATURES */
-                [4] = 1,        /* SECTORS */
-                [5] = 0,        /* LBA LOW */
-                [6] = 0,        /* LBA MID */
-                [7] = 0,        /* LBA HIGH */
-                [8] = 0 & 0x4F, /* SELECT */
-                [9] = 0xEC,     /* Command: ATA IDENTIFY DEVICE */
-        };
-        uint8_t sense[32] = {};
-        uint8_t *desc = sense + 8;
-        struct sg_io_v4 io_v4 = {
-                .guard = 'Q',
-                .protocol = BSG_PROTOCOL_SCSI,
-                .subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD,
-                .request_len = sizeof(cdb),
-                .request = (uintptr_t) cdb,
-                .max_response_len = sizeof(sense),
-                .response = (uintptr_t) sense,
-                .din_xfer_len = buf_len,
-                .din_xferp = (uintptr_t) buf,
-                .timeout = COMMAND_TIMEOUT_MSEC,
-        };
-        int ret;
-
-        ret = ioctl(fd, SG_IO, &io_v4);
-        if (ret != 0) {
-                /* could be that the driver doesn't do version 4, try version 3 */
-                if (errno == EINVAL) {
-                        struct sg_io_hdr io_hdr = {
-                                .interface_id = 'S',
-                                .cmdp = (unsigned char*) cdb,
-                                .cmd_len = sizeof (cdb),
-                                .dxferp = buf,
-                                .dxfer_len = buf_len,
-                                .sbp = sense,
-                                .mx_sb_len = sizeof (sense),
-                                .dxfer_direction = SG_DXFER_FROM_DEV,
-                                .timeout = COMMAND_TIMEOUT_MSEC,
-                        };
-
-                        ret = ioctl(fd, SG_IO, &io_hdr);
-                        if (ret != 0)
-                                return ret;
-                } else
-                        return ret;
-        }
-
-        if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
-                errno = EIO;
-                return -1;
-        }
-
-        return 0;
-}
-
-static int disk_identify_packet_device_command(int          fd,
-                                               void         *buf,
-                                               size_t          buf_len)
-{
-        uint8_t cdb[16] = {
-                /*
-                 * ATA Pass-Through 16 byte command, as described in
-                 *
-                 *  T10 04-262r8 ATA Command Pass-Through
-                 *
-                 * from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
-                 */
-                [0] = 0x85,   /* OPERATION CODE: 16 byte pass through */
-                [1] = 4 << 1, /* PROTOCOL: PIO Data-in */
-                [2] = 0x2e,   /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
-                [3] = 0,      /* FEATURES */
-                [4] = 0,      /* FEATURES */
-                [5] = 0,      /* SECTORS */
-                [6] = 1,      /* SECTORS */
-                [7] = 0,      /* LBA LOW */
-                [8] = 0,      /* LBA LOW */
-                [9] = 0,      /* LBA MID */
-                [10] = 0,     /* LBA MID */
-                [11] = 0,     /* LBA HIGH */
-                [12] = 0,     /* LBA HIGH */
-                [13] = 0,     /* DEVICE */
-                [14] = 0xA1,  /* Command: ATA IDENTIFY PACKET DEVICE */
-                [15] = 0,     /* CONTROL */
-        };
-        uint8_t sense[32] = {};
-        uint8_t *desc = sense + 8;
-        struct sg_io_v4 io_v4 = {
-                .guard = 'Q',
-                .protocol = BSG_PROTOCOL_SCSI,
-                .subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD,
-                .request_len = sizeof (cdb),
-                .request = (uintptr_t) cdb,
-                .max_response_len = sizeof (sense),
-                .response = (uintptr_t) sense,
-                .din_xfer_len = buf_len,
-                .din_xferp = (uintptr_t) buf,
-                .timeout = COMMAND_TIMEOUT_MSEC,
-        };
-        int ret;
-
-        ret = ioctl(fd, SG_IO, &io_v4);
-        if (ret != 0) {
-                /* could be that the driver doesn't do version 4, try version 3 */
-                if (errno == EINVAL) {
-                        struct sg_io_hdr io_hdr = {
-                                .interface_id = 'S',
-                                .cmdp = (unsigned char*) cdb,
-                                .cmd_len = sizeof (cdb),
-                                .dxferp = buf,
-                                .dxfer_len = buf_len,
-                                .sbp = sense,
-                                .mx_sb_len = sizeof (sense),
-                                .dxfer_direction = SG_DXFER_FROM_DEV,
-                                .timeout = COMMAND_TIMEOUT_MSEC,
-                        };
-
-                        ret = ioctl(fd, SG_IO, &io_hdr);
-                        if (ret != 0)
-                                return ret;
-                } else
-                        return ret;
-        }
-
-        if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
-                errno = EIO;
-                return -1;
-        }
-
-        return 0;
-}
-
-/**
- * disk_identify_get_string:
- * @identify: A block of IDENTIFY data
- * @offset_words: Offset of the string to get, in words.
- * @dest: Destination buffer for the string.
- * @dest_len: Length of destination buffer, in bytes.
- *
- * Copies the ATA string from @identify located at @offset_words into @dest.
- */
-static void disk_identify_get_string(uint8_t identify[512],
-                                     unsigned int offset_words,
-                                     char *dest,
-                                     size_t dest_len)
-{
-        unsigned int c1;
-        unsigned int c2;
-
-        while (dest_len > 0) {
-                c1 = identify[offset_words * 2 + 1];
-                c2 = identify[offset_words * 2];
-                *dest = c1;
-                dest++;
-                *dest = c2;
-                dest++;
-                offset_words++;
-                dest_len -= 2;
-        }
-}
-
-static void disk_identify_fixup_string(uint8_t identify[512],
-                                       unsigned int offset_words,
-                                       size_t len)
-{
-        disk_identify_get_string(identify, offset_words,
-                                 (char *) identify + offset_words * 2, len);
-}
-
-static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offset_words)
-{
-        uint16_t *p;
-
-        p = (uint16_t *) identify;
-        p[offset_words] = le16toh (p[offset_words]);
-}
-
-/**
- * disk_identify:
- * @udev: The libudev context.
- * @fd: File descriptor for the block device.
- * @out_identify: Return location for IDENTIFY data.
- * @out_is_packet_device: Return location for whether returned data is from a IDENTIFY PACKET DEVICE.
- *
- * Sends the IDENTIFY DEVICE or IDENTIFY PACKET DEVICE command to the
- * device represented by @fd. If successful, then the result will be
- * copied into @out_identify and @out_is_packet_device.
- *
- * This routine is based on code from libatasmart, Copyright 2008
- * Lennart Poettering, LGPL v2.1.
- *
- * Returns: 0 if the data was successfully obtained, otherwise
- * non-zero with errno set.
- */
-static int disk_identify(struct udev *udev,
-                         int fd,
-                         uint8_t out_identify[512],
-                         int *out_is_packet_device)
-{
-        int ret;
-        uint8_t inquiry_buf[36];
-        int peripheral_device_type;
-        int all_nul_bytes;
-        int n;
-        int is_packet_device = 0;
-
-        /* init results */
-        memzero(out_identify, 512);
-
-        /* If we were to use ATA PASS_THROUGH (12) on an ATAPI device
-         * we could accidentally blank media. This is because MMC's BLANK
-         * command has the same op-code (0x61).
-         *
-         * To prevent this from happening we bail out if the device
-         * isn't a Direct Access Block Device, e.g. SCSI type 0x00
-         * (CD/DVD devices are type 0x05). So we send a SCSI INQUIRY
-         * command first... libata is handling this via its SCSI
-         * emulation layer.
-         *
-         * This also ensures that we're actually dealing with a device
-         * that understands SCSI commands.
-         *
-         * (Yes, it is a bit perverse that we're tunneling the ATA
-         * command through SCSI and relying on the ATA driver
-         * emulating SCSI well-enough...)
-         *
-         * (See commit 160b069c25690bfb0c785994c7c3710289179107 for
-         * the original bug-fix and see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=556635
-         * for the original bug-report.)
-         */
-        ret = disk_scsi_inquiry_command (fd, inquiry_buf, sizeof (inquiry_buf));
-        if (ret != 0)
-                goto out;
-
-        /* SPC-4, section 6.4.2: Standard INQUIRY data */
-        peripheral_device_type = inquiry_buf[0] & 0x1f;
-        if (peripheral_device_type == 0x05)
-          {
-            is_packet_device = 1;
-            ret = disk_identify_packet_device_command(fd, out_identify, 512);
-            goto check_nul_bytes;
-          }
-        if (peripheral_device_type != 0x00) {
-                ret = -1;
-                errno = EIO;
-                goto out;
-        }
-
-        /* OK, now issue the IDENTIFY DEVICE command */
-        ret = disk_identify_command(fd, out_identify, 512);
-        if (ret != 0)
-                goto out;
-
- check_nul_bytes:
-         /* Check if IDENTIFY data is all NUL bytes - if so, bail */
-        all_nul_bytes = 1;
-        for (n = 0; n < 512; n++) {
-                if (out_identify[n] != '\0') {
-                        all_nul_bytes = 0;
-                        break;
-                }
-        }
-
-        if (all_nul_bytes) {
-                ret = -1;
-                errno = EIO;
-                goto out;
-        }
-
-out:
-        if (out_is_packet_device != NULL)
-                *out_is_packet_device = is_packet_device;
-        return ret;
-}
-
-int main(int argc, char *argv[])
-{
-        _cleanup_udev_unref_ struct udev *udev = NULL;
-        struct hd_driveid id;
-        union {
-                uint8_t  byte[512];
-                uint16_t wyde[256];
-                uint64_t octa[64];
-        } identify;
-        char model[41];
-        char model_enc[256];
-        char serial[21];
-        char revision[9];
-        const char *node = NULL;
-        int export = 0;
-        _cleanup_close_ int fd = -1;
-        uint16_t word;
-        int is_packet_device = 0;
-        static const struct option options[] = {
-                { "export", no_argument, NULL, 'x' },
-                { "help", no_argument, NULL, 'h' },
-                {}
-        };
-
-        log_parse_environment();
-        log_open();
-
-        udev = udev_new();
-        if (udev == NULL)
-                return 0;
-
-        while (1) {
-                int option;
-
-                option = getopt_long(argc, argv, "xh", options, NULL);
-                if (option == -1)
-                        break;
-
-                switch (option) {
-                case 'x':
-                        export = 1;
-                        break;
-                case 'h':
-                        printf("Usage: ata_id [--export] [--help] <device>\n"
-                               "  -x,--export    print values as environment keys\n"
-                               "  -h,--help      print this help text\n\n");
-                        return 0;
-                }
-        }
-
-        node = argv[optind];
-        if (node == NULL) {
-                log_error("no node specified");
-                return 1;
-        }
-
-        fd = open(node, O_RDONLY|O_NONBLOCK|O_CLOEXEC);
-        if (fd < 0) {
-                log_error("unable to open '%s'", node);
-                return 1;
-        }
-
-        if (disk_identify(udev, fd, identify.byte, &is_packet_device) == 0) {
-                /*
-                 * fix up only the fields from the IDENTIFY data that we are going to
-                 * use and copy it into the hd_driveid struct for convenience
-                 */
-                disk_identify_fixup_string(identify.byte,  10, 20); /* serial */
-                disk_identify_fixup_string(identify.byte,  23,  8); /* fwrev */
-                disk_identify_fixup_string(identify.byte,  27, 40); /* model */
-                disk_identify_fixup_uint16(identify.byte,  0);      /* configuration */
-                disk_identify_fixup_uint16(identify.byte,  75);     /* queue depth */
-                disk_identify_fixup_uint16(identify.byte,  75);     /* SATA capabilities */
-                disk_identify_fixup_uint16(identify.byte,  82);     /* command set supported */
-                disk_identify_fixup_uint16(identify.byte,  83);     /* command set supported */
-                disk_identify_fixup_uint16(identify.byte,  84);     /* command set supported */
-                disk_identify_fixup_uint16(identify.byte,  85);     /* command set supported */
-                disk_identify_fixup_uint16(identify.byte,  86);     /* command set supported */
-                disk_identify_fixup_uint16(identify.byte,  87);     /* command set supported */
-                disk_identify_fixup_uint16(identify.byte,  89);     /* time required for SECURITY ERASE UNIT */
-                disk_identify_fixup_uint16(identify.byte,  90);     /* time required for enhanced SECURITY ERASE UNIT */
-                disk_identify_fixup_uint16(identify.byte,  91);     /* current APM values */
-                disk_identify_fixup_uint16(identify.byte,  94);     /* current AAM value */
-                disk_identify_fixup_uint16(identify.byte, 128);     /* device lock function */
-                disk_identify_fixup_uint16(identify.byte, 217);     /* nominal media rotation rate */
-                memcpy(&id, identify.byte, sizeof id);
-        } else {
-                /* If this fails, then try HDIO_GET_IDENTITY */
-                if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0) {
-                        log_debug_errno(errno, "HDIO_GET_IDENTITY failed for '%s': %m", node);
-                        return 2;
-                }
-        }
-
-        memcpy (model, id.model, 40);
-        model[40] = '\0';
-        udev_util_encode_string(model, model_enc, sizeof(model_enc));
-        util_replace_whitespace((char *) id.model, model, 40);
-        util_replace_chars(model, NULL);
-        util_replace_whitespace((char *) id.serial_no, serial, 20);
-        util_replace_chars(serial, NULL);
-        util_replace_whitespace((char *) id.fw_rev, revision, 8);
-        util_replace_chars(revision, NULL);
-
-        if (export) {
-                /* Set this to convey the disk speaks the ATA protocol */
-                printf("ID_ATA=1\n");
-
-                if ((id.config >> 8) & 0x80) {
-                        /* This is an ATAPI device */
-                        switch ((id.config >> 8) & 0x1f) {
-                        case 0:
-                                printf("ID_TYPE=cd\n");
-                                break;
-                        case 1:
-                                printf("ID_TYPE=tape\n");
-                                break;
-                        case 5:
-                                printf("ID_TYPE=cd\n");
-                                break;
-                        case 7:
-                                printf("ID_TYPE=optical\n");
-                                break;
-                        default:
-                                printf("ID_TYPE=generic\n");
-                                break;
-                        }
-                } else {
-                        printf("ID_TYPE=disk\n");
-                }
-                printf("ID_BUS=ata\n");
-                printf("ID_MODEL=%s\n", model);
-                printf("ID_MODEL_ENC=%s\n", model_enc);
-                printf("ID_REVISION=%s\n", revision);
-                if (serial[0] != '\0') {
-                        printf("ID_SERIAL=%s_%s\n", model, serial);
-                        printf("ID_SERIAL_SHORT=%s\n", serial);
-                } else {
-                        printf("ID_SERIAL=%s\n", model);
-                }
-
-                if (id.command_set_1 & (1<<5)) {
-                        printf("ID_ATA_WRITE_CACHE=1\n");
-                        printf("ID_ATA_WRITE_CACHE_ENABLED=%d\n", (id.cfs_enable_1 & (1<<5)) ? 1 : 0);
-                }
-                if (id.command_set_1 & (1<<10)) {
-                        printf("ID_ATA_FEATURE_SET_HPA=1\n");
-                        printf("ID_ATA_FEATURE_SET_HPA_ENABLED=%d\n", (id.cfs_enable_1 & (1<<10)) ? 1 : 0);
-
-                        /*
-                         * TODO: use the READ NATIVE MAX ADDRESS command to get the native max address
-                         * so it is easy to check whether the protected area is in use.
-                         */
-                }
-                if (id.command_set_1 & (1<<3)) {
-                        printf("ID_ATA_FEATURE_SET_PM=1\n");
-                        printf("ID_ATA_FEATURE_SET_PM_ENABLED=%d\n", (id.cfs_enable_1 & (1<<3)) ? 1 : 0);
-                }
-                if (id.command_set_1 & (1<<1)) {
-                        printf("ID_ATA_FEATURE_SET_SECURITY=1\n");
-                        printf("ID_ATA_FEATURE_SET_SECURITY_ENABLED=%d\n", (id.cfs_enable_1 & (1<<1)) ? 1 : 0);
-                        printf("ID_ATA_FEATURE_SET_SECURITY_ERASE_UNIT_MIN=%d\n", id.trseuc * 2);
-                        if ((id.cfs_enable_1 & (1<<1))) /* enabled */ {
-                                if (id.dlf & (1<<8))
-                                        printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=maximum\n");
-                                else
-                                        printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=high\n");
-                        }
-                        if (id.dlf & (1<<5))
-                                printf("ID_ATA_FEATURE_SET_SECURITY_ENHANCED_ERASE_UNIT_MIN=%d\n", id.trsEuc * 2);
-                        if (id.dlf & (1<<4))
-                                printf("ID_ATA_FEATURE_SET_SECURITY_EXPIRE=1\n");
-                        if (id.dlf & (1<<3))
-                                printf("ID_ATA_FEATURE_SET_SECURITY_FROZEN=1\n");
-                        if (id.dlf & (1<<2))
-                                printf("ID_ATA_FEATURE_SET_SECURITY_LOCKED=1\n");
-                }
-                if (id.command_set_1 & (1<<0)) {
-                        printf("ID_ATA_FEATURE_SET_SMART=1\n");
-                        printf("ID_ATA_FEATURE_SET_SMART_ENABLED=%d\n", (id.cfs_enable_1 & (1<<0)) ? 1 : 0);
-                }
-                if (id.command_set_2 & (1<<9)) {
-                        printf("ID_ATA_FEATURE_SET_AAM=1\n");
-                        printf("ID_ATA_FEATURE_SET_AAM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<9)) ? 1 : 0);
-                        printf("ID_ATA_FEATURE_SET_AAM_VENDOR_RECOMMENDED_VALUE=%d\n", id.acoustic >> 8);
-                        printf("ID_ATA_FEATURE_SET_AAM_CURRENT_VALUE=%d\n", id.acoustic & 0xff);
-                }
-                if (id.command_set_2 & (1<<5)) {
-                        printf("ID_ATA_FEATURE_SET_PUIS=1\n");
-                        printf("ID_ATA_FEATURE_SET_PUIS_ENABLED=%d\n", (id.cfs_enable_2 & (1<<5)) ? 1 : 0);
-                }
-                if (id.command_set_2 & (1<<3)) {
-                        printf("ID_ATA_FEATURE_SET_APM=1\n");
-                        printf("ID_ATA_FEATURE_SET_APM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<3)) ? 1 : 0);
-                        if ((id.cfs_enable_2 & (1<<3)))
-                                printf("ID_ATA_FEATURE_SET_APM_CURRENT_VALUE=%d\n", id.CurAPMvalues & 0xff);
-                }
-                if (id.command_set_2 & (1<<0))
-                        printf("ID_ATA_DOWNLOAD_MICROCODE=1\n");
-
-                /*
-                 * Word 76 indicates the capabilities of a SATA device. A PATA device shall set
-                 * word 76 to 0000h or FFFFh. If word 76 is set to 0000h or FFFFh, then
-                 * the device does not claim compliance with the Serial ATA specification and words
-                 * 76 through 79 are not valid and shall be ignored.
-                 */
-
-                word = identify.wyde[76];
-                if (word != 0x0000 && word != 0xffff) {
-                        printf("ID_ATA_SATA=1\n");
-                        /*
-                         * If bit 2 of word 76 is set to one, then the device supports the Gen2
-                         * signaling rate of 3.0 Gb/s (see SATA 2.6).
-                         *
-                         * If bit 1 of word 76 is set to one, then the device supports the Gen1
-                         * signaling rate of 1.5 Gb/s (see SATA 2.6).
-                         */
-                        if (word & (1<<2))
-                                printf("ID_ATA_SATA_SIGNAL_RATE_GEN2=1\n");
-                        if (word & (1<<1))
-                                printf("ID_ATA_SATA_SIGNAL_RATE_GEN1=1\n");
-                }
-
-                /* Word 217 indicates the nominal media rotation rate of the device */
-                word = identify.wyde[217];
-                if (word == 0x0001)
-                        printf ("ID_ATA_ROTATION_RATE_RPM=0\n"); /* non-rotating e.g. SSD */
-                else if (word >= 0x0401 && word <= 0xfffe)
-                        printf ("ID_ATA_ROTATION_RATE_RPM=%d\n", word);
-
-                /*
-                 * Words 108-111 contain a mandatory World Wide Name (WWN) in the NAA IEEE Registered identifier
-                 * format. Word 108 bits (15:12) shall contain 5h, indicating that the naming authority is IEEE.
-                 * All other values are reserved.
-                 */
-                word = identify.wyde[108];
-                if ((word & 0xf000) == 0x5000)
-                        printf("ID_WWN=0x%1$"PRIu64"x\n"
-                               "ID_WWN_WITH_EXTENSION=0x%1$"PRIu64"x\n",
-                               identify.octa[108/4]);
-
-                /* from Linux's include/linux/ata.h */
-                if (identify.wyde[0] == 0x848a ||
-                    identify.wyde[0] == 0x844a ||
-                    (identify.wyde[83] & 0xc004) == 0x4004)
-                        printf("ID_ATA_CFA=1\n");
-        } else {
-                if (serial[0] != '\0')
-                        printf("%s_%s\n", model, serial);
-                else
-                        printf("%s\n", model);
-        }
-
-        return 0;
-}
diff --git a/src/udev/cdrom_id/Makefile b/src/udev/cdrom_id/Makefile
deleted file mode 120000 (symlink)
index d0b0e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c
deleted file mode 100644 (file)
index 54a5075..0000000
+++ /dev/null
@@ -1,1084 +0,0 @@
-/*
- * cdrom_id - optical drive and media information prober
- *
- * Copyright (C) 2008-2010 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <getopt.h>
-#include <time.h>
-#include <scsi/sg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <linux/cdrom.h>
-
-#include "libudev.h"
-#include "libudev-private.h"
-
-/* device info */
-static unsigned int cd_cd_rom;
-static unsigned int cd_cd_r;
-static unsigned int cd_cd_rw;
-static unsigned int cd_dvd_rom;
-static unsigned int cd_dvd_r;
-static unsigned int cd_dvd_rw;
-static unsigned int cd_dvd_ram;
-static unsigned int cd_dvd_plus_r;
-static unsigned int cd_dvd_plus_rw;
-static unsigned int cd_dvd_plus_r_dl;
-static unsigned int cd_dvd_plus_rw_dl;
-static unsigned int cd_bd;
-static unsigned int cd_bd_r;
-static unsigned int cd_bd_re;
-static unsigned int cd_hddvd;
-static unsigned int cd_hddvd_r;
-static unsigned int cd_hddvd_rw;
-static unsigned int cd_mo;
-static unsigned int cd_mrw;
-static unsigned int cd_mrw_w;
-
-/* media info */
-static unsigned int cd_media;
-static unsigned int cd_media_cd_rom;
-static unsigned int cd_media_cd_r;
-static unsigned int cd_media_cd_rw;
-static unsigned int cd_media_dvd_rom;
-static unsigned int cd_media_dvd_r;
-static unsigned int cd_media_dvd_rw;
-static unsigned int cd_media_dvd_rw_ro; /* restricted overwrite mode */
-static unsigned int cd_media_dvd_rw_seq; /* sequential mode */
-static unsigned int cd_media_dvd_ram;
-static unsigned int cd_media_dvd_plus_r;
-static unsigned int cd_media_dvd_plus_rw;
-static unsigned int cd_media_dvd_plus_r_dl;
-static unsigned int cd_media_dvd_plus_rw_dl;
-static unsigned int cd_media_bd;
-static unsigned int cd_media_bd_r;
-static unsigned int cd_media_bd_re;
-static unsigned int cd_media_hddvd;
-static unsigned int cd_media_hddvd_r;
-static unsigned int cd_media_hddvd_rw;
-static unsigned int cd_media_mo;
-static unsigned int cd_media_mrw;
-static unsigned int cd_media_mrw_w;
-
-static const char *cd_media_state = NULL;
-static unsigned int cd_media_session_next;
-static unsigned int cd_media_session_count;
-static unsigned int cd_media_track_count;
-static unsigned int cd_media_track_count_data;
-static unsigned int cd_media_track_count_audio;
-static unsigned long long int cd_media_session_last_offset;
-
-#define ERRCODE(s)        ((((s)[2] & 0x0F) << 16) | ((s)[12] << 8) | ((s)[13]))
-#define SK(errcode)        (((errcode) >> 16) & 0xF)
-#define ASC(errcode)        (((errcode) >> 8) & 0xFF)
-#define ASCQ(errcode)        ((errcode) & 0xFF)
-
-static bool is_mounted(const char *device)
-{
-        struct stat statbuf;
-        FILE *fp;
-        int maj, min;
-        bool mounted = false;
-
-        if (stat(device, &statbuf) < 0)
-                return -ENODEV;
-
-        fp = fopen("/proc/self/mountinfo", "re");
-        if (fp == NULL)
-                return -ENOSYS;
-        while (fscanf(fp, "%*s %*s %i:%i %*[^\n]", &maj, &min) == 2) {
-                if (makedev(maj, min) == statbuf.st_rdev) {
-                        mounted = true;
-                        break;
-                }
-        }
-        fclose(fp);
-        return mounted;
-}
-
-static void info_scsi_cmd_err(struct udev *udev, const char *cmd, int err)
-{
-        if (err == -1) {
-                log_debug("%s failed", cmd);
-                return;
-        }
-        log_debug("%s failed with SK=%Xh/ASC=%02Xh/ACQ=%02Xh", cmd, SK(err), ASC(err), ASCQ(err));
-}
-
-struct scsi_cmd {
-        struct cdrom_generic_command cgc;
-        union {
-                struct request_sense s;
-                unsigned char u[18];
-        } _sense;
-        struct sg_io_hdr sg_io;
-};
-
-static void scsi_cmd_init(struct udev *udev, struct scsi_cmd *cmd)
-{
-        memzero(cmd, sizeof(struct scsi_cmd));
-        cmd->cgc.quiet = 1;
-        cmd->cgc.sense = &cmd->_sense.s;
-        cmd->sg_io.interface_id = 'S';
-        cmd->sg_io.mx_sb_len = sizeof(cmd->_sense);
-        cmd->sg_io.cmdp = cmd->cgc.cmd;
-        cmd->sg_io.sbp = cmd->_sense.u;
-        cmd->sg_io.flags = SG_FLAG_LUN_INHIBIT | SG_FLAG_DIRECT_IO;
-}
-
-static void scsi_cmd_set(struct udev *udev, struct scsi_cmd *cmd, size_t i, unsigned char arg)
-{
-        cmd->sg_io.cmd_len = i + 1;
-        cmd->cgc.cmd[i] = arg;
-}
-
-#define CHECK_CONDITION 0x01
-
-static int scsi_cmd_run(struct udev *udev, struct scsi_cmd *cmd, int fd, unsigned char *buf, size_t bufsize)
-{
-        int ret = 0;
-
-        if (bufsize > 0) {
-                cmd->sg_io.dxferp = buf;
-                cmd->sg_io.dxfer_len = bufsize;
-                cmd->sg_io.dxfer_direction = SG_DXFER_FROM_DEV;
-        } else {
-                cmd->sg_io.dxfer_direction = SG_DXFER_NONE;
-        }
-        if (ioctl(fd, SG_IO, &cmd->sg_io))
-                return -1;
-
-        if ((cmd->sg_io.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
-                errno = EIO;
-                ret = -1;
-                if (cmd->sg_io.masked_status & CHECK_CONDITION) {
-                        ret = ERRCODE(cmd->_sense.u);
-                        if (ret == 0)
-                                ret = -1;
-                }
-        }
-        return ret;
-}
-
-static int media_lock(struct udev *udev, int fd, bool lock)
-{
-        int err;
-
-        /* disable the kernel's lock logic */
-        err = ioctl(fd, CDROM_CLEAR_OPTIONS, CDO_LOCK);
-        if (err < 0)
-                log_debug("CDROM_CLEAR_OPTIONS, CDO_LOCK failed");
-
-        err = ioctl(fd, CDROM_LOCKDOOR, lock ? 1 : 0);
-        if (err < 0)
-                log_debug("CDROM_LOCKDOOR failed");
-
-        return err;
-}
-
-static int media_eject(struct udev *udev, int fd)
-{
-        struct scsi_cmd sc;
-        int err;
-
-        scsi_cmd_init(udev, &sc);
-        scsi_cmd_set(udev, &sc, 0, 0x1b);
-        scsi_cmd_set(udev, &sc, 4, 0x02);
-        scsi_cmd_set(udev, &sc, 5, 0);
-        err = scsi_cmd_run(udev, &sc, fd, NULL, 0);
-        if ((err != 0)) {
-                info_scsi_cmd_err(udev, "START_STOP_UNIT", err);
-                return -1;
-        }
-        return 0;
-}
-
-static int cd_capability_compat(struct udev *udev, int fd)
-{
-        int capability;
-
-        capability = ioctl(fd, CDROM_GET_CAPABILITY, NULL);
-        if (capability < 0) {
-                log_debug("CDROM_GET_CAPABILITY failed");
-                return -1;
-        }
-
-        if (capability & CDC_CD_R)
-                cd_cd_r = 1;
-        if (capability & CDC_CD_RW)
-                cd_cd_rw = 1;
-        if (capability & CDC_DVD)
-                cd_dvd_rom = 1;
-        if (capability & CDC_DVD_R)
-                cd_dvd_r = 1;
-        if (capability & CDC_DVD_RAM)
-                cd_dvd_ram = 1;
-        if (capability & CDC_MRW)
-                cd_mrw = 1;
-        if (capability & CDC_MRW_W)
-                cd_mrw_w = 1;
-        return 0;
-}
-
-static int cd_media_compat(struct udev *udev, int fd)
-{
-        if (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) != CDS_DISC_OK) {
-                log_debug("CDROM_DRIVE_STATUS != CDS_DISC_OK");
-                return -1;
-        }
-        cd_media = 1;
-        return 0;
-}
-
-static int cd_inquiry(struct udev *udev, int fd)
-{
-        struct scsi_cmd sc;
-        unsigned char inq[128];
-        int err;
-
-        scsi_cmd_init(udev, &sc);
-        scsi_cmd_set(udev, &sc, 0, 0x12);
-        scsi_cmd_set(udev, &sc, 4, 36);
-        scsi_cmd_set(udev, &sc, 5, 0);
-        err = scsi_cmd_run(udev, &sc, fd, inq, 36);
-        if ((err != 0)) {
-                info_scsi_cmd_err(udev, "INQUIRY", err);
-                return -1;
-        }
-
-        if ((inq[0] & 0x1F) != 5) {
-                log_debug("not an MMC unit");
-                return -1;
-        }
-
-        log_debug("INQUIRY: [%.8s][%.16s][%.4s]", inq + 8, inq + 16, inq + 32);
-        return 0;
-}
-
-static void feature_profile_media(struct udev *udev, int cur_profile)
-{
-        switch (cur_profile) {
-        case 0x03:
-        case 0x04:
-        case 0x05:
-                log_debug("profile 0x%02x ", cur_profile);
-                cd_media = 1;
-                cd_media_mo = 1;
-                break;
-        case 0x08:
-                log_debug("profile 0x%02x media_cd_rom", cur_profile);
-                cd_media = 1;
-                cd_media_cd_rom = 1;
-                break;
-        case 0x09:
-                log_debug("profile 0x%02x media_cd_r", cur_profile);
-                cd_media = 1;
-                cd_media_cd_r = 1;
-                break;
-        case 0x0a:
-                log_debug("profile 0x%02x media_cd_rw", cur_profile);
-                cd_media = 1;
-                cd_media_cd_rw = 1;
-                break;
-        case 0x10:
-                log_debug("profile 0x%02x media_dvd_ro", cur_profile);
-                cd_media = 1;
-                cd_media_dvd_rom = 1;
-                break;
-        case 0x11:
-                log_debug("profile 0x%02x media_dvd_r", cur_profile);
-                cd_media = 1;
-                cd_media_dvd_r = 1;
-                break;
-        case 0x12:
-                log_debug("profile 0x%02x media_dvd_ram", cur_profile);
-                cd_media = 1;
-                cd_media_dvd_ram = 1;
-                break;
-        case 0x13:
-                log_debug("profile 0x%02x media_dvd_rw_ro", cur_profile);
-                cd_media = 1;
-                cd_media_dvd_rw = 1;
-                cd_media_dvd_rw_ro = 1;
-                break;
-        case 0x14:
-                log_debug("profile 0x%02x media_dvd_rw_seq", cur_profile);
-                cd_media = 1;
-                cd_media_dvd_rw = 1;
-                cd_media_dvd_rw_seq = 1;
-                break;
-        case 0x1B:
-                log_debug("profile 0x%02x media_dvd_plus_r", cur_profile);
-                cd_media = 1;
-                cd_media_dvd_plus_r = 1;
-                break;
-        case 0x1A:
-                log_debug("profile 0x%02x media_dvd_plus_rw", cur_profile);
-                cd_media = 1;
-                cd_media_dvd_plus_rw = 1;
-                break;
-        case 0x2A:
-                log_debug("profile 0x%02x media_dvd_plus_rw_dl", cur_profile);
-                cd_media = 1;
-                cd_media_dvd_plus_rw_dl = 1;
-                break;
-        case 0x2B:
-                log_debug("profile 0x%02x media_dvd_plus_r_dl", cur_profile);
-                cd_media = 1;
-                cd_media_dvd_plus_r_dl = 1;
-                break;
-        case 0x40:
-                log_debug("profile 0x%02x media_bd", cur_profile);
-                cd_media = 1;
-                cd_media_bd = 1;
-                break;
-        case 0x41:
-        case 0x42:
-                log_debug("profile 0x%02x media_bd_r", cur_profile);
-                cd_media = 1;
-                cd_media_bd_r = 1;
-                break;
-        case 0x43:
-                log_debug("profile 0x%02x media_bd_re", cur_profile);
-                cd_media = 1;
-                cd_media_bd_re = 1;
-                break;
-        case 0x50:
-                log_debug("profile 0x%02x media_hddvd", cur_profile);
-                cd_media = 1;
-                cd_media_hddvd = 1;
-                break;
-        case 0x51:
-                log_debug("profile 0x%02x media_hddvd_r", cur_profile);
-                cd_media = 1;
-                cd_media_hddvd_r = 1;
-                break;
-        case 0x52:
-                log_debug("profile 0x%02x media_hddvd_rw", cur_profile);
-                cd_media = 1;
-                cd_media_hddvd_rw = 1;
-                break;
-        default:
-                log_debug("profile 0x%02x <ignored>", cur_profile);
-                break;
-        }
-}
-
-static int feature_profiles(struct udev *udev, const unsigned char *profiles, size_t size)
-{
-        unsigned int i;
-
-        for (i = 0; i+4 <= size; i += 4) {
-                int profile;
-
-                profile = profiles[i] << 8 | profiles[i+1];
-                switch (profile) {
-                case 0x03:
-                case 0x04:
-                case 0x05:
-                        log_debug("profile 0x%02x mo", profile);
-                        cd_mo = 1;
-                        break;
-                case 0x08:
-                        log_debug("profile 0x%02x cd_rom", profile);
-                        cd_cd_rom = 1;
-                        break;
-                case 0x09:
-                        log_debug("profile 0x%02x cd_r", profile);
-                        cd_cd_r = 1;
-                        break;
-                case 0x0A:
-                        log_debug("profile 0x%02x cd_rw", profile);
-                        cd_cd_rw = 1;
-                        break;
-                case 0x10:
-                        log_debug("profile 0x%02x dvd_rom", profile);
-                        cd_dvd_rom = 1;
-                        break;
-                case 0x12:
-                        log_debug("profile 0x%02x dvd_ram", profile);
-                        cd_dvd_ram = 1;
-                        break;
-                case 0x13:
-                case 0x14:
-                        log_debug("profile 0x%02x dvd_rw", profile);
-                        cd_dvd_rw = 1;
-                        break;
-                case 0x1B:
-                        log_debug("profile 0x%02x dvd_plus_r", profile);
-                        cd_dvd_plus_r = 1;
-                        break;
-                case 0x1A:
-                        log_debug("profile 0x%02x dvd_plus_rw", profile);
-                        cd_dvd_plus_rw = 1;
-                        break;
-                case 0x2A:
-                        log_debug("profile 0x%02x dvd_plus_rw_dl", profile);
-                        cd_dvd_plus_rw_dl = 1;
-                        break;
-                case 0x2B:
-                        log_debug("profile 0x%02x dvd_plus_r_dl", profile);
-                        cd_dvd_plus_r_dl = 1;
-                        break;
-                case 0x40:
-                        cd_bd = 1;
-                        log_debug("profile 0x%02x bd", profile);
-                        break;
-                case 0x41:
-                case 0x42:
-                        cd_bd_r = 1;
-                        log_debug("profile 0x%02x bd_r", profile);
-                        break;
-                case 0x43:
-                        cd_bd_re = 1;
-                        log_debug("profile 0x%02x bd_re", profile);
-                        break;
-                case 0x50:
-                        cd_hddvd = 1;
-                        log_debug("profile 0x%02x hddvd", profile);
-                        break;
-                case 0x51:
-                        cd_hddvd_r = 1;
-                        log_debug("profile 0x%02x hddvd_r", profile);
-                        break;
-                case 0x52:
-                        cd_hddvd_rw = 1;
-                        log_debug("profile 0x%02x hddvd_rw", profile);
-                        break;
-                default:
-                        log_debug("profile 0x%02x <ignored>", profile);
-                        break;
-                }
-        }
-        return 0;
-}
-
-/* returns 0 if media was detected */
-static int cd_profiles_old_mmc(struct udev *udev, int fd)
-{
-        struct scsi_cmd sc;
-        int err;
-
-        unsigned char header[32];
-
-        scsi_cmd_init(udev, &sc);
-        scsi_cmd_set(udev, &sc, 0, 0x51);
-        scsi_cmd_set(udev, &sc, 8, sizeof(header));
-        scsi_cmd_set(udev, &sc, 9, 0);
-        err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header));
-        if ((err != 0)) {
-                info_scsi_cmd_err(udev, "READ DISC INFORMATION", err);
-                if (cd_media == 1) {
-                        log_debug("no current profile, but disc is present; assuming CD-ROM");
-                        cd_media_cd_rom = 1;
-                        cd_media_track_count = 1;
-                        cd_media_track_count_data = 1;
-                        return 0;
-                } else {
-                        log_debug("no current profile, assuming no media");
-                        return -1;
-                }
-        };
-
-        cd_media = 1;
-
-        if (header[2] & 16) {
-                cd_media_cd_rw = 1;
-                log_debug("profile 0x0a media_cd_rw");
-        } else if ((header[2] & 3) < 2 && cd_cd_r) {
-                cd_media_cd_r = 1;
-                log_debug("profile 0x09 media_cd_r");
-        } else {
-                cd_media_cd_rom = 1;
-                log_debug("profile 0x08 media_cd_rom");
-        }
-        return 0;
-}
-
-/* returns 0 if media was detected */
-static int cd_profiles(struct udev *udev, int fd)
-{
-        struct scsi_cmd sc;
-        unsigned char features[65530];
-        unsigned int cur_profile = 0;
-        unsigned int len;
-        unsigned int i;
-        int err;
-        int ret;
-
-        ret = -1;
-
-        /* First query the current profile */
-        scsi_cmd_init(udev, &sc);
-        scsi_cmd_set(udev, &sc, 0, 0x46);
-        scsi_cmd_set(udev, &sc, 8, 8);
-        scsi_cmd_set(udev, &sc, 9, 0);
-        err = scsi_cmd_run(udev, &sc, fd, features, 8);
-        if ((err != 0)) {
-                info_scsi_cmd_err(udev, "GET CONFIGURATION", err);
-                /* handle pre-MMC2 drives which do not support GET CONFIGURATION */
-                if (SK(err) == 0x5 && (ASC(err) == 0x20 || ASC(err) == 0x24)) {
-                        log_debug("drive is pre-MMC2 and does not support 46h get configuration command");
-                        log_debug("trying to work around the problem");
-                        ret = cd_profiles_old_mmc(udev, fd);
-                }
-                goto out;
-        }
-
-        cur_profile = features[6] << 8 | features[7];
-        if (cur_profile > 0) {
-                log_debug("current profile 0x%02x", cur_profile);
-                feature_profile_media (udev, cur_profile);
-                ret = 0; /* we have media */
-        } else {
-                log_debug("no current profile, assuming no media");
-        }
-
-        len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3];
-        log_debug("GET CONFIGURATION: size of features buffer 0x%04x", len);
-
-        if (len > sizeof(features)) {
-                log_debug("can not get features in a single query, truncating");
-                len = sizeof(features);
-        } else if (len <= 8) {
-                len = sizeof(features);
-        }
-
-        /* Now get the full feature buffer */
-        scsi_cmd_init(udev, &sc);
-        scsi_cmd_set(udev, &sc, 0, 0x46);
-        scsi_cmd_set(udev, &sc, 7, ( len >> 8 ) & 0xff);
-        scsi_cmd_set(udev, &sc, 8, len & 0xff);
-        scsi_cmd_set(udev, &sc, 9, 0);
-        err = scsi_cmd_run(udev, &sc, fd, features, len);
-        if ((err != 0)) {
-                info_scsi_cmd_err(udev, "GET CONFIGURATION", err);
-                return -1;
-        }
-
-        /* parse the length once more, in case the drive decided to have other features suddenly :) */
-        len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3];
-        log_debug("GET CONFIGURATION: size of features buffer 0x%04x", len);
-
-        if (len > sizeof(features)) {
-                log_debug("can not get features in a single query, truncating");
-                len = sizeof(features);
-        }
-
-        /* device features */
-        for (i = 8; i+4 < len; i += (4 + features[i+3])) {
-                unsigned int feature;
-
-                feature = features[i] << 8 | features[i+1];
-
-                switch (feature) {
-                case 0x00:
-                        log_debug("GET CONFIGURATION: feature 'profiles', with %i entries", features[i+3] / 4);
-                        feature_profiles(udev, &features[i]+4, MIN(features[i+3], len - i - 4));
-                        break;
-                default:
-                        log_debug("GET CONFIGURATION: feature 0x%04x <ignored>, with 0x%02x bytes", feature, features[i+3]);
-                        break;
-                }
-        }
-out:
-        return ret;
-}
-
-static int cd_media_info(struct udev *udev, int fd)
-{
-        struct scsi_cmd sc;
-        unsigned char header[32];
-        static const char *media_status[] = {
-                "blank",
-                "appendable",
-                "complete",
-                "other"
-        };
-        int err;
-
-        scsi_cmd_init(udev, &sc);
-        scsi_cmd_set(udev, &sc, 0, 0x51);
-        scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff);
-        scsi_cmd_set(udev, &sc, 9, 0);
-        err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header));
-        if ((err != 0)) {
-                info_scsi_cmd_err(udev, "READ DISC INFORMATION", err);
-                return -1;
-        };
-
-        cd_media = 1;
-        log_debug("disk type %02x", header[8]);
-        log_debug("hardware reported media status: %s", media_status[header[2] & 3]);
-
-        /* exclude plain CDROM, some fake cdroms return 0 for "blank" media here */
-        if (!cd_media_cd_rom)
-                cd_media_state = media_status[header[2] & 3];
-
-        /* fresh DVD-RW in restricted overwite mode reports itself as
-         * "appendable"; change it to "blank" to make it consistent with what
-         * gets reported after blanking, and what userspace expects  */
-        if (cd_media_dvd_rw_ro && (header[2] & 3) == 1)
-                cd_media_state = media_status[0];
-
-        /* DVD+RW discs (and DVD-RW in restricted mode) once formatted are
-         * always "complete", DVD-RAM are "other" or "complete" if the disc is
-         * write protected; we need to check the contents if it is blank */
-        if ((cd_media_dvd_rw_ro || cd_media_dvd_plus_rw || cd_media_dvd_plus_rw_dl || cd_media_dvd_ram) && (header[2] & 3) > 1) {
-                unsigned char buffer[32 * 2048];
-                unsigned char len;
-                int offset;
-
-                if (cd_media_dvd_ram) {
-                        /* a write protected dvd-ram may report "complete" status */
-
-                        unsigned char dvdstruct[8];
-                        unsigned char format[12];
-
-                        scsi_cmd_init(udev, &sc);
-                        scsi_cmd_set(udev, &sc, 0, 0xAD);
-                        scsi_cmd_set(udev, &sc, 7, 0xC0);
-                        scsi_cmd_set(udev, &sc, 9, sizeof(dvdstruct));
-                        scsi_cmd_set(udev, &sc, 11, 0);
-                        err = scsi_cmd_run(udev, &sc, fd, dvdstruct, sizeof(dvdstruct));
-                        if ((err != 0)) {
-                                info_scsi_cmd_err(udev, "READ DVD STRUCTURE", err);
-                                return -1;
-                        }
-                        if (dvdstruct[4] & 0x02) {
-                                cd_media_state = media_status[2];
-                                log_debug("write-protected DVD-RAM media inserted");
-                                goto determined;
-                        }
-
-                        /* let's make sure we don't try to read unformatted media */
-                        scsi_cmd_init(udev, &sc);
-                        scsi_cmd_set(udev, &sc, 0, 0x23);
-                        scsi_cmd_set(udev, &sc, 8, sizeof(format));
-                        scsi_cmd_set(udev, &sc, 9, 0);
-                        err = scsi_cmd_run(udev, &sc, fd, format, sizeof(format));
-                        if ((err != 0)) {
-                                info_scsi_cmd_err(udev, "READ DVD FORMAT CAPACITIES", err);
-                                return -1;
-                        }
-
-                        len = format[3];
-                        if (len & 7 || len < 16) {
-                                log_debug("invalid format capacities length");
-                                return -1;
-                        }
-
-                        switch(format[8] & 3) {
-                            case 1:
-                                log_debug("unformatted DVD-RAM media inserted");
-                                /* This means that last format was interrupted
-                                 * or failed, blank dvd-ram discs are factory
-                                 * formatted. Take no action here as it takes
-                                 * quite a while to reformat a dvd-ram and it's
-                                 * not automatically started */
-                                goto determined;
-
-                            case 2:
-                                log_debug("formatted DVD-RAM media inserted");
-                                break;
-
-                            case 3:
-                                cd_media = 0; //return no media
-                                log_debug("format capacities returned no media");
-                                return -1;
-                        }
-                }
-
-                /* Take a closer look at formatted media (unformatted DVD+RW
-                 * has "blank" status", DVD-RAM was examined earlier) and check
-                 * for ISO and UDF PVDs or a fs superblock presence and do it
-                 * in one ioctl (we need just sectors 0 and 16) */
-                scsi_cmd_init(udev, &sc);
-                scsi_cmd_set(udev, &sc, 0, 0x28);
-                scsi_cmd_set(udev, &sc, 5, 0);
-                scsi_cmd_set(udev, &sc, 8, 32);
-                scsi_cmd_set(udev, &sc, 9, 0);
-                err = scsi_cmd_run(udev, &sc, fd, buffer, sizeof(buffer));
-                if ((err != 0)) {
-                        cd_media = 0;
-                        info_scsi_cmd_err(udev, "READ FIRST 32 BLOCKS", err);
-                        return -1;
-                }
-
-                /* if any non-zero data is found in sector 16 (iso and udf) or
-                 * eventually 0 (fat32 boot sector, ext2 superblock, etc), disc
-                 * is assumed non-blank */
-
-                for (offset = 32768; offset < (32768 + 2048); offset++) {
-                        if (buffer [offset]) {
-                                log_debug("data in block 16, assuming complete");
-                                goto determined;
-                        }
-                }
-
-                for (offset = 0; offset < 2048; offset++) {
-                        if (buffer [offset]) {
-                                log_debug("data in block 0, assuming complete");
-                                goto determined;
-                        }
-                }
-
-                cd_media_state = media_status[0];
-                log_debug("no data in blocks 0 or 16, assuming blank");
-        }
-
-determined:
-        /* "other" is e. g. DVD-RAM, can't append sessions there; DVDs in
-         * restricted overwrite mode can never append, only in sequential mode */
-        if ((header[2] & 3) < 2 && !cd_media_dvd_rw_ro)
-                cd_media_session_next = header[10] << 8 | header[5];
-        cd_media_session_count = header[9] << 8 | header[4];
-        cd_media_track_count = header[11] << 8 | header[6];
-
-        return 0;
-}
-
-static int cd_media_toc(struct udev *udev, int fd)
-{
-        struct scsi_cmd sc;
-        unsigned char header[12];
-        unsigned char toc[65536];
-        unsigned int len, i, num_tracks;
-        unsigned char *p;
-        int err;
-
-        scsi_cmd_init(udev, &sc);
-        scsi_cmd_set(udev, &sc, 0, 0x43);
-        scsi_cmd_set(udev, &sc, 6, 1);
-        scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff);
-        scsi_cmd_set(udev, &sc, 9, 0);
-        err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header));
-        if ((err != 0)) {
-                info_scsi_cmd_err(udev, "READ TOC", err);
-                return -1;
-        }
-
-        len = (header[0] << 8 | header[1]) + 2;
-        log_debug("READ TOC: len: %d, start track: %d, end track: %d", len, header[2], header[3]);
-        if (len > sizeof(toc))
-                return -1;
-        if (len < 2)
-                return -1;
-        /* 2: first track, 3: last track */
-        num_tracks = header[3] - header[2] + 1;
-
-        /* empty media has no tracks */
-        if (len < 8)
-                return 0;
-
-        scsi_cmd_init(udev, &sc);
-        scsi_cmd_set(udev, &sc, 0, 0x43);
-        scsi_cmd_set(udev, &sc, 6, header[2]); /* First Track/Session Number */
-        scsi_cmd_set(udev, &sc, 7, (len >> 8) & 0xff);
-        scsi_cmd_set(udev, &sc, 8, len & 0xff);
-        scsi_cmd_set(udev, &sc, 9, 0);
-        err = scsi_cmd_run(udev, &sc, fd, toc, len);
-        if ((err != 0)) {
-                info_scsi_cmd_err(udev, "READ TOC (tracks)", err);
-                return -1;
-        }
-
-        /* Take care to not iterate beyond the last valid track as specified in
-         * the TOC, but also avoid going beyond the TOC length, just in case
-         * the last track number is invalidly large */
-        for (p = toc+4, i = 4; i < len-8 && num_tracks > 0; i += 8, p += 8, --num_tracks) {
-                unsigned int block;
-                unsigned int is_data_track;
-
-                is_data_track = (p[1] & 0x04) != 0;
-
-                block = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7];
-                log_debug("track=%u info=0x%x(%s) start_block=%u",
-                     p[2], p[1] & 0x0f, is_data_track ? "data":"audio", block);
-
-                if (is_data_track)
-                        cd_media_track_count_data++;
-                else
-                        cd_media_track_count_audio++;
-        }
-
-        scsi_cmd_init(udev, &sc);
-        scsi_cmd_set(udev, &sc, 0, 0x43);
-        scsi_cmd_set(udev, &sc, 2, 1); /* Session Info */
-        scsi_cmd_set(udev, &sc, 8, sizeof(header));
-        scsi_cmd_set(udev, &sc, 9, 0);
-        err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header));
-        if ((err != 0)) {
-                info_scsi_cmd_err(udev, "READ TOC (multi session)", err);
-                return -1;
-        }
-        len = header[4+4] << 24 | header[4+5] << 16 | header[4+6] << 8 | header[4+7];
-        log_debug("last track %u starts at block %u", header[4+2], len);
-        cd_media_session_last_offset = (unsigned long long int)len * 2048;
-        return 0;
-}
-
-int main(int argc, char *argv[])
-{
-        struct udev *udev;
-        static const struct option options[] = {
-                { "lock-media", no_argument, NULL, 'l' },
-                { "unlock-media", no_argument, NULL, 'u' },
-                { "eject-media", no_argument, NULL, 'e' },
-                { "debug", no_argument, NULL, 'd' },
-                { "help", no_argument, NULL, 'h' },
-                {}
-        };
-        bool eject = false;
-        bool lock = false;
-        bool unlock = false;
-        const char *node = NULL;
-        int fd = -1;
-        int cnt;
-        int rc = 0;
-
-        log_parse_environment();
-        log_open();
-
-        udev = udev_new();
-        if (udev == NULL)
-                goto exit;
-
-        while (1) {
-                int option;
-
-                option = getopt_long(argc, argv, "deluh", options, NULL);
-                if (option == -1)
-                        break;
-
-                switch (option) {
-                case 'l':
-                        lock = true;
-                        break;
-                case 'u':
-                        unlock = true;
-                        break;
-                case 'e':
-                        eject = true;
-                        break;
-                case 'd':
-                        log_set_target(LOG_TARGET_CONSOLE);
-                        log_set_max_level(LOG_DEBUG);
-                        log_open();
-                        break;
-                case 'h':
-                        printf("Usage: cdrom_id [options] <device>\n"
-                               "  -l,--lock-media    lock the media (to enable eject request events)\n"
-                               "  -u,--unlock-media  unlock the media\n"
-                               "  -e,--eject-media   eject the media\n"
-                               "  -d,--debug         debug to stderr\n"
-                               "  -h,--help          print this help text\n\n");
-                        goto exit;
-                default:
-                        rc = 1;
-                        goto exit;
-                }
-        }
-
-        node = argv[optind];
-        if (!node) {
-                log_error("no device");
-                fprintf(stderr, "no device\n");
-                rc = 1;
-                goto exit;
-        }
-
-        initialize_srand();
-        for (cnt = 20; cnt > 0; cnt--) {
-                struct timespec duration;
-
-                fd = open(node, O_RDONLY|O_NONBLOCK|O_CLOEXEC|(is_mounted(node) ? 0 : O_EXCL));
-                if (fd >= 0 || errno != EBUSY)
-                        break;
-                duration.tv_sec = 0;
-                duration.tv_nsec = (100 * 1000 * 1000) + (rand() % 100 * 1000 * 1000);
-                nanosleep(&duration, NULL);
-        }
-        if (fd < 0) {
-                log_debug("unable to open '%s'", node);
-                fprintf(stderr, "unable to open '%s'\n", node);
-                rc = 1;
-                goto exit;
-        }
-        log_debug("probing: '%s'", node);
-
-        /* same data as original cdrom_id */
-        if (cd_capability_compat(udev, fd) < 0) {
-                rc = 1;
-                goto exit;
-        }
-
-        /* check for media - don't bail if there's no media as we still need to
-         * to read profiles */
-        cd_media_compat(udev, fd);
-
-        /* check if drive talks MMC */
-        if (cd_inquiry(udev, fd) < 0)
-                goto work;
-
-        /* read drive and possibly current profile */
-        if (cd_profiles(udev, fd) != 0)
-                goto work;
-
-        /* at this point we are guaranteed to have media in the drive - find out more about it */
-
-        /* get session/track info */
-        cd_media_toc(udev, fd);
-
-        /* get writable media state */
-        cd_media_info(udev, fd);
-
-work:
-        /* lock the media, so we enable eject button events */
-        if (lock && cd_media) {
-                log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)");
-                media_lock(udev, fd, true);
-        }
-
-        if (unlock && cd_media) {
-                log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)");
-                media_lock(udev, fd, false);
-        }
-
-        if (eject) {
-                log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)");
-                media_lock(udev, fd, false);
-                log_debug("START_STOP_UNIT (eject)");
-                media_eject(udev, fd);
-        }
-
-        printf("ID_CDROM=1\n");
-        if (cd_cd_rom)
-                printf("ID_CDROM_CD=1\n");
-        if (cd_cd_r)
-                printf("ID_CDROM_CD_R=1\n");
-        if (cd_cd_rw)
-                printf("ID_CDROM_CD_RW=1\n");
-        if (cd_dvd_rom)
-                printf("ID_CDROM_DVD=1\n");
-        if (cd_dvd_r)
-                printf("ID_CDROM_DVD_R=1\n");
-        if (cd_dvd_rw)
-                printf("ID_CDROM_DVD_RW=1\n");
-        if (cd_dvd_ram)
-                printf("ID_CDROM_DVD_RAM=1\n");
-        if (cd_dvd_plus_r)
-                printf("ID_CDROM_DVD_PLUS_R=1\n");
-        if (cd_dvd_plus_rw)
-                printf("ID_CDROM_DVD_PLUS_RW=1\n");
-        if (cd_dvd_plus_r_dl)
-                printf("ID_CDROM_DVD_PLUS_R_DL=1\n");
-        if (cd_dvd_plus_rw_dl)
-                printf("ID_CDROM_DVD_PLUS_RW_DL=1\n");
-        if (cd_bd)
-                printf("ID_CDROM_BD=1\n");
-        if (cd_bd_r)
-                printf("ID_CDROM_BD_R=1\n");
-        if (cd_bd_re)
-                printf("ID_CDROM_BD_RE=1\n");
-        if (cd_hddvd)
-                printf("ID_CDROM_HDDVD=1\n");
-        if (cd_hddvd_r)
-                printf("ID_CDROM_HDDVD_R=1\n");
-        if (cd_hddvd_rw)
-                printf("ID_CDROM_HDDVD_RW=1\n");
-        if (cd_mo)
-                printf("ID_CDROM_MO=1\n");
-        if (cd_mrw)
-                printf("ID_CDROM_MRW=1\n");
-        if (cd_mrw_w)
-                printf("ID_CDROM_MRW_W=1\n");
-
-        if (cd_media)
-                printf("ID_CDROM_MEDIA=1\n");
-        if (cd_media_mo)
-                printf("ID_CDROM_MEDIA_MO=1\n");
-        if (cd_media_mrw)
-                printf("ID_CDROM_MEDIA_MRW=1\n");
-        if (cd_media_mrw_w)
-                printf("ID_CDROM_MEDIA_MRW_W=1\n");
-        if (cd_media_cd_rom)
-                printf("ID_CDROM_MEDIA_CD=1\n");
-        if (cd_media_cd_r)
-                printf("ID_CDROM_MEDIA_CD_R=1\n");
-        if (cd_media_cd_rw)
-                printf("ID_CDROM_MEDIA_CD_RW=1\n");
-        if (cd_media_dvd_rom)
-                printf("ID_CDROM_MEDIA_DVD=1\n");
-        if (cd_media_dvd_r)
-                printf("ID_CDROM_MEDIA_DVD_R=1\n");
-        if (cd_media_dvd_ram)
-                printf("ID_CDROM_MEDIA_DVD_RAM=1\n");
-        if (cd_media_dvd_rw)
-                printf("ID_CDROM_MEDIA_DVD_RW=1\n");
-        if (cd_media_dvd_plus_r)
-                printf("ID_CDROM_MEDIA_DVD_PLUS_R=1\n");
-        if (cd_media_dvd_plus_rw)
-                printf("ID_CDROM_MEDIA_DVD_PLUS_RW=1\n");
-        if (cd_media_dvd_plus_rw_dl)
-                printf("ID_CDROM_MEDIA_DVD_PLUS_RW_DL=1\n");
-        if (cd_media_dvd_plus_r_dl)
-                printf("ID_CDROM_MEDIA_DVD_PLUS_R_DL=1\n");
-        if (cd_media_bd)
-                printf("ID_CDROM_MEDIA_BD=1\n");
-        if (cd_media_bd_r)
-                printf("ID_CDROM_MEDIA_BD_R=1\n");
-        if (cd_media_bd_re)
-                printf("ID_CDROM_MEDIA_BD_RE=1\n");
-        if (cd_media_hddvd)
-                printf("ID_CDROM_MEDIA_HDDVD=1\n");
-        if (cd_media_hddvd_r)
-                printf("ID_CDROM_MEDIA_HDDVD_R=1\n");
-        if (cd_media_hddvd_rw)
-                printf("ID_CDROM_MEDIA_HDDVD_RW=1\n");
-
-        if (cd_media_state != NULL)
-                printf("ID_CDROM_MEDIA_STATE=%s\n", cd_media_state);
-        if (cd_media_session_next > 0)
-                printf("ID_CDROM_MEDIA_SESSION_NEXT=%u\n", cd_media_session_next);
-        if (cd_media_session_count > 0)
-                printf("ID_CDROM_MEDIA_SESSION_COUNT=%u\n", cd_media_session_count);
-        if (cd_media_session_count > 1 && cd_media_session_last_offset > 0)
-                printf("ID_CDROM_MEDIA_SESSION_LAST_OFFSET=%llu\n", cd_media_session_last_offset);
-        if (cd_media_track_count > 0)
-                printf("ID_CDROM_MEDIA_TRACK_COUNT=%u\n", cd_media_track_count);
-        if (cd_media_track_count_audio > 0)
-                printf("ID_CDROM_MEDIA_TRACK_COUNT_AUDIO=%u\n", cd_media_track_count_audio);
-        if (cd_media_track_count_data > 0)
-                printf("ID_CDROM_MEDIA_TRACK_COUNT_DATA=%u\n", cd_media_track_count_data);
-exit:
-        if (fd >= 0)
-                close(fd);
-        udev_unref(udev);
-        log_close();
-        return rc;
-}
diff --git a/src/udev/collect/Makefile b/src/udev/collect/Makefile
deleted file mode 120000 (symlink)
index d0b0e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/src/udev/collect/collect.c b/src/udev/collect/collect.c
deleted file mode 100644 (file)
index 6cf41c6..0000000
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Collect variables across events.
- *
- * usage: collect [--add|--remove] <checkpoint> <id> <idlist>
- *
- * Adds ID <id> to the list governed by <checkpoint>.
- * <id> must be part of the ID list <idlist>.
- * If all IDs given by <idlist> are listed (ie collect has been
- * invoked for each ID in <idlist>) collect returns 0, the
- * number of missing IDs otherwise.
- * A negative number is returned on error.
- *
- * Copyright(C) 2007, Hannes Reinecke <hare@suse.de>
- *
- * 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 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libudev-private.h"
-#include "macro.h"
-
-#define BUFSIZE 16
-#define UDEV_ALARM_TIMEOUT 180
-
-enum collect_state {
-        STATE_NONE,
-        STATE_OLD,
-        STATE_CONFIRMED,
-};
-
-struct _mate {
-        struct udev_list_node node;
-        char *name;
-        enum collect_state state;
-};
-
-static struct udev_list_node bunch;
-static int debug;
-
-/* This can increase dynamically */
-static size_t bufsize = BUFSIZE;
-
-static inline struct _mate *node_to_mate(struct udev_list_node *node)
-{
-        return container_of(node, struct _mate, node);
-}
-
-noreturn static void sig_alrm(int signo)
-{
-        exit(4);
-}
-
-static void usage(void)
-{
-        printf("%s [options] <checkpoint> <id> <idlist>\n\n"
-               "Collect variables across events.\n\n"
-               "  -h --help        Print this message\n"
-               "  -a --add         Add ID <id> to the list <idlist>\n"
-               "  -r --remove      Remove ID <id> from the list <idlist>\n"
-               "  -d --debug       Debug to stderr\n\n"
-               "  Adds ID <id> to the list governed by <checkpoint>.\n"
-               "  <id> must be part of the list <idlist>.\n"
-               "  If all IDs given by <idlist> are listed (ie collect has been\n"
-               "  invoked for each ID in <idlist>) collect returns 0, the\n"
-               "  number of missing IDs otherwise.\n"
-               "  On error a negative number is returned.\n\n"
-               , program_invocation_short_name);
-}
-
-/*
- * prepare
- *
- * Prepares the database file
- */
-static int prepare(char *dir, char *filename)
-{
-        char buf[512];
-        int r, fd;
-
-        r = mkdir(dir, 0700);
-        if (r < 0 && errno != EEXIST)
-                return -errno;
-
-        snprintf(buf, sizeof(buf), "%s/%s", dir, filename);
-
-        fd = open(buf,O_RDWR|O_CREAT|O_CLOEXEC, S_IRUSR|S_IWUSR);
-        if (fd < 0)
-                fprintf(stderr, "Cannot open %s: %m\n", buf);
-
-        if (lockf(fd,F_TLOCK,0) < 0) {
-                if (debug)
-                        fprintf(stderr, "Lock taken, wait for %d seconds\n", UDEV_ALARM_TIMEOUT);
-                if (errno == EAGAIN || errno == EACCES) {
-                        alarm(UDEV_ALARM_TIMEOUT);
-                        lockf(fd, F_LOCK, 0);
-                        if (debug)
-                                fprintf(stderr, "Acquired lock on %s\n", buf);
-                } else {
-                        if (debug)
-                                fprintf(stderr, "Could not get lock on %s: %m\n", buf);
-                }
-        }
-
-        return fd;
-}
-
-/*
- * Read checkpoint file
- *
- * Tricky reading this. We allocate a buffer twice as large
- * as we're going to read. Then we read into the upper half
- * of that buffer and start parsing.
- * Once we do _not_ find end-of-work terminator (whitespace
- * character) we move the upper half to the lower half,
- * adjust the read pointer and read the next bit.
- * Quite clever methinks :-)
- * I should become a programmer ...
- *
- * Yes, one could have used fgets() for this. But then we'd
- * have to use freopen etc which I found quite tedious.
- */
-static int checkout(int fd)
-{
-        int len;
-        char *buf, *ptr, *word = NULL;
-        struct _mate *him;
-
- restart:
-        len = bufsize >> 1;
-        buf = malloc(bufsize + 1);
-        if (!buf)
-                return log_oom();
-        memset(buf, ' ', bufsize);
-        buf[bufsize] = '\0';
-
-        ptr = buf + len;
-        while ((read(fd, buf + len, len)) > 0) {
-                while (ptr && *ptr) {
-                        word = ptr;
-                        ptr = strpbrk(word," \n\t\r");
-                        if (!ptr && word < (buf + len)) {
-                                bufsize = bufsize << 1;
-                                if (debug)
-                                        fprintf(stderr, "ID overflow, restarting with size %zu\n", bufsize);
-                                free(buf);
-                                lseek(fd, 0, SEEK_SET);
-                                goto restart;
-                        }
-                        if (ptr) {
-                                *ptr = '\0';
-                                ptr++;
-                                if (!strlen(word))
-                                        continue;
-
-                                if (debug)
-                                        fprintf(stderr, "Found word %s\n", word);
-                                him = malloc(sizeof (struct _mate));
-                                if (!him) {
-                                        free(buf);
-                                        return log_oom();
-                                }
-                                him->name = strdup(word);
-                                if (!him->name) {
-                                        free(buf);
-                                        free(him);
-                                        return log_oom();
-                                }
-                                him->state = STATE_OLD;
-                                udev_list_node_append(&him->node, &bunch);
-                                word = NULL;
-                        }
-                }
-                memcpy(buf, buf + len, len);
-                memset(buf + len, ' ', len);
-
-                if (!ptr)
-                        ptr = word;
-                if (!ptr)
-                        break;
-                ptr -= len;
-        }
-
-        free(buf);
-        return 0;
-}
-
-/*
- * invite
- *
- * Adds a new ID 'us' to the internal list,
- * marks it as confirmed.
- */
-static void invite(char *us)
-{
-        struct udev_list_node *him_node;
-        struct _mate *who = NULL;
-
-        if (debug)
-                fprintf(stderr, "Adding ID '%s'\n", us);
-
-        udev_list_node_foreach(him_node, &bunch) {
-                struct _mate *him = node_to_mate(him_node);
-
-                if (streq(him->name, us)) {
-                        him->state = STATE_CONFIRMED;
-                        who = him;
-                }
-        }
-        if (debug && !who)
-                fprintf(stderr, "ID '%s' not in database\n", us);
-
-}
-
-/*
- * reject
- *
- * Marks the ID 'us' as invalid,
- * causing it to be removed when the
- * list is written out.
- */
-static void reject(char *us)
-{
-        struct udev_list_node *him_node;
-        struct _mate *who = NULL;
-
-        if (debug)
-                fprintf(stderr, "Removing ID '%s'\n", us);
-
-        udev_list_node_foreach(him_node, &bunch) {
-                struct _mate *him = node_to_mate(him_node);
-
-                if (streq(him->name, us)) {
-                        him->state = STATE_NONE;
-                        who = him;
-                }
-        }
-        if (debug && !who)
-                fprintf(stderr, "ID '%s' not in database\n", us);
-}
-
-/*
- * kickout
- *
- * Remove all IDs in the internal list which are not part
- * of the list passed via the command line.
- */
-static void kickout(void)
-{
-        struct udev_list_node *him_node;
-        struct udev_list_node *tmp;
-
-        udev_list_node_foreach_safe(him_node, tmp, &bunch) {
-                struct _mate *him = node_to_mate(him_node);
-
-                if (him->state == STATE_OLD) {
-                        udev_list_node_remove(&him->node);
-                        free(him->name);
-                        free(him);
-                }
-        }
-}
-
-/*
- * missing
- *
- * Counts all missing IDs in the internal list.
- */
-static int missing(int fd)
-{
-        char *buf;
-        int ret = 0;
-        struct udev_list_node *him_node;
-
-        buf = malloc(bufsize);
-        if (!buf)
-                return log_oom();
-
-        udev_list_node_foreach(him_node, &bunch) {
-                struct _mate *him = node_to_mate(him_node);
-
-                if (him->state == STATE_NONE) {
-                        ret++;
-                } else {
-                        while (strlen(him->name)+1 >= bufsize) {
-                                char *tmpbuf;
-
-                                bufsize = bufsize << 1;
-                                tmpbuf = realloc(buf, bufsize);
-                                if (!tmpbuf) {
-                                        free(buf);
-                                        return log_oom();
-                                }
-                                buf = tmpbuf;
-                        }
-                        snprintf(buf, strlen(him->name)+2, "%s ", him->name);
-                        if (write(fd, buf, strlen(buf)) < 0) {
-                                free(buf);
-                                return -1;
-                        }
-                }
-        }
-
-        free(buf);
-        return ret;
-}
-
-/*
- * everybody
- *
- * Prints out the status of the internal list.
- */
-static void everybody(void)
-{
-        struct udev_list_node *him_node;
-        const char *state = "";
-
-        udev_list_node_foreach(him_node, &bunch) {
-                struct _mate *him = node_to_mate(him_node);
-
-                switch (him->state) {
-                case STATE_NONE:
-                        state = "none";
-                        break;
-                case STATE_OLD:
-                        state = "old";
-                        break;
-                case STATE_CONFIRMED:
-                        state = "confirmed";
-                        break;
-                }
-                fprintf(stderr, "ID: %s=%s\n", him->name, state);
-        }
-}
-
-int main(int argc, char **argv)
-{
-        struct udev *udev;
-        static const struct option options[] = {
-                { "add", no_argument, NULL, 'a' },
-                { "remove", no_argument, NULL, 'r' },
-                { "debug", no_argument, NULL, 'd' },
-                { "help", no_argument, NULL, 'h' },
-                {}
-        };
-        int argi;
-        char *checkpoint, *us;
-        int fd;
-        int i;
-        int ret = EXIT_SUCCESS;
-        int prune = 0;
-        char tmpdir[UTIL_PATH_SIZE];
-
-        udev = udev_new();
-        if (udev == NULL) {
-                ret = EXIT_FAILURE;
-                goto exit;
-        }
-
-        while (1) {
-                int option;
-
-                option = getopt_long(argc, argv, "ardh", options, NULL);
-                if (option == -1)
-                        break;
-
-                switch (option) {
-                case 'a':
-                        prune = 0;
-                        break;
-                case 'r':
-                        prune = 1;
-                        break;
-                case 'd':
-                        debug = 1;
-                        break;
-                case 'h':
-                        usage();
-                        goto exit;
-                default:
-                        ret = 1;
-                        goto exit;
-                }
-        }
-
-        argi = optind;
-        if (argi + 2 > argc) {
-                printf("Missing parameter(s)\n");
-                ret = 1;
-                goto exit;
-        }
-        checkpoint = argv[argi++];
-        us = argv[argi++];
-
-        if (signal(SIGALRM, sig_alrm) == SIG_ERR) {
-                fprintf(stderr, "Cannot set SIGALRM: %m\n");
-                ret = 2;
-                goto exit;
-        }
-
-        udev_list_node_init(&bunch);
-
-        if (debug)
-                fprintf(stderr, "Using checkpoint '%s'\n", checkpoint);
-
-        strscpyl(tmpdir, sizeof(tmpdir), "/run/udev/collect", NULL);
-        fd = prepare(tmpdir, checkpoint);
-        if (fd < 0) {
-                ret = 3;
-                goto out;
-        }
-
-        if (checkout(fd) < 0) {
-                ret = 2;
-                goto out;
-        }
-
-        for (i = argi; i < argc; i++) {
-                struct udev_list_node *him_node;
-                struct _mate *who;
-
-                who = NULL;
-                udev_list_node_foreach(him_node, &bunch) {
-                        struct _mate *him = node_to_mate(him_node);
-
-                        if (streq(him->name, argv[i]))
-                                who = him;
-                }
-                if (!who) {
-                        struct _mate *him;
-
-                        if (debug)
-                                fprintf(stderr, "ID %s: not in database\n", argv[i]);
-                        him = new(struct _mate, 1);
-                        if (!him) {
-                                ret = ENOMEM;
-                                goto out;
-                        }
-
-                        him->name = strdup(argv[i]);
-                        if (!him->name) {
-                                free(him);
-                                ret = ENOMEM;
-                                goto out;
-                        }
-
-                        him->state = STATE_NONE;
-                        udev_list_node_append(&him->node, &bunch);
-                } else {
-                        if (debug)
-                                fprintf(stderr, "ID %s: found in database\n", argv[i]);
-                        who->state = STATE_CONFIRMED;
-                }
-        }
-
-        if (prune)
-                reject(us);
-        else
-                invite(us);
-
-        if (debug) {
-                everybody();
-                fprintf(stderr, "Prune lists\n");
-        }
-        kickout();
-
-        lseek(fd, 0, SEEK_SET);
-        ftruncate(fd, 0);
-        ret = missing(fd);
-
-        lockf(fd, F_ULOCK, 0);
-        close(fd);
-out:
-        if (debug)
-                everybody();
-        if (ret >= 0)
-                printf("COLLECT_%s=%d\n", checkpoint, ret);
-exit:
-        udev_unref(udev);
-        return ret;
-}
diff --git a/src/udev/mtd_probe/Makefile b/src/udev/mtd_probe/Makefile
deleted file mode 120000 (symlink)
index d0b0e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/src/udev/mtd_probe/mtd_probe.c b/src/udev/mtd_probe/mtd_probe.c
deleted file mode 100644 (file)
index 67b750c..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 - Maxim Levitsky
- *
- * mtd_probe 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 of the License, or
- * (at your option) any later version.
- *
- * mtd_probe 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 mtd_probe; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA  02110-1301  USA
- */
-
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <mtd/mtd-user.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include "mtd_probe.h"
-
-int main(int argc, char** argv)
-{
-        int mtd_fd;
-        int error;
-        mtd_info_t mtd_info;
-
-        if (argc != 2) {
-                printf("usage: mtd_probe /dev/mtd[n]\n");
-                return 1;
-        }
-
-        mtd_fd = open(argv[1], O_RDONLY|O_CLOEXEC);
-        if (mtd_fd == -1) {
-                perror("open");
-                exit(-1);
-        }
-
-        error = ioctl(mtd_fd, MEMGETINFO, &mtd_info);
-        if (error == -1) {
-                perror("ioctl");
-                exit(-1);
-        }
-
-        probe_smart_media(mtd_fd, &mtd_info);
-        return -1;
-}
diff --git a/src/udev/mtd_probe/mtd_probe.h b/src/udev/mtd_probe/mtd_probe.h
deleted file mode 100644 (file)
index caea5c2..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 - Maxim Levitsky
- *
- * mtd_probe 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 of the License, or
- * (at your option) any later version.
- *
- * mtd_probe 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 mtd_probe; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA  02110-1301  USA
- */
-
-#pragma once
-
-#include <mtd/mtd-user.h>
-
-#include "macro.h"
-
-/* Full oob structure as written on the flash */
-struct sm_oob {
-        uint32_t reserved;
-        uint8_t data_status;
-        uint8_t block_status;
-        uint8_t lba_copy1[2];
-        uint8_t ecc2[3];
-        uint8_t lba_copy2[2];
-        uint8_t ecc1[3];
-} _packed_;
-
-/* one sector is always 512 bytes, but it can consist of two nand pages */
-#define SM_SECTOR_SIZE                512
-
-/* oob area is also 16 bytes, but might be from two pages */
-#define SM_OOB_SIZE                16
-
-/* This is maximum zone size, and all devices that have more that one zone
-   have this size */
-#define SM_MAX_ZONE_SIZE         1024
-
-/* support for small page nand */
-#define SM_SMALL_PAGE                 256
-#define SM_SMALL_OOB_SIZE        8
-
-void probe_smart_media(int mtd_fd, mtd_info_t *info);
diff --git a/src/udev/mtd_probe/probe_smartmedia.c b/src/udev/mtd_probe/probe_smartmedia.c
deleted file mode 100644 (file)
index a007cce..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2010 - Maxim Levitsky
- *
- * mtd_probe 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 of the License, or
- * (at your option) any later version.
- *
- * mtd_probe 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 mtd_probe; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA  02110-1301  USA
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <mtd/mtd-user.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdint.h>
-#include "mtd_probe.h"
-
-static const uint8_t cis_signature[] = {
-        0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20
-};
-
-
-void probe_smart_media(int mtd_fd, mtd_info_t* info)
-{
-        int sector_size;
-        int block_size;
-        int size_in_megs;
-        int spare_count;
-        char* cis_buffer = malloc(SM_SECTOR_SIZE);
-        int offset;
-        int cis_found = 0;
-
-        if (!cis_buffer)
-                return;
-
-        if (info->type != MTD_NANDFLASH)
-                goto exit;
-
-        sector_size = info->writesize;
-        block_size = info->erasesize;
-        size_in_megs = info->size / (1024 * 1024);
-
-        if (sector_size != SM_SECTOR_SIZE && sector_size != SM_SMALL_PAGE)
-                goto exit;
-
-        switch(size_in_megs) {
-        case 1:
-        case 2:
-                spare_count = 6;
-                break;
-        case 4:
-                spare_count = 12;
-                break;
-        default:
-                spare_count = 24;
-                break;
-        }
-
-        for (offset = 0 ; offset < block_size * spare_count ;
-                                                offset += sector_size) {
-                lseek(mtd_fd, SEEK_SET, offset);
-                if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE){
-                        cis_found = 1;
-                        break;
-                }
-        }
-
-        if (!cis_found)
-                goto exit;
-
-        if (memcmp(cis_buffer, cis_signature, sizeof(cis_signature)) != 0 &&
-                (memcmp(cis_buffer + SM_SMALL_PAGE, cis_signature,
-                        sizeof(cis_signature)) != 0))
-                goto exit;
-
-        printf("MTD_FTL=smartmedia\n");
-        free(cis_buffer);
-        exit(0);
-exit:
-        free(cis_buffer);
-        return;
-}
diff --git a/src/udev/net/.gitignore b/src/udev/net/.gitignore
deleted file mode 100644 (file)
index 9ca85ba..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/link-config-gperf.c
diff --git a/src/udev/net/Makefile b/src/udev/net/Makefile
deleted file mode 120000 (symlink)
index 94aaae2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../Makefile
\ No newline at end of file
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c
deleted file mode 100644 (file)
index ec67126..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <linux/ethtool.h>
-#include <linux/sockios.h>
-
-#include "ethtool-util.h"
-
-#include "strxcpyx.h"
-#include "util.h"
-#include "log.h"
-#include "conf-parser.h"
-
-static const char* const duplex_table[_DUP_MAX] = {
-        [DUP_FULL] = "full",
-        [DUP_HALF] = "half"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(duplex, Duplex);
-DEFINE_CONFIG_PARSE_ENUM(config_parse_duplex, duplex, Duplex, "Failed to parse duplex setting");
-
-static const char* const wol_table[_WOL_MAX] = {
-        [WOL_PHY] = "phy",
-        [WOL_MAGIC] = "magic",
-        [WOL_OFF] = "off"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(wol, WakeOnLan);
-DEFINE_CONFIG_PARSE_ENUM(config_parse_wol, wol, WakeOnLan, "Failed to parse WakeOnLan setting");
-
-int ethtool_connect(int *ret) {
-        int fd;
-
-        assert_return(ret, -EINVAL);
-
-        fd = socket(PF_INET, SOCK_DGRAM, 0);
-        if (fd < 0) {
-                return -errno;
-        }
-
-        *ret = fd;
-
-        return 0;
-}
-
-int ethtool_get_driver(int *fd, const char *ifname, char **ret) {
-        struct ethtool_drvinfo ecmd = {
-                .cmd = ETHTOOL_GDRVINFO
-        };
-        struct ifreq ifr = {
-                .ifr_data = (void*) &ecmd
-        };
-        char *d;
-        int r;
-
-        if (*fd < 0) {
-                r = ethtool_connect(fd);
-                if (r < 0)
-                        return log_warning_errno(r, "link_config: could not connect to ethtool: %m");
-        }
-
-        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-
-        r = ioctl(*fd, SIOCETHTOOL, &ifr);
-        if (r < 0)
-                return -errno;
-
-        d = strdup(ecmd.driver);
-        if (!d)
-                return -ENOMEM;
-
-        *ret = d;
-        return 0;
-}
-
-int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex)
-{
-        struct ethtool_cmd ecmd = {
-                .cmd = ETHTOOL_GSET
-        };
-        struct ifreq ifr = {
-                .ifr_data = (void*) &ecmd
-        };
-        bool need_update = false;
-        int r;
-
-        if (speed == 0 && duplex == _DUP_INVALID)
-                return 0;
-
-        if (*fd < 0) {
-                r = ethtool_connect(fd);
-                if (r < 0)
-                        return log_warning_errno(r, "link_config: could not connect to ethtool: %m");
-        }
-
-        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-
-        r = ioctl(*fd, SIOCETHTOOL, &ifr);
-        if (r < 0)
-                return -errno;
-
-        if (ethtool_cmd_speed(&ecmd) != speed) {
-                ethtool_cmd_speed_set(&ecmd, speed);
-                need_update = true;
-        }
-
-        switch (duplex) {
-                case DUP_HALF:
-                        if (ecmd.duplex != DUPLEX_HALF) {
-                                ecmd.duplex = DUPLEX_HALF;
-                                need_update = true;
-                        }
-                        break;
-                case DUP_FULL:
-                        if (ecmd.duplex != DUPLEX_FULL) {
-                                ecmd.duplex = DUPLEX_FULL;
-                                need_update = true;
-                        }
-                        break;
-                default:
-                        break;
-        }
-
-        if (need_update) {
-                ecmd.cmd = ETHTOOL_SSET;
-
-                r = ioctl(*fd, SIOCETHTOOL, &ifr);
-                if (r < 0)
-                        return -errno;
-        }
-
-        return 0;
-}
-
-int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol) {
-        struct ethtool_wolinfo ecmd = {
-                .cmd = ETHTOOL_GWOL
-        };
-        struct ifreq ifr = {
-                .ifr_data = (void*) &ecmd
-        };
-        bool need_update = false;
-        int r;
-
-        if (wol == _WOL_INVALID)
-                return 0;
-
-        if (*fd < 0) {
-                r = ethtool_connect(fd);
-                if (r < 0)
-                        return log_warning_errno(r, "link_config: could not connect to ethtool: %m");
-        }
-
-        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
-
-        r = ioctl(*fd, SIOCETHTOOL, &ifr);
-        if (r < 0)
-                return -errno;
-
-        switch (wol) {
-                case WOL_PHY:
-                        if (ecmd.wolopts != WAKE_PHY) {
-                                ecmd.wolopts = WAKE_PHY;
-                                need_update = true;
-                        }
-                        break;
-                case WOL_MAGIC:
-                        if (ecmd.wolopts != WAKE_MAGIC) {
-                                ecmd.wolopts = WAKE_MAGIC;
-                                need_update = true;
-                        }
-                        break;
-                case WOL_OFF:
-                        if (ecmd.wolopts != 0) {
-                                ecmd.wolopts = 0;
-                                need_update = true;
-                        }
-                        break;
-                default:
-                        break;
-        }
-
-        if (need_update) {
-                ecmd.cmd = ETHTOOL_SWOL;
-
-                r = ioctl(*fd, SIOCETHTOOL, &ifr);
-                if (r < 0)
-                        return -errno;
-        }
-
-        return 0;
-}
diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
deleted file mode 100644 (file)
index 690b1a6..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#include <macro.h>
-
-/* we can't use DUPLEX_ prefix, as it
- * clashes with <linux/ethtool.h> */
-typedef enum Duplex {
-        DUP_FULL,
-        DUP_HALF,
-        _DUP_MAX,
-        _DUP_INVALID = -1
-} Duplex;
-
-typedef enum WakeOnLan {
-        WOL_PHY,
-        WOL_MAGIC,
-        WOL_OFF,
-        _WOL_MAX,
-        _WOL_INVALID = -1
-} WakeOnLan;
-
-int ethtool_connect(int *ret);
-
-int ethtool_get_driver(int *fd, const char *ifname, char **ret);
-int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex);
-int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
-
-const char *duplex_to_string(Duplex d) _const_;
-Duplex duplex_from_string(const char *d) _pure_;
-
-const char *wol_to_string(WakeOnLan wol) _const_;
-WakeOnLan wol_from_string(const char *wol) _pure_;
-
-int config_parse_duplex(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_wol(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
deleted file mode 100644 (file)
index b25e4b3..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-%{
-#include <stddef.h>
-#include "conf-parser.h"
-#include "network-internal.h"
-#include "link-config.h"
-#include "ethtool-util.h"
-%}
-struct ConfigPerfItem;
-%null_strings
-%language=ANSI-C
-%define slot-name section_and_lvalue
-%define hash-function-name link_config_gperf_hash
-%define lookup-function-name link_config_gperf_lookup
-%readonly-tables
-%omit-struct-type
-%struct-type
-%includes
-%%
-Match.MACAddress,          config_parse_hwaddr,        0,                             offsetof(link_config, match_mac)
-Match.OriginalName,        config_parse_ifnames,       0,                             offsetof(link_config, match_name)
-Match.Path,                config_parse_strv,          0,                             offsetof(link_config, match_path)
-Match.Driver,              config_parse_strv,          0,                             offsetof(link_config, match_driver)
-Match.Type,                config_parse_strv,          0,                             offsetof(link_config, match_type)
-Match.Host,                config_parse_net_condition, CONDITION_HOST,                offsetof(link_config, match_host)
-Match.Virtualization,      config_parse_net_condition, CONDITION_VIRTUALIZATION,      offsetof(link_config, match_virt)
-Match.KernelCommandLine,   config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel)
-Match.Architecture,        config_parse_net_condition, CONDITION_ARCHITECTURE,        offsetof(link_config, match_arch)
-Link.Description,          config_parse_string,        0,                             offsetof(link_config, description)
-Link.MACAddressPolicy,     config_parse_mac_policy,    0,                             offsetof(link_config, mac_policy)
-Link.MACAddress,           config_parse_hwaddr,        0,                             offsetof(link_config, mac)
-Link.NamePolicy,           config_parse_name_policy,   0,                             offsetof(link_config, name_policy)
-Link.Name,                 config_parse_ifname,        0,                             offsetof(link_config, name)
-Link.Alias,                config_parse_ifalias,       0,                             offsetof(link_config, alias)
-Link.MTUBytes,             config_parse_iec_size,      0,                             offsetof(link_config, mtu)
-Link.BitsPerSecond,        config_parse_si_size,       0,                             offsetof(link_config, speed)
-Link.Duplex,               config_parse_duplex,        0,                             offsetof(link_config, duplex)
-Link.WakeOnLan,            config_parse_wol,           0,                             offsetof(link_config, wol)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
deleted file mode 100644 (file)
index 86d09bb..0000000
+++ /dev/null
@@ -1,508 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <netinet/ether.h>
-#include <linux/netdevice.h>
-
-
-#include "missing.h"
-#include "link-config.h"
-#include "ethtool-util.h"
-
-#include "libudev-private.h"
-#include "sd-rtnl.h"
-#include "util.h"
-#include "log.h"
-#include "strv.h"
-#include "path-util.h"
-#include "conf-parser.h"
-#include "conf-files.h"
-#include "rtnl-util.h"
-#include "network-internal.h"
-
-struct link_config_ctx {
-        LIST_HEAD(link_config, links);
-
-        int ethtool_fd;
-
-        bool enable_name_policy;
-
-        sd_rtnl *rtnl;
-
-        usec_t link_dirs_ts_usec;
-};
-
-static const char* const link_dirs[] = {
-        "/etc/systemd/network",
-        "/run/systemd/network",
-        "/usr/lib/systemd/network",
-#ifdef HAVE_SPLIT_USR
-        "/lib/systemd/network",
-#endif
-        NULL};
-
-static void link_config_free(link_config *link) {
-        if (!link)
-                return;
-
-        free(link->filename);
-
-        free(link->match_mac);
-        free(link->match_path);
-        free(link->match_driver);
-        free(link->match_type);
-        free(link->match_name);
-        free(link->match_host);
-        free(link->match_virt);
-        free(link->match_kernel);
-        free(link->match_arch);
-
-        free(link->description);
-        free(link->mac);
-        free(link->name_policy);
-        free(link->name);
-        free(link->alias);
-
-        free(link);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(link_config*, link_config_free);
-
-static void link_configs_free(link_config_ctx *ctx) {
-        link_config *link, *link_next;
-
-        if (!ctx)
-                return;
-
-        LIST_FOREACH_SAFE(links, link, link_next, ctx->links)
-                link_config_free(link);
-}
-
-void link_config_ctx_free(link_config_ctx *ctx) {
-        if (!ctx)
-                return;
-
-        safe_close(ctx->ethtool_fd);
-
-        sd_rtnl_unref(ctx->rtnl);
-
-        link_configs_free(ctx);
-
-        free(ctx);
-
-        return;
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(link_config_ctx*, link_config_ctx_free);
-
-int link_config_ctx_new(link_config_ctx **ret) {
-        _cleanup_(link_config_ctx_freep) link_config_ctx *ctx = NULL;
-
-        if (!ret)
-                return -EINVAL;
-
-        ctx = new0(link_config_ctx, 1);
-        if (!ctx)
-                return -ENOMEM;
-
-        LIST_HEAD_INIT(ctx->links);
-
-        ctx->ethtool_fd = -1;
-
-        ctx->enable_name_policy = true;
-
-        *ret = ctx;
-        ctx = NULL;
-
-        return 0;
-}
-
-static int load_link(link_config_ctx *ctx, const char *filename) {
-        _cleanup_(link_config_freep) link_config *link = NULL;
-        _cleanup_fclose_ FILE *file = NULL;
-        int r;
-
-        assert(ctx);
-        assert(filename);
-
-        file = fopen(filename, "re");
-        if (!file) {
-                if (errno == ENOENT)
-                        return 0;
-                else
-                        return -errno;
-        }
-
-        if (null_or_empty_fd(fileno(file))) {
-                log_debug("Skipping empty file: %s", filename);
-                return 0;
-        }
-
-        link = new0(link_config, 1);
-        if (!link)
-                return log_oom();
-
-        link->mac_policy = _MACPOLICY_INVALID;
-        link->wol = _WOL_INVALID;
-        link->duplex = _DUP_INVALID;
-
-        r = config_parse(NULL, filename, file,
-                         "Match\0Link\0Ethernet\0",
-                         config_item_perf_lookup, link_config_gperf_lookup,
-                         false, false, true, link);
-        if (r < 0)
-                return r;
-        else
-                log_debug("Parsed configuration file %s", filename);
-
-        link->filename = strdup(filename);
-
-        LIST_PREPEND(links, ctx->links, link);
-        link = NULL;
-
-        return 0;
-}
-
-static bool enable_name_policy(void) {
-        _cleanup_free_ char *line = NULL;
-        const char *word, *state;
-        int r;
-        size_t l;
-
-        r = proc_cmdline(&line);
-        if (r < 0) {
-                log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m");
-                return true;
-        }
-
-        FOREACH_WORD_QUOTED(word, l, line, state)
-                if (strneq(word, "net.ifnames=0", l))
-                        return false;
-
-        return true;
-}
-
-int link_config_load(link_config_ctx *ctx) {
-        int r;
-        _cleanup_strv_free_ char **files;
-        char **f;
-
-        link_configs_free(ctx);
-
-        if (!enable_name_policy()) {
-                ctx->enable_name_policy = false;
-                log_info("Network interface NamePolicy= disabled on kernel command line, ignoring.");
-        }
-
-        /* update timestamp */
-        paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, true);
-
-        r = conf_files_list_strv(&files, ".link", NULL, link_dirs);
-        if (r < 0)
-                return log_error_errno(r, "failed to enumerate link files: %m");
-
-        STRV_FOREACH_BACKWARDS(f, files) {
-                r = load_link(ctx, *f);
-                if (r < 0)
-                        return r;
-        }
-
-        return 0;
-}
-
-bool link_config_should_reload(link_config_ctx *ctx) {
-        return paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, false);
-}
-
-int link_config_get(link_config_ctx *ctx, struct udev_device *device,
-                    link_config **ret) {
-        link_config *link;
-
-        LIST_FOREACH(links, link, ctx->links) {
-                const char* attr_value;
-
-                attr_value = udev_device_get_sysattr_value(device, "address");
-
-                if (net_match_config(link->match_mac, link->match_path, link->match_driver,
-                                     link->match_type, link->match_name, link->match_host,
-                                     link->match_virt, link->match_kernel, link->match_arch,
-                                     attr_value ? ether_aton(attr_value) : NULL,
-                                     udev_device_get_property_value(device, "ID_PATH"),
-                                     udev_device_get_driver(udev_device_get_parent(device)),
-                                     udev_device_get_property_value(device, "ID_NET_DRIVER"),
-                                     udev_device_get_devtype(device),
-                                     udev_device_get_sysname(device))) {
-                        if (link->match_name) {
-                                unsigned char name_assign_type = NET_NAME_UNKNOWN;
-
-                                attr_value = udev_device_get_sysattr_value(device, "name_assign_type");
-                                if (attr_value)
-                                        (void) safe_atou8(attr_value, &name_assign_type);
-
-                                if (name_assign_type == NET_NAME_ENUM) {
-                                        log_warning("Config file %s applies to device based on potentially unpredictable interface name '%s'",
-                                                  link->filename, udev_device_get_sysname(device));
-                                        *ret = link;
-
-                                        return 0;
-                                } else if (name_assign_type == NET_NAME_RENAMED) {
-                                        log_warning("Config file %s matches device based on renamed interface name '%s', ignoring",
-                                                  link->filename, udev_device_get_sysname(device));
-
-                                        continue;
-                                }
-                        }
-
-                        log_debug("Config file %s applies to device %s",
-                                  link->filename,  udev_device_get_sysname(device));
-
-                        *ret = link;
-
-                        return 0;
-                }
-        }
-
-        *ret = NULL;
-
-        return -ENOENT;
-}
-
-static bool mac_is_random(struct udev_device *device) {
-        const char *s;
-        unsigned type;
-        int r;
-
-        /* if we can't get the assign type, assume it is not random */
-        s = udev_device_get_sysattr_value(device, "addr_assign_type");
-        if (!s)
-                return false;
-
-        r = safe_atou(s, &type);
-        if (r < 0)
-                return false;
-
-        return type == NET_ADDR_RANDOM;
-}
-
-static bool should_rename(struct udev_device *device, bool respect_predictable) {
-        const char *s;
-        unsigned type;
-        int r;
-
-        /* if we can't get the assgin type, assume we should rename */
-        s = udev_device_get_sysattr_value(device, "name_assign_type");
-        if (!s)
-                return true;
-
-        r = safe_atou(s, &type);
-        if (r < 0)
-                return true;
-
-        switch (type) {
-        case NET_NAME_USER:
-        case NET_NAME_RENAMED:
-                /* these were already named by userspace, do not touch again */
-                return false;
-        case NET_NAME_PREDICTABLE:
-                /* the kernel claims to have given a predictable name */
-                if (respect_predictable)
-                        return false;
-                /* fall through */
-        case NET_NAME_ENUM:
-        default:
-                /* the name is known to be bad, or of an unknown type */
-                return true;
-        }
-}
-
-static int get_mac(struct udev_device *device, bool want_random,
-                   struct ether_addr *mac) {
-        int r;
-
-        if (want_random)
-                random_bytes(mac->ether_addr_octet, ETH_ALEN);
-        else {
-                uint8_t result[8];
-
-                r = net_get_unique_predictable_data(device, result);
-                if (r < 0)
-                        return r;
-
-                assert_cc(ETH_ALEN <= sizeof(result));
-                memcpy(mac->ether_addr_octet, result, ETH_ALEN);
-        }
-
-        /* see eth_random_addr in the kernel */
-        mac->ether_addr_octet[0] &= 0xfe;  /* clear multicast bit */
-        mac->ether_addr_octet[0] |= 0x02;  /* set local assignment bit (IEEE802) */
-
-        return 0;
-}
-
-int link_config_apply(link_config_ctx *ctx, link_config *config,
-                      struct udev_device *device, const char **name) {
-        const char *old_name;
-        const char *new_name = NULL;
-        struct ether_addr generated_mac;
-        struct ether_addr *mac = NULL;
-        bool respect_predictable = false;
-        int r, ifindex;
-
-        assert(ctx);
-        assert(config);
-        assert(device);
-        assert(name);
-
-        old_name = udev_device_get_sysname(device);
-        if (!old_name)
-                return -EINVAL;
-
-        r = ethtool_set_speed(&ctx->ethtool_fd, old_name, config->speed / 1024,
-                              config->duplex);
-        if (r < 0)
-                log_warning_errno(r, "Could not set speed or duplex of %s to %u Mbps (%s): %m",
-                                  old_name, config->speed / 1024,
-                                  duplex_to_string(config->duplex));
-
-        r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol);
-        if (r < 0)
-                log_warning_errno(r, "Could not set WakeOnLan of %s to %s: %m",
-                                  old_name, wol_to_string(config->wol));
-
-        ifindex = udev_device_get_ifindex(device);
-        if (ifindex <= 0) {
-                log_warning("Could not find ifindex");
-                return -ENODEV;
-        }
-
-        if (ctx->enable_name_policy && config->name_policy) {
-                NamePolicy *policy;
-
-                for (policy = config->name_policy;
-                     !new_name && *policy != _NAMEPOLICY_INVALID; policy++) {
-                        switch (*policy) {
-                                case NAMEPOLICY_KERNEL:
-                                        respect_predictable = true;
-                                        break;
-                                case NAMEPOLICY_DATABASE:
-                                        new_name = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE");
-                                        break;
-                                case NAMEPOLICY_ONBOARD:
-                                        new_name = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD");
-                                        break;
-                                case NAMEPOLICY_SLOT:
-                                        new_name = udev_device_get_property_value(device, "ID_NET_NAME_SLOT");
-                                        break;
-                                case NAMEPOLICY_PATH:
-                                        new_name = udev_device_get_property_value(device, "ID_NET_NAME_PATH");
-                                        break;
-                                case NAMEPOLICY_MAC:
-                                        new_name = udev_device_get_property_value(device, "ID_NET_NAME_MAC");
-                                        break;
-                                default:
-                                        break;
-                        }
-                }
-        }
-
-        if (should_rename(device, respect_predictable)) {
-                /* if not set by policy, fall back manually set name */
-                if (!new_name)
-                        new_name = config->name;
-        } else
-                new_name = NULL;
-
-        switch (config->mac_policy) {
-                case MACPOLICY_PERSISTENT:
-                        if (mac_is_random(device)) {
-                                r = get_mac(device, false, &generated_mac);
-                                if (r == -ENOENT) {
-                                        log_warning_errno(r, "Could not generate persistent MAC address for %s: %m", old_name);
-                                        break;
-                                } else if (r < 0)
-                                        return r;
-                                mac = &generated_mac;
-                        }
-                        break;
-                case MACPOLICY_RANDOM:
-                        if (!mac_is_random(device)) {
-                                r = get_mac(device, true, &generated_mac);
-                                if (r == -ENOENT) {
-                                        log_warning_errno(r, "Could not generate random MAC address for %s: %m", old_name);
-                                        break;
-                                } else if (r < 0)
-                                        return r;
-                                mac = &generated_mac;
-                        }
-                        break;
-                default:
-                        mac = config->mac;
-        }
-
-        r = rtnl_set_link_properties(&ctx->rtnl, ifindex, config->alias, mac,
-                                     config->mtu);
-        if (r < 0)
-                return log_warning_errno(r, "Could not set Alias, MACAddress or MTU on %s: %m", old_name);
-
-        *name = new_name;
-
-        return 0;
-}
-
-int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret) {
-        const char *name;
-        char *driver = NULL;
-        int r;
-
-        name = udev_device_get_sysname(device);
-        if (!name)
-                return -EINVAL;
-
-        r = ethtool_get_driver(&ctx->ethtool_fd, name, &driver);
-        if (r < 0)
-                return r;
-
-        *ret = driver;
-        return 0;
-}
-
-static const char* const mac_policy_table[_MACPOLICY_MAX] = {
-        [MACPOLICY_PERSISTENT] = "persistent",
-        [MACPOLICY_RANDOM] = "random"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(mac_policy, MACPolicy);
-DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy,
-                         "Failed to parse MAC address policy");
-
-static const char* const name_policy_table[_NAMEPOLICY_MAX] = {
-        [NAMEPOLICY_KERNEL] = "kernel",
-        [NAMEPOLICY_DATABASE] = "database",
-        [NAMEPOLICY_ONBOARD] = "onboard",
-        [NAMEPOLICY_SLOT] = "slot",
-        [NAMEPOLICY_PATH] = "path",
-        [NAMEPOLICY_MAC] = "mac"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy);
-DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy,
-                          _NAMEPOLICY_INVALID,
-                          "Failed to parse interface name policy");
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
deleted file mode 100644 (file)
index 34facde..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#include "ethtool-util.h"
-#include "condition.h"
-#include "list.h"
-#include "libudev.h"
-
-typedef struct link_config_ctx link_config_ctx;
-typedef struct link_config link_config;
-
-typedef enum MACPolicy {
-        MACPOLICY_PERSISTENT,
-        MACPOLICY_RANDOM,
-        _MACPOLICY_MAX,
-        _MACPOLICY_INVALID = -1
-} MACPolicy;
-
-typedef enum NamePolicy {
-        NAMEPOLICY_KERNEL,
-        NAMEPOLICY_DATABASE,
-        NAMEPOLICY_ONBOARD,
-        NAMEPOLICY_SLOT,
-        NAMEPOLICY_PATH,
-        NAMEPOLICY_MAC,
-        _NAMEPOLICY_MAX,
-        _NAMEPOLICY_INVALID = -1
-} NamePolicy;
-
-struct link_config {
-        char *filename;
-
-        struct ether_addr *match_mac;
-        char **match_path;
-        char **match_driver;
-        char **match_type;
-        char **match_name;
-        Condition *match_host;
-        Condition *match_virt;
-        Condition *match_kernel;
-        Condition *match_arch;
-
-        char *description;
-        struct ether_addr *mac;
-        MACPolicy mac_policy;
-        NamePolicy *name_policy;
-        char *name;
-        char *alias;
-        unsigned int mtu;
-        unsigned int speed;
-        Duplex duplex;
-        WakeOnLan wol;
-
-        LIST_FIELDS(link_config, links);
-};
-
-int link_config_ctx_new(link_config_ctx **ret);
-void link_config_ctx_free(link_config_ctx *ctx);
-
-int link_config_load(link_config_ctx *ctx);
-bool link_config_should_reload(link_config_ctx *ctx);
-
-int link_config_get(link_config_ctx *ctx, struct udev_device *device, struct link_config **ret);
-int link_config_apply(link_config_ctx *ctx, struct link_config *config, struct udev_device *device, const char **name);
-
-int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret);
-
-const char *name_policy_to_string(NamePolicy p) _const_;
-NamePolicy name_policy_from_string(const char *p) _pure_;
-
-const char *mac_policy_to_string(MACPolicy p) _const_;
-MACPolicy mac_policy_from_string(const char *p) _pure_;
-
-/* gperf lookup function */
-const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, unsigned length);
-
-int config_parse_mac_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_name_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/udev/scsi_id/.gitignore b/src/udev/scsi_id/.gitignore
deleted file mode 100644 (file)
index 6aebddd..0000000
+++ /dev/null
@@ -1 +0,0 @@
-scsi_id_version.h
diff --git a/src/udev/scsi_id/Makefile b/src/udev/scsi_id/Makefile
deleted file mode 120000 (symlink)
index d0b0e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/src/udev/scsi_id/README b/src/udev/scsi_id/README
deleted file mode 100644 (file)
index 9cfe739..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-scsi_id - generate a SCSI unique identifier for a given SCSI device
-
-Please send questions, comments or patches to <patmans@us.ibm.com> or
-<linux-hotplug-devel@lists.sourceforge.net>.
diff --git a/src/udev/scsi_id/scsi.h b/src/udev/scsi_id/scsi.h
deleted file mode 100644 (file)
index 3f99ae7..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * scsi.h
- *
- * General scsi and linux scsi specific defines and structs.
- *
- * Copyright (C) IBM Corp. 2003
- *
- *        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 version 2 of the License.
- */
-
-#pragma once
-
-#include <scsi/scsi.h>
-
-struct scsi_ioctl_command {
-        unsigned int inlen;        /* excluding scsi command length */
-        unsigned int outlen;
-        unsigned char data[1];
-        /* on input, scsi command starts here then opt. data */
-};
-
-/*
- * Default 5 second timeout
- */
-#define DEF_TIMEOUT        5000
-
-#define SENSE_BUFF_LEN        32
-
-/*
- * The request buffer size passed to the SCSI INQUIRY commands, use 254,
- * as this is a nice value for some devices, especially some of the usb
- * mass storage devices.
- */
-#define        SCSI_INQ_BUFF_LEN        254
-
-/*
- * SCSI INQUIRY vendor and model (really product) lengths.
- */
-#define VENDOR_LENGTH        8
-#define        MODEL_LENGTH        16
-
-#define INQUIRY_CMD     0x12
-#define INQUIRY_CMDLEN  6
-
-/*
- * INQUIRY VPD page 0x83 identifier descriptor related values. Reference the
- * SCSI Primary Commands specification for details.
- */
-
-/*
- * id type values of id descriptors. These are assumed to fit in 4 bits.
- */
-#define SCSI_ID_VENDOR_SPECIFIC        0
-#define SCSI_ID_T10_VENDOR        1
-#define SCSI_ID_EUI_64                2
-#define SCSI_ID_NAA                3
-#define SCSI_ID_RELPORT                4
-#define SCSI_ID_TGTGROUP        5
-#define SCSI_ID_LUNGROUP        6
-#define SCSI_ID_MD5                7
-#define SCSI_ID_NAME                8
-
-/*
- * Supported NAA values. These fit in 4 bits, so the "don't care" value
- * cannot conflict with real values.
- */
-#define        SCSI_ID_NAA_DONT_CARE                0xff
-#define        SCSI_ID_NAA_IEEE_REG                5
-#define        SCSI_ID_NAA_IEEE_REG_EXTENDED        6
-
-/*
- * Supported Code Set values.
- */
-#define        SCSI_ID_BINARY        1
-#define        SCSI_ID_ASCII        2
-
-struct scsi_id_search_values {
-        u_char        id_type;
-        u_char        naa_type;
-        u_char        code_set;
-};
-
-/*
- * Following are the "true" SCSI status codes. Linux has traditionally
- * used a 1 bit right and masked version of these. So now CHECK_CONDITION
- * and friends (in <scsi/scsi.h>) are deprecated.
- */
-#define SCSI_CHECK_CONDITION 0x2
-#define SCSI_CONDITION_MET 0x4
-#define SCSI_BUSY 0x8
-#define SCSI_IMMEDIATE 0x10
-#define SCSI_IMMEDIATE_CONDITION_MET 0x14
-#define SCSI_RESERVATION_CONFLICT 0x18
-#define SCSI_COMMAND_TERMINATED 0x22
-#define SCSI_TASK_SET_FULL 0x28
-#define SCSI_ACA_ACTIVE 0x30
-#define SCSI_TASK_ABORTED 0x40
diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c
deleted file mode 100644 (file)
index a1b8e75..0000000
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * Copyright (C) IBM Corp. 2003
- * Copyright (C) SUSE Linux Products GmbH, 2006
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-#include <getopt.h>
-#include <sys/stat.h>
-
-#include "libudev.h"
-#include "libudev-private.h"
-#include "scsi_id.h"
-#include "udev-util.h"
-
-static const struct option options[] = {
-        { "device",             required_argument, NULL, 'd' },
-        { "config",             required_argument, NULL, 'f' },
-        { "page",               required_argument, NULL, 'p' },
-        { "blacklisted",        no_argument,       NULL, 'b' },
-        { "whitelisted",        no_argument,       NULL, 'g' },
-        { "replace-whitespace", no_argument,       NULL, 'u' },
-        { "sg-version",         required_argument, NULL, 's' },
-        { "verbose",            no_argument,       NULL, 'v' },
-        { "version",            no_argument,       NULL, 'V' }, /* don't advertise -V */
-        { "export",             no_argument,       NULL, 'x' },
-        { "help",               no_argument,       NULL, 'h' },
-        {}
-};
-
-static bool all_good = false;
-static bool dev_specified = false;
-static char config_file[MAX_PATH_LEN] = "/etc/scsi_id.config";
-static enum page_code default_page_code = PAGE_UNSPECIFIED;
-static int sg_version = 4;
-static bool reformat_serial = false;
-static bool export = false;
-static char vendor_str[64];
-static char model_str[64];
-static char vendor_enc_str[256];
-static char model_enc_str[256];
-static char revision_str[16];
-static char type_str[16];
-
-static void set_type(const char *from, char *to, size_t len)
-{
-        int type_num;
-        char *eptr;
-        const char *type = "generic";
-
-        type_num = strtoul(from, &eptr, 0);
-        if (eptr != from) {
-                switch (type_num) {
-                case 0:
-                        type = "disk";
-                        break;
-                case 1:
-                        type = "tape";
-                        break;
-                case 4:
-                        type = "optical";
-                        break;
-                case 5:
-                        type = "cd";
-                        break;
-                case 7:
-                        type = "optical";
-                        break;
-                case 0xe:
-                        type = "disk";
-                        break;
-                case 0xf:
-                        type = "optical";
-                        break;
-                default:
-                        break;
-                }
-        }
-        strscpy(to, len, type);
-}
-
-/*
- * get_value:
- *
- * buf points to an '=' followed by a quoted string ("foo") or a string ending
- * with a space or ','.
- *
- * Return a pointer to the NUL terminated string, returns NULL if no
- * matches.
- */
-static char *get_value(char **buffer)
-{
-        static const char *quote_string = "\"\n";
-        static const char *comma_string = ",\n";
-        char *val;
-        const char *end;
-
-        if (**buffer == '"') {
-                /*
-                 * skip leading quote, terminate when quote seen
-                 */
-                (*buffer)++;
-                end = quote_string;
-        } else {
-                end = comma_string;
-        }
-        val = strsep(buffer, end);
-        if (val && end == quote_string)
-                /*
-                 * skip trailing quote
-                 */
-                (*buffer)++;
-
-        while (isspace(**buffer))
-                (*buffer)++;
-
-        return val;
-}
-
-static int argc_count(char *opts)
-{
-        int i = 0;
-        while (*opts != '\0')
-                if (*opts++ == ' ')
-                        i++;
-        return i;
-}
-
-/*
- * get_file_options:
- *
- * If vendor == NULL, find a line in the config file with only "OPTIONS=";
- * if vendor and model are set find the first OPTIONS line in the config
- * file that matches. Set argc and argv to match the OPTIONS string.
- *
- * vendor and model can end in '\n'.
- */
-static int get_file_options(struct udev *udev,
-                            const char *vendor, const char *model,
-                            int *argc, char ***newargv)
-{
-        char *buffer;
-        _cleanup_fclose_ FILE *f;
-        char *buf;
-        char *str1;
-        char *vendor_in, *model_in, *options_in; /* read in from file */
-        int lineno;
-        int c;
-        int retval = 0;
-
-        f = fopen(config_file, "re");
-        if (f == NULL) {
-                if (errno == ENOENT)
-                        return 1;
-                else {
-                        log_error_errno(errno, "can't open %s: %m", config_file);
-                        return -1;
-                }
-        }
-
-        /*
-         * Allocate a buffer rather than put it on the stack so we can
-         * keep it around to parse any options (any allocated newargv
-         * points into this buffer for its strings).
-         */
-        buffer = malloc(MAX_BUFFER_LEN);
-        if (!buffer)
-                return log_oom();
-
-        *newargv = NULL;
-        lineno = 0;
-        while (1) {
-                vendor_in = model_in = options_in = NULL;
-
-                buf = fgets(buffer, MAX_BUFFER_LEN, f);
-                if (buf == NULL)
-                        break;
-                lineno++;
-                if (buf[strlen(buffer) - 1] != '\n') {
-                        log_error("Config file line %d too long", lineno);
-                        break;
-                }
-
-                while (isspace(*buf))
-                        buf++;
-
-                /* blank or all whitespace line */
-                if (*buf == '\0')
-                        continue;
-
-                /* comment line */
-                if (*buf == '#')
-                        continue;
-
-                str1 = strsep(&buf, "=");
-                if (str1 && strcaseeq(str1, "VENDOR")) {
-                        str1 = get_value(&buf);
-                        if (!str1) {
-                                retval = log_oom();
-                                break;
-                        }
-                        vendor_in = str1;
-
-                        str1 = strsep(&buf, "=");
-                        if (str1 && strcaseeq(str1, "MODEL")) {
-                                str1 = get_value(&buf);
-                                if (!str1) {
-                                        retval = log_oom();
-                                        break;
-                                }
-                                model_in = str1;
-                                str1 = strsep(&buf, "=");
-                        }
-                }
-
-                if (str1 && strcaseeq(str1, "OPTIONS")) {
-                        str1 = get_value(&buf);
-                        if (!str1) {
-                                retval = log_oom();
-                                break;
-                        }
-                        options_in = str1;
-                }
-
-                /*
-                 * Only allow: [vendor=foo[,model=bar]]options=stuff
-                 */
-                if (!options_in || (!vendor_in && model_in)) {
-                        log_error("Error parsing config file line %d '%s'", lineno, buffer);
-                        retval = -1;
-                        break;
-                }
-                if (vendor == NULL) {
-                        if (vendor_in == NULL)
-                                break;
-                } else if (vendor_in &&
-                           strneq(vendor, vendor_in, strlen(vendor_in)) &&
-                           (!model_in ||
-                            (strneq(model, model_in, strlen(model_in))))) {
-                                /*
-                                 * Matched vendor and optionally model.
-                                 *
-                                 * Note: a short vendor_in or model_in can
-                                 * give a partial match (that is FOO
-                                 * matches FOOBAR).
-                                 */
-                                break;
-                }
-        }
-
-        if (retval == 0) {
-                if (vendor_in != NULL || model_in != NULL ||
-                    options_in != NULL) {
-                        /*
-                         * Something matched. Allocate newargv, and store
-                         * values found in options_in.
-                         */
-                        strcpy(buffer, options_in);
-                        c = argc_count(buffer) + 2;
-                        *newargv = calloc(c, sizeof(**newargv));
-                        if (!*newargv) {
-                                retval = log_oom();
-                        } else {
-                                *argc = c;
-                                c = 0;
-                                /*
-                                 * argv[0] at 0 is skipped by getopt, but
-                                 * store the buffer address there for
-                                 * later freeing
-                                 */
-                                (*newargv)[c] = buffer;
-                                for (c = 1; c < *argc; c++)
-                                        (*newargv)[c] = strsep(&buffer, " \t");
-                        }
-                } else {
-                        /* No matches  */
-                        retval = 1;
-                }
-        }
-        if (retval != 0)
-                free(buffer);
-        return retval;
-}
-
-static void help(void) {
-        printf("Usage: %s [OPTION...] DEVICE\n\n"
-               "SCSI device identification.\n\n"
-               "  -h --help                        Print this message\n"
-               "     --version                     Print version of the program\n\n"
-               "  -d --device=                     Device node for SG_IO commands\n"
-               "  -f --config=                     Location of config file\n"
-               "  -p --page=0x80|0x83|pre-spc3-83  SCSI page (0x80, 0x83, pre-spc3-83)\n"
-               "  -s --sg-version=3|4              Use SGv3 or SGv4\n"
-               "  -b --blacklisted                 Treat device as blacklisted\n"
-               "  -g --whitelisted                 Treat device as whitelisted\n"
-               "  -u --replace-whitespace          Replace all whitespace by underscores\n"
-               "  -v --verbose                     Verbose logging\n"
-               "  -x --export                      Print values as environment keys\n"
-               , program_invocation_short_name);
-
-}
-
-static int set_options(struct udev *udev,
-                       int argc, char **argv,
-                       char *maj_min_dev)
-{
-        int option;
-
-        /*
-         * optind is a global extern used by getopt. Since we can call
-         * set_options twice (once for command line, and once for config
-         * file) we have to reset this back to 1.
-         */
-        optind = 1;
-        while ((option = getopt_long(argc, argv, "d:f:gp:uvVxh", options, NULL)) >= 0)
-                switch (option) {
-                case 'b':
-                        all_good = false;
-                        break;
-
-                case 'd':
-                        dev_specified = true;
-                        strscpy(maj_min_dev, MAX_PATH_LEN, optarg);
-                        break;
-
-                case 'f':
-                        strscpy(config_file, MAX_PATH_LEN, optarg);
-                        break;
-
-                case 'g':
-                        all_good = true;
-                        break;
-
-                case 'h':
-                        help();
-                        exit(0);
-
-                case 'p':
-                        if (streq(optarg, "0x80"))
-                                default_page_code = PAGE_80;
-                        else if (streq(optarg, "0x83"))
-                                default_page_code = PAGE_83;
-                        else if (streq(optarg, "pre-spc3-83"))
-                                default_page_code = PAGE_83_PRE_SPC3;
-                        else {
-                                log_error("Unknown page code '%s'", optarg);
-                                return -1;
-                        }
-                        break;
-
-                case 's':
-                        sg_version = atoi(optarg);
-                        if (sg_version < 3 || sg_version > 4) {
-                                log_error("Unknown SG version '%s'", optarg);
-                                return -1;
-                        }
-                        break;
-
-                case 'u':
-                        reformat_serial = true;
-                        break;
-
-                case 'v':
-                        log_set_target(LOG_TARGET_CONSOLE);
-                        log_set_max_level(LOG_DEBUG);
-                        log_open();
-                        break;
-
-                case 'V':
-                        printf("%s\n", VERSION);
-                        exit(0);
-
-                case 'x':
-                        export = true;
-                        break;
-
-                case '?':
-                        return -1;
-
-                default:
-                        assert_not_reached("Unknown option");
-                }
-
-        if (optind < argc && !dev_specified) {
-                dev_specified = true;
-                strscpy(maj_min_dev, MAX_PATH_LEN, argv[optind]);
-        }
-
-        return 0;
-}
-
-static int per_dev_options(struct udev *udev,
-                           struct scsi_id_device *dev_scsi, int *good_bad, int *page_code)
-{
-        int retval;
-        int newargc;
-        char **newargv = NULL;
-        int option;
-
-        *good_bad = all_good;
-        *page_code = default_page_code;
-
-        retval = get_file_options(udev, vendor_str, model_str, &newargc, &newargv);
-
-        optind = 1; /* reset this global extern */
-        while (retval == 0) {
-                option = getopt_long(newargc, newargv, "bgp:", options, NULL);
-                if (option == -1)
-                        break;
-
-                switch (option) {
-                case 'b':
-                        *good_bad = 0;
-                        break;
-
-                case 'g':
-                        *good_bad = 1;
-                        break;
-
-                case 'p':
-                        if (streq(optarg, "0x80")) {
-                                *page_code = PAGE_80;
-                        } else if (streq(optarg, "0x83")) {
-                                *page_code = PAGE_83;
-                        } else if (streq(optarg, "pre-spc3-83")) {
-                                *page_code = PAGE_83_PRE_SPC3;
-                        } else {
-                                log_error("Unknown page code '%s'", optarg);
-                                retval = -1;
-                        }
-                        break;
-
-                default:
-                        log_error("Unknown or bad option '%c' (0x%x)", option, option);
-                        retval = -1;
-                        break;
-                }
-        }
-
-        if (newargv) {
-                free(newargv[0]);
-                free(newargv);
-        }
-        return retval;
-}
-
-static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, const char *path)
-{
-        int retval;
-
-        dev_scsi->use_sg = sg_version;
-
-        retval = scsi_std_inquiry(udev, dev_scsi, path);
-        if (retval)
-                return retval;
-
-        udev_util_encode_string(dev_scsi->vendor, vendor_enc_str, sizeof(vendor_enc_str));
-        udev_util_encode_string(dev_scsi->model, model_enc_str, sizeof(model_enc_str));
-
-        util_replace_whitespace(dev_scsi->vendor, vendor_str, sizeof(vendor_str));
-        util_replace_chars(vendor_str, NULL);
-        util_replace_whitespace(dev_scsi->model, model_str, sizeof(model_str));
-        util_replace_chars(model_str, NULL);
-        set_type(dev_scsi->type, type_str, sizeof(type_str));
-        util_replace_whitespace(dev_scsi->revision, revision_str, sizeof(revision_str));
-        util_replace_chars(revision_str, NULL);
-        return 0;
-}
-
-/*
- * scsi_id: try to get an id, if one is found, printf it to stdout.
- * returns a value passed to exit() - 0 if printed an id, else 1.
- */
-static int scsi_id(struct udev *udev, char *maj_min_dev)
-{
-        struct scsi_id_device dev_scsi = {};
-        int good_dev;
-        int page_code;
-        int retval = 0;
-
-        if (set_inq_values(udev, &dev_scsi, maj_min_dev) < 0) {
-                retval = 1;
-                goto out;
-        }
-
-        /* get per device (vendor + model) options from the config file */
-        per_dev_options(udev, &dev_scsi, &good_dev, &page_code);
-        if (!good_dev) {
-                retval = 1;
-                goto out;
-        }
-
-        /* read serial number from mode pages (no values for optical drives) */
-        scsi_get_serial(udev, &dev_scsi, maj_min_dev, page_code, MAX_SERIAL_LEN);
-
-        if (export) {
-                char serial_str[MAX_SERIAL_LEN];
-
-                printf("ID_SCSI=1\n");
-                printf("ID_VENDOR=%s\n", vendor_str);
-                printf("ID_VENDOR_ENC=%s\n", vendor_enc_str);
-                printf("ID_MODEL=%s\n", model_str);
-                printf("ID_MODEL_ENC=%s\n", model_enc_str);
-                printf("ID_REVISION=%s\n", revision_str);
-                printf("ID_TYPE=%s\n", type_str);
-                if (dev_scsi.serial[0] != '\0') {
-                        util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str));
-                        util_replace_chars(serial_str, NULL);
-                        printf("ID_SERIAL=%s\n", serial_str);
-                        util_replace_whitespace(dev_scsi.serial_short, serial_str, sizeof(serial_str));
-                        util_replace_chars(serial_str, NULL);
-                        printf("ID_SERIAL_SHORT=%s\n", serial_str);
-                }
-                if (dev_scsi.wwn[0] != '\0') {
-                        printf("ID_WWN=0x%s\n", dev_scsi.wwn);
-                        if (dev_scsi.wwn_vendor_extension[0] != '\0') {
-                                printf("ID_WWN_VENDOR_EXTENSION=0x%s\n", dev_scsi.wwn_vendor_extension);
-                                printf("ID_WWN_WITH_EXTENSION=0x%s%s\n", dev_scsi.wwn, dev_scsi.wwn_vendor_extension);
-                        } else {
-                                printf("ID_WWN_WITH_EXTENSION=0x%s\n", dev_scsi.wwn);
-                        }
-                }
-                if (dev_scsi.tgpt_group[0] != '\0') {
-                        printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group);
-                }
-                if (dev_scsi.unit_serial_number[0] != '\0') {
-                        printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number);
-                }
-                goto out;
-        }
-
-        if (dev_scsi.serial[0] == '\0') {
-                retval = 1;
-                goto out;
-        }
-
-        if (reformat_serial) {
-                char serial_str[MAX_SERIAL_LEN];
-
-                util_replace_whitespace(dev_scsi.serial, serial_str, sizeof(serial_str));
-                util_replace_chars(serial_str, NULL);
-                printf("%s\n", serial_str);
-                goto out;
-        }
-
-        printf("%s\n", dev_scsi.serial);
-out:
-        return retval;
-}
-
-int main(int argc, char **argv)
-{
-        _cleanup_udev_unref_ struct udev *udev;
-        int retval = 0;
-        char maj_min_dev[MAX_PATH_LEN];
-        int newargc;
-        char **newargv = NULL;
-
-        log_parse_environment();
-        log_open();
-
-        udev = udev_new();
-        if (udev == NULL)
-                goto exit;
-
-        /*
-         * Get config file options.
-         */
-        retval = get_file_options(udev, NULL, NULL, &newargc, &newargv);
-        if (retval < 0) {
-                retval = 1;
-                goto exit;
-        }
-        if (retval == 0) {
-                assert(newargv);
-
-                if (set_options(udev, newargc, newargv, maj_min_dev) < 0) {
-                        retval = 2;
-                        goto exit;
-                }
-        }
-
-        /*
-         * Get command line options (overriding any config file settings).
-         */
-        if (set_options(udev, argc, argv, maj_min_dev) < 0)
-                exit(1);
-
-        if (!dev_specified) {
-                log_error("No device specified.");
-                retval = 1;
-                goto exit;
-        }
-
-        retval = scsi_id(udev, maj_min_dev);
-
-exit:
-        if (newargv) {
-                free(newargv[0]);
-                free(newargv);
-        }
-        log_close();
-        return retval;
-}
diff --git a/src/udev/scsi_id/scsi_id.h b/src/udev/scsi_id/scsi_id.h
deleted file mode 100644 (file)
index 141b116..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) IBM Corp. 2003
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#define MAX_PATH_LEN 512
-
-/*
- * MAX_ATTR_LEN: maximum length of the result of reading a sysfs
- * attribute.
- */
-#define MAX_ATTR_LEN 256
-
-/*
- * MAX_SERIAL_LEN: the maximum length of the serial number, including
- * added prefixes such as vendor and product (model) strings.
- */
-#define MAX_SERIAL_LEN 256
-
-/*
- * MAX_BUFFER_LEN: maximum buffer size and line length used while reading
- * the config file.
- */
-#define MAX_BUFFER_LEN 256
-
-struct scsi_id_device {
-        char vendor[9];
-        char model[17];
-        char revision[5];
-        char type[33];
-        char kernel[64];
-        char serial[MAX_SERIAL_LEN];
-        char serial_short[MAX_SERIAL_LEN];
-        int use_sg;
-
-        /* Always from page 0x80 e.g. 'B3G1P8500RWT' - may not be unique */
-        char unit_serial_number[MAX_SERIAL_LEN];
-
-        /* NULs if not set - otherwise hex encoding using lower-case e.g. '50014ee0016eb572' */
-        char wwn[17];
-
-        /* NULs if not set - otherwise hex encoding using lower-case e.g. '0xe00000d80000' */
-        char wwn_vendor_extension[17];
-
-        /* NULs if not set - otherwise decimal number */
-        char tgpt_group[8];
-};
-
-int scsi_std_inquiry(struct udev *udev, struct scsi_id_device *dev_scsi, const char *devname);
-int scsi_get_serial(struct udev *udev, struct scsi_id_device *dev_scsi, const char *devname,
-                    int page_code, int len);
-
-/*
- * Page code values.
- */
-enum page_code {
-        PAGE_83_PRE_SPC3 = -0x83,
-        PAGE_UNSPECIFIED = 0x00,
-        PAGE_80          = 0x80,
-        PAGE_83          = 0x83,
-};
diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c
deleted file mode 100644 (file)
index dcfff1d..0000000
+++ /dev/null
@@ -1,965 +0,0 @@
-/*
- * Copyright (C) IBM Corp. 2003
- *
- * Author: Patrick Mansfield<patmans@us.ibm.com>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-#include <inttypes.h>
-#include <scsi/scsi.h>
-#include <scsi/sg.h>
-#include <linux/types.h>
-#include <linux/bsg.h>
-
-#include "libudev.h"
-#include "libudev-private.h"
-#include "scsi.h"
-#include "scsi_id.h"
-
-/*
- * A priority based list of id, naa, and binary/ascii for the identifier
- * descriptor in VPD page 0x83.
- *
- * Brute force search for a match starting with the first value in the
- * following id_search_list. This is not a performance issue, since there
- * is normally one or some small number of descriptors.
- */
-static const struct scsi_id_search_values id_search_list[] = {
-        { SCSI_ID_TGTGROUP,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
-        { SCSI_ID_NAA,        SCSI_ID_NAA_IEEE_REG_EXTENDED,        SCSI_ID_BINARY },
-        { SCSI_ID_NAA,        SCSI_ID_NAA_IEEE_REG_EXTENDED,        SCSI_ID_ASCII },
-        { SCSI_ID_NAA,        SCSI_ID_NAA_IEEE_REG,        SCSI_ID_BINARY },
-        { SCSI_ID_NAA,        SCSI_ID_NAA_IEEE_REG,        SCSI_ID_ASCII },
-        /*
-         * Devices already exist using NAA values that are now marked
-         * reserved. These should not conflict with other values, or it is
-         * a bug in the device. As long as we find the IEEE extended one
-         * first, we really don't care what other ones are used. Using
-         * don't care here means that a device that returns multiple
-         * non-IEEE descriptors in a random order will get different
-         * names.
-         */
-        { SCSI_ID_NAA,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
-        { SCSI_ID_NAA,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_ASCII },
-        { SCSI_ID_EUI_64,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
-        { SCSI_ID_EUI_64,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_ASCII },
-        { SCSI_ID_T10_VENDOR,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
-        { SCSI_ID_T10_VENDOR,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_ASCII },
-        { SCSI_ID_VENDOR_SPECIFIC,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_BINARY },
-        { SCSI_ID_VENDOR_SPECIFIC,        SCSI_ID_NAA_DONT_CARE,        SCSI_ID_ASCII },
-};
-
-static const char hex_str[]="0123456789abcdef";
-
-/*
- * Values returned in the result/status, only the ones used by the code
- * are used here.
- */
-
-#define DID_NO_CONNECT                        0x01        /* Unable to connect before timeout */
-#define DID_BUS_BUSY                        0x02        /* Bus remain busy until timeout */
-#define DID_TIME_OUT                        0x03        /* Timed out for some other reason */
-#define DRIVER_TIMEOUT                        0x06
-#define DRIVER_SENSE                        0x08        /* Sense_buffer has been set */
-
-/* The following "category" function returns one of the following */
-#define SG_ERR_CAT_CLEAN                0        /* No errors or other information */
-#define SG_ERR_CAT_MEDIA_CHANGED        1        /* interpreted from sense buffer */
-#define SG_ERR_CAT_RESET                2        /* interpreted from sense buffer */
-#define SG_ERR_CAT_TIMEOUT                3
-#define SG_ERR_CAT_RECOVERED                4        /* Successful command after recovered err */
-#define SG_ERR_CAT_NOTSUPPORTED                5        /* Illegal / unsupported command */
-#define SG_ERR_CAT_SENSE                98        /* Something else in the sense buffer */
-#define SG_ERR_CAT_OTHER                99        /* Some other error/warning */
-
-static int do_scsi_page80_inquiry(struct udev *udev,
-                                  struct scsi_id_device *dev_scsi, int fd,
-                                  char *serial, char *serial_short, int max_len);
-
-static int sg_err_category_new(struct udev *udev,
-                               int scsi_status, int msg_status, int
-                               host_status, int driver_status, const
-                               unsigned char *sense_buffer, int sb_len)
-{
-        scsi_status &= 0x7e;
-
-        /*
-         * XXX change to return only two values - failed or OK.
-         */
-
-        if (!scsi_status && !host_status && !driver_status)
-                return SG_ERR_CAT_CLEAN;
-
-        if ((scsi_status == SCSI_CHECK_CONDITION) ||
-            (scsi_status == SCSI_COMMAND_TERMINATED) ||
-            ((driver_status & 0xf) == DRIVER_SENSE)) {
-                if (sense_buffer && (sb_len > 2)) {
-                        int sense_key;
-                        unsigned char asc;
-
-                        if (sense_buffer[0] & 0x2) {
-                                sense_key = sense_buffer[1] & 0xf;
-                                asc = sense_buffer[2];
-                        } else {
-                                sense_key = sense_buffer[2] & 0xf;
-                                asc = (sb_len > 12) ? sense_buffer[12] : 0;
-                        }
-
-                        if (sense_key == RECOVERED_ERROR)
-                                return SG_ERR_CAT_RECOVERED;
-                        else if (sense_key == UNIT_ATTENTION) {
-                                if (0x28 == asc)
-                                        return SG_ERR_CAT_MEDIA_CHANGED;
-                                if (0x29 == asc)
-                                        return SG_ERR_CAT_RESET;
-                        } else if (sense_key == ILLEGAL_REQUEST) {
-                                return SG_ERR_CAT_NOTSUPPORTED;
-                        }
-                }
-                return SG_ERR_CAT_SENSE;
-        }
-        if (host_status) {
-                if ((host_status == DID_NO_CONNECT) ||
-                    (host_status == DID_BUS_BUSY) ||
-                    (host_status == DID_TIME_OUT))
-                        return SG_ERR_CAT_TIMEOUT;
-        }
-        if (driver_status) {
-                if (driver_status == DRIVER_TIMEOUT)
-                        return SG_ERR_CAT_TIMEOUT;
-        }
-        return SG_ERR_CAT_OTHER;
-}
-
-static int sg_err_category3(struct udev *udev, struct sg_io_hdr *hp)
-{
-        return sg_err_category_new(udev,
-                                   hp->status, hp->msg_status,
-                                   hp->host_status, hp->driver_status,
-                                   hp->sbp, hp->sb_len_wr);
-}
-
-static int sg_err_category4(struct udev *udev, struct sg_io_v4 *hp)
-{
-        return sg_err_category_new(udev, hp->device_status, 0,
-                                   hp->transport_status, hp->driver_status,
-                                   (unsigned char *)(uintptr_t)hp->response,
-                                   hp->response_len);
-}
-
-static int scsi_dump_sense(struct udev *udev,
-                           struct scsi_id_device *dev_scsi,
-                           unsigned char *sense_buffer, int sb_len)
-{
-        int s;
-        int code;
-        int sense_class;
-        int sense_key;
-        int asc, ascq;
-#ifdef DUMP_SENSE
-        char out_buffer[256];
-        int i, j;
-#endif
-
-        /*
-         * Figure out and print the sense key, asc and ascq.
-         *
-         * If you want to suppress these for a particular drive model, add
-         * a black list entry in the scsi_id config file.
-         *
-         * XXX We probably need to: lookup the sense/asc/ascq in a retry
-         * table, and if found return 1 (after dumping the sense, asc, and
-         * ascq). So, if/when we get something like a power on/reset,
-         * we'll retry the command.
-         */
-
-        if (sb_len < 1) {
-                log_debug("%s: sense buffer empty", dev_scsi->kernel);
-                return -1;
-        }
-
-        sense_class = (sense_buffer[0] >> 4) & 0x07;
-        code = sense_buffer[0] & 0xf;
-
-        if (sense_class == 7) {
-                /*
-                 * extended sense data.
-                 */
-                s = sense_buffer[7] + 8;
-                if (sb_len < s) {
-                        log_debug("%s: sense buffer too small %d bytes, %d bytes too short",
-                            dev_scsi->kernel, sb_len, s - sb_len);
-                        return -1;
-                }
-                if ((code == 0x0) || (code == 0x1)) {
-                        sense_key = sense_buffer[2] & 0xf;
-                        if (s < 14) {
-                                /*
-                                 * Possible?
-                                 */
-                                log_debug("%s: sense result too" " small %d bytes",
-                                    dev_scsi->kernel, s);
-                                return -1;
-                        }
-                        asc = sense_buffer[12];
-                        ascq = sense_buffer[13];
-                } else if ((code == 0x2) || (code == 0x3)) {
-                        sense_key = sense_buffer[1] & 0xf;
-                        asc = sense_buffer[2];
-                        ascq = sense_buffer[3];
-                } else {
-                        log_debug("%s: invalid sense code 0x%x",
-                            dev_scsi->kernel, code);
-                        return -1;
-                }
-                log_debug("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x",
-                    dev_scsi->kernel, sense_key, asc, ascq);
-        } else {
-                if (sb_len < 4) {
-                        log_debug("%s: sense buffer too small %d bytes, %d bytes too short",
-                            dev_scsi->kernel, sb_len, 4 - sb_len);
-                        return -1;
-                }
-
-                if (sense_buffer[0] < 15)
-                        log_debug("%s: old sense key: 0x%x", dev_scsi->kernel, sense_buffer[0] & 0x0f);
-                else
-                        log_debug("%s: sense = %2x %2x",
-                            dev_scsi->kernel, sense_buffer[0], sense_buffer[2]);
-                log_debug("%s: non-extended sense class %d code 0x%0x",
-                    dev_scsi->kernel, sense_class, code);
-
-        }
-
-#ifdef DUMP_SENSE
-        for (i = 0, j = 0; (i < s) && (j < 254); i++) {
-                out_buffer[j++] = hex_str[(sense_buffer[i] & 0xf0) >> 4];
-                out_buffer[j++] = hex_str[sense_buffer[i] & 0x0f];
-                out_buffer[j++] = ' ';
-        }
-        out_buffer[j] = '\0';
-        log_debug("%s: sense dump:", dev_scsi->kernel);
-        log_debug("%s: %s", dev_scsi->kernel, out_buffer);
-
-#endif
-        return -1;
-}
-
-static int scsi_dump(struct udev *udev,
-                     struct scsi_id_device *dev_scsi, struct sg_io_hdr *io)
-{
-        if (!io->status && !io->host_status && !io->msg_status &&
-            !io->driver_status) {
-                /*
-                 * Impossible, should not be called.
-                 */
-                log_debug("%s: called with no error", __FUNCTION__);
-                return -1;
-        }
-
-        log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x",
-            dev_scsi->kernel, io->driver_status, io->host_status, io->msg_status, io->status);
-        if (io->status == SCSI_CHECK_CONDITION)
-                return scsi_dump_sense(udev, dev_scsi, io->sbp, io->sb_len_wr);
-        else
-                return -1;
-}
-
-static int scsi_dump_v4(struct udev *udev,
-                        struct scsi_id_device *dev_scsi, struct sg_io_v4 *io)
-{
-        if (!io->device_status && !io->transport_status &&
-            !io->driver_status) {
-                /*
-                 * Impossible, should not be called.
-                 */
-                log_debug("%s: called with no error", __FUNCTION__);
-                return -1;
-        }
-
-        log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x",
-            dev_scsi->kernel, io->driver_status, io->transport_status,
-             io->device_status);
-        if (io->device_status == SCSI_CHECK_CONDITION)
-                return scsi_dump_sense(udev, dev_scsi, (unsigned char *)(uintptr_t)io->response,
-                                       io->response_len);
-        else
-                return -1;
-}
-
-static int scsi_inquiry(struct udev *udev,
-                        struct scsi_id_device *dev_scsi, int fd,
-                        unsigned char evpd, unsigned char page,
-                        unsigned char *buf, unsigned int buflen)
-{
-        unsigned char inq_cmd[INQUIRY_CMDLEN] =
-                { INQUIRY_CMD, evpd, page, 0, buflen, 0 };
-        unsigned char sense[SENSE_BUFF_LEN];
-        void *io_buf;
-        struct sg_io_v4 io_v4;
-        struct sg_io_hdr io_hdr;
-        int retry = 3; /* rather random */
-        int retval;
-
-        if (buflen > SCSI_INQ_BUFF_LEN) {
-                log_debug("buflen %d too long", buflen);
-                return -1;
-        }
-
-resend:
-        if (dev_scsi->use_sg == 4) {
-                memzero(&io_v4, sizeof(struct sg_io_v4));
-                io_v4.guard = 'Q';
-                io_v4.protocol = BSG_PROTOCOL_SCSI;
-                io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
-                io_v4.request_len = sizeof(inq_cmd);
-                io_v4.request = (uintptr_t)inq_cmd;
-                io_v4.max_response_len = sizeof(sense);
-                io_v4.response = (uintptr_t)sense;
-                io_v4.din_xfer_len = buflen;
-                io_v4.din_xferp = (uintptr_t)buf;
-                io_buf = (void *)&io_v4;
-        } else {
-                memzero(&io_hdr, sizeof(struct sg_io_hdr));
-                io_hdr.interface_id = 'S';
-                io_hdr.cmd_len = sizeof(inq_cmd);
-                io_hdr.mx_sb_len = sizeof(sense);
-                io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
-                io_hdr.dxfer_len = buflen;
-                io_hdr.dxferp = buf;
-                io_hdr.cmdp = inq_cmd;
-                io_hdr.sbp = sense;
-                io_hdr.timeout = DEF_TIMEOUT;
-                io_buf = (void *)&io_hdr;
-        }
-
-        retval = ioctl(fd, SG_IO, io_buf);
-        if (retval < 0) {
-                if ((errno == EINVAL || errno == ENOSYS) && dev_scsi->use_sg == 4) {
-                        dev_scsi->use_sg = 3;
-                        goto resend;
-                }
-                log_debug_errno(errno, "%s: ioctl failed: %m", dev_scsi->kernel);
-                goto error;
-        }
-
-        if (dev_scsi->use_sg == 4)
-                retval = sg_err_category4(udev, io_buf);
-        else
-                retval = sg_err_category3(udev, io_buf);
-
-        switch (retval) {
-                case SG_ERR_CAT_NOTSUPPORTED:
-                        buf[1] = 0;
-                        /* Fallthrough */
-                case SG_ERR_CAT_CLEAN:
-                case SG_ERR_CAT_RECOVERED:
-                        retval = 0;
-                        break;
-
-                default:
-                        if (dev_scsi->use_sg == 4)
-                                retval = scsi_dump_v4(udev, dev_scsi, io_buf);
-                        else
-                                retval = scsi_dump(udev, dev_scsi, io_buf);
-        }
-
-        if (!retval) {
-                retval = buflen;
-        } else if (retval > 0) {
-                if (--retry > 0)
-                        goto resend;
-                retval = -1;
-        }
-
-error:
-        if (retval < 0)
-                log_debug("%s: Unable to get INQUIRY vpd %d page 0x%x.",
-                    dev_scsi->kernel, evpd, page);
-
-        return retval;
-}
-
-/* Get list of supported EVPD pages */
-static int do_scsi_page0_inquiry(struct udev *udev,
-                                 struct scsi_id_device *dev_scsi, int fd,
-                                 unsigned char *buffer, unsigned int len)
-{
-        int retval;
-
-        memzero(buffer, len);
-        retval = scsi_inquiry(udev, dev_scsi, fd, 1, 0x0, buffer, len);
-        if (retval < 0)
-                return 1;
-
-        if (buffer[1] != 0) {
-                log_debug("%s: page 0 not available.", dev_scsi->kernel);
-                return 1;
-        }
-        if (buffer[3] > len) {
-                log_debug("%s: page 0 buffer too long %d", dev_scsi->kernel,         buffer[3]);
-                return 1;
-        }
-
-        /*
-         * Following check is based on code once included in the 2.5.x
-         * kernel.
-         *
-         * Some ill behaved devices return the standard inquiry here
-         * rather than the evpd data, snoop the data to verify.
-         */
-        if (buffer[3] > MODEL_LENGTH) {
-                /*
-                 * If the vendor id appears in the page assume the page is
-                 * invalid.
-                 */
-                if (strneq((char *)&buffer[VENDOR_LENGTH], dev_scsi->vendor, VENDOR_LENGTH)) {
-                        log_debug("%s: invalid page0 data", dev_scsi->kernel);
-                        return 1;
-                }
-        }
-        return 0;
-}
-
-/*
- * The caller checks that serial is long enough to include the vendor +
- * model.
- */
-static int prepend_vendor_model(struct udev *udev,
-                                struct scsi_id_device *dev_scsi, char *serial)
-{
-        int ind;
-
-        strncpy(serial, dev_scsi->vendor, VENDOR_LENGTH);
-        strncat(serial, dev_scsi->model, MODEL_LENGTH);
-        ind = strlen(serial);
-
-        /*
-         * This is not a complete check, since we are using strncat/cpy
-         * above, ind will never be too large.
-         */
-        if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) {
-                log_debug("%s: expected length %d, got length %d",
-                     dev_scsi->kernel, (VENDOR_LENGTH + MODEL_LENGTH), ind);
-                return -1;
-        }
-        return ind;
-}
-
-/*
- * check_fill_0x83_id - check the page 0x83 id, if OK allocate and fill
- * serial number.
- */
-static int check_fill_0x83_id(struct udev *udev,
-                              struct scsi_id_device *dev_scsi,
-                              unsigned char *page_83,
-                              const struct scsi_id_search_values
-                              *id_search, char *serial, char *serial_short,
-                              int max_len, char *wwn,
-                              char *wwn_vendor_extension, char *tgpt_group)
-{
-        int i, j, s, len;
-
-        /*
-         * ASSOCIATION must be with the device (value 0)
-         * or with the target port for SCSI_ID_TGTPORT
-         */
-        if ((page_83[1] & 0x30) == 0x10) {
-                if (id_search->id_type != SCSI_ID_TGTGROUP)
-                        return 1;
-        } else if ((page_83[1] & 0x30) != 0) {
-                return 1;
-        }
-
-        if ((page_83[1] & 0x0f) != id_search->id_type)
-                return 1;
-
-        /*
-         * Possibly check NAA sub-type.
-         */
-        if ((id_search->naa_type != SCSI_ID_NAA_DONT_CARE) &&
-            (id_search->naa_type != (page_83[4] & 0xf0) >> 4))
-                return 1;
-
-        /*
-         * Check for matching code set - ASCII or BINARY.
-         */
-        if ((page_83[0] & 0x0f) != id_search->code_set)
-                return 1;
-
-        /*
-         * page_83[3]: identifier length
-         */
-        len = page_83[3];
-        if ((page_83[0] & 0x0f) != SCSI_ID_ASCII)
-                /*
-                 * If not ASCII, use two bytes for each binary value.
-                 */
-                len *= 2;
-
-        /*
-         * Add one byte for the NUL termination, and one for the id_type.
-         */
-        len += 2;
-        if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC)
-                len += VENDOR_LENGTH + MODEL_LENGTH;
-
-        if (max_len < len) {
-                log_debug("%s: length %d too short - need %d",
-                    dev_scsi->kernel, max_len, len);
-                return 1;
-        }
-
-        if (id_search->id_type == SCSI_ID_TGTGROUP && tgpt_group != NULL) {
-                unsigned int group;
-
-                group = ((unsigned int)page_83[6] << 8) | page_83[7];
-                sprintf(tgpt_group,"%x", group);
-                return 1;
-        }
-
-        serial[0] = hex_str[id_search->id_type];
-
-        /*
-         * For SCSI_ID_VENDOR_SPECIFIC prepend the vendor and model before
-         * the id since it is not unique across all vendors and models,
-         * this differs from SCSI_ID_T10_VENDOR, where the vendor is
-         * included in the identifier.
-         */
-        if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC)
-                if (prepend_vendor_model(udev, dev_scsi, &serial[1]) < 0)
-                        return 1;
-
-        i = 4; /* offset to the start of the identifier */
-        s = j = strlen(serial);
-        if ((page_83[0] & 0x0f) == SCSI_ID_ASCII) {
-                /*
-                 * ASCII descriptor.
-                 */
-                while (i < (4 + page_83[3]))
-                        serial[j++] = page_83[i++];
-        } else {
-                /*
-                 * Binary descriptor, convert to ASCII, using two bytes of
-                 * ASCII for each byte in the page_83.
-                 */
-                while (i < (4 + page_83[3])) {
-                        serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4];
-                        serial[j++] = hex_str[page_83[i] & 0x0f];
-                        i++;
-                }
-        }
-
-        strcpy(serial_short, &serial[s]);
-
-        if (id_search->id_type == SCSI_ID_NAA && wwn != NULL) {
-                strncpy(wwn, &serial[s], 16);
-                if (wwn_vendor_extension != NULL) {
-                        strncpy(wwn_vendor_extension, &serial[s + 16], 16);
-                }
-        }
-
-        return 0;
-}
-
-/* Extract the raw binary from VPD 0x83 pre-SPC devices */
-static int check_fill_0x83_prespc3(struct udev *udev,
-                                   struct scsi_id_device *dev_scsi,
-                                   unsigned char *page_83,
-                                   const struct scsi_id_search_values
-                                   *id_search, char *serial, char *serial_short, int max_len)
-{
-        int i, j;
-
-        serial[0] = hex_str[id_search->id_type];
-        /* serial has been memset to zero before */
-        j = strlen(serial);        /* j = 1; */
-
-        for (i = 0; (i < page_83[3]) && (j < max_len-3); ++i) {
-                serial[j++] = hex_str[(page_83[4+i] & 0xf0) >> 4];
-                serial[j++] = hex_str[ page_83[4+i] & 0x0f];
-        }
-        serial[max_len-1] = 0;
-        strncpy(serial_short, serial, max_len-1);
-        return 0;
-}
-
-
-/* Get device identification VPD page */
-static int do_scsi_page83_inquiry(struct udev *udev,
-                                  struct scsi_id_device *dev_scsi, int fd,
-                                  char *serial, char *serial_short, int len,
-                                  char *unit_serial_number, char *wwn,
-                                  char *wwn_vendor_extension, char *tgpt_group)
-{
-        int retval;
-        unsigned int id_ind, j;
-        unsigned char page_83[SCSI_INQ_BUFF_LEN];
-
-        /* also pick up the page 80 serial number */
-        do_scsi_page80_inquiry(udev, dev_scsi, fd, NULL, unit_serial_number, MAX_SERIAL_LEN);
-
-        memzero(page_83, SCSI_INQ_BUFF_LEN);
-        retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_83, page_83,
-                              SCSI_INQ_BUFF_LEN);
-        if (retval < 0)
-                return 1;
-
-        if (page_83[1] != PAGE_83) {
-                log_debug("%s: Invalid page 0x83", dev_scsi->kernel);
-                return 1;
-        }
-
-        /*
-         * XXX Some devices (IBM 3542) return all spaces for an identifier if
-         * the LUN is not actually configured. This leads to identifiers of
-         * the form: "1            ".
-         */
-
-        /*
-         * Model 4, 5, and (some) model 6 EMC Symmetrix devices return
-         * a page 83 reply according to SCSI-2 format instead of SPC-2/3.
-         *
-         * The SCSI-2 page 83 format returns an IEEE WWN in binary
-         * encoded hexi-decimal in the 16 bytes following the initial
-         * 4-byte page 83 reply header.
-         *
-         * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part
-         * of an Identification descriptor.  The 3rd byte of the first
-         * Identification descriptor is a reserved (BSZ) byte field.
-         *
-         * Reference the 7th byte of the page 83 reply to determine
-         * whether the reply is compliant with SCSI-2 or SPC-2/3
-         * specifications.  A zero value in the 7th byte indicates
-         * an SPC-2/3 conformant reply, (i.e., the reserved field of the
-         * first Identification descriptor).  This byte will be non-zero
-         * for a SCSI-2 conformant page 83 reply from these EMC
-         * Symmetrix models since the 7th byte of the reply corresponds
-         * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is,
-         * 0x006048.
-         */
-
-        if (page_83[6] != 0)
-                return check_fill_0x83_prespc3(udev,
-                                               dev_scsi, page_83, id_search_list,
-                                               serial, serial_short, len);
-
-        /*
-         * Search for a match in the prioritized id_search_list - since WWN ids
-         * come first we can pick up the WWN in check_fill_0x83_id().
-         */
-        for (id_ind = 0;
-             id_ind < sizeof(id_search_list)/sizeof(id_search_list[0]);
-             id_ind++) {
-                /*
-                 * Examine each descriptor returned. There is normally only
-                 * one or a small number of descriptors.
-                 */
-                for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) {
-                        retval = check_fill_0x83_id(udev,
-                                                    dev_scsi, &page_83[j],
-                                                    &id_search_list[id_ind],
-                                                    serial, serial_short, len,
-                                                    wwn, wwn_vendor_extension,
-                                                    tgpt_group);
-                        if (!retval)
-                                return retval;
-                        else if (retval < 0)
-                                return retval;
-                }
-        }
-        return 1;
-}
-
-/*
- * Get device identification VPD page for older SCSI-2 device which is not
- * compliant with either SPC-2 or SPC-3 format.
- *
- * Return the hard coded error code value 2 if the page 83 reply is not
- * conformant to the SCSI-2 format.
- */
-static int do_scsi_page83_prespc3_inquiry(struct udev *udev,
-                                          struct scsi_id_device *dev_scsi, int fd,
-                                          char *serial, char *serial_short, int len)
-{
-        int retval;
-        int i, j;
-        unsigned char page_83[SCSI_INQ_BUFF_LEN];
-
-        memzero(page_83, SCSI_INQ_BUFF_LEN);
-        retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN);
-        if (retval < 0)
-                return 1;
-
-        if (page_83[1] != PAGE_83) {
-                log_debug("%s: Invalid page 0x83", dev_scsi->kernel);
-                return 1;
-        }
-        /*
-         * Model 4, 5, and (some) model 6 EMC Symmetrix devices return
-         * a page 83 reply according to SCSI-2 format instead of SPC-2/3.
-         *
-         * The SCSI-2 page 83 format returns an IEEE WWN in binary
-         * encoded hexi-decimal in the 16 bytes following the initial
-         * 4-byte page 83 reply header.
-         *
-         * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part
-         * of an Identification descriptor.  The 3rd byte of the first
-         * Identification descriptor is a reserved (BSZ) byte field.
-         *
-         * Reference the 7th byte of the page 83 reply to determine
-         * whether the reply is compliant with SCSI-2 or SPC-2/3
-         * specifications.  A zero value in the 7th byte indicates
-         * an SPC-2/3 conformant reply, (i.e., the reserved field of the
-         * first Identification descriptor).  This byte will be non-zero
-         * for a SCSI-2 conformant page 83 reply from these EMC
-         * Symmetrix models since the 7th byte of the reply corresponds
-         * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is,
-         * 0x006048.
-         */
-        if (page_83[6] == 0)
-                return 2;
-
-        serial[0] = hex_str[id_search_list[0].id_type];
-        /*
-         * The first four bytes contain data, not a descriptor.
-         */
-        i = 4;
-        j = strlen(serial);
-        /*
-         * Binary descriptor, convert to ASCII,
-         * using two bytes of ASCII for each byte
-         * in the page_83.
-         */
-        while (i < (page_83[3]+4)) {
-                serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4];
-                serial[j++] = hex_str[page_83[i] & 0x0f];
-                i++;
-        }
-        return 0;
-}
-
-/* Get unit serial number VPD page */
-static int do_scsi_page80_inquiry(struct udev *udev,
-                                  struct scsi_id_device *dev_scsi, int fd,
-                                  char *serial, char *serial_short, int max_len)
-{
-        int retval;
-        int ser_ind;
-        int i;
-        int len;
-        unsigned char buf[SCSI_INQ_BUFF_LEN];
-
-        memzero(buf, SCSI_INQ_BUFF_LEN);
-        retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN);
-        if (retval < 0)
-                return retval;
-
-        if (buf[1] != PAGE_80) {
-                log_debug("%s: Invalid page 0x80", dev_scsi->kernel);
-                return 1;
-        }
-
-        len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3];
-        if (max_len < len) {
-                log_debug("%s: length %d too short - need %d",
-                     dev_scsi->kernel, max_len, len);
-                return 1;
-        }
-        /*
-         * Prepend 'S' to avoid unlikely collision with page 0x83 vendor
-         * specific type where we prepend '0' + vendor + model.
-         */
-        len = buf[3];
-        if (serial != NULL) {
-                serial[0] = 'S';
-                ser_ind = prepend_vendor_model(udev, dev_scsi, &serial[1]);
-                if (ser_ind < 0)
-                        return 1;
-                ser_ind++; /* for the leading 'S' */
-                for (i = 4; i < len + 4; i++, ser_ind++)
-                        serial[ser_ind] = buf[i];
-        }
-        if (serial_short != NULL) {
-                memcpy(serial_short, &buf[4], len);
-                serial_short[len] = '\0';
-        }
-        return 0;
-}
-
-int scsi_std_inquiry(struct udev *udev,
-                     struct scsi_id_device *dev_scsi, const char *devname)
-{
-        int fd;
-        unsigned char buf[SCSI_INQ_BUFF_LEN];
-        struct stat statbuf;
-        int err = 0;
-
-        fd = open(devname, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
-        if (fd < 0) {
-                log_debug_errno(errno, "scsi_id: cannot open %s: %m", devname);
-                return 1;
-        }
-
-        if (fstat(fd, &statbuf) < 0) {
-                log_debug_errno(errno, "scsi_id: cannot stat %s: %m", devname);
-                err = 2;
-                goto out;
-        }
-        sprintf(dev_scsi->kernel,"%d:%d", major(statbuf.st_rdev),
-                minor(statbuf.st_rdev));
-
-        memzero(buf, SCSI_INQ_BUFF_LEN);
-        err = scsi_inquiry(udev, dev_scsi, fd, 0, 0, buf, SCSI_INQ_BUFF_LEN);
-        if (err < 0)
-                goto out;
-
-        err = 0;
-        memcpy(dev_scsi->vendor, buf + 8, 8);
-        dev_scsi->vendor[8] = '\0';
-        memcpy(dev_scsi->model, buf + 16, 16);
-        dev_scsi->model[16] = '\0';
-        memcpy(dev_scsi->revision, buf + 32, 4);
-        dev_scsi->revision[4] = '\0';
-        sprintf(dev_scsi->type,"%x", buf[0] & 0x1f);
-
-out:
-        close(fd);
-        return err;
-}
-
-int scsi_get_serial(struct udev *udev,
-                    struct scsi_id_device *dev_scsi, const char *devname,
-                    int page_code, int len)
-{
-        unsigned char page0[SCSI_INQ_BUFF_LEN];
-        int fd = -1;
-        int cnt;
-        int ind;
-        int retval;
-
-        memzero(dev_scsi->serial, len);
-        initialize_srand();
-        for (cnt = 20; cnt > 0; cnt--) {
-                struct timespec duration;
-
-                fd = open(devname, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
-                if (fd >= 0 || errno != EBUSY)
-                        break;
-                duration.tv_sec = 0;
-                duration.tv_nsec = (200 * 1000 * 1000) + (rand() % 100 * 1000 * 1000);
-                nanosleep(&duration, NULL);
-        }
-        if (fd < 0)
-                return 1;
-
-        if (page_code == PAGE_80) {
-                if (do_scsi_page80_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len)) {
-                        retval = 1;
-                        goto completed;
-                } else  {
-                        retval = 0;
-                        goto completed;
-                }
-        } else if (page_code == PAGE_83) {
-                if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) {
-                        retval = 1;
-                        goto completed;
-                } else  {
-                        retval = 0;
-                        goto completed;
-                }
-        } else if (page_code == PAGE_83_PRE_SPC3) {
-                retval = do_scsi_page83_prespc3_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len);
-                if (retval) {
-                        /*
-                         * Fallback to servicing a SPC-2/3 compliant page 83
-                         * inquiry if the page 83 reply format does not
-                         * conform to pre-SPC3 expectations.
-                         */
-                        if (retval == 2) {
-                                if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) {
-                                        retval = 1;
-                                        goto completed;
-                                } else  {
-                                        retval = 0;
-                                        goto completed;
-                                }
-                        }
-                        else {
-                                retval = 1;
-                                goto completed;
-                        }
-                } else  {
-                        retval = 0;
-                        goto completed;
-                }
-        } else if (page_code != 0x00) {
-                log_debug("%s: unsupported page code 0x%d", dev_scsi->kernel, page_code);
-                retval = 1;
-                goto completed;
-        }
-
-        /*
-         * Get page 0, the page of the pages. By default, try from best to
-         * worst of supported pages: 0x83 then 0x80.
-         */
-        if (do_scsi_page0_inquiry(udev, dev_scsi, fd, page0, SCSI_INQ_BUFF_LEN)) {
-                /*
-                 * Don't try anything else. Black list if a specific page
-                 * should be used for this vendor+model, or maybe have an
-                 * optional fall-back to page 0x80 or page 0x83.
-                 */
-                retval = 1;
-                goto completed;
-        }
-
-        for (ind = 4; ind <= page0[3] + 3; ind++)
-                if (page0[ind] == PAGE_83)
-                        if (!do_scsi_page83_inquiry(udev, dev_scsi, fd,
-                                                    dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) {
-                                /*
-                                 * Success
-                                 */
-                                retval = 0;
-                                goto completed;
-                        }
-
-        for (ind = 4; ind <= page0[3] + 3; ind++)
-                if (page0[ind] == PAGE_80)
-                        if (!do_scsi_page80_inquiry(udev, dev_scsi, fd,
-                                                    dev_scsi->serial, dev_scsi->serial_short, len)) {
-                                /*
-                                 * Success
-                                 */
-                                retval = 0;
-                                goto completed;
-                        }
-        retval = 1;
-
-completed:
-        close(fd);
-        return retval;
-}
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
deleted file mode 100644 (file)
index f4f6900..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * probe disks for filesystems and partitions
- *
- * Copyright (C) 2011 Kay Sievers <kay@vrfy.org>
- * Copyright (C) 2011 Karel Zak <kzak@redhat.com>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <sys/stat.h>
-#include <blkid/blkid.h>
-
-#include "sd-id128.h"
-#include "gpt.h"
-#include "efivars.h"
-#include "udev.h"
-
-static void print_property(struct udev_device *dev, bool test, const char *name, const char *value) {
-        char s[256];
-
-        s[0] = '\0';
-
-        if (streq(name, "TYPE")) {
-                udev_builtin_add_property(dev, test, "ID_FS_TYPE", value);
-
-        } else if (streq(name, "USAGE")) {
-                udev_builtin_add_property(dev, test, "ID_FS_USAGE", value);
-
-        } else if (streq(name, "VERSION")) {
-                udev_builtin_add_property(dev, test, "ID_FS_VERSION", value);
-
-        } else if (streq(name, "UUID")) {
-                blkid_safe_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_UUID", s);
-                blkid_encode_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_UUID_ENC", s);
-
-        } else if (streq(name, "UUID_SUB")) {
-                blkid_safe_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB", s);
-                blkid_encode_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_UUID_SUB_ENC", s);
-
-        } else if (streq(name, "LABEL")) {
-                blkid_safe_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_LABEL", s);
-                blkid_encode_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_LABEL_ENC", s);
-
-        } else if (streq(name, "PTTYPE")) {
-                udev_builtin_add_property(dev, test, "ID_PART_TABLE_TYPE", value);
-
-        } else if (streq(name, "PTUUID")) {
-                udev_builtin_add_property(dev, test, "ID_PART_TABLE_UUID", value);
-
-        } else if (streq(name, "PART_ENTRY_NAME")) {
-                blkid_encode_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_PART_ENTRY_NAME", s);
-
-        } else if (streq(name, "PART_ENTRY_TYPE")) {
-                blkid_encode_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_PART_ENTRY_TYPE", s);
-
-        } else if (startswith(name, "PART_ENTRY_")) {
-                strscpyl(s, sizeof(s), "ID_", name, NULL);
-                udev_builtin_add_property(dev, test, s, value);
-
-        } else if (streq(name, "SYSTEM_ID")) {
-                blkid_encode_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_SYSTEM_ID", s);
-
-        } else if (streq(name, "PUBLISHER_ID")) {
-                blkid_encode_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_PUBLISHER_ID", s);
-
-        } else if (streq(name, "APPLICATION_ID")) {
-                blkid_encode_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_APPLICATION_ID", s);
-
-        } else if (streq(name, "BOOT_SYSTEM_ID")) {
-                blkid_encode_string(value, s, sizeof(s));
-                udev_builtin_add_property(dev, test, "ID_FS_BOOT_SYSTEM_ID", s);
-        }
-}
-
-static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) {
-
-#if defined(GPT_ROOT_NATIVE) && defined(ENABLE_EFI)
-
-        _cleanup_free_ char *root_id = NULL;
-        bool found_esp = false;
-        blkid_partlist pl;
-        int i, nvals, r;
-
-        assert(pr);
-
-        /* Iterate through the partitions on this disk, and see if the
-         * EFI ESP we booted from is on it. If so, find the first root
-         * disk, and add a property indicating its partition UUID. */
-
-        errno = 0;
-        pl = blkid_probe_get_partitions(pr);
-        if (!pl)
-                return errno ? -errno : -ENOMEM;
-
-        nvals = blkid_partlist_numof_partitions(pl);
-        for (i = 0; i < nvals; i++) {
-                blkid_partition pp;
-                const char *stype, *sid;
-                sd_id128_t type;
-
-                pp = blkid_partlist_get_partition(pl, i);
-                if (!pp)
-                        continue;
-
-                sid = blkid_partition_get_uuid(pp);
-                if (!sid)
-                        continue;
-
-                stype = blkid_partition_get_type_string(pp);
-                if (!stype)
-                        continue;
-
-                if (sd_id128_from_string(stype, &type) < 0)
-                        continue;
-
-                if (sd_id128_equal(type, GPT_ESP)) {
-                        sd_id128_t id, esp;
-
-                        /* We found an ESP, let's see if it matches
-                         * the ESP we booted from. */
-
-                        if (sd_id128_from_string(sid, &id) < 0)
-                                continue;
-
-                        r = efi_loader_get_device_part_uuid(&esp);
-                        if (r < 0)
-                                return r;
-
-                        if (sd_id128_equal(id, esp))
-                                found_esp = true;
-
-                } else if (sd_id128_equal(type, GPT_ROOT_NATIVE)) {
-
-                        /* We found a suitable root partition, let's
-                         * remember the first one. */
-
-                        if (!root_id) {
-                                root_id = strdup(sid);
-                                if (!root_id)
-                                        return -ENOMEM;
-                        }
-                }
-        }
-
-        /* We found the ESP on this disk, and also found a root
-         * partition, nice! Let's export its UUID */
-        if (found_esp && root_id)
-                udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT_UUID", root_id);
-#endif
-
-        return 0;
-}
-
-static int probe_superblocks(blkid_probe pr) {
-        struct stat st;
-        int rc;
-
-        if (fstat(blkid_probe_get_fd(pr), &st))
-                return -1;
-
-        blkid_probe_enable_partitions(pr, 1);
-
-        if (!S_ISCHR(st.st_mode) &&
-            blkid_probe_get_size(pr) <= 1024 * 1440 &&
-            blkid_probe_is_wholedisk(pr)) {
-                /*
-                 * check if the small disk is partitioned, if yes then
-                 * don't probe for filesystems.
-                 */
-                blkid_probe_enable_superblocks(pr, 0);
-
-                rc = blkid_do_fullprobe(pr);
-                if (rc < 0)
-                        return rc;        /* -1 = error, 1 = nothing, 0 = success */
-
-                if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0)
-                        return 0;        /* partition table detected */
-        }
-
-        blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
-        blkid_probe_enable_superblocks(pr, 1);
-
-        return blkid_do_safeprobe(pr);
-}
-
-static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test) {
-        const char *root_partition;
-        int64_t offset = 0;
-        bool noraid = false;
-        _cleanup_close_ int fd = -1;
-        blkid_probe pr;
-        const char *data;
-        const char *name;
-        const char *prtype = NULL;
-        int nvals;
-        int i;
-        int err = 0;
-        bool is_gpt = false;
-
-        static const struct option options[] = {
-                { "offset", optional_argument, NULL, 'o' },
-                { "noraid", no_argument, NULL, 'R' },
-                {}
-        };
-
-        for (;;) {
-                int option;
-
-                option = getopt_long(argc, argv, "oR", options, NULL);
-                if (option == -1)
-                        break;
-
-                switch (option) {
-                case 'o':
-                        offset = strtoull(optarg, NULL, 0);
-                        break;
-                case 'R':
-                        noraid = true;
-                        break;
-                }
-        }
-
-        pr = blkid_new_probe();
-        if (!pr)
-                return EXIT_FAILURE;
-
-        blkid_probe_set_superblocks_flags(pr,
-                BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
-                BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
-                BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION |
-                BLKID_SUBLKS_BADCSUM);
-
-        if (noraid)
-                blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID);
-
-        fd = open(udev_device_get_devnode(dev), O_RDONLY|O_CLOEXEC);
-        if (fd < 0) {
-                fprintf(stderr, "error: %s: %m\n", udev_device_get_devnode(dev));
-                goto out;
-        }
-
-        err = blkid_probe_set_device(pr, fd, offset, 0);
-        if (err < 0)
-                goto out;
-
-        log_debug("probe %s %sraid offset=%"PRIi64,
-                  udev_device_get_devnode(dev),
-                  noraid ? "no" : "", offset);
-
-        err = probe_superblocks(pr);
-        if (err < 0)
-                goto out;
-        if (blkid_probe_has_value(pr, "SBBADCSUM")) {
-                if (!blkid_probe_lookup_value(pr, "TYPE", &prtype, NULL))
-                        log_warning("incorrect %s checksum on %s",
-                                    prtype, udev_device_get_devnode(dev));
-                else
-                        log_warning("incorrect checksum on %s",
-                                    udev_device_get_devnode(dev));
-                goto out;
-        }
-
-        /* If we are a partition then our parent passed on the root
-         * partition UUID to us */
-        root_partition = udev_device_get_property_value(dev, "ID_PART_GPT_AUTO_ROOT_UUID");
-
-        nvals = blkid_probe_numof_values(pr);
-        for (i = 0; i < nvals; i++) {
-                if (blkid_probe_get_value(pr, i, &name, &data, NULL))
-                        continue;
-
-                print_property(dev, test, name, data);
-
-                /* Is this a disk with GPT partition table? */
-                if (streq(name, "PTTYPE") && streq(data, "gpt"))
-                        is_gpt = true;
-
-                /* Is this a partition that matches the root partition
-                 * property we inherited from our parent? */
-                if (root_partition && streq(name, "PART_ENTRY_UUID") && streq(data, root_partition))
-                        udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT", "1");
-        }
-
-        if (is_gpt)
-                find_gpt_root(dev, pr, test);
-
-        blkid_free_probe(pr);
-out:
-        if (err < 0)
-                return EXIT_FAILURE;
-
-        return EXIT_SUCCESS;
-}
-
-const struct udev_builtin udev_builtin_blkid = {
-        .name = "blkid",
-        .cmd = builtin_blkid,
-        .help = "Filesystem and partition probing",
-        .run_once = true,
-};
diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c
deleted file mode 100644 (file)
index 3352821..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2012 Kay Sievers <kay@vrfy.org>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#ifdef HAVE_LINUX_BTRFS_H
-#include <linux/btrfs.h>
-#endif
-
-#include "missing.h"
-#include "udev.h"
-
-static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool test) {
-        struct btrfs_ioctl_vol_args args = {};
-        _cleanup_close_ int fd = -1;
-        int err;
-
-        if (argc != 3 || !streq(argv[1], "ready"))
-                return EXIT_FAILURE;
-
-        fd = open("/dev/btrfs-control", O_RDWR|O_CLOEXEC);
-        if (fd < 0)
-                return EXIT_FAILURE;
-
-        strscpy(args.name, sizeof(args.name), argv[2]);
-        err = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args);
-        if (err < 0)
-                return EXIT_FAILURE;
-
-        udev_builtin_add_property(dev, test, "ID_BTRFS_READY", one_zero(err == 0));
-        return EXIT_SUCCESS;
-}
-
-const struct udev_builtin udev_builtin_btrfs = {
-        .name = "btrfs",
-        .cmd = builtin_btrfs,
-        .help = "btrfs volume management",
-};
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
deleted file mode 100644 (file)
index 5e0e7eb..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2012 Kay Sievers <kay@vrfy.org>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fnmatch.h>
-#include <getopt.h>
-
-#include "udev.h"
-#include "sd-hwdb.h"
-
-#include "hwdb-util.h"
-
-static sd_hwdb *hwdb;
-
-int udev_builtin_hwdb_lookup(struct udev_device *dev,
-                             const char *prefix, const char *modalias,
-                             const char *filter, bool test) {
-        _cleanup_free_ const char *lookup = NULL;
-        const char *key, *value;
-        int n = 0;
-
-        if (!hwdb)
-                return -ENOENT;
-
-        if (prefix) {
-                lookup = strjoin(prefix, modalias, NULL);
-                if (!lookup)
-                        return -ENOMEM;
-                modalias = lookup;
-        }
-
-        SD_HWDB_FOREACH_PROPERTY(hwdb, modalias, key, value) {
-                if (filter && fnmatch(filter, key, FNM_NOESCAPE) != 0)
-                        continue;
-
-                if (udev_builtin_add_property(dev, test, key, value) < 0)
-                        return -ENOMEM;
-                n++;
-        }
-        return n;
-}
-
-static const char *modalias_usb(struct udev_device *dev, char *s, size_t size) {
-        const char *v, *p;
-        int vn, pn;
-
-        v = udev_device_get_sysattr_value(dev, "idVendor");
-        if (!v)
-                return NULL;
-        p = udev_device_get_sysattr_value(dev, "idProduct");
-        if (!p)
-                return NULL;
-        vn = strtol(v, NULL, 16);
-        if (vn <= 0)
-                return NULL;
-        pn = strtol(p, NULL, 16);
-        if (pn <= 0)
-                return NULL;
-        snprintf(s, size, "usb:v%04Xp%04X*", vn, pn);
-        return s;
-}
-
-static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device *srcdev,
-                                    const char *subsystem, const char *prefix,
-                                    const char *filter, bool test) {
-        struct udev_device *d;
-        char s[16];
-        bool last = false;
-        int r = 0;
-
-        for (d = srcdev; d && !last; d = udev_device_get_parent(d)) {
-                const char *dsubsys;
-                const char *modalias = NULL;
-
-                dsubsys = udev_device_get_subsystem(d);
-                if (!dsubsys)
-                        continue;
-
-                /* look only at devices of a specific subsystem */
-                if (subsystem && !streq(dsubsys, subsystem))
-                        continue;
-
-                modalias = udev_device_get_property_value(d, "MODALIAS");
-
-                if (streq(dsubsys, "usb") && streq_ptr(udev_device_get_devtype(d), "usb_device")) {
-                        /* if the usb_device does not have a modalias, compose one */
-                        if (!modalias)
-                                modalias = modalias_usb(d, s, sizeof(s));
-
-                        /* avoid looking at any parent device, they are usually just a USB hub */
-                        last = true;
-                }
-
-                if (!modalias)
-                        continue;
-
-                r = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, test);
-                if (r > 0)
-                        break;
-        }
-
-        return r;
-}
-
-static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool test) {
-        static const struct option options[] = {
-                { "filter", required_argument, NULL, 'f' },
-                { "device", required_argument, NULL, 'd' },
-                { "subsystem", required_argument, NULL, 's' },
-                { "lookup-prefix", required_argument, NULL, 'p' },
-                {}
-        };
-        const char *filter = NULL;
-        const char *device = NULL;
-        const char *subsystem = NULL;
-        const char *prefix = NULL;
-        struct udev_device *srcdev;
-
-        if (!hwdb)
-                return EXIT_FAILURE;
-
-        for (;;) {
-                int option;
-
-                option = getopt_long(argc, argv, "f:d:s:p:", options, NULL);
-                if (option == -1)
-                        break;
-
-                switch (option) {
-                case 'f':
-                        filter = optarg;
-                        break;
-
-                case 'd':
-                        device = optarg;
-                        break;
-
-                case 's':
-                        subsystem = optarg;
-                        break;
-
-                case 'p':
-                        prefix = optarg;
-                        break;
-                }
-        }
-
-        /* query a specific key given as argument */
-        if (argv[optind]) {
-                if (udev_builtin_hwdb_lookup(dev, prefix, argv[optind], filter, test) > 0)
-                        return EXIT_SUCCESS;
-                return EXIT_FAILURE;
-        }
-
-        /* read data from another device than the device we will store the data */
-        if (device) {
-                srcdev = udev_device_new_from_device_id(udev_device_get_udev(dev), device);
-                if (!srcdev)
-                        return EXIT_FAILURE;
-        } else
-                srcdev = dev;
-
-        if (udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test) > 0)
-                return EXIT_SUCCESS;
-        return EXIT_FAILURE;
-}
-
-/* called at udev startup and reload */
-static int builtin_hwdb_init(struct udev *udev) {
-        int r;
-
-        if (hwdb)
-                return 0;
-
-        r = sd_hwdb_new(&hwdb);
-        if (r < 0)
-                return r;
-
-        return 0;
-}
-
-/* called on udev shutdown and reload request */
-static void builtin_hwdb_exit(struct udev *udev) {
-        hwdb = sd_hwdb_unref(hwdb);
-}
-
-/* called every couple of seconds during event activity; 'true' if config has changed */
-static bool builtin_hwdb_validate(struct udev *udev) {
-        return hwdb_validate(hwdb);
-}
-
-const struct udev_builtin udev_builtin_hwdb = {
-        .name = "hwdb",
-        .cmd = builtin_hwdb,
-        .init = builtin_hwdb_init,
-        .exit = builtin_hwdb_exit,
-        .validate = builtin_hwdb_validate,
-        .help = "Hardware database",
-};
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
deleted file mode 100644 (file)
index 46f1c53..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * expose input properties via udev
- *
- * Copyright (C) 2009 Martin Pitt <martin.pitt@ubuntu.com>
- * Portions Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
- * Copyright (C) 2011 Kay Sievers <kay@vrfy.org>
- * Copyright (C) 2014 Carlos Garnacho <carlosg@gnome.org>
- * Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <linux/limits.h>
-#include <linux/input.h>
-
-#include "udev.h"
-#include "util.h"
-
-/* we must use this kernel-compatible implementation */
-#define BITS_PER_LONG (sizeof(unsigned long) * 8)
-#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
-#define OFF(x)  ((x)%BITS_PER_LONG)
-#define BIT(x)  (1UL<<OFF(x))
-#define LONG(x) ((x)/BITS_PER_LONG)
-#define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
-
-static inline int abs_size_mm(const struct input_absinfo *absinfo) {
-        /* Resolution is defined to be in units/mm for ABS_X/Y */
-        return (absinfo->maximum - absinfo->minimum) / absinfo->resolution;
-}
-
-static void extract_info(struct udev_device *dev, const char *devpath, bool test) {
-        char width[DECIMAL_STR_MAX(int)], height[DECIMAL_STR_MAX(int)];
-        struct input_absinfo xabsinfo = {}, yabsinfo = {};
-        _cleanup_close_ int fd = -1;
-
-        fd = open(devpath, O_RDONLY|O_CLOEXEC);
-        if (fd < 0)
-                return;
-
-        if (ioctl(fd, EVIOCGABS(ABS_X), &xabsinfo) < 0 ||
-            ioctl(fd, EVIOCGABS(ABS_Y), &yabsinfo) < 0)
-                return;
-
-        if (xabsinfo.resolution <= 0 || yabsinfo.resolution <= 0)
-                return;
-
-        snprintf(width, sizeof(width), "%d", abs_size_mm(&xabsinfo));
-        snprintf(height, sizeof(height), "%d", abs_size_mm(&yabsinfo));
-
-        udev_builtin_add_property(dev, test, "ID_INPUT_WIDTH_MM", width);
-        udev_builtin_add_property(dev, test, "ID_INPUT_HEIGHT_MM", height);
-}
-
-/*
- * Read a capability attribute and return bitmask.
- * @param dev udev_device
- * @param attr sysfs attribute name (e. g. "capabilities/key")
- * @param bitmask: Output array which has a sizeof of bitmask_size
- */
-static void get_cap_mask(struct udev_device *dev,
-                         struct udev_device *pdev, const char* attr,
-                         unsigned long *bitmask, size_t bitmask_size,
-                         bool test) {
-        const char *v;
-        char text[4096];
-        unsigned i;
-        char* word;
-        unsigned long val;
-
-        v = udev_device_get_sysattr_value(pdev, attr);
-        if (!v)
-                v = "";
-
-        snprintf(text, sizeof(text), "%s", v);
-        log_debug("%s raw kernel attribute: %s", attr, text);
-
-        memzero(bitmask, bitmask_size);
-        i = 0;
-        while ((word = strrchr(text, ' ')) != NULL) {
-                val = strtoul (word+1, NULL, 16);
-                if (i < bitmask_size/sizeof(unsigned long))
-                        bitmask[i] = val;
-                else
-                        log_debug("ignoring %s block %lX which is larger than maximum size", attr, val);
-                *word = '\0';
-                ++i;
-        }
-        val = strtoul (text, NULL, 16);
-        if (i < bitmask_size / sizeof(unsigned long))
-                bitmask[i] = val;
-        else
-                log_debug("ignoring %s block %lX which is larger than maximum size", attr, val);
-
-        if (test) {
-                /* printf pattern with the right unsigned long number of hex chars */
-                snprintf(text, sizeof(text), "  bit %%4u: %%0%zulX\n", 2 * sizeof(unsigned long));
-                log_debug("%s decoded bit map:", attr);
-                val = bitmask_size / sizeof (unsigned long);
-                /* skip over leading zeros */
-                while (bitmask[val-1] == 0 && val > 0)
-                        --val;
-                for (i = 0; i < val; ++i) {
-                        DISABLE_WARNING_FORMAT_NONLITERAL;
-                        log_debug(text, i * BITS_PER_LONG, bitmask[i]);
-                        REENABLE_WARNING;
-                }
-        }
-}
-
-/* pointer devices */
-static void test_pointers (struct udev_device *dev,
-                           const unsigned long* bitmask_ev,
-                           const unsigned long* bitmask_abs,
-                           const unsigned long* bitmask_key,
-                           const unsigned long* bitmask_rel,
-                           bool test) {
-        int is_mouse = 0;
-        int is_touchpad = 0;
-
-        if (!test_bit (EV_KEY, bitmask_ev)) {
-                if (test_bit (EV_ABS, bitmask_ev) &&
-                    test_bit (ABS_X, bitmask_abs) &&
-                    test_bit (ABS_Y, bitmask_abs) &&
-                    test_bit (ABS_Z, bitmask_abs))
-                        udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1");
-                return;
-        }
-
-        if (test_bit (EV_ABS, bitmask_ev) &&
-            test_bit (ABS_X, bitmask_abs) && test_bit (ABS_Y, bitmask_abs)) {
-                if (test_bit (BTN_STYLUS, bitmask_key) || test_bit (BTN_TOOL_PEN, bitmask_key))
-                        udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1");
-                else if (test_bit (BTN_TOOL_FINGER, bitmask_key) && !test_bit (BTN_TOOL_PEN, bitmask_key))
-                        is_touchpad = 1;
-                else if (test_bit (BTN_MOUSE, bitmask_key))
-                        /* This path is taken by VMware's USB mouse, which has
-                         * absolute axes, but no touch/pressure button. */
-                        is_mouse = 1;
-                else if (test_bit (BTN_TOUCH, bitmask_key))
-                        udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1");
-                /* joysticks don't necessarily have to have buttons; e. g.
-                 * rudders/pedals are joystick-like, but buttonless; they have
-                 * other fancy axes */
-                else if (test_bit (BTN_TRIGGER, bitmask_key) ||
-                         test_bit (BTN_A, bitmask_key) ||
-                         test_bit (BTN_1, bitmask_key) ||
-                         test_bit (ABS_RX, bitmask_abs) ||
-                         test_bit (ABS_RY, bitmask_abs) ||
-                         test_bit (ABS_RZ, bitmask_abs) ||
-                         test_bit (ABS_THROTTLE, bitmask_abs) ||
-                         test_bit (ABS_RUDDER, bitmask_abs) ||
-                         test_bit (ABS_WHEEL, bitmask_abs) ||
-                         test_bit (ABS_GAS, bitmask_abs) ||
-                         test_bit (ABS_BRAKE, bitmask_abs))
-                        udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
-        }
-
-        if (test_bit (EV_REL, bitmask_ev) &&
-            test_bit (REL_X, bitmask_rel) && test_bit (REL_Y, bitmask_rel) &&
-            test_bit (BTN_MOUSE, bitmask_key))
-                is_mouse = 1;
-
-        if (is_mouse)
-                udev_builtin_add_property(dev, test, "ID_INPUT_MOUSE", "1");
-        if (is_touchpad)
-                udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHPAD", "1");
-}
-
-/* key like devices */
-static void test_key (struct udev_device *dev,
-                      const unsigned long* bitmask_ev,
-                      const unsigned long* bitmask_key,
-                      bool test) {
-        unsigned i;
-        unsigned long found;
-        unsigned long mask;
-
-        /* do we have any KEY_* capability? */
-        if (!test_bit (EV_KEY, bitmask_ev)) {
-                log_debug("test_key: no EV_KEY capability");
-                return;
-        }
-
-        /* only consider KEY_* here, not BTN_* */
-        found = 0;
-        for (i = 0; i < BTN_MISC/BITS_PER_LONG; ++i) {
-                found |= bitmask_key[i];
-                log_debug("test_key: checking bit block %lu for any keys; found=%i", (unsigned long)i*BITS_PER_LONG, found > 0);
-        }
-        /* If there are no keys in the lower block, check the higher block */
-        if (!found) {
-                for (i = KEY_OK; i < BTN_TRIGGER_HAPPY; ++i) {
-                        if (test_bit (i, bitmask_key)) {
-                                log_debug("test_key: Found key %x in high block", i);
-                                found = 1;
-                                break;
-                        }
-                }
-        }
-
-        if (found > 0)
-                udev_builtin_add_property(dev, test, "ID_INPUT_KEY", "1");
-
-        /* the first 32 bits are ESC, numbers, and Q to D; if we have all of
-         * those, consider it a full keyboard; do not test KEY_RESERVED, though */
-        mask = 0xFFFFFFFE;
-        if ((bitmask_key[0] & mask) == mask)
-                udev_builtin_add_property(dev, test, "ID_INPUT_KEYBOARD", "1");
-}
-
-static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], bool test) {
-        struct udev_device *pdev;
-        unsigned long bitmask_ev[NBITS(EV_MAX)];
-        unsigned long bitmask_abs[NBITS(ABS_MAX)];
-        unsigned long bitmask_key[NBITS(KEY_MAX)];
-        unsigned long bitmask_rel[NBITS(REL_MAX)];
-        const char *sysname, *devnode;
-
-        /* walk up the parental chain until we find the real input device; the
-         * argument is very likely a subdevice of this, like eventN */
-        pdev = dev;
-        while (pdev != NULL && udev_device_get_sysattr_value(pdev, "capabilities/ev") == NULL)
-                pdev = udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
-
-        if (pdev) {
-                /* Use this as a flag that input devices were detected, so that this
-                 * program doesn't need to be called more than once per device */
-                udev_builtin_add_property(dev, test, "ID_INPUT", "1");
-                get_cap_mask(dev, pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), test);
-                get_cap_mask(dev, pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), test);
-                get_cap_mask(dev, pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), test);
-                get_cap_mask(dev, pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test);
-                test_pointers(dev, bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel, test);
-                test_key(dev, bitmask_ev, bitmask_key, test);
-        }
-
-        devnode = udev_device_get_devnode(dev);
-        sysname = udev_device_get_sysname(dev);
-        if (devnode && sysname && startswith(sysname, "event"))
-                extract_info(dev, devnode, test);
-
-        return EXIT_SUCCESS;
-}
-
-const struct udev_builtin udev_builtin_input_id = {
-        .name = "input_id",
-        .cmd = builtin_input_id,
-        .help = "Input device properties",
-};
diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c
deleted file mode 100644 (file)
index 8ab1be8..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2013 Kay Sievers <kay@vrfy.org>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <linux/input.h>
-
-#include "udev.h"
-
-static const struct key *keyboard_lookup_key(const char *str, unsigned len);
-#include "keyboard-keys-from-name.h"
-
-static int install_force_release(struct udev_device *dev, const unsigned *release, unsigned release_count) {
-        struct udev_device *atkbd;
-        const char *cur;
-        char codes[4096];
-        char *s;
-        size_t l;
-        unsigned i;
-        int ret;
-
-        atkbd = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL);
-        if (!atkbd)
-                return -ENODEV;
-
-        cur = udev_device_get_sysattr_value(atkbd, "force_release");
-        if (!cur)
-                return -ENODEV;
-
-        s = codes;
-        l = sizeof(codes);
-
-        /* copy current content */
-        l = strpcpy(&s, l, cur);
-
-        /* append new codes */
-        for (i = 0; i < release_count; i++)
-                l = strpcpyf(&s, l, ",%u", release[i]);
-
-        log_debug("keyboard: updating force-release list with '%s'", codes);
-        ret = udev_device_set_sysattr_value(atkbd, "force_release", codes);
-        if (ret < 0)
-                log_error_errno(ret, "Error writing force-release attribute: %m");
-        return ret;
-}
-
-static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], bool test) {
-        struct udev_list_entry *entry;
-        struct {
-                unsigned scan;
-                unsigned key;
-        } map[1024];
-        unsigned map_count = 0;
-        unsigned release[1024];
-        unsigned release_count = 0;
-
-        udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) {
-                const char *key;
-                unsigned scancode, keycode_num;
-                char *endptr;
-                const char *keycode;
-                const struct key *k;
-
-                key = udev_list_entry_get_name(entry);
-                if (!startswith(key, "KEYBOARD_KEY_"))
-                        continue;
-
-                /* KEYBOARD_KEY_<hex scan code>=<key identifier string> */
-                scancode = strtoul(key + 13, &endptr, 16);
-                if (endptr[0] != '\0') {
-                        log_error("Error, unable to parse scan code from '%s'", key);
-                        continue;
-                }
-
-                keycode = udev_list_entry_get_value(entry);
-
-                /* a leading '!' needs a force-release entry */
-                if (keycode[0] == '!') {
-                        keycode++;
-
-                        release[release_count] = scancode;
-                        if (release_count <  ELEMENTSOF(release)-1)
-                                release_count++;
-
-                        if (keycode[0] == '\0')
-                                continue;
-                }
-
-                /* translate identifier to key code */
-                k = keyboard_lookup_key(keycode, strlen(keycode));
-                if (k) {
-                        keycode_num = k->id;
-                } else {
-                        /* check if it's a numeric code already */
-                        keycode_num = strtoul(keycode, &endptr, 0);
-                        if (endptr[0] !='\0') {
-                                log_error("Error, unknown key identifier '%s'", keycode);
-                                continue;
-                        }
-                }
-
-                map[map_count].scan = scancode;
-                map[map_count].key = keycode_num;
-                if (map_count < ELEMENTSOF(map)-1)
-                        map_count++;
-        }
-
-        if (map_count > 0 || release_count > 0) {
-                const char *node;
-                int fd;
-                unsigned i;
-
-                node = udev_device_get_devnode(dev);
-                if (!node) {
-                        log_error("Error, no device node for '%s'", udev_device_get_syspath(dev));
-                        return EXIT_FAILURE;
-                }
-
-                fd = open(udev_device_get_devnode(dev), O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
-                if (fd < 0) {
-                        log_error_errno(errno, "Error, opening device '%s': %m", node);
-                        return EXIT_FAILURE;
-                }
-
-                /* install list of map codes */
-                for (i = 0; i < map_count; i++) {
-                        log_debug("keyboard: mapping scan code %d (0x%x) to key code %d (0x%x)",
-                                  map[i].scan, map[i].scan, map[i].key, map[i].key);
-                        if (ioctl(fd, EVIOCSKEYCODE, &map[i]) < 0)
-                                log_error_errno(errno, "Error calling EVIOCSKEYCODE on device node '%s' (scan code 0x%x, key code %d): %m", node, map[i].scan, map[i].key);
-                }
-
-                /* install list of force-release codes */
-                if (release_count > 0)
-                        install_force_release(dev, release, release_count);
-
-                close(fd);
-        }
-
-        return EXIT_SUCCESS;
-}
-
-const struct udev_builtin udev_builtin_keyboard = {
-        .name = "keyboard",
-        .cmd = builtin_keyboard,
-        .help = "Keyboard scan code to key mapping",
-};
diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c
deleted file mode 100644 (file)
index 81e78a8..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * load kernel modules
- *
- * Copyright (C) 2011-2012 Kay Sievers <kay@vrfy.org>
- * Copyright (C) 2011 ProFUSION embedded systems
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <libkmod.h>
-
-#include "udev.h"
-
-static struct kmod_ctx *ctx = NULL;
-
-static int load_module(struct udev *udev, const char *alias) {
-        struct kmod_list *list = NULL;
-        struct kmod_list *l;
-        int err;
-
-        err = kmod_module_new_from_lookup(ctx, alias, &list);
-        if (err < 0)
-                return err;
-
-        if (list == NULL)
-                log_debug("No module matches '%s'", alias);
-
-        kmod_list_foreach(l, list) {
-                struct kmod_module *mod = kmod_module_get_module(l);
-
-                err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
-                if (err == KMOD_PROBE_APPLY_BLACKLIST)
-                        log_debug("Module '%s' is blacklisted", kmod_module_get_name(mod));
-                else if (err == 0)
-                        log_debug("Inserted '%s'", kmod_module_get_name(mod));
-                else
-                        log_debug("Failed to insert '%s'", kmod_module_get_name(mod));
-
-                kmod_module_unref(mod);
-        }
-
-        kmod_module_unref_list(list);
-        return err;
-}
-
-_printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *file, int line, const char *fn, const char *format, va_list args) {
-        log_internalv(priority, 0, file, line, fn, format, args);
-}
-
-static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) {
-        struct udev *udev = udev_device_get_udev(dev);
-        int i;
-
-        if (!ctx)
-                return 0;
-
-        if (argc < 3 || !streq(argv[1], "load")) {
-                log_error("expect: %s load <module>", argv[0]);
-                return EXIT_FAILURE;
-        }
-
-        for (i = 2; argv[i]; i++) {
-                log_debug("Execute '%s' '%s'", argv[1], argv[i]);
-                load_module(udev, argv[i]);
-        }
-
-        return EXIT_SUCCESS;
-}
-
-/* called at udev startup and reload */
-static int builtin_kmod_init(struct udev *udev) {
-        if (ctx)
-                return 0;
-
-        ctx = kmod_new(NULL, NULL);
-        if (!ctx)
-                return -ENOMEM;
-
-        log_debug("Load module index");
-        kmod_set_log_fn(ctx, udev_kmod_log, udev);
-        kmod_load_resources(ctx);
-        return 0;
-}
-
-/* called on udev shutdown and reload request */
-static void builtin_kmod_exit(struct udev *udev) {
-        log_debug("Unload module index");
-        ctx = kmod_unref(ctx);
-}
-
-/* called every couple of seconds during event activity; 'true' if config has changed */
-static bool builtin_kmod_validate(struct udev *udev) {
-        log_debug("Validate module index");
-        if (!ctx)
-                return false;
-        return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK);
-}
-
-const struct udev_builtin udev_builtin_kmod = {
-        .name = "kmod",
-        .cmd = builtin_kmod,
-        .init = builtin_kmod_init,
-        .exit = builtin_kmod_exit,
-        .validate = builtin_kmod_validate,
-        .help = "Kernel module loader",
-        .run_once = false,
-};
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
deleted file mode 100644 (file)
index 78aef20..0000000
+++ /dev/null
@@ -1,583 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2012 Kay Sievers <kay@vrfy.org>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-/*
- * Predictable network interface device names based on:
- *  - firmware/bios-provided index numbers for on-board devices
- *  - firmware-provided pci-express hotplug slot index number
- *  - physical/geographical location of the hardware
- *  - the interface's MAC address
- *
- * http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
- *
- * Two character prefixes based on the type of interface:
- *   en -- ethernet
- *   sl -- serial line IP (slip)
- *   wl -- wlan
- *   ww -- wwan
- *
- * Type of names:
- *   b<number>                             -- BCMA bus core number
- *   ccw<name>                             -- CCW bus group name
- *   o<index>[d<dev_port>]                 -- on-board device index number
- *   s<slot>[f<function>][d<dev_port>]     -- hotplug slot index number
- *   x<MAC>                                -- MAC address
- *   [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>]
- *                                         -- PCI geographical location
- *   [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
- *                                         -- USB port number chain
- *
- * All multi-function PCI devices will carry the [f<function>] number in the
- * device name, including the function 0 device.
- *
- * When using PCI geography, The PCI domain is only prepended when it is not 0.
- *
- * For USB devices the full chain of port numbers of hubs is composed. If the
- * name gets longer than the maximum number of 15 characters, the name is not
- * exported.
- * The usual USB configuration == 1 and interface == 0 values are suppressed.
- *
- * PCI ethernet card with firmware index "1":
- *   ID_NET_NAME_ONBOARD=eno1
- *   ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
- *
- * PCI ethernet card in hotplug slot with firmware index number:
- *   /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
- *   ID_NET_NAME_MAC=enx000000000466
- *   ID_NET_NAME_PATH=enp5s0
- *   ID_NET_NAME_SLOT=ens1
- *
- * PCI ethernet multi-function card with 2 ports:
- *   /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0
- *   ID_NET_NAME_MAC=enx78e7d1ea46da
- *   ID_NET_NAME_PATH=enp2s0f0
- *   /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1
- *   ID_NET_NAME_MAC=enx78e7d1ea46dc
- *   ID_NET_NAME_PATH=enp2s0f1
- *
- * PCI wlan card:
- *   /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0
- *   ID_NET_NAME_MAC=wlx0024d7e31130
- *   ID_NET_NAME_PATH=wlp3s0
- *
- * USB built-in 3G modem:
- *   /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6
- *   ID_NET_NAME_MAC=wwx028037ec0200
- *   ID_NET_NAME_PATH=wwp0s29u1u4i6
- *
- * USB Android phone:
- *   /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2
- *   ID_NET_NAME_MAC=enxd626b3450fb5
- *   ID_NET_NAME_PATH=enp0s29u1u2
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <linux/pci_regs.h>
-
-#include "udev.h"
-#include "fileio.h"
-
-enum netname_type{
-        NET_UNDEF,
-        NET_PCI,
-        NET_USB,
-        NET_BCMA,
-        NET_VIRTIO,
-        NET_CCWGROUP,
-};
-
-struct netnames {
-        enum netname_type type;
-
-        uint8_t mac[6];
-        bool mac_valid;
-
-        struct udev_device *pcidev;
-        char pci_slot[IFNAMSIZ];
-        char pci_path[IFNAMSIZ];
-        char pci_onboard[IFNAMSIZ];
-        const char *pci_onboard_label;
-
-        char usb_ports[IFNAMSIZ];
-        char bcma_core[IFNAMSIZ];
-        char ccw_group[IFNAMSIZ];
-};
-
-/* retrieve on-board index number and label from firmware */
-static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
-        unsigned dev_port = 0;
-        size_t l;
-        char *s;
-        const char *attr;
-        int idx;
-
-        /* ACPI _DSM  -- device specific method for naming a PCI or PCI Express device */
-        attr = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
-        /* SMBIOS type 41 -- Onboard Devices Extended Information */
-        if (!attr)
-                attr = udev_device_get_sysattr_value(names->pcidev, "index");
-        if (!attr)
-                return -ENOENT;
-
-        idx = strtoul(attr, NULL, 0);
-        if (idx <= 0)
-                return -EINVAL;
-
-        /* kernel provided port index for multiple ports on a single PCI function */
-        attr = udev_device_get_sysattr_value(dev, "dev_port");
-        if (attr)
-                dev_port = strtol(attr, NULL, 10);
-
-        s = names->pci_onboard;
-        l = sizeof(names->pci_onboard);
-        l = strpcpyf(&s, l, "o%d", idx);
-        if (dev_port > 0)
-                l = strpcpyf(&s, l, "d%d", dev_port);
-        if (l == 0)
-                names->pci_onboard[0] = '\0';
-
-        names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");
-
-        return 0;
-}
-
-/* read the 256 bytes PCI configuration space to check the multi-function bit */
-static bool is_pci_multifunction(struct udev_device *dev) {
-        _cleanup_fclose_ FILE *f = NULL;
-        const char *filename;
-        uint8_t config[64];
-
-        filename = strjoina(udev_device_get_syspath(dev), "/config");
-        f = fopen(filename, "re");
-        if (!f)
-                return false;
-        if (fread(&config, sizeof(config), 1, f) != 1)
-                return false;
-
-        /* bit 0-6 header type, bit 7 multi/single function device */
-        if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
-                return true;
-
-        return false;
-}
-
-static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
-        struct udev *udev = udev_device_get_udev(names->pcidev);
-        unsigned domain, bus, slot, func, dev_port = 0;
-        size_t l;
-        char *s;
-        const char *attr;
-        struct udev_device *pci = NULL;
-        char slots[256], str[256];
-        _cleanup_closedir_ DIR *dir = NULL;
-        struct dirent *dent;
-        int hotplug_slot = 0, err = 0;
-
-        if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4)
-                return -ENOENT;
-
-        /* kernel provided port index for multiple ports on a single PCI function */
-        attr = udev_device_get_sysattr_value(dev, "dev_port");
-        if (attr)
-                dev_port = strtol(attr, NULL, 10);
-
-        /* compose a name based on the raw kernel's PCI bus, slot numbers */
-        s = names->pci_path;
-        l = sizeof(names->pci_path);
-        if (domain > 0)
-                l = strpcpyf(&s, l, "P%u", domain);
-        l = strpcpyf(&s, l, "p%us%u", bus, slot);
-        if (func > 0 || is_pci_multifunction(names->pcidev))
-                l = strpcpyf(&s, l, "f%u", func);
-        if (dev_port > 0)
-                l = strpcpyf(&s, l, "d%u", dev_port);
-        if (l == 0)
-                names->pci_path[0] = '\0';
-
-        /* ACPI _SUN  -- slot user number */
-        pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
-        if (!pci) {
-                err = -ENOENT;
-                goto out;
-        }
-        snprintf(slots, sizeof(slots), "%s/slots", udev_device_get_syspath(pci));
-        dir = opendir(slots);
-        if (!dir) {
-                err = -errno;
-                goto out;
-        }
-
-        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
-                int i;
-                char *rest;
-                char *address;
-
-                if (dent->d_name[0] == '.')
-                        continue;
-                i = strtol(dent->d_name, &rest, 10);
-                if (rest[0] != '\0')
-                        continue;
-                if (i < 1)
-                        continue;
-                snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name);
-                if (read_one_line_file(str, &address) >= 0) {
-                        /* match slot address with device by stripping the function */
-                        if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address)))
-                                hotplug_slot = i;
-                        free(address);
-                }
-
-                if (hotplug_slot > 0)
-                        break;
-        }
-
-        if (hotplug_slot > 0) {
-                s = names->pci_slot;
-                l = sizeof(names->pci_slot);
-                if (domain > 0)
-                        l = strpcpyf(&s, l, "P%d", domain);
-                l = strpcpyf(&s, l, "s%d", hotplug_slot);
-                if (func > 0 || is_pci_multifunction(names->pcidev))
-                        l = strpcpyf(&s, l, "f%d", func);
-                if (dev_port > 0)
-                        l = strpcpyf(&s, l, "d%d", dev_port);
-                if (l == 0)
-                        names->pci_slot[0] = '\0';
-        }
-out:
-        udev_device_unref(pci);
-        return err;
-}
-
-static int names_pci(struct udev_device *dev, struct netnames *names) {
-        struct udev_device *parent;
-
-        parent = udev_device_get_parent(dev);
-        if (!parent)
-                return -ENOENT;
-        /* check if our direct parent is a PCI device with no other bus in-between */
-        if (streq_ptr("pci", udev_device_get_subsystem(parent))) {
-                names->type = NET_PCI;
-                names->pcidev = parent;
-        } else {
-                names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
-                if (!names->pcidev)
-                        return -ENOENT;
-        }
-        dev_pci_onboard(dev, names);
-        dev_pci_slot(dev, names);
-        return 0;
-}
-
-static int names_usb(struct udev_device *dev, struct netnames *names) {
-        struct udev_device *usbdev;
-        char name[256];
-        char *ports;
-        char *config;
-        char *interf;
-        size_t l;
-        char *s;
-
-        usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
-        if (!usbdev)
-                return -ENOENT;
-
-        /* get USB port number chain, configuration, interface */
-        strscpy(name, sizeof(name), udev_device_get_sysname(usbdev));
-        s = strchr(name, '-');
-        if (!s)
-                return -EINVAL;
-        ports = s+1;
-
-        s = strchr(ports, ':');
-        if (!s)
-                return -EINVAL;
-        s[0] = '\0';
-        config = s+1;
-
-        s = strchr(config, '.');
-        if (!s)
-                return -EINVAL;
-        s[0] = '\0';
-        interf = s+1;
-
-        /* prefix every port number in the chain with "u" */
-        s = ports;
-        while ((s = strchr(s, '.')))
-                s[0] = 'u';
-        s = names->usb_ports;
-        l = strpcpyl(&s, sizeof(names->usb_ports), "u", ports, NULL);
-
-        /* append USB config number, suppress the common config == 1 */
-        if (!streq(config, "1"))
-                l = strpcpyl(&s, sizeof(names->usb_ports), "c", config, NULL);
-
-        /* append USB interface number, suppress the interface == 0 */
-        if (!streq(interf, "0"))
-                l = strpcpyl(&s, sizeof(names->usb_ports), "i", interf, NULL);
-        if (l == 0)
-                return -ENAMETOOLONG;
-
-        names->type = NET_USB;
-        return 0;
-}
-
-static int names_bcma(struct udev_device *dev, struct netnames *names) {
-        struct udev_device *bcmadev;
-        unsigned int core;
-
-        bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL);
-        if (!bcmadev)
-                return -ENOENT;
-
-        /* bus num:core num */
-        if (sscanf(udev_device_get_sysname(bcmadev), "bcma%*u:%u", &core) != 1)
-                return -EINVAL;
-        /* suppress the common core == 0 */
-        if (core > 0)
-                snprintf(names->bcma_core, sizeof(names->bcma_core), "b%u", core);
-
-        names->type = NET_BCMA;
-        return 0;
-}
-
-static int names_ccw(struct  udev_device *dev, struct netnames *names) {
-        struct udev_device *cdev;
-        const char *bus_id;
-        size_t bus_id_len;
-        int rc;
-
-        /* Retrieve the associated CCW device */
-        cdev = udev_device_get_parent(dev);
-        if (!cdev)
-                return -ENOENT;
-
-        /* Network devices are always grouped CCW devices */
-        if (!streq_ptr("ccwgroup", udev_device_get_subsystem(cdev)))
-                return -ENOENT;
-
-        /* Retrieve bus-ID of the grouped CCW device.  The bus-ID uniquely
-         * identifies the network device on the Linux on System z channel
-         * subsystem.  Note that the bus-ID contains lowercase characters.
-         */
-        bus_id = udev_device_get_sysname(cdev);
-        if (!bus_id)
-                return -ENOENT;
-
-        /* Check the length of the bus-ID.  Rely on that the kernel provides
-         * a correct bus-ID; alternatively, improve this check and parse and
-         * verify each bus-ID part...
-         */
-        bus_id_len = strlen(bus_id);
-        if (!bus_id_len || bus_id_len < 8 || bus_id_len > 9)
-                return -EINVAL;
-
-        /* Store the CCW bus-ID for use as network device name */
-        rc = snprintf(names->ccw_group, sizeof(names->ccw_group), "ccw%s", bus_id);
-        if (rc >= 0 && rc < (int)sizeof(names->ccw_group))
-                names->type = NET_CCWGROUP;
-        return 0;
-}
-
-static int names_mac(struct udev_device *dev, struct netnames *names) {
-        const char *s;
-        unsigned int i;
-        unsigned int a1, a2, a3, a4, a5, a6;
-
-        /* check for NET_ADDR_PERM, skip random MAC addresses */
-        s = udev_device_get_sysattr_value(dev, "addr_assign_type");
-        if (!s)
-                return EXIT_FAILURE;
-        i = strtoul(s, NULL, 0);
-        if (i != 0)
-                return 0;
-
-        s = udev_device_get_sysattr_value(dev, "address");
-        if (!s)
-                return -ENOENT;
-        if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6)
-                return -EINVAL;
-
-        /* skip empty MAC addresses */
-        if (a1 + a2 + a3 + a4 + a5 + a6 == 0)
-                return -EINVAL;
-
-        names->mac[0] = a1;
-        names->mac[1] = a2;
-        names->mac[2] = a3;
-        names->mac[3] = a4;
-        names->mac[4] = a5;
-        names->mac[5] = a6;
-        names->mac_valid = true;
-        return 0;
-}
-
-/* IEEE Organizationally Unique Identifier vendor string */
-static int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) {
-        char str[32];
-
-        if (!names->mac_valid)
-                return -ENOENT;
-        /* skip commonly misused 00:00:00 (Xerox) prefix */
-        if (memcmp(names->mac, "\0\0\0", 3) == 0)
-                return -EINVAL;
-        snprintf(str, sizeof(str), "OUI:%02X%02X%02X%02X%02X%02X",
-                 names->mac[0], names->mac[1], names->mac[2],
-                 names->mac[3], names->mac[4], names->mac[5]);
-        udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test);
-        return 0;
-}
-
-static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) {
-        const char *s;
-        const char *p;
-        unsigned int i;
-        const char *devtype;
-        const char *prefix = "en";
-        struct netnames names = {};
-        int err;
-
-        /* handle only ARPHRD_ETHER and ARPHRD_SLIP devices */
-        s = udev_device_get_sysattr_value(dev, "type");
-        if (!s)
-                return EXIT_FAILURE;
-        i = strtoul(s, NULL, 0);
-        switch (i) {
-        case ARPHRD_ETHER:
-                prefix = "en";
-                break;
-        case ARPHRD_SLIP:
-                prefix = "sl";
-                break;
-        default:
-                return 0;
-        }
-
-        /* skip stacked devices, like VLANs, ... */
-        s = udev_device_get_sysattr_value(dev, "ifindex");
-        if (!s)
-                return EXIT_FAILURE;
-        p = udev_device_get_sysattr_value(dev, "iflink");
-        if (!p)
-                return EXIT_FAILURE;
-        if (!streq(s, p))
-                return 0;
-
-        devtype = udev_device_get_devtype(dev);
-        if (devtype) {
-                if (streq("wlan", devtype))
-                        prefix = "wl";
-                else if (streq("wwan", devtype))
-                        prefix = "ww";
-        }
-
-        err = names_mac(dev, &names);
-        if (err >= 0 && names.mac_valid) {
-                char str[IFNAMSIZ];
-
-                snprintf(str, sizeof(str), "%sx%02x%02x%02x%02x%02x%02x", prefix,
-                         names.mac[0], names.mac[1], names.mac[2],
-                         names.mac[3], names.mac[4], names.mac[5]);
-                udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
-
-                ieee_oui(dev, &names, test);
-        }
-
-        /* get path names for Linux on System z network devices */
-        err = names_ccw(dev, &names);
-        if (err >= 0 && names.type == NET_CCWGROUP) {
-                char str[IFNAMSIZ];
-
-                if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_group) < (int)sizeof(str))
-                        udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
-                goto out;
-        }
-
-        /* get PCI based path names, we compose only PCI based paths */
-        err = names_pci(dev, &names);
-        if (err < 0)
-                goto out;
-
-        /* plain PCI device */
-        if (names.type == NET_PCI) {
-                char str[IFNAMSIZ];
-
-                if (names.pci_onboard[0])
-                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", str);
-
-                if (names.pci_onboard_label)
-                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard_label) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", str);
-
-                if (names.pci_path[0])
-                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_path) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
-
-                if (names.pci_slot[0])
-                        if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_slot) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
-                goto out;
-        }
-
-        /* USB device */
-        err = names_usb(dev, &names);
-        if (err >= 0 && names.type == NET_USB) {
-                char str[IFNAMSIZ];
-
-                if (names.pci_path[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.usb_ports) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
-
-                if (names.pci_slot[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.usb_ports) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
-                goto out;
-        }
-
-        /* Broadcom bus */
-        err = names_bcma(dev, &names);
-        if (err >= 0 && names.type == NET_BCMA) {
-                char str[IFNAMSIZ];
-
-                if (names.pci_path[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.bcma_core) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
-
-                if (names.pci_slot[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.bcma_core) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
-                goto out;
-        }
-out:
-        return EXIT_SUCCESS;
-}
-
-const struct udev_builtin udev_builtin_net_id = {
-        .name = "net_id",
-        .cmd = builtin_net_id,
-        .help = "Network device properties",
-};
diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c
deleted file mode 100644 (file)
index d458947..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright 2013 Tom Gundersen
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "link-config.h"
-#include "udev.h"
-#include "log.h"
-
-static link_config_ctx *ctx = NULL;
-
-static int builtin_net_setup_link(struct udev_device *dev, int argc, char **argv, bool test) {
-        _cleanup_free_ char *driver = NULL;
-        const char *name = NULL;
-        link_config *link;
-        int r;
-
-        if (argc > 1) {
-                log_error("This program takes no arguments.");
-                return EXIT_FAILURE;
-        }
-
-        r = link_get_driver(ctx, dev, &driver);
-        if (r >= 0)
-                udev_builtin_add_property(dev, test, "ID_NET_DRIVER", driver);
-
-        r = link_config_get(ctx, dev, &link);
-        if (r < 0) {
-                if (r == -ENOENT) {
-                        log_debug("No matching link configuration found.");
-                        return EXIT_SUCCESS;
-                } else {
-                        log_error_errno(r, "Could not get link config: %m");
-                        return EXIT_FAILURE;
-                }
-        }
-
-        r = link_config_apply(ctx, link, dev, &name);
-        if (r < 0) {
-                log_error_errno(r, "Could not apply link config to %s: %m", udev_device_get_sysname(dev));
-                return EXIT_FAILURE;
-        }
-
-        udev_builtin_add_property(dev, test, "ID_NET_LINK_FILE", link->filename);
-
-        if (name)
-                udev_builtin_add_property(dev, test, "ID_NET_NAME", name);
-
-        return EXIT_SUCCESS;
-}
-
-static int builtin_net_setup_link_init(struct udev *udev) {
-        int r;
-
-        if (ctx)
-                return 0;
-
-        r = link_config_ctx_new(&ctx);
-        if (r < 0)
-                return r;
-
-        r = link_config_load(ctx);
-        if (r < 0)
-                return r;
-
-        log_debug("Created link configuration context.");
-        return 0;
-}
-
-static void builtin_net_setup_link_exit(struct udev *udev) {
-        link_config_ctx_free(ctx);
-        ctx = NULL;
-        log_debug("Unloaded link configuration context.");
-}
-
-static bool builtin_net_setup_link_validate(struct udev *udev) {
-        log_debug("Check if link configuration needs reloading.");
-        if (!ctx)
-                return false;
-
-        return link_config_should_reload(ctx);
-}
-
-const struct udev_builtin udev_builtin_net_setup_link = {
-        .name = "net_setup_link",
-        .cmd = builtin_net_setup_link,
-        .init = builtin_net_setup_link_init,
-        .exit = builtin_net_setup_link_exit,
-        .validate = builtin_net_setup_link_validate,
-        .help = "Configure network link",
-        .run_once = false,
-};
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
deleted file mode 100644 (file)
index b6749aa..0000000
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
- * compose persistent device path
- *
- * Copyright (C) 2009-2011 Kay Sievers <kay@vrfy.org>
- *
- * Logic based on Hannes Reinecke's shell script.
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <getopt.h>
-
-#include "udev.h"
-
-_printf_(2,3)
-static int path_prepend(char **path, const char *fmt, ...) {
-        va_list va;
-        char *pre;
-        int err = 0;
-
-        va_start(va, fmt);
-        err = vasprintf(&pre, fmt, va);
-        va_end(va);
-        if (err < 0)
-                goto out;
-
-        if (*path != NULL) {
-                char *new;
-
-                err = asprintf(&new, "%s-%s", pre, *path);
-                free(pre);
-                if (err < 0)
-                        goto out;
-                free(*path);
-                *path = new;
-        } else {
-                *path = pre;
-        }
-out:
-        return err;
-}
-
-/*
-** Linux only supports 32 bit luns.
-** See drivers/scsi/scsi_scan.c::scsilun_to_int() for more details.
-*/
-static int format_lun_number(struct udev_device *dev, char **path) {
-        unsigned long lun = strtoul(udev_device_get_sysnum(dev), NULL, 10);
-
-        /* address method 0, peripheral device addressing with bus id of zero */
-        if (lun < 256)
-                return path_prepend(path, "lun-%lu", lun);
-        /* handle all other lun addressing methods by using a variant of the original lun format */
-        return path_prepend(path, "lun-0x%04lx%04lx00000000", lun & 0xffff, (lun >> 16) & 0xffff);
-}
-
-static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys) {
-        struct udev_device *parent = dev;
-
-        while (parent != NULL) {
-                const char *subsystem;
-
-                subsystem = udev_device_get_subsystem(parent);
-                if (subsystem == NULL || !streq(subsystem, subsys))
-                        break;
-                dev = parent;
-                parent = udev_device_get_parent(parent);
-        }
-        return dev;
-}
-
-static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path) {
-        struct udev *udev  = udev_device_get_udev(parent);
-        struct udev_device *targetdev;
-        struct udev_device *fcdev = NULL;
-        const char *port;
-        char *lun = NULL;
-
-        targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
-        if (targetdev == NULL)
-                return NULL;
-
-        fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_transport", udev_device_get_sysname(targetdev));
-        if (fcdev == NULL)
-                return NULL;
-        port = udev_device_get_sysattr_value(fcdev, "port_name");
-        if (port == NULL) {
-                parent = NULL;
-                goto out;
-        }
-
-        format_lun_number(parent, &lun);
-        path_prepend(path, "fc-%s-%s", port, lun);
-        if (lun)
-                free(lun);
-out:
-        udev_device_unref(fcdev);
-        return parent;
-}
-
-static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent, char **path) {
-        struct udev *udev  = udev_device_get_udev(parent);
-        struct udev_device *targetdev;
-        struct udev_device *target_parent;
-        struct udev_device *sasdev;
-        const char *sas_address;
-        char *lun = NULL;
-
-        targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
-        if (targetdev == NULL)
-                return NULL;
-
-        target_parent = udev_device_get_parent(targetdev);
-        if (target_parent == NULL)
-                return NULL;
-
-        sasdev = udev_device_new_from_subsystem_sysname(udev, "sas_device",
-                                udev_device_get_sysname(target_parent));
-        if (sasdev == NULL)
-                return NULL;
-
-        sas_address = udev_device_get_sysattr_value(sasdev, "sas_address");
-        if (sas_address == NULL) {
-                parent = NULL;
-                goto out;
-        }
-
-        format_lun_number(parent, &lun);
-        path_prepend(path, "sas-%s-%s", sas_address, lun);
-        if (lun)
-                free(lun);
-out:
-        udev_device_unref(sasdev);
-        return parent;
-}
-
-static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path)
-{
-        struct udev *udev  = udev_device_get_udev(parent);
-        struct udev_device *targetdev;
-        struct udev_device *target_parent;
-        struct udev_device *port;
-        struct udev_device *expander;
-        struct udev_device *target_sasdev = NULL;
-        struct udev_device *expander_sasdev = NULL;
-        struct udev_device *port_sasdev = NULL;
-        const char *sas_address = NULL;
-        const char *phy_id;
-        const char *phy_count;
-        char *lun = NULL;
-
-        targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
-        if (targetdev == NULL)
-                return NULL;
-
-        target_parent = udev_device_get_parent(targetdev);
-        if (target_parent == NULL)
-                return NULL;
-
-        /* Get sas device */
-        target_sasdev = udev_device_new_from_subsystem_sysname(udev,
-                          "sas_device", udev_device_get_sysname(target_parent));
-        if (target_sasdev == NULL)
-                return NULL;
-
-        /* The next parent is sas port */
-        port = udev_device_get_parent(target_parent);
-        if (port == NULL) {
-                parent = NULL;
-                goto out;
-        }
-
-        /* Get port device */
-        port_sasdev = udev_device_new_from_subsystem_sysname(udev,
-                          "sas_port", udev_device_get_sysname(port));
-
-        phy_count = udev_device_get_sysattr_value(port_sasdev, "num_phys");
-        if (phy_count == NULL) {
-               parent = NULL;
-               goto out;
-        }
-
-        /* Check if we are simple disk */
-        if (strncmp(phy_count, "1", 2) != 0) {
-                 parent = handle_scsi_sas_wide_port(parent, path);
-                 goto out;
-        }
-
-        /* Get connected phy */
-        phy_id = udev_device_get_sysattr_value(target_sasdev, "phy_identifier");
-        if (phy_id == NULL) {
-                parent = NULL;
-                goto out;
-        }
-
-        /* The port's parent is either hba or expander */
-        expander = udev_device_get_parent(port);
-        if (expander == NULL) {
-                parent = NULL;
-                goto out;
-        }
-
-        /* Get expander device */
-        expander_sasdev = udev_device_new_from_subsystem_sysname(udev,
-                          "sas_device", udev_device_get_sysname(expander));
-        if (expander_sasdev != NULL) {
-                 /* Get expander's address */
-                 sas_address = udev_device_get_sysattr_value(expander_sasdev,
-                                                    "sas_address");
-                 if (sas_address == NULL) {
-                        parent = NULL;
-                        goto out;
-                 }
-        }
-
-        format_lun_number(parent, &lun);
-        if (sas_address)
-                 path_prepend(path, "sas-exp%s-phy%s-%s", sas_address, phy_id, lun);
-        else
-                 path_prepend(path, "sas-phy%s-%s", phy_id, lun);
-
-        if (lun)
-                free(lun);
-out:
-        udev_device_unref(target_sasdev);
-        udev_device_unref(expander_sasdev);
-        udev_device_unref(port_sasdev);
-        return parent;
-}
-
-static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path) {
-        struct udev *udev  = udev_device_get_udev(parent);
-        struct udev_device *transportdev;
-        struct udev_device *sessiondev = NULL;
-        const char *target;
-        char *connname;
-        struct udev_device *conndev = NULL;
-        const char *addr;
-        const char *port;
-        char *lun = NULL;
-
-        /* find iscsi session */
-        transportdev = parent;
-        for (;;) {
-                transportdev = udev_device_get_parent(transportdev);
-                if (transportdev == NULL)
-                        return NULL;
-                if (startswith(udev_device_get_sysname(transportdev), "session"))
-                        break;
-        }
-
-        /* find iscsi session device */
-        sessiondev = udev_device_new_from_subsystem_sysname(udev, "iscsi_session", udev_device_get_sysname(transportdev));
-        if (sessiondev == NULL)
-                return NULL;
-        target = udev_device_get_sysattr_value(sessiondev, "targetname");
-        if (target == NULL) {
-                parent = NULL;
-                goto out;
-        }
-
-        if (asprintf(&connname, "connection%s:0", udev_device_get_sysnum(transportdev)) < 0) {
-                parent = NULL;
-                goto out;
-        }
-        conndev = udev_device_new_from_subsystem_sysname(udev, "iscsi_connection", connname);
-        free(connname);
-        if (conndev == NULL) {
-                parent = NULL;
-                goto out;
-        }
-        addr = udev_device_get_sysattr_value(conndev, "persistent_address");
-        port = udev_device_get_sysattr_value(conndev, "persistent_port");
-        if (addr == NULL || port == NULL) {
-                parent = NULL;
-                goto out;
-        }
-
-        format_lun_number(parent, &lun);
-        path_prepend(path, "ip-%s:%s-iscsi-%s-%s", addr, port, target, lun);
-        if (lun)
-                free(lun);
-out:
-        udev_device_unref(sessiondev);
-        udev_device_unref(conndev);
-        return parent;
-}
-
-static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path) {
-        struct udev_device *hostdev;
-        int host, bus, target, lun;
-        const char *name;
-        char *base;
-        char *pos;
-        DIR *dir;
-        struct dirent *dent;
-        int basenum;
-
-        hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
-        if (hostdev == NULL)
-                return NULL;
-
-        name = udev_device_get_sysname(parent);
-        if (sscanf(name, "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4)
-                return NULL;
-
-        /*
-         * Rebase host offset to get the local relative number
-         *
-         * Note: This is by definition racy, unreliable and too simple.
-         * Please do not copy this model anywhere. It's just a left-over
-         * from the time we had no idea how things should look like in
-         * the end.
-         *
-         * Making assumptions about a global in-kernel counter and use
-         * that to calculate a local offset is a very broken concept. It
-         * can only work as long as things are in strict order.
-         *
-         * The kernel needs to export the instance/port number of a
-         * controller directly, without the need for rebase magic like
-         * this. Manual driver unbind/bind, parallel hotplug/unplug will
-         * get into the way of this "I hope it works" logic.
-         */
-        basenum = -1;
-        base = strdup(udev_device_get_syspath(hostdev));
-        if (base == NULL)
-                return NULL;
-        pos = strrchr(base, '/');
-        if (pos == NULL) {
-                parent = NULL;
-                goto out;
-        }
-        pos[0] = '\0';
-        dir = opendir(base);
-        if (dir == NULL) {
-                parent = NULL;
-                goto out;
-        }
-        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
-                char *rest;
-                int i;
-
-                if (dent->d_name[0] == '.')
-                        continue;
-                if (dent->d_type != DT_DIR && dent->d_type != DT_LNK)
-                        continue;
-                if (!startswith(dent->d_name, "host"))
-                        continue;
-                i = strtoul(&dent->d_name[4], &rest, 10);
-                if (rest[0] != '\0')
-                        continue;
-                /*
-                 * find the smallest number; the host really needs to export its
-                 * own instance number per parent device; relying on the global host
-                 * enumeration and plainly rebasing the numbers sounds unreliable
-                 */
-                if (basenum == -1 || i < basenum)
-                        basenum = i;
-        }
-        closedir(dir);
-        if (basenum == -1) {
-                parent = NULL;
-                goto out;
-        }
-        host -= basenum;
-
-        path_prepend(path, "scsi-%u:%u:%u:%u", host, bus, target, lun);
-out:
-        free(base);
-        return hostdev;
-}
-
-static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char **path) {
-        struct udev_device *hostdev;
-        struct udev_device *vmbusdev;
-        const char *guid_str;
-        char *lun = NULL;
-        char guid[38];
-        size_t i, k;
-
-        hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
-        if (!hostdev)
-                return NULL;
-
-        vmbusdev = udev_device_get_parent(hostdev);
-        if (!vmbusdev)
-                return NULL;
-
-        guid_str = udev_device_get_sysattr_value(vmbusdev, "device_id");
-        if (!guid_str)
-                return NULL;
-
-        if (strlen(guid_str) < 37 || guid_str[0] != '{' || guid_str[36] != '}')
-                return NULL;
-
-        for (i = 1, k = 0; i < 36; i++) {
-                if (guid_str[i] == '-')
-                        continue;
-                guid[k++] = guid_str[i];
-        }
-        guid[k] = '\0';
-
-        format_lun_number(parent, &lun);
-        path_prepend(path, "vmbus-%s-%s", guid, lun);
-        free(lun);
-        return parent;
-}
-
-static struct udev_device *handle_scsi(struct udev_device *parent, char **path, bool *supported_parent) {
-        const char *devtype;
-        const char *name;
-        const char *id;
-
-        devtype = udev_device_get_devtype(parent);
-        if (devtype == NULL || !streq(devtype, "scsi_device"))
-                return parent;
-
-        /* firewire */
-        id = udev_device_get_sysattr_value(parent, "ieee1394_id");
-        if (id != NULL) {
-                parent = skip_subsystem(parent, "scsi");
-                path_prepend(path, "ieee1394-0x%s", id);
-                *supported_parent = true;
-                goto out;
-        }
-
-        /* scsi sysfs does not have a "subsystem" for the transport */
-        name = udev_device_get_syspath(parent);
-
-        if (strstr(name, "/rport-") != NULL) {
-                parent = handle_scsi_fibre_channel(parent, path);
-                *supported_parent = true;
-                goto out;
-        }
-
-        if (strstr(name, "/end_device-") != NULL) {
-                parent = handle_scsi_sas(parent, path);
-                *supported_parent = true;
-                goto out;
-        }
-
-        if (strstr(name, "/session") != NULL) {
-                parent = handle_scsi_iscsi(parent, path);
-                *supported_parent = true;
-                goto out;
-        }
-
-        /*
-         * We do not support the ATA transport class, it uses global counters
-         * to name the ata devices which numbers spread across multiple
-         * controllers.
-         *
-         * The real link numbers are not exported. Also, possible chains of ports
-         * behind port multipliers cannot be composed that way.
-         *
-         * Until all that is solved at the kernel level, there are no by-path/
-         * links for ATA devices.
-         */
-        if (strstr(name, "/ata") != NULL) {
-                parent = NULL;
-                goto out;
-        }
-
-        if (strstr(name, "/vmbus_") != NULL) {
-                parent = handle_scsi_hyperv(parent, path);
-                goto out;
-        }
-
-        parent = handle_scsi_default(parent, path);
-out:
-        return parent;
-}
-
-static struct udev_device *handle_cciss(struct udev_device *parent, char **path) {
-        const char *str;
-        unsigned int controller, disk;
-
-        str = udev_device_get_sysname(parent);
-        if (sscanf(str, "c%ud%u%*s", &controller, &disk) != 2)
-                return NULL;
-
-        path_prepend(path, "cciss-disk%u", disk);
-        parent = skip_subsystem(parent, "cciss");
-        return parent;
-}
-
-static void handle_scsi_tape(struct udev_device *dev, char **path) {
-        const char *name;
-
-        /* must be the last device in the syspath */
-        if (*path != NULL)
-                return;
-
-        name = udev_device_get_sysname(dev);
-        if (startswith(name, "nst") && strchr("lma", name[3]) != NULL)
-                path_prepend(path, "nst%c", name[3]);
-        else if (startswith(name, "st") && strchr("lma", name[2]) != NULL)
-                path_prepend(path, "st%c", name[2]);
-}
-
-static struct udev_device *handle_usb(struct udev_device *parent, char **path) {
-        const char *devtype;
-        const char *str;
-        const char *port;
-
-        devtype = udev_device_get_devtype(parent);
-        if (devtype == NULL)
-                return parent;
-        if (!streq(devtype, "usb_interface") && !streq(devtype, "usb_device"))
-                return parent;
-
-        str = udev_device_get_sysname(parent);
-        port = strchr(str, '-');
-        if (port == NULL)
-                return parent;
-        port++;
-
-        parent = skip_subsystem(parent, "usb");
-        path_prepend(path, "usb-0:%s", port);
-        return parent;
-}
-
-static struct udev_device *handle_bcma(struct udev_device *parent, char **path) {
-        const char *sysname;
-        unsigned int core;
-
-        sysname = udev_device_get_sysname(parent);
-        if (sscanf(sysname, "bcma%*u:%u", &core) != 1)
-                return NULL;
-
-        path_prepend(path, "bcma-%u", core);
-        return parent;
-}
-
-static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path) {
-        struct udev_device *scsi_dev;
-
-        scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
-        if (scsi_dev != NULL) {
-                const char *wwpn;
-                const char *lun;
-                const char *hba_id;
-
-                hba_id = udev_device_get_sysattr_value(scsi_dev, "hba_id");
-                wwpn = udev_device_get_sysattr_value(scsi_dev, "wwpn");
-                lun = udev_device_get_sysattr_value(scsi_dev, "fcp_lun");
-                if (hba_id != NULL && lun != NULL && wwpn != NULL) {
-                        path_prepend(path, "ccw-%s-zfcp-%s:%s", hba_id, wwpn, lun);
-                        goto out;
-                }
-        }
-
-        path_prepend(path, "ccw-%s", udev_device_get_sysname(parent));
-out:
-        parent = skip_subsystem(parent, "ccw");
-        return parent;
-}
-
-static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test) {
-        struct udev_device *parent;
-        char *path = NULL;
-        bool supported_transport = false;
-        bool supported_parent = false;
-
-        /* S390 ccw bus */
-        parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
-        if (parent != NULL) {
-                handle_ccw(parent, dev, &path);
-                goto out;
-        }
-
-        /* walk up the chain of devices and compose path */
-        parent = dev;
-        while (parent != NULL) {
-                const char *subsys;
-
-                subsys = udev_device_get_subsystem(parent);
-                if (subsys == NULL) {
-                        ;
-                } else if (streq(subsys, "scsi_tape")) {
-                        handle_scsi_tape(parent, &path);
-                } else if (streq(subsys, "scsi")) {
-                        parent = handle_scsi(parent, &path, &supported_parent);
-                        supported_transport = true;
-                } else if (streq(subsys, "cciss")) {
-                        parent = handle_cciss(parent, &path);
-                        supported_transport = true;
-                } else if (streq(subsys, "usb")) {
-                        parent = handle_usb(parent, &path);
-                        supported_transport = true;
-                } else if (streq(subsys, "bcma")) {
-                        parent = handle_bcma(parent, &path);
-                        supported_transport = true;
-                } else if (streq(subsys, "serio")) {
-                        path_prepend(&path, "serio-%s", udev_device_get_sysnum(parent));
-                        parent = skip_subsystem(parent, "serio");
-                } else if (streq(subsys, "pci")) {
-                        path_prepend(&path, "pci-%s", udev_device_get_sysname(parent));
-                        parent = skip_subsystem(parent, "pci");
-                        supported_parent = true;
-                } else if (streq(subsys, "platform")) {
-                        path_prepend(&path, "platform-%s", udev_device_get_sysname(parent));
-                        parent = skip_subsystem(parent, "platform");
-                        supported_transport = true;
-                        supported_parent = true;
-                } else if (streq(subsys, "acpi")) {
-                        path_prepend(&path, "acpi-%s", udev_device_get_sysname(parent));
-                        parent = skip_subsystem(parent, "acpi");
-                        supported_parent = true;
-                } else if (streq(subsys, "xen")) {
-                        path_prepend(&path, "xen-%s", udev_device_get_sysname(parent));
-                        parent = skip_subsystem(parent, "xen");
-                        supported_parent = true;
-                } else if (streq(subsys, "scm")) {
-                        path_prepend(&path, "scm-%s", udev_device_get_sysname(parent));
-                        parent = skip_subsystem(parent, "scm");
-                        supported_transport = true;
-                        supported_parent = true;
-                }
-
-                parent = udev_device_get_parent(parent);
-        }
-
-        /*
-         * Do not return devices with an unknown parent device type. They
-         * might produce conflicting IDs if the parent does not provide a
-         * unique and predictable name.
-         */
-        if (!supported_parent) {
-                free(path);
-                path = NULL;
-        }
-
-        /*
-         * Do not return block devices without a well-known transport. Some
-         * devices do not expose their buses and do not provide a unique
-         * and predictable name that way.
-         */
-        if (streq(udev_device_get_subsystem(dev), "block") && !supported_transport) {
-                free(path);
-                path = NULL;
-        }
-
-out:
-        if (path != NULL) {
-                char tag[UTIL_NAME_SIZE];
-                size_t i;
-                const char *p;
-
-                /* compose valid udev tag name */
-                for (p = path, i = 0; *p; p++) {
-                        if ((*p >= '0' && *p <= '9') ||
-                            (*p >= 'A' && *p <= 'Z') ||
-                            (*p >= 'a' && *p <= 'z') ||
-                            *p == '-') {
-                                tag[i++] = *p;
-                                continue;
-                        }
-
-                        /* skip all leading '_' */
-                        if (i == 0)
-                                continue;
-
-                        /* avoid second '_' */
-                        if (tag[i-1] == '_')
-                                continue;
-
-                        tag[i++] = '_';
-                }
-                /* strip trailing '_' */
-                while (i > 0 && tag[i-1] == '_')
-                        i--;
-                tag[i] = '\0';
-
-                udev_builtin_add_property(dev, test, "ID_PATH", path);
-                udev_builtin_add_property(dev, test, "ID_PATH_TAG", tag);
-                free(path);
-                return EXIT_SUCCESS;
-        }
-        return EXIT_FAILURE;
-}
-
-const struct udev_builtin udev_builtin_path_id = {
-        .name = "path_id",
-        .cmd = builtin_path_id,
-        .help = "Compose persistent device path",
-        .run_once = true,
-};
diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c
deleted file mode 100644 (file)
index 99bb91a..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * manage device node user ACL
- *
- * Copyright 2010-2012 Kay Sievers <kay@vrfy.org>
- * Copyright 2010 Lennart Poettering
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include "systemd/sd-login.h"
-#include "logind-acl.h"
-#include "udev.h"
-#include "util.h"
-
-static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool test) {
-        int r;
-        const char *path = NULL, *seat;
-        bool changed_acl = false;
-        uid_t uid;
-
-        umask(0022);
-
-        /* don't muck around with ACLs when the system is not running systemd */
-        if (!logind_running())
-                return 0;
-
-        path = udev_device_get_devnode(dev);
-        seat = udev_device_get_property_value(dev, "ID_SEAT");
-        if (!seat)
-                seat = "seat0";
-
-        r = sd_seat_get_active(seat, NULL, &uid);
-        if (r == -ENOENT) {
-                /* No active session on this seat */
-                r = 0;
-                goto finish;
-        } else if (r < 0) {
-                log_error("Failed to determine active user on seat %s.", seat);
-                goto finish;
-        }
-
-        r = devnode_acl(path, true, false, 0, true, uid);
-        if (r < 0) {
-                log_error_errno(r, "Failed to apply ACL on %s: %m", path);
-                goto finish;
-        }
-
-        changed_acl = true;
-        r = 0;
-
-finish:
-        if (path && !changed_acl) {
-                int k;
-
-                /* Better be safe than sorry and reset ACL */
-                k = devnode_acl(path, true, false, 0, false, 0);
-                if (k < 0) {
-                        log_error_errno(k, "Failed to apply ACL on %s: %m", path);
-                        if (r >= 0)
-                                r = k;
-                }
-        }
-
-        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-}
-
-const struct udev_builtin udev_builtin_uaccess = {
-        .name = "uaccess",
-        .cmd = builtin_uaccess,
-        .help = "Manage device node user ACL",
-};
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
deleted file mode 100644 (file)
index e6c27a9..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * USB device properties and persistent device path
- *
- * Copyright (c) 2005 SUSE Linux Products GmbH, Germany
- *   Author: Hannes Reinecke <hare@suse.de>
- *
- * Copyright (C) 2005-2011 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "udev.h"
-
-static void set_usb_iftype(char *to, int if_class_num, size_t len) {
-        const char *type = "generic";
-
-        switch (if_class_num) {
-        case 1:
-                type = "audio";
-                break;
-        case 2: /* CDC-Control */
-                break;
-        case 3:
-                type = "hid";
-                break;
-        case 5: /* Physical */
-                break;
-        case 6:
-                type = "media";
-                break;
-        case 7:
-                type = "printer";
-                break;
-        case 8:
-                type = "storage";
-                break;
-        case 9:
-                type = "hub";
-                break;
-        case 0x0a: /* CDC-Data */
-                break;
-        case 0x0b: /* Chip/Smart Card */
-                break;
-        case 0x0d: /* Content Security */
-                break;
-        case 0x0e:
-                type = "video";
-                break;
-        case 0xdc: /* Diagnostic Device */
-                break;
-        case 0xe0: /* Wireless Controller */
-                break;
-        case 0xfe: /* Application-specific */
-                break;
-        case 0xff: /* Vendor-specific */
-                break;
-        default:
-                break;
-        }
-        strncpy(to, type, len);
-        to[len-1] = '\0';
-}
-
-static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len) {
-        int type_num = 0;
-        char *eptr;
-        const char *type = "generic";
-
-        type_num = strtoul(from, &eptr, 0);
-        if (eptr != from) {
-                switch (type_num) {
-                case 1: /* RBC devices */
-                        type = "rbc";
-                        break;
-                case 2:
-                        type = "atapi";
-                        break;
-                case 3:
-                        type = "tape";
-                        break;
-                case 4: /* UFI */
-                        type = "floppy";
-                        break;
-                case 6: /* Transparent SPC-2 devices */
-                        type = "scsi";
-                        break;
-                default:
-                        break;
-                }
-        }
-        strscpy(to, len, type);
-        return type_num;
-}
-
-static void set_scsi_type(char *to, const char *from, size_t len) {
-        int type_num;
-        char *eptr;
-        const char *type = "generic";
-
-        type_num = strtoul(from, &eptr, 0);
-        if (eptr != from) {
-                switch (type_num) {
-                case 0:
-                case 0xe:
-                        type = "disk";
-                        break;
-                case 1:
-                        type = "tape";
-                        break;
-                case 4:
-                case 7:
-                case 0xf:
-                        type = "optical";
-                        break;
-                case 5:
-                        type = "cd";
-                        break;
-                default:
-                        break;
-                }
-        }
-        strscpy(to, len, type);
-}
-
-#define USB_DT_DEVICE                        0x01
-#define USB_DT_INTERFACE                0x04
-
-static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len) {
-        _cleanup_free_ char *filename = NULL;
-        _cleanup_close_ int fd = -1;
-        ssize_t size;
-        unsigned char buf[18 + 65535];
-        size_t pos = 0;
-        unsigned strpos = 0;
-        struct usb_interface_descriptor {
-                uint8_t bLength;
-                uint8_t bDescriptorType;
-                uint8_t bInterfaceNumber;
-                uint8_t bAlternateSetting;
-                uint8_t bNumEndpoints;
-                uint8_t bInterfaceClass;
-                uint8_t bInterfaceSubClass;
-                uint8_t bInterfaceProtocol;
-                uint8_t iInterface;
-        } _packed_;
-
-        if (asprintf(&filename, "%s/descriptors", udev_device_get_syspath(dev)) < 0)
-                return log_oom();
-
-        fd = open(filename, O_RDONLY|O_CLOEXEC);
-        if (fd < 0) {
-                fprintf(stderr, "error opening USB device 'descriptors' file\n");
-                return -errno;
-        }
-
-        size = read(fd, buf, sizeof(buf));
-        if (size < 18 || size == sizeof(buf))
-                return -EIO;
-
-        ifs_str[0] = '\0';
-        while (pos + sizeof(struct usb_interface_descriptor) < (size_t) size &&
-               strpos + 7 < len - 2) {
-
-                struct usb_interface_descriptor *desc;
-                char if_str[8];
-
-                desc = (struct usb_interface_descriptor *) &buf[pos];
-                if (desc->bLength < 3)
-                        break;
-                pos += desc->bLength;
-
-                if (desc->bDescriptorType != USB_DT_INTERFACE)
-                        continue;
-
-                if (snprintf(if_str, 8, ":%02x%02x%02x",
-                             desc->bInterfaceClass,
-                             desc->bInterfaceSubClass,
-                             desc->bInterfaceProtocol) != 7)
-                        continue;
-
-                if (strstr(ifs_str, if_str) != NULL)
-                        continue;
-
-                memcpy(&ifs_str[strpos], if_str, 8),
-                strpos += 7;
-        }
-
-        if (strpos > 0) {
-                ifs_str[strpos++] = ':';
-                ifs_str[strpos++] = '\0';
-        }
-
-        return 0;
-}
-
-/*
- * A unique USB identification is generated like this:
- *
- * 1.) Get the USB device type from InterfaceClass and InterfaceSubClass
- * 2.) If the device type is 'Mass-Storage/SPC-2' or 'Mass-Storage/RBC',
- *     use the SCSI vendor and model as USB-Vendor and USB-model.
- * 3.) Otherwise, use the USB manufacturer and product as
- *     USB-Vendor and USB-model. Any non-printable characters
- *     in those strings will be skipped; a slash '/' will be converted
- *     into a full stop '.'.
- * 4.) If that fails, too, we will use idVendor and idProduct
- *     as USB-Vendor and USB-model.
- * 5.) The USB identification is the USB-vendor and USB-model
- *     string concatenated with an underscore '_'.
- * 6.) If the device supplies a serial number, this number
- *     is concatenated with the identification with an underscore '_'.
- */
-static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool test) {
-        char vendor_str[64];
-        char vendor_str_enc[256];
-        const char *vendor_id;
-        char model_str[64];
-        char model_str_enc[256];
-        const char *product_id;
-        char serial_str[UTIL_NAME_SIZE];
-        char packed_if_str[UTIL_NAME_SIZE];
-        char revision_str[64];
-        char type_str[64];
-        char instance_str[64];
-        const char *ifnum = NULL;
-        const char *driver = NULL;
-        char serial[256];
-
-        struct udev_device *dev_interface = NULL;
-        struct udev_device *dev_usb = NULL;
-        const char *if_class, *if_subclass;
-        int if_class_num;
-        int protocol = 0;
-        size_t l;
-        char *s;
-
-        vendor_str[0] = '\0';
-        model_str[0] = '\0';
-        serial_str[0] = '\0';
-        packed_if_str[0] = '\0';
-        revision_str[0] = '\0';
-        type_str[0] = '\0';
-        instance_str[0] = '\0';
-
-        /* shortcut, if we are called directly for a "usb_device" type */
-        if (udev_device_get_devtype(dev) != NULL && streq(udev_device_get_devtype(dev), "usb_device")) {
-                dev_if_packed_info(dev, packed_if_str, sizeof(packed_if_str));
-                dev_usb = dev;
-                goto fallback;
-        }
-
-        /* usb interface directory */
-        dev_interface = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
-        if (dev_interface == NULL) {
-                log_debug("unable to access usb_interface device of '%s'",
-                     udev_device_get_syspath(dev));
-                return EXIT_FAILURE;
-        }
-
-        ifnum = udev_device_get_sysattr_value(dev_interface, "bInterfaceNumber");
-        driver = udev_device_get_sysattr_value(dev_interface, "driver");
-
-        if_class = udev_device_get_sysattr_value(dev_interface, "bInterfaceClass");
-        if (!if_class) {
-                log_debug("%s: cannot get bInterfaceClass attribute",
-                     udev_device_get_sysname(dev));
-                return EXIT_FAILURE;
-        }
-
-        if_class_num = strtoul(if_class, NULL, 16);
-        if (if_class_num == 8) {
-                /* mass storage */
-                if_subclass = udev_device_get_sysattr_value(dev_interface, "bInterfaceSubClass");
-                if (if_subclass != NULL)
-                        protocol = set_usb_mass_storage_ifsubtype(type_str, if_subclass, sizeof(type_str)-1);
-        } else {
-                set_usb_iftype(type_str, if_class_num, sizeof(type_str)-1);
-        }
-
-        log_debug("%s: if_class %d protocol %d",
-             udev_device_get_syspath(dev_interface), if_class_num, protocol);
-
-        /* usb device directory */
-        dev_usb = udev_device_get_parent_with_subsystem_devtype(dev_interface, "usb", "usb_device");
-        if (!dev_usb) {
-                log_debug("unable to find parent 'usb' device of '%s'",
-                     udev_device_get_syspath(dev));
-                return EXIT_FAILURE;
-        }
-
-        /* all interfaces of the device in a single string */
-        dev_if_packed_info(dev_usb, packed_if_str, sizeof(packed_if_str));
-
-        /* mass storage : SCSI or ATAPI */
-        if ((protocol == 6 || protocol == 2)) {
-                struct udev_device *dev_scsi;
-                const char *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev;
-                int host, bus, target, lun;
-
-                /* get scsi device */
-                dev_scsi = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
-                if (dev_scsi == NULL) {
-                        log_debug("unable to find parent 'scsi' device of '%s'",
-                             udev_device_get_syspath(dev));
-                        goto fallback;
-                }
-                if (sscanf(udev_device_get_sysname(dev_scsi), "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) {
-                        log_debug("invalid scsi device '%s'", udev_device_get_sysname(dev_scsi));
-                        goto fallback;
-                }
-
-                /* Generic SPC-2 device */
-                scsi_vendor = udev_device_get_sysattr_value(dev_scsi, "vendor");
-                if (!scsi_vendor) {
-                        log_debug("%s: cannot get SCSI vendor attribute",
-                             udev_device_get_sysname(dev_scsi));
-                        goto fallback;
-                }
-                udev_util_encode_string(scsi_vendor, vendor_str_enc, sizeof(vendor_str_enc));
-                util_replace_whitespace(scsi_vendor, vendor_str, sizeof(vendor_str)-1);
-                util_replace_chars(vendor_str, NULL);
-
-                scsi_model = udev_device_get_sysattr_value(dev_scsi, "model");
-                if (!scsi_model) {
-                        log_debug("%s: cannot get SCSI model attribute",
-                             udev_device_get_sysname(dev_scsi));
-                        goto fallback;
-                }
-                udev_util_encode_string(scsi_model, model_str_enc, sizeof(model_str_enc));
-                util_replace_whitespace(scsi_model, model_str, sizeof(model_str)-1);
-                util_replace_chars(model_str, NULL);
-
-                scsi_type = udev_device_get_sysattr_value(dev_scsi, "type");
-                if (!scsi_type) {
-                        log_debug("%s: cannot get SCSI type attribute",
-                             udev_device_get_sysname(dev_scsi));
-                        goto fallback;
-                }
-                set_scsi_type(type_str, scsi_type, sizeof(type_str)-1);
-
-                scsi_rev = udev_device_get_sysattr_value(dev_scsi, "rev");
-                if (!scsi_rev) {
-                        log_debug("%s: cannot get SCSI revision attribute",
-                             udev_device_get_sysname(dev_scsi));
-                        goto fallback;
-                }
-                util_replace_whitespace(scsi_rev, revision_str, sizeof(revision_str)-1);
-                util_replace_chars(revision_str, NULL);
-
-                /*
-                 * some broken devices have the same identifiers
-                 * for all luns, export the target:lun number
-                 */
-                sprintf(instance_str, "%d:%d", target, lun);
-        }
-
-fallback:
-        vendor_id = udev_device_get_sysattr_value(dev_usb, "idVendor");
-        product_id = udev_device_get_sysattr_value(dev_usb, "idProduct");
-
-        /* fallback to USB vendor & device */
-        if (vendor_str[0] == '\0') {
-                const char *usb_vendor = NULL;
-
-                usb_vendor = udev_device_get_sysattr_value(dev_usb, "manufacturer");
-                if (!usb_vendor)
-                        usb_vendor = vendor_id;
-                if (!usb_vendor) {
-                        log_debug("No USB vendor information available");
-                        return EXIT_FAILURE;
-                }
-                udev_util_encode_string(usb_vendor, vendor_str_enc, sizeof(vendor_str_enc));
-                util_replace_whitespace(usb_vendor, vendor_str, sizeof(vendor_str)-1);
-                util_replace_chars(vendor_str, NULL);
-        }
-
-        if (model_str[0] == '\0') {
-                const char *usb_model = NULL;
-
-                usb_model = udev_device_get_sysattr_value(dev_usb, "product");
-                if (!usb_model)
-                        usb_model = product_id;
-                if (!usb_model)
-                        return EXIT_FAILURE;
-                udev_util_encode_string(usb_model, model_str_enc, sizeof(model_str_enc));
-                util_replace_whitespace(usb_model, model_str, sizeof(model_str)-1);
-                util_replace_chars(model_str, NULL);
-        }
-
-        if (revision_str[0] == '\0') {
-                const char *usb_rev;
-
-                usb_rev = udev_device_get_sysattr_value(dev_usb, "bcdDevice");
-                if (usb_rev) {
-                        util_replace_whitespace(usb_rev, revision_str, sizeof(revision_str)-1);
-                        util_replace_chars(revision_str, NULL);
-                }
-        }
-
-        if (serial_str[0] == '\0') {
-                const char *usb_serial;
-
-                usb_serial = udev_device_get_sysattr_value(dev_usb, "serial");
-                if (usb_serial) {
-                        const unsigned char *p;
-
-                        /* http://msdn.microsoft.com/en-us/library/windows/hardware/gg487321.aspx */
-                        for (p = (unsigned char *)usb_serial; *p != '\0'; p++)
-                                if (*p < 0x20 || *p > 0x7f || *p == ',') {
-                                        usb_serial = NULL;
-                                        break;
-                                }
-                }
-
-                if (usb_serial) {
-                        util_replace_whitespace(usb_serial, serial_str, sizeof(serial_str)-1);
-                        util_replace_chars(serial_str, NULL);
-                }
-        }
-
-        s = serial;
-        l = strpcpyl(&s, sizeof(serial), vendor_str, "_", model_str, NULL);
-        if (serial_str[0] != '\0')
-                l = strpcpyl(&s, l, "_", serial_str, NULL);
-
-        if (instance_str[0] != '\0')
-                strpcpyl(&s, l, "-", instance_str, NULL);
-
-        udev_builtin_add_property(dev, test, "ID_VENDOR", vendor_str);
-        udev_builtin_add_property(dev, test, "ID_VENDOR_ENC", vendor_str_enc);
-        udev_builtin_add_property(dev, test, "ID_VENDOR_ID", vendor_id);
-        udev_builtin_add_property(dev, test, "ID_MODEL", model_str);
-        udev_builtin_add_property(dev, test, "ID_MODEL_ENC", model_str_enc);
-        udev_builtin_add_property(dev, test, "ID_MODEL_ID", product_id);
-        udev_builtin_add_property(dev, test, "ID_REVISION", revision_str);
-        udev_builtin_add_property(dev, test, "ID_SERIAL", serial);
-        if (serial_str[0] != '\0')
-                udev_builtin_add_property(dev, test, "ID_SERIAL_SHORT", serial_str);
-        if (type_str[0] != '\0')
-                udev_builtin_add_property(dev, test, "ID_TYPE", type_str);
-        if (instance_str[0] != '\0')
-                udev_builtin_add_property(dev, test, "ID_INSTANCE", instance_str);
-        udev_builtin_add_property(dev, test, "ID_BUS", "usb");
-        if (packed_if_str[0] != '\0')
-                udev_builtin_add_property(dev, test, "ID_USB_INTERFACES", packed_if_str);
-        if (ifnum != NULL)
-                udev_builtin_add_property(dev, test, "ID_USB_INTERFACE_NUM", ifnum);
-        if (driver != NULL)
-                udev_builtin_add_property(dev, test, "ID_USB_DRIVER", driver);
-        return EXIT_SUCCESS;
-}
-
-const struct udev_builtin udev_builtin_usb_id = {
-        .name = "usb_id",
-        .cmd = builtin_usb_id,
-        .help = "USB device properties",
-        .run_once = true,
-};
diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c
deleted file mode 100644 (file)
index fabc653..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2007-2012 Kay Sievers <kay@vrfy.org>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdio.h>
-#include <string.h>
-#include <getopt.h>
-
-#include "udev.h"
-
-static bool initialized;
-
-static const struct udev_builtin *builtins[] = {
-#ifdef HAVE_BLKID
-        [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
-#endif
-        [UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs,
-        [UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb,
-        [UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id,
-        [UDEV_BUILTIN_KEYBOARD] = &udev_builtin_keyboard,
-#ifdef HAVE_KMOD
-        [UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
-#endif
-        [UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id,
-        [UDEV_BUILTIN_NET_LINK] = &udev_builtin_net_setup_link,
-        [UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id,
-        [UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id,
-#ifdef HAVE_ACL
-        [UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess,
-#endif
-};
-
-void udev_builtin_init(struct udev *udev) {
-        unsigned int i;
-
-        if (initialized)
-                return;
-
-        for (i = 0; i < ELEMENTSOF(builtins); i++)
-                if (builtins[i]->init)
-                        builtins[i]->init(udev);
-
-        initialized = true;
-}
-
-void udev_builtin_exit(struct udev *udev) {
-        unsigned int i;
-
-        if (!initialized)
-                return;
-
-        for (i = 0; i < ELEMENTSOF(builtins); i++)
-                if (builtins[i]->exit)
-                        builtins[i]->exit(udev);
-
-        initialized = false;
-}
-
-bool udev_builtin_validate(struct udev *udev) {
-        unsigned int i;
-
-        for (i = 0; i < ELEMENTSOF(builtins); i++)
-                if (builtins[i]->validate && builtins[i]->validate(udev))
-                        return true;
-        return false;
-}
-
-void udev_builtin_list(struct udev *udev) {
-        unsigned int i;
-
-        for (i = 0; i < ELEMENTSOF(builtins); i++)
-                fprintf(stderr, "  %-14s  %s\n", builtins[i]->name, builtins[i]->help);
-}
-
-const char *udev_builtin_name(enum udev_builtin_cmd cmd) {
-        return builtins[cmd]->name;
-}
-
-bool udev_builtin_run_once(enum udev_builtin_cmd cmd) {
-        return builtins[cmd]->run_once;
-}
-
-enum udev_builtin_cmd udev_builtin_lookup(const char *command) {
-        char name[UTIL_PATH_SIZE];
-        enum udev_builtin_cmd i;
-        char *pos;
-
-        strscpy(name, sizeof(name), command);
-        pos = strchr(name, ' ');
-        if (pos)
-                pos[0] = '\0';
-        for (i = 0; i < ELEMENTSOF(builtins); i++)
-                if (streq(builtins[i]->name, name))
-                        return i;
-        return UDEV_BUILTIN_MAX;
-}
-
-int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test) {
-        char arg[UTIL_PATH_SIZE];
-        int argc;
-        char *argv[128];
-
-        /* we need '0' here to reset the internal state */
-        optind = 0;
-        strscpy(arg, sizeof(arg), command);
-        udev_build_argv(udev_device_get_udev(dev), arg, &argc, argv);
-        return builtins[cmd]->cmd(dev, argc, argv, test);
-}
-
-int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val) {
-        udev_device_add_property(dev, key, val);
-
-        if (test)
-                printf("%s=%s\n", key, val);
-        return 0;
-}
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
deleted file mode 100644 (file)
index 61d3c5b..0000000
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * libudev - interface to udev device information
- *
- * Copyright (C) 2008 Kay Sievers <kay@vrfy.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <unistd.h>
-#include <poll.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include "socket-util.h"
-#include "udev.h"
-
-/* wire protocol magic must match */
-#define UDEV_CTRL_MAGIC                                0xdead1dea
-
-enum udev_ctrl_msg_type {
-        UDEV_CTRL_UNKNOWN,
-        UDEV_CTRL_SET_LOG_LEVEL,
-        UDEV_CTRL_STOP_EXEC_QUEUE,
-        UDEV_CTRL_START_EXEC_QUEUE,
-        UDEV_CTRL_RELOAD,
-        UDEV_CTRL_SET_ENV,
-        UDEV_CTRL_SET_CHILDREN_MAX,
-        UDEV_CTRL_PING,
-        UDEV_CTRL_EXIT,
-};
-
-struct udev_ctrl_msg_wire {
-        char version[16];
-        unsigned int magic;
-        enum udev_ctrl_msg_type type;
-        union {
-                int intval;
-                char buf[256];
-        };
-};
-
-struct udev_ctrl_msg {
-        int refcount;
-        struct udev_ctrl_connection *conn;
-        struct udev_ctrl_msg_wire ctrl_msg_wire;
-};
-
-struct udev_ctrl {
-        int refcount;
-        struct udev *udev;
-        int sock;
-        union sockaddr_union saddr;
-        socklen_t addrlen;
-        bool bound;
-        bool cleanup_socket;
-        bool connected;
-};
-
-struct udev_ctrl_connection {
-        int refcount;
-        struct udev_ctrl *uctrl;
-        int sock;
-};
-
-struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) {
-        struct udev_ctrl *uctrl;
-        const int on = 1;
-        int r;
-
-        uctrl = new0(struct udev_ctrl, 1);
-        if (uctrl == NULL)
-                return NULL;
-        uctrl->refcount = 1;
-        uctrl->udev = udev;
-
-        if (fd < 0) {
-                uctrl->sock = socket(AF_LOCAL, SOCK_SEQPACKET|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
-                if (uctrl->sock < 0) {
-                        log_error_errno(errno, "error getting socket: %m");
-                        udev_ctrl_unref(uctrl);
-                        return NULL;
-                }
-        } else {
-                uctrl->bound = true;
-                uctrl->sock = fd;
-        }
-        r = setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
-        if (r < 0)
-                log_warning_errno(errno, "could not set SO_PASSCRED: %m");
-
-        uctrl->saddr.un.sun_family = AF_LOCAL;
-        strscpy(uctrl->saddr.un.sun_path, sizeof(uctrl->saddr.un.sun_path), "/run/udev/control");
-        uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.un.sun_path);
-        return uctrl;
-}
-
-struct udev_ctrl *udev_ctrl_new(struct udev *udev) {
-        return udev_ctrl_new_from_fd(udev, -1);
-}
-
-int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) {
-        int err;
-
-        if (!uctrl->bound) {
-                err = bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen);
-                if (err < 0 && errno == EADDRINUSE) {
-                        unlink(uctrl->saddr.un.sun_path);
-                        err = bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen);
-                }
-
-                if (err < 0) {
-                        err = -errno;
-                        log_error_errno(errno, "bind failed: %m");
-                        return err;
-                }
-
-                err = listen(uctrl->sock, 0);
-                if (err < 0) {
-                        err = -errno;
-                        log_error_errno(errno, "listen failed: %m");
-                        return err;
-                }
-
-                uctrl->bound = true;
-                uctrl->cleanup_socket = true;
-        }
-        return 0;
-}
-
-struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl) {
-        return uctrl->udev;
-}
-
-static struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl) {
-        if (uctrl == NULL)
-                return NULL;
-        uctrl->refcount++;
-        return uctrl;
-}
-
-struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl) {
-        if (uctrl == NULL)
-                return NULL;
-        uctrl->refcount--;
-        if (uctrl->refcount > 0)
-                return uctrl;
-        if (uctrl->sock >= 0)
-                close(uctrl->sock);
-        free(uctrl);
-        return NULL;
-}
-
-int udev_ctrl_cleanup(struct udev_ctrl *uctrl) {
-        if (uctrl == NULL)
-                return 0;
-        if (uctrl->cleanup_socket)
-                unlink(uctrl->saddr.un.sun_path);
-        return 0;
-}
-
-int udev_ctrl_get_fd(struct udev_ctrl *uctrl) {
-        if (uctrl == NULL)
-                return -EINVAL;
-        return uctrl->sock;
-}
-
-struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) {
-        struct udev_ctrl_connection *conn;
-        struct ucred ucred = {};
-        const int on = 1;
-        int r;
-
-        conn = new(struct udev_ctrl_connection, 1);
-        if (conn == NULL)
-                return NULL;
-        conn->refcount = 1;
-        conn->uctrl = uctrl;
-
-        conn->sock = accept4(uctrl->sock, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK);
-        if (conn->sock < 0) {
-                if (errno != EINTR)
-                        log_error_errno(errno, "unable to receive ctrl connection: %m");
-                goto err;
-        }
-
-        /* check peer credential of connection */
-        r = getpeercred(conn->sock, &ucred);
-        if (r < 0) {
-                log_error_errno(r, "unable to receive credentials of ctrl connection: %m");
-                goto err;
-        }
-        if (ucred.uid > 0) {
-                log_error("sender uid="UID_FMT", message ignored", ucred.uid);
-                goto err;
-        }
-
-        /* enable receiving of the sender credentials in the messages */
-        r = setsockopt(conn->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
-        if (r < 0)
-                log_warning_errno(errno, "could not set SO_PASSCRED: %m");
-
-        udev_ctrl_ref(uctrl);
-        return conn;
-err:
-        if (conn->sock >= 0)
-                close(conn->sock);
-        free(conn);
-        return NULL;
-}
-
-struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn) {
-        if (conn == NULL)
-                return NULL;
-        conn->refcount++;
-        return conn;
-}
-
-struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn) {
-        if (conn == NULL)
-                return NULL;
-        conn->refcount--;
-        if (conn->refcount > 0)
-                return conn;
-        if (conn->sock >= 0)
-                close(conn->sock);
-        udev_ctrl_unref(conn->uctrl);
-        free(conn);
-        return NULL;
-}
-
-static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int intval, const char *buf, int timeout) {
-        struct udev_ctrl_msg_wire ctrl_msg_wire;
-        int err = 0;
-
-        memzero(&ctrl_msg_wire, sizeof(struct udev_ctrl_msg_wire));
-        strcpy(ctrl_msg_wire.version, "udev-" VERSION);
-        ctrl_msg_wire.magic = UDEV_CTRL_MAGIC;
-        ctrl_msg_wire.type = type;
-
-        if (buf != NULL)
-                strscpy(ctrl_msg_wire.buf, sizeof(ctrl_msg_wire.buf), buf);
-        else
-                ctrl_msg_wire.intval = intval;
-
-        if (!uctrl->connected) {
-                if (connect(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen) < 0) {
-                        err = -errno;
-                        goto out;
-                }
-                uctrl->connected = true;
-        }
-        if (send(uctrl->sock, &ctrl_msg_wire, sizeof(ctrl_msg_wire), 0) < 0) {
-                err = -errno;
-                goto out;
-        }
-
-        /* wait for peer message handling or disconnect */
-        for (;;) {
-                struct pollfd pfd[1];
-                int r;
-
-                pfd[0].fd = uctrl->sock;
-                pfd[0].events = POLLIN;
-                r = poll(pfd, 1, timeout * MSEC_PER_SEC);
-                if (r  < 0) {
-                        if (errno == EINTR)
-                                continue;
-                        err = -errno;
-                        break;
-                }
-
-                if (r > 0 && pfd[0].revents & POLLERR) {
-                        err = -EIO;
-                        break;
-                }
-
-                if (r == 0)
-                        err = -ETIMEDOUT;
-                break;
-        }
-out:
-        return err;
-}
-
-int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority, int timeout) {
-        return ctrl_send(uctrl, UDEV_CTRL_SET_LOG_LEVEL, priority, NULL, timeout);
-}
-
-int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl, int timeout) {
-        return ctrl_send(uctrl, UDEV_CTRL_STOP_EXEC_QUEUE, 0, NULL, timeout);
-}
-
-int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl, int timeout) {
-        return ctrl_send(uctrl, UDEV_CTRL_START_EXEC_QUEUE, 0, NULL, timeout);
-}
-
-int udev_ctrl_send_reload(struct udev_ctrl *uctrl, int timeout) {
-        return ctrl_send(uctrl, UDEV_CTRL_RELOAD, 0, NULL, timeout);
-}
-
-int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key, int timeout) {
-        return ctrl_send(uctrl, UDEV_CTRL_SET_ENV, 0, key, timeout);
-}
-
-int udev_ctrl_send_set_children_max(struct udev_ctrl *uctrl, int count, int timeout) {
-        return ctrl_send(uctrl, UDEV_CTRL_SET_CHILDREN_MAX, count, NULL, timeout);
-}
-
-int udev_ctrl_send_ping(struct udev_ctrl *uctrl, int timeout) {
-        return ctrl_send(uctrl, UDEV_CTRL_PING, 0, NULL, timeout);
-}
-
-int udev_ctrl_send_exit(struct udev_ctrl *uctrl, int timeout) {
-        return ctrl_send(uctrl, UDEV_CTRL_EXIT, 0, NULL, timeout);
-}
-
-struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) {
-        struct udev_ctrl_msg *uctrl_msg;
-        ssize_t size;
-        struct cmsghdr *cmsg;
-        struct iovec iov;
-        char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
-        struct msghdr smsg = {
-                .msg_iov = &iov,
-                .msg_iovlen = 1,
-                .msg_control = cred_msg,
-                .msg_controllen = sizeof(cred_msg),
-        };
-        struct ucred *cred;
-
-        uctrl_msg = new0(struct udev_ctrl_msg, 1);
-        if (uctrl_msg == NULL)
-                return NULL;
-        uctrl_msg->refcount = 1;
-        uctrl_msg->conn = conn;
-        udev_ctrl_connection_ref(conn);
-
-        /* wait for the incoming message */
-        for (;;) {
-                struct pollfd pfd[1];
-                int r;
-
-                pfd[0].fd = conn->sock;
-                pfd[0].events = POLLIN;
-
-                r = poll(pfd, 1, 10000);
-                if (r  < 0) {
-                        if (errno == EINTR)
-                                continue;
-                        goto err;
-                } else if (r == 0) {
-                        log_error("timeout waiting for ctrl message");
-                        goto err;
-                } else {
-                        if (!(pfd[0].revents & POLLIN)) {
-                                log_error_errno(errno, "ctrl connection error: %m");
-                                goto err;
-                        }
-                }
-
-                break;
-        }
-
-        iov.iov_base = &uctrl_msg->ctrl_msg_wire;
-        iov.iov_len = sizeof(struct udev_ctrl_msg_wire);
-
-        size = recvmsg(conn->sock, &smsg, 0);
-        if (size <  0) {
-                log_error_errno(errno, "unable to receive ctrl message: %m");
-                goto err;
-        }
-
-        cmsg_close_all(&smsg);
-
-        cmsg = CMSG_FIRSTHDR(&smsg);
-        cred = (struct ucred *) CMSG_DATA(cmsg);
-
-        if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
-                log_error("no sender credentials received, message ignored");
-                goto err;
-        }
-
-        if (cred->uid != 0) {
-                log_error("sender uid="UID_FMT", message ignored", cred->uid);
-                goto err;
-        }
-
-        if (uctrl_msg->ctrl_msg_wire.magic != UDEV_CTRL_MAGIC) {
-                log_error("message magic 0x%08x doesn't match, ignore it", uctrl_msg->ctrl_msg_wire.magic);
-                goto err;
-        }
-
-        return uctrl_msg;
-err:
-        udev_ctrl_msg_unref(uctrl_msg);
-        return NULL;
-}
-
-struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg) {
-        if (ctrl_msg == NULL)
-                return NULL;
-        ctrl_msg->refcount--;
-        if (ctrl_msg->refcount > 0)
-                return ctrl_msg;
-        udev_ctrl_connection_unref(ctrl_msg->conn);
-        free(ctrl_msg);
-        return NULL;
-}
-
-int udev_ctrl_get_set_log_level(struct udev_ctrl_msg *ctrl_msg) {
-        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_LOG_LEVEL)
-                return ctrl_msg->ctrl_msg_wire.intval;
-        return -1;
-}
-
-int udev_ctrl_get_stop_exec_queue(struct udev_ctrl_msg *ctrl_msg) {
-        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_STOP_EXEC_QUEUE)
-                return 1;
-        return -1;
-}
-
-int udev_ctrl_get_start_exec_queue(struct udev_ctrl_msg *ctrl_msg) {
-        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_START_EXEC_QUEUE)
-                return 1;
-        return -1;
-}
-
-int udev_ctrl_get_reload(struct udev_ctrl_msg *ctrl_msg) {
-        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_RELOAD)
-                return 1;
-        return -1;
-}
-
-const char *udev_ctrl_get_set_env(struct udev_ctrl_msg *ctrl_msg) {
-        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_ENV)
-                return ctrl_msg->ctrl_msg_wire.buf;
-        return NULL;
-}
-
-int udev_ctrl_get_set_children_max(struct udev_ctrl_msg *ctrl_msg) {
-        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_CHILDREN_MAX)
-                return ctrl_msg->ctrl_msg_wire.intval;
-        return -1;
-}
-
-int udev_ctrl_get_ping(struct udev_ctrl_msg *ctrl_msg) {
-        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_PING)
-                return 1;
-        return -1;
-}
-
-int udev_ctrl_get_exit(struct udev_ctrl_msg *ctrl_msg) {
-        if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_EXIT)
-                return 1;
-        return -1;
-}
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
deleted file mode 100644 (file)
index 3a165b0..0000000
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * Copyright (C) 2003-2013 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <string.h>
-#include <net/if.h>
-#include <sys/prctl.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/wait.h>
-#include <sys/signalfd.h>
-
-#include "udev.h"
-#include "rtnl-util.h"
-
-struct udev_event *udev_event_new(struct udev_device *dev) {
-        struct udev *udev = udev_device_get_udev(dev);
-        struct udev_event *event;
-
-        event = new0(struct udev_event, 1);
-        if (event == NULL)
-                return NULL;
-        event->dev = dev;
-        event->udev = udev;
-        udev_list_init(udev, &event->run_list, false);
-        udev_list_init(udev, &event->seclabel_list, false);
-        event->fd_signal = -1;
-        event->birth_usec = now(CLOCK_MONOTONIC);
-        return event;
-}
-
-void udev_event_unref(struct udev_event *event) {
-        if (event == NULL)
-                return;
-        sd_rtnl_unref(event->rtnl);
-        udev_list_cleanup(&event->run_list);
-        udev_list_cleanup(&event->seclabel_list);
-        free(event->program_result);
-        free(event->name);
-        free(event);
-}
-
-size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size) {
-        struct udev_device *dev = event->dev;
-        enum subst_type {
-                SUBST_UNKNOWN,
-                SUBST_DEVNODE,
-                SUBST_ATTR,
-                SUBST_ENV,
-                SUBST_KERNEL,
-                SUBST_KERNEL_NUMBER,
-                SUBST_DRIVER,
-                SUBST_DEVPATH,
-                SUBST_ID,
-                SUBST_MAJOR,
-                SUBST_MINOR,
-                SUBST_RESULT,
-                SUBST_PARENT,
-                SUBST_NAME,
-                SUBST_LINKS,
-                SUBST_ROOT,
-                SUBST_SYS,
-        };
-        static const struct subst_map {
-                const char *name;
-                const char fmt;
-                enum subst_type type;
-        } map[] = {
-                { .name = "devnode",  .fmt = 'N', .type = SUBST_DEVNODE },
-                { .name = "tempnode", .fmt = 'N', .type = SUBST_DEVNODE },
-                { .name = "attr",     .fmt = 's', .type = SUBST_ATTR },
-                { .name = "sysfs",    .fmt = 's', .type = SUBST_ATTR },
-                { .name = "env",      .fmt = 'E', .type = SUBST_ENV },
-                { .name = "kernel",   .fmt = 'k', .type = SUBST_KERNEL },
-                { .name = "number",   .fmt = 'n', .type = SUBST_KERNEL_NUMBER },
-                { .name = "driver",   .fmt = 'd', .type = SUBST_DRIVER },
-                { .name = "devpath",  .fmt = 'p', .type = SUBST_DEVPATH },
-                { .name = "id",       .fmt = 'b', .type = SUBST_ID },
-                { .name = "major",    .fmt = 'M', .type = SUBST_MAJOR },
-                { .name = "minor",    .fmt = 'm', .type = SUBST_MINOR },
-                { .name = "result",   .fmt = 'c', .type = SUBST_RESULT },
-                { .name = "parent",   .fmt = 'P', .type = SUBST_PARENT },
-                { .name = "name",     .fmt = 'D', .type = SUBST_NAME },
-                { .name = "links",    .fmt = 'L', .type = SUBST_LINKS },
-                { .name = "root",     .fmt = 'r', .type = SUBST_ROOT },
-                { .name = "sys",      .fmt = 'S', .type = SUBST_SYS },
-        };
-        const char *from;
-        char *s;
-        size_t l;
-
-        from = src;
-        s = dest;
-        l = size;
-
-        for (;;) {
-                enum subst_type type = SUBST_UNKNOWN;
-                char attrbuf[UTIL_PATH_SIZE];
-                char *attr = NULL;
-
-                while (from[0] != '\0') {
-                        if (from[0] == '$') {
-                                /* substitute named variable */
-                                unsigned int i;
-
-                                if (from[1] == '$') {
-                                        from++;
-                                        goto copy;
-                                }
-
-                                for (i = 0; i < ELEMENTSOF(map); i++) {
-                                        if (startswith(&from[1], map[i].name)) {
-                                                type = map[i].type;
-                                                from += strlen(map[i].name)+1;
-                                                goto subst;
-                                        }
-                                }
-                        } else if (from[0] == '%') {
-                                /* substitute format char */
-                                unsigned int i;
-
-                                if (from[1] == '%') {
-                                        from++;
-                                        goto copy;
-                                }
-
-                                for (i = 0; i < ELEMENTSOF(map); i++) {
-                                        if (from[1] == map[i].fmt) {
-                                                type = map[i].type;
-                                                from += 2;
-                                                goto subst;
-                                        }
-                                }
-                        }
-copy:
-                        /* copy char */
-                        if (l == 0)
-                                goto out;
-                        s[0] = from[0];
-                        from++;
-                        s++;
-                        l--;
-                }
-
-                goto out;
-subst:
-                /* extract possible $format{attr} */
-                if (from[0] == '{') {
-                        unsigned int i;
-
-                        from++;
-                        for (i = 0; from[i] != '}'; i++) {
-                                if (from[i] == '\0') {
-                                        log_error("missing closing brace for format '%s'", src);
-                                        goto out;
-                                }
-                        }
-                        if (i >= sizeof(attrbuf))
-                                goto out;
-                        memcpy(attrbuf, from, i);
-                        attrbuf[i] = '\0';
-                        from += i+1;
-                        attr = attrbuf;
-                } else {
-                        attr = NULL;
-                }
-
-                switch (type) {
-                case SUBST_DEVPATH:
-                        l = strpcpy(&s, l, udev_device_get_devpath(dev));
-                        break;
-                case SUBST_KERNEL:
-                        l = strpcpy(&s, l, udev_device_get_sysname(dev));
-                        break;
-                case SUBST_KERNEL_NUMBER:
-                        if (udev_device_get_sysnum(dev) == NULL)
-                                break;
-                        l = strpcpy(&s, l, udev_device_get_sysnum(dev));
-                        break;
-                case SUBST_ID:
-                        if (event->dev_parent == NULL)
-                                break;
-                        l = strpcpy(&s, l, udev_device_get_sysname(event->dev_parent));
-                        break;
-                case SUBST_DRIVER: {
-                        const char *driver;
-
-                        if (event->dev_parent == NULL)
-                                break;
-
-                        driver = udev_device_get_driver(event->dev_parent);
-                        if (driver == NULL)
-                                break;
-                        l = strpcpy(&s, l, driver);
-                        break;
-                }
-                case SUBST_MAJOR: {
-                        char num[UTIL_PATH_SIZE];
-
-                        sprintf(num, "%u", major(udev_device_get_devnum(dev)));
-                        l = strpcpy(&s, l, num);
-                        break;
-                }
-                case SUBST_MINOR: {
-                        char num[UTIL_PATH_SIZE];
-
-                        sprintf(num, "%u", minor(udev_device_get_devnum(dev)));
-                        l = strpcpy(&s, l, num);
-                        break;
-                }
-                case SUBST_RESULT: {
-                        char *rest;
-                        int i;
-
-                        if (event->program_result == NULL)
-                                break;
-                        /* get part part of the result string */
-                        i = 0;
-                        if (attr != NULL)
-                                i = strtoul(attr, &rest, 10);
-                        if (i > 0) {
-                                char result[UTIL_PATH_SIZE];
-                                char tmp[UTIL_PATH_SIZE];
-                                char *cpos;
-
-                                strscpy(result, sizeof(result), event->program_result);
-                                cpos = result;
-                                while (--i) {
-                                        while (cpos[0] != '\0' && !isspace(cpos[0]))
-                                                cpos++;
-                                        while (isspace(cpos[0]))
-                                                cpos++;
-                                        if (cpos[0] == '\0')
-                                                break;
-                                }
-                                if (i > 0) {
-                                        log_error("requested part of result string not found");
-                                        break;
-                                }
-                                strscpy(tmp, sizeof(tmp), cpos);
-                                /* %{2+}c copies the whole string from the second part on */
-                                if (rest[0] != '+') {
-                                        cpos = strchr(tmp, ' ');
-                                        if (cpos)
-                                                cpos[0] = '\0';
-                                }
-                                l = strpcpy(&s, l, tmp);
-                        } else {
-                                l = strpcpy(&s, l, event->program_result);
-                        }
-                        break;
-                }
-                case SUBST_ATTR: {
-                        const char *value = NULL;
-                        char vbuf[UTIL_NAME_SIZE];
-                        size_t len;
-                        int count;
-
-                        if (attr == NULL) {
-                                log_error("missing file parameter for attr");
-                                break;
-                        }
-
-                        /* try to read the value specified by "[dmi/id]product_name" */
-                        if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0)
-                                value = vbuf;
-
-                        /* try to read the attribute the device */
-                        if (value == NULL)
-                                value = udev_device_get_sysattr_value(event->dev, attr);
-
-                        /* try to read the attribute of the parent device, other matches have selected */
-                        if (value == NULL && event->dev_parent != NULL && event->dev_parent != event->dev)
-                                value = udev_device_get_sysattr_value(event->dev_parent, attr);
-
-                        if (value == NULL)
-                                break;
-
-                        /* strip trailing whitespace, and replace unwanted characters */
-                        if (value != vbuf)
-                                strscpy(vbuf, sizeof(vbuf), value);
-                        len = strlen(vbuf);
-                        while (len > 0 && isspace(vbuf[--len]))
-                                vbuf[len] = '\0';
-                        count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
-                        if (count > 0)
-                                log_debug("%i character(s) replaced" , count);
-                        l = strpcpy(&s, l, vbuf);
-                        break;
-                }
-                case SUBST_PARENT: {
-                        struct udev_device *dev_parent;
-                        const char *devnode;
-
-                        dev_parent = udev_device_get_parent(event->dev);
-                        if (dev_parent == NULL)
-                                break;
-                        devnode = udev_device_get_devnode(dev_parent);
-                        if (devnode != NULL)
-                                l = strpcpy(&s, l, devnode + strlen("/dev/"));
-                        break;
-                }
-                case SUBST_DEVNODE:
-                        if (udev_device_get_devnode(dev) != NULL)
-                                l = strpcpy(&s, l, udev_device_get_devnode(dev));
-                        break;
-                case SUBST_NAME:
-                        if (event->name != NULL)
-                                l = strpcpy(&s, l, event->name);
-                        else if (udev_device_get_devnode(dev) != NULL)
-                                l = strpcpy(&s, l, udev_device_get_devnode(dev) + strlen("/dev/"));
-                        else
-                                l = strpcpy(&s, l, udev_device_get_sysname(dev));
-                        break;
-                case SUBST_LINKS: {
-                        struct udev_list_entry *list_entry;
-
-                        list_entry = udev_device_get_devlinks_list_entry(dev);
-                        if (list_entry == NULL)
-                                break;
-                        l = strpcpy(&s, l, udev_list_entry_get_name(list_entry) + strlen("/dev/"));
-                        udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
-                                l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry) + strlen("/dev/"), NULL);
-                        break;
-                }
-                case SUBST_ROOT:
-                        l = strpcpy(&s, l, "/dev");
-                        break;
-                case SUBST_SYS:
-                        l = strpcpy(&s, l, "/sys");
-                        break;
-                case SUBST_ENV:
-                        if (attr == NULL) {
-                                break;
-                        } else {
-                                const char *value;
-
-                                value = udev_device_get_property_value(event->dev, attr);
-                                if (value == NULL)
-                                        break;
-                                l = strpcpy(&s, l, value);
-                                break;
-                        }
-                default:
-                        log_error("unknown substitution type=%i", type);
-                        break;
-                }
-        }
-
-out:
-        s[0] = '\0';
-        return l;
-}
-
-static int spawn_exec(struct udev_event *event,
-                      const char *cmd, char *const argv[], char **envp, const sigset_t *sigmask,
-                      int fd_stdout, int fd_stderr) {
-        _cleanup_close_ int fd = -1;
-
-        /* discard child output or connect to pipe */
-        fd = open("/dev/null", O_RDWR);
-        if (fd >= 0) {
-                dup2(fd, STDIN_FILENO);
-                if (fd_stdout < 0)
-                        dup2(fd, STDOUT_FILENO);
-                if (fd_stderr < 0)
-                        dup2(fd, STDERR_FILENO);
-        } else
-                log_error_errno(errno, "open /dev/null failed: %m");
-
-        /* connect pipes to std{out,err} */
-        if (fd_stdout >= 0) {
-                dup2(fd_stdout, STDOUT_FILENO);
-                safe_close(fd_stdout);
-        }
-        if (fd_stderr >= 0) {
-                dup2(fd_stderr, STDERR_FILENO);
-                safe_close(fd_stderr);
-        }
-
-        /* terminate child in case parent goes away */
-        prctl(PR_SET_PDEATHSIG, SIGTERM);
-
-        /* restore original udev sigmask before exec */
-        if (sigmask)
-                sigprocmask(SIG_SETMASK, sigmask, NULL);
-
-        execve(argv[0], argv, envp);
-
-        /* exec failed */
-        log_error_errno(errno, "failed to execute '%s' '%s': %m", argv[0], cmd);
-
-        return -errno;
-}
-
-static void spawn_read(struct udev_event *event,
-                       usec_t timeout_usec,
-                       const char *cmd,
-                       int fd_stdout, int fd_stderr,
-                       char *result, size_t ressize) {
-        _cleanup_close_ int fd_ep = -1;
-        struct epoll_event ep_outpipe = {
-                .events = EPOLLIN,
-                .data.ptr = &fd_stdout,
-        };
-        struct epoll_event ep_errpipe = {
-                .events = EPOLLIN,
-                .data.ptr = &fd_stderr,
-        };
-        size_t respos = 0;
-        int r;
-
-        /* read from child if requested */
-        if (fd_stdout < 0 && fd_stderr < 0)
-                return;
-
-        fd_ep = epoll_create1(EPOLL_CLOEXEC);
-        if (fd_ep < 0) {
-                log_error_errno(errno, "error creating epoll fd: %m");
-                return;
-        }
-
-        if (fd_stdout >= 0) {
-                r = epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stdout, &ep_outpipe);
-                if (r < 0) {
-                        log_error_errno(errno, "fail to add stdout fd to epoll: %m");
-                        return;
-                }
-        }
-
-        if (fd_stderr >= 0) {
-                r = epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stderr, &ep_errpipe);
-                if (r < 0) {
-                        log_error_errno(errno, "fail to add stderr fd to epoll: %m");
-                        return;
-                }
-        }
-
-        /* read child output */
-        while (fd_stdout >= 0 || fd_stderr >= 0) {
-                int timeout;
-                int fdcount;
-                struct epoll_event ev[4];
-                int i;
-
-                if (timeout_usec > 0) {
-                        usec_t age_usec;
-
-                        age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
-                        if (age_usec >= timeout_usec) {
-                                log_error("timeout '%s'", cmd);
-                                return;
-                        }
-                        timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
-                } else {
-                        timeout = -1;
-                }
-
-                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
-                if (fdcount < 0) {
-                        if (errno == EINTR)
-                                continue;
-                        log_error_errno(errno, "failed to poll: %m");
-                        return;
-                } else if (fdcount == 0) {
-                        log_error("timeout '%s'", cmd);
-                        return;
-                }
-
-                for (i = 0; i < fdcount; i++) {
-                        int *fd = (int *)ev[i].data.ptr;
-
-                        if (*fd < 0)
-                                continue;
-
-                        if (ev[i].events & EPOLLIN) {
-                                ssize_t count;
-                                char buf[4096];
-
-                                count = read(*fd, buf, sizeof(buf)-1);
-                                if (count <= 0)
-                                        continue;
-                                buf[count] = '\0';
-
-                                /* store stdout result */
-                                if (result != NULL && *fd == fd_stdout) {
-                                        if (respos + count < ressize) {
-                                                memcpy(&result[respos], buf, count);
-                                                respos += count;
-                                        } else {
-                                                log_error("'%s' ressize %zu too short", cmd, ressize);
-                                        }
-                                }
-
-                                /* log debug output only if we watch stderr */
-                                if (fd_stderr >= 0) {
-                                        char *pos;
-                                        char *line;
-
-                                        pos = buf;
-                                        while ((line = strsep(&pos, "\n"))) {
-                                                if (pos != NULL || line[0] != '\0')
-                                                        log_debug("'%s'(%s) '%s'", cmd, *fd == fd_stdout ? "out" : "err" , line);
-                                        }
-                                }
-                        } else if (ev[i].events & EPOLLHUP) {
-                                r = epoll_ctl(fd_ep, EPOLL_CTL_DEL, *fd, NULL);
-                                if (r < 0) {
-                                        log_error_errno(errno, "failed to remove fd from epoll: %m");
-                                        return;
-                                }
-                                *fd = -1;
-                        }
-                }
-        }
-
-        /* return the child's stdout string */
-        if (result != NULL)
-                result[respos] = '\0';
-}
-
-static int spawn_wait(struct udev_event *event,
-                      usec_t timeout_usec,
-                      usec_t timeout_warn_usec,
-                      const char *cmd, pid_t pid) {
-        struct pollfd pfd[1];
-        int err = 0;
-
-        pfd[0].events = POLLIN;
-        pfd[0].fd = event->fd_signal;
-
-        while (pid > 0) {
-                int timeout;
-                int timeout_warn = 0;
-                int fdcount;
-
-                if (timeout_usec > 0) {
-                        usec_t age_usec;
-
-                        age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
-                        if (age_usec >= timeout_usec)
-                                timeout = 1000;
-                        else {
-                                if (timeout_warn_usec > 0)
-                                        timeout_warn = ((timeout_warn_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
-
-                                timeout = ((timeout_usec - timeout_warn_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
-                        }
-                } else {
-                        timeout = -1;
-                }
-
-                fdcount = poll(pfd, 1, timeout_warn);
-                if (fdcount < 0) {
-                        if (errno == EINTR)
-                                continue;
-                        err = -errno;
-                        log_error_errno(errno, "failed to poll: %m");
-                        goto out;
-                }
-                if (fdcount == 0) {
-                        log_warning("slow: '%s' ["PID_FMT"]", cmd, pid);
-
-                        fdcount = poll(pfd, 1, timeout);
-                        if (fdcount < 0) {
-                                if (errno == EINTR)
-                                        continue;
-                                err = -errno;
-                                log_error_errno(errno, "failed to poll: %m");
-                                goto out;
-                        }
-                        if (fdcount == 0) {
-                                log_error("timeout: killing '%s' ["PID_FMT"]", cmd, pid);
-                                kill(pid, SIGKILL);
-                        }
-                }
-
-                if (pfd[0].revents & POLLIN) {
-                        struct signalfd_siginfo fdsi;
-                        int status;
-                        ssize_t size;
-
-                        size = read(event->fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
-                        if (size != sizeof(struct signalfd_siginfo))
-                                continue;
-
-                        switch (fdsi.ssi_signo) {
-                        case SIGTERM:
-                                event->sigterm = true;
-                                break;
-                        case SIGCHLD:
-                                if (waitpid(pid, &status, WNOHANG) < 0)
-                                        break;
-                                if (WIFEXITED(status)) {
-                                        log_debug("'%s' ["PID_FMT"] exit with return code %i", cmd, pid, WEXITSTATUS(status));
-                                        if (WEXITSTATUS(status) != 0)
-                                                err = -1;
-                                } else if (WIFSIGNALED(status)) {
-                                        log_error("'%s' ["PID_FMT"] terminated by signal %i (%s)", cmd, pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
-                                        err = -1;
-                                } else if (WIFSTOPPED(status)) {
-                                        log_error("'%s' ["PID_FMT"] stopped", cmd, pid);
-                                        err = -1;
-                                } else if (WIFCONTINUED(status)) {
-                                        log_error("'%s' ["PID_FMT"] continued", cmd, pid);
-                                        err = -1;
-                                } else {
-                                        log_error("'%s' ["PID_FMT"] exit with status 0x%04x", cmd, pid, status);
-                                        err = -1;
-                                }
-                                pid = 0;
-                                break;
-                        }
-                }
-        }
-out:
-        return err;
-}
-
-int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]) {
-        int i = 0;
-        char *pos;
-
-        if (strchr(cmd, ' ') == NULL) {
-                argv[i++] = cmd;
-                goto out;
-        }
-
-        pos = cmd;
-        while (pos != NULL && pos[0] != '\0') {
-                if (pos[0] == '\'') {
-                        /* do not separate quotes */
-                        pos++;
-                        argv[i] = strsep(&pos, "\'");
-                        if (pos != NULL)
-                                while (pos[0] == ' ')
-                                        pos++;
-                } else {
-                        argv[i] = strsep(&pos, " ");
-                        if (pos != NULL)
-                                while (pos[0] == ' ')
-                                        pos++;
-                }
-                i++;
-        }
-out:
-        argv[i] = NULL;
-        if (argc)
-                *argc = i;
-        return 0;
-}
-
-int udev_event_spawn(struct udev_event *event,
-                     usec_t timeout_usec,
-                     usec_t timeout_warn_usec,
-                     const char *cmd, char **envp, const sigset_t *sigmask,
-                     char *result, size_t ressize) {
-        int outpipe[2] = {-1, -1};
-        int errpipe[2] = {-1, -1};
-        pid_t pid;
-        char arg[UTIL_PATH_SIZE];
-        char *argv[128];
-        char program[UTIL_PATH_SIZE];
-        int err = 0;
-
-        strscpy(arg, sizeof(arg), cmd);
-        udev_build_argv(event->udev, arg, NULL, argv);
-
-        /* pipes from child to parent */
-        if (result != NULL || log_get_max_level() >= LOG_INFO) {
-                if (pipe2(outpipe, O_NONBLOCK) != 0) {
-                        err = -errno;
-                        log_error_errno(errno, "pipe failed: %m");
-                        goto out;
-                }
-        }
-        if (log_get_max_level() >= LOG_INFO) {
-                if (pipe2(errpipe, O_NONBLOCK) != 0) {
-                        err = -errno;
-                        log_error_errno(errno, "pipe failed: %m");
-                        goto out;
-                }
-        }
-
-        /* allow programs in /usr/lib/udev/ to be called without the path */
-        if (argv[0][0] != '/') {
-                strscpyl(program, sizeof(program), UDEVLIBEXECDIR "/", argv[0], NULL);
-                argv[0] = program;
-        }
-
-        pid = fork();
-        switch(pid) {
-        case 0:
-                /* child closes parent's ends of pipes */
-                if (outpipe[READ_END] >= 0) {
-                        close(outpipe[READ_END]);
-                        outpipe[READ_END] = -1;
-                }
-                if (errpipe[READ_END] >= 0) {
-                        close(errpipe[READ_END]);
-                        errpipe[READ_END] = -1;
-                }
-
-                log_debug("starting '%s'", cmd);
-
-                spawn_exec(event, cmd, argv, envp, sigmask,
-                           outpipe[WRITE_END], errpipe[WRITE_END]);
-
-                _exit(2 );
-        case -1:
-                log_error_errno(errno, "fork of '%s' failed: %m", cmd);
-                err = -1;
-                goto out;
-        default:
-                /* parent closed child's ends of pipes */
-                if (outpipe[WRITE_END] >= 0) {
-                        close(outpipe[WRITE_END]);
-                        outpipe[WRITE_END] = -1;
-                }
-                if (errpipe[WRITE_END] >= 0) {
-                        close(errpipe[WRITE_END]);
-                        errpipe[WRITE_END] = -1;
-                }
-
-                spawn_read(event,
-                           timeout_usec,
-                           cmd,
-                           outpipe[READ_END], errpipe[READ_END],
-                           result, ressize);
-
-                err = spawn_wait(event, timeout_usec, timeout_warn_usec, cmd, pid);
-        }
-
-out:
-        if (outpipe[READ_END] >= 0)
-                close(outpipe[READ_END]);
-        if (outpipe[WRITE_END] >= 0)
-                close(outpipe[WRITE_END]);
-        if (errpipe[READ_END] >= 0)
-                close(errpipe[READ_END]);
-        if (errpipe[WRITE_END] >= 0)
-                close(errpipe[WRITE_END]);
-        return err;
-}
-
-static int rename_netif(struct udev_event *event) {
-        struct udev_device *dev = event->dev;
-        char name[IFNAMSIZ];
-        const char *oldname;
-        int r;
-
-        oldname = udev_device_get_sysname(dev);
-
-        strscpy(name, IFNAMSIZ, event->name);
-
-        r = rtnl_set_link_name(&event->rtnl, udev_device_get_ifindex(dev), name);
-        if (r < 0)
-                return log_error_errno(r, "Error changing net interface name '%s' to '%s': %m", oldname, name);
-
-        log_debug("renamed network interface '%s' to '%s'", oldname, name);
-
-        return 0;
-}
-
-void udev_event_execute_rules(struct udev_event *event,
-                              usec_t timeout_usec, usec_t timeout_warn_usec,
-                              struct udev_list *properties_list,
-                              struct udev_rules *rules,
-                              const sigset_t *sigmask) {
-        struct udev_device *dev = event->dev;
-
-        if (udev_device_get_subsystem(dev) == NULL)
-                return;
-
-        if (streq(udev_device_get_action(dev), "remove")) {
-                if (major(udev_device_get_devnum(dev)) != 0)
-                        udev_watch_end(event->udev, dev);
-
-                udev_rules_apply_to_event(rules, event,
-                                          timeout_usec, timeout_warn_usec,
-                                          properties_list,
-                                          sigmask);
-
-                if (major(udev_device_get_devnum(dev)) != 0)
-                        udev_node_remove(dev);
-
-                udev_device_delete_db(dev);
-                udev_device_tag_index(dev, NULL, false);
-        } else {
-                event->dev_db = udev_device_clone_with_db(dev);
-                if (event->dev_db != NULL) {
-                        /* disable watch during event processing */
-                        if (major(udev_device_get_devnum(dev)) != 0)
-                                udev_watch_end(event->udev, event->dev_db);
-                }
-
-                if (major(udev_device_get_devnum(dev)) == 0 &&
-                    streq(udev_device_get_action(dev), "move"))
-                        udev_device_copy_properties(dev, event->dev_db);
-
-                udev_rules_apply_to_event(rules, event,
-                                          timeout_usec, timeout_warn_usec,
-                                          properties_list,
-                                          sigmask);
-
-                /* rename a new network interface, if needed */
-                if (udev_device_get_ifindex(dev) > 0 && streq(udev_device_get_action(dev), "add") &&
-                    event->name != NULL && !streq(event->name, udev_device_get_sysname(dev))) {
-                        int r;
-
-                        r = rename_netif(event);
-                        if (r < 0)
-                                log_warning_errno(r, "could not rename interface '%d' from '%s' to '%s': %m", udev_device_get_ifindex(dev),
-                                                  udev_device_get_sysname(dev), event->name);
-                        else {
-                                r = udev_device_rename(dev, event->name);
-                                if (r < 0)
-                                        log_warning_errno(r, "renamed interface '%d' from '%s' to '%s', but could not update udev_device: %m",
-                                                          udev_device_get_ifindex(dev), udev_device_get_sysname(dev), event->name);
-                                else
-                                        log_debug("changed devpath to '%s'", udev_device_get_devpath(dev));
-                        }
-                }
-
-                if (major(udev_device_get_devnum(dev)) > 0) {
-                        bool apply;
-
-                        /* remove/update possible left-over symlinks from old database entry */
-                        if (event->dev_db != NULL)
-                                udev_node_update_old_links(dev, event->dev_db);
-
-                        if (!event->owner_set)
-                                event->uid = udev_device_get_devnode_uid(dev);
-
-                        if (!event->group_set)
-                                event->gid = udev_device_get_devnode_gid(dev);
-
-                        if (!event->mode_set) {
-                                if (udev_device_get_devnode_mode(dev) > 0) {
-                                        /* kernel supplied value */
-                                        event->mode = udev_device_get_devnode_mode(dev);
-                                } else if (event->gid > 0) {
-                                        /* default 0660 if a group is assigned */
-                                        event->mode = 0660;
-                                } else {
-                                        /* default 0600 */
-                                        event->mode = 0600;
-                                }
-                        }
-
-                        apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set;
-                        udev_node_add(dev, apply, event->mode, event->uid, event->gid, &event->seclabel_list);
-                }
-
-                /* preserve old, or get new initialization timestamp */
-                udev_device_ensure_usec_initialized(event->dev, event->dev_db);
-
-                /* (re)write database file */
-                udev_device_update_db(dev);
-                udev_device_tag_index(dev, event->dev_db, true);
-                udev_device_set_is_initialized(dev);
-
-                udev_device_unref(event->dev_db);
-                event->dev_db = NULL;
-        }
-}
-
-void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, const sigset_t *sigmask) {
-        struct udev_list_entry *list_entry;
-
-        udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
-                const char *cmd = udev_list_entry_get_name(list_entry);
-                enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry);
-
-                if (builtin_cmd < UDEV_BUILTIN_MAX) {
-                        char command[UTIL_PATH_SIZE];
-
-                        udev_event_apply_format(event, cmd, command, sizeof(command));
-                        udev_builtin_run(event->dev, builtin_cmd, command, false);
-                } else {
-                        char program[UTIL_PATH_SIZE];
-                        char **envp;
-
-                        if (event->exec_delay > 0) {
-                                log_debug("delay execution of '%s'", program);
-                                sleep(event->exec_delay);
-                        }
-
-                        udev_event_apply_format(event, cmd, program, sizeof(program));
-                        envp = udev_device_get_properties_envp(event->dev);
-                        udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, NULL, 0);
-                }
-        }
-}
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
deleted file mode 100644 (file)
index debf9ea..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright (C) 2003-2013 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dirent.h>
-#include <sys/stat.h>
-
-#include "udev.h"
-#include "smack-util.h"
-#include "selinux-util.h"
-
-static int node_symlink(struct udev_device *dev, const char *node, const char *slink) {
-        struct stat stats;
-        char target[UTIL_PATH_SIZE];
-        char *s;
-        size_t l;
-        char slink_tmp[UTIL_PATH_SIZE + 32];
-        int i = 0;
-        int tail = 0;
-        int err = 0;
-
-        /* use relative link */
-        target[0] = '\0';
-        while (node[i] && (node[i] == slink[i])) {
-                if (node[i] == '/')
-                        tail = i+1;
-                i++;
-        }
-        s = target;
-        l = sizeof(target);
-        while (slink[i] != '\0') {
-                if (slink[i] == '/')
-                        l = strpcpy(&s, l, "../");
-                i++;
-        }
-        l = strscpy(s, l, &node[tail]);
-        if (l == 0) {
-                err = -EINVAL;
-                goto exit;
-        }
-
-        /* preserve link with correct target, do not replace node of other device */
-        if (lstat(slink, &stats) == 0) {
-                if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) {
-                        log_error("conflicting device node '%s' found, link to '%s' will not be created", slink, node);
-                        goto exit;
-                } else if (S_ISLNK(stats.st_mode)) {
-                        char buf[UTIL_PATH_SIZE];
-                        int len;
-
-                        len = readlink(slink, buf, sizeof(buf));
-                        if (len > 0 && len < (int)sizeof(buf)) {
-                                buf[len] = '\0';
-                                if (streq(target, buf)) {
-                                        log_debug("preserve already existing symlink '%s' to '%s'", slink, target);
-                                        label_fix(slink, true, false);
-                                        utimensat(AT_FDCWD, slink, NULL, AT_SYMLINK_NOFOLLOW);
-                                        goto exit;
-                                }
-                        }
-                }
-        } else {
-                log_debug("creating symlink '%s' to '%s'", slink, target);
-                do {
-                        err = mkdir_parents_label(slink, 0755);
-                        if (err != 0 && err != -ENOENT)
-                                break;
-                        mac_selinux_create_file_prepare(slink, S_IFLNK);
-                        err = symlink(target, slink);
-                        if (err != 0)
-                                err = -errno;
-                        mac_selinux_create_file_clear();
-                } while (err == -ENOENT);
-                if (err == 0)
-                        goto exit;
-        }
-
-        log_debug("atomically replace '%s'", slink);
-        strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", udev_device_get_id_filename(dev), NULL);
-        unlink(slink_tmp);
-        do {
-                err = mkdir_parents_label(slink_tmp, 0755);
-                if (err != 0 && err != -ENOENT)
-                        break;
-                mac_selinux_create_file_prepare(slink_tmp, S_IFLNK);
-                err = symlink(target, slink_tmp);
-                if (err != 0)
-                        err = -errno;
-                mac_selinux_create_file_clear();
-        } while (err == -ENOENT);
-        if (err != 0) {
-                log_error_errno(errno, "symlink '%s' '%s' failed: %m", target, slink_tmp);
-                goto exit;
-        }
-        err = rename(slink_tmp, slink);
-        if (err != 0) {
-                log_error_errno(errno, "rename '%s' '%s' failed: %m", slink_tmp, slink);
-                unlink(slink_tmp);
-        }
-exit:
-        return err;
-}
-
-/* find device node of device with highest priority */
-static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize) {
-        struct udev *udev = udev_device_get_udev(dev);
-        DIR *dir;
-        int priority = 0;
-        const char *target = NULL;
-
-        if (add) {
-                priority = udev_device_get_devlink_priority(dev);
-                strscpy(buf, bufsize, udev_device_get_devnode(dev));
-                target = buf;
-        }
-
-        dir = opendir(stackdir);
-        if (dir == NULL)
-                return target;
-        for (;;) {
-                struct udev_device *dev_db;
-                struct dirent *dent;
-
-                dent = readdir(dir);
-                if (dent == NULL || dent->d_name[0] == '\0')
-                        break;
-                if (dent->d_name[0] == '.')
-                        continue;
-
-                log_debug("found '%s' claiming '%s'", dent->d_name, stackdir);
-
-                /* did we find ourself? */
-                if (streq(dent->d_name, udev_device_get_id_filename(dev)))
-                        continue;
-
-                dev_db = udev_device_new_from_device_id(udev, dent->d_name);
-                if (dev_db != NULL) {
-                        const char *devnode;
-
-                        devnode = udev_device_get_devnode(dev_db);
-                        if (devnode != NULL) {
-                                if (target == NULL || udev_device_get_devlink_priority(dev_db) > priority) {
-                                        log_debug("'%s' claims priority %i for '%s'",
-                                                  udev_device_get_syspath(dev_db), udev_device_get_devlink_priority(dev_db), stackdir);
-                                        priority = udev_device_get_devlink_priority(dev_db);
-                                        strscpy(buf, bufsize, devnode);
-                                        target = buf;
-                                }
-                        }
-                        udev_device_unref(dev_db);
-                }
-        }
-        closedir(dir);
-        return target;
-}
-
-/* manage "stack of names" with possibly specified device priorities */
-static void link_update(struct udev_device *dev, const char *slink, bool add) {
-        char name_enc[UTIL_PATH_SIZE];
-        char filename[UTIL_PATH_SIZE * 2];
-        char dirname[UTIL_PATH_SIZE];
-        const char *target;
-        char buf[UTIL_PATH_SIZE];
-
-        util_path_encode(slink + strlen("/dev"), name_enc, sizeof(name_enc));
-        strscpyl(dirname, sizeof(dirname), "/run/udev/links/", name_enc, NULL);
-        strscpyl(filename, sizeof(filename), dirname, "/", udev_device_get_id_filename(dev), NULL);
-
-        if (!add && unlink(filename) == 0)
-                rmdir(dirname);
-
-        target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf));
-        if (target == NULL) {
-                log_debug("no reference left, remove '%s'", slink);
-                if (unlink(slink) == 0)
-                        rmdir_parents(slink, "/");
-        } else {
-                log_debug("creating link '%s' to '%s'", slink, target);
-                node_symlink(dev, target, slink);
-        }
-
-        if (add) {
-                int err;
-
-                do {
-                        int fd;
-
-                        err = mkdir_parents(filename, 0755);
-                        if (err != 0 && err != -ENOENT)
-                                break;
-                        fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
-                        if (fd >= 0)
-                                close(fd);
-                        else
-                                err = -errno;
-                } while (err == -ENOENT);
-        }
-}
-
-void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old) {
-        struct udev_list_entry *list_entry;
-
-        /* update possible left-over symlinks */
-        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev_old)) {
-                const char *name = udev_list_entry_get_name(list_entry);
-                struct udev_list_entry *list_entry_current;
-                int found;
-
-                /* check if old link name still belongs to this device */
-                found = 0;
-                udev_list_entry_foreach(list_entry_current, udev_device_get_devlinks_list_entry(dev)) {
-                        const char *name_current = udev_list_entry_get_name(list_entry_current);
-
-                        if (streq(name, name_current)) {
-                                found = 1;
-                                break;
-                        }
-                }
-                if (found)
-                        continue;
-
-                log_debug("update old name, '%s' no longer belonging to '%s'",
-                     name, udev_device_get_devpath(dev));
-                link_update(dev, name, false);
-        }
-}
-
-static int node_permissions_apply(struct udev_device *dev, bool apply,
-                                  mode_t mode, uid_t uid, gid_t gid,
-                                  struct udev_list *seclabel_list) {
-        const char *devnode = udev_device_get_devnode(dev);
-        dev_t devnum = udev_device_get_devnum(dev);
-        struct stat stats;
-        struct udev_list_entry *entry;
-        int err = 0;
-
-        if (streq(udev_device_get_subsystem(dev), "block"))
-                mode |= S_IFBLK;
-        else
-                mode |= S_IFCHR;
-
-        if (lstat(devnode, &stats) != 0) {
-                err = -errno;
-                log_debug_errno(errno, "can not stat() node '%s' (%m)", devnode);
-                goto out;
-        }
-
-        if (((stats.st_mode & S_IFMT) != (mode & S_IFMT)) || (stats.st_rdev != devnum)) {
-                err = -EEXIST;
-                log_debug("found node '%s' with non-matching devnum %s, skip handling",
-                          udev_device_get_devnode(dev), udev_device_get_id_filename(dev));
-                goto out;
-        }
-
-        if (apply) {
-                bool selinux = false;
-                bool smack = false;
-
-                if ((stats.st_mode & 0777) != (mode & 0777) || stats.st_uid != uid || stats.st_gid != gid) {
-                        log_debug("set permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
-                        err = chmod(devnode, mode);
-                        if (err < 0)
-                                log_warning_errno(errno, "setting mode of %s to %#o failed: %m", devnode, mode);
-                        err = chown(devnode, uid, gid);
-                        if (err < 0)
-                                log_warning_errno(errno, "setting owner of %s to uid=%u, gid=%u failed: %m", devnode, uid, gid);
-                } else {
-                        log_debug("preserve permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
-                }
-
-                /* apply SECLABEL{$module}=$label */
-                udev_list_entry_foreach(entry, udev_list_get_entry(seclabel_list)) {
-                        const char *name, *label;
-                        int r;
-
-                        name = udev_list_entry_get_name(entry);
-                        label = udev_list_entry_get_value(entry);
-
-                        if (streq(name, "selinux")) {
-                                selinux = true;
-
-                                r = mac_selinux_apply(devnode, label);
-                                if (r < 0)
-                                        log_error_errno(r, "SECLABEL: failed to set SELinux label '%s': %m", label);
-                                else
-                                        log_debug("SECLABEL: set SELinux label '%s'", label);
-
-                        } else if (streq(name, "smack")) {
-                                smack = true;
-
-                                r = mac_smack_apply(devnode, label);
-                                if (r < 0)
-                                        log_error_errno(r, "SECLABEL: failed to set SMACK label '%s': %m", label);
-                                else
-                                        log_debug("SECLABEL: set SMACK label '%s'", label);
-
-                        } else
-                                log_error("SECLABEL: unknown subsystem, ignoring '%s'='%s'", name, label);
-                }
-
-                /* set the defaults */
-                if (!selinux)
-                        mac_selinux_fix(devnode, true, false);
-                if (!smack)
-                        mac_smack_apply(devnode, NULL);
-        }
-
-        /* always update timestamp when we re-use the node, like on media change events */
-        utimensat(AT_FDCWD, devnode, NULL, 0);
-out:
-        return err;
-}
-
-void udev_node_add(struct udev_device *dev, bool apply,
-                   mode_t mode, uid_t uid, gid_t gid,
-                   struct udev_list *seclabel_list) {
-        char filename[UTIL_PATH_SIZE];
-        struct udev_list_entry *list_entry;
-
-        log_debug("handling device node '%s', devnum=%s, mode=%#o, uid="UID_FMT", gid="GID_FMT,
-                  udev_device_get_devnode(dev), udev_device_get_id_filename(dev), mode, uid, gid);
-
-        if (node_permissions_apply(dev, apply, mode, uid, gid, seclabel_list) < 0)
-                return;
-
-        /* always add /dev/{block,char}/$major:$minor */
-        snprintf(filename, sizeof(filename), "/dev/%s/%u:%u",
-                 streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
-                 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
-        node_symlink(dev, udev_device_get_devnode(dev), filename);
-
-        /* create/update symlinks, add symlinks to name index */
-        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
-                        link_update(dev, udev_list_entry_get_name(list_entry), true);
-}
-
-void udev_node_remove(struct udev_device *dev) {
-        struct udev_list_entry *list_entry;
-        char filename[UTIL_PATH_SIZE];
-
-        /* remove/update symlinks, remove symlinks from name index */
-        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
-                link_update(dev, udev_list_entry_get_name(list_entry), false);
-
-        /* remove /dev/{block,char}/$major:$minor */
-        snprintf(filename, sizeof(filename), "/dev/%s/%u:%u",
-                 streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
-                 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
-        unlink(filename);
-}
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
deleted file mode 100644 (file)
index 4262119..0000000
+++ /dev/null
@@ -1,2763 +0,0 @@
-/*
- * Copyright (C) 2003-2012 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stddef.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dirent.h>
-#include <fnmatch.h>
-#include <time.h>
-
-#include "udev.h"
-#include "path-util.h"
-#include "conf-files.h"
-#include "strbuf.h"
-#include "strv.h"
-#include "util.h"
-#include "sysctl-util.h"
-
-#define PREALLOC_TOKEN          2048
-
-struct uid_gid {
-        unsigned int name_off;
-        union {
-                uid_t uid;
-                gid_t gid;
-        };
-};
-
-static const char* const rules_dirs[] = {
-        "/etc/udev/rules.d",
-        "/run/udev/rules.d",
-        UDEVLIBEXECDIR "/rules.d",
-        NULL};
-
-struct udev_rules {
-        struct udev *udev;
-        usec_t dirs_ts_usec;
-        int resolve_names;
-
-        /* every key in the rules file becomes a token */
-        struct token *tokens;
-        unsigned int token_cur;
-        unsigned int token_max;
-
-        /* all key strings are copied and de-duplicated in a single continuous string buffer */
-        struct strbuf *strbuf;
-
-        /* during rule parsing, uid/gid lookup results are cached */
-        struct uid_gid *uids;
-        unsigned int uids_cur;
-        unsigned int uids_max;
-        struct uid_gid *gids;
-        unsigned int gids_cur;
-        unsigned int gids_max;
-};
-
-static char *rules_str(struct udev_rules *rules, unsigned int off) {
-        return rules->strbuf->buf + off;
-}
-
-static unsigned int rules_add_string(struct udev_rules *rules, const char *s) {
-        return strbuf_add_string(rules->strbuf, s, strlen(s));
-}
-
-/* KEY=="", KEY!="", KEY+="", KEY-="", KEY="", KEY:="" */
-enum operation_type {
-        OP_UNSET,
-
-        OP_MATCH,
-        OP_NOMATCH,
-        OP_MATCH_MAX,
-
-        OP_ADD,
-        OP_REMOVE,
-        OP_ASSIGN,
-        OP_ASSIGN_FINAL,
-};
-
-enum string_glob_type {
-        GL_UNSET,
-        GL_PLAIN,                       /* no special chars */
-        GL_GLOB,                        /* shell globs ?,*,[] */
-        GL_SPLIT,                       /* multi-value A|B */
-        GL_SPLIT_GLOB,                  /* multi-value with glob A*|B* */
-        GL_SOMETHING,                   /* commonly used "?*" */
-};
-
-enum string_subst_type {
-        SB_UNSET,
-        SB_NONE,
-        SB_FORMAT,
-        SB_SUBSYS,
-};
-
-/* tokens of a rule are sorted/handled in this order */
-enum token_type {
-        TK_UNSET,
-        TK_RULE,
-
-        TK_M_ACTION,                    /* val */
-        TK_M_DEVPATH,                   /* val */
-        TK_M_KERNEL,                    /* val */
-        TK_M_DEVLINK,                   /* val */
-        TK_M_NAME,                      /* val */
-        TK_M_ENV,                       /* val, attr */
-        TK_M_TAG,                       /* val */
-        TK_M_SUBSYSTEM,                 /* val */
-        TK_M_DRIVER,                    /* val */
-        TK_M_WAITFOR,                   /* val */
-        TK_M_ATTR,                      /* val, attr */
-        TK_M_SYSCTL,                    /* val, attr */
-
-        TK_M_PARENTS_MIN,
-        TK_M_KERNELS,                   /* val */
-        TK_M_SUBSYSTEMS,                /* val */
-        TK_M_DRIVERS,                   /* val */
-        TK_M_ATTRS,                     /* val, attr */
-        TK_M_TAGS,                      /* val */
-        TK_M_PARENTS_MAX,
-
-        TK_M_TEST,                      /* val, mode_t */
-        TK_M_PROGRAM,                   /* val */
-        TK_M_IMPORT_FILE,               /* val */
-        TK_M_IMPORT_PROG,               /* val */
-        TK_M_IMPORT_BUILTIN,            /* val */
-        TK_M_IMPORT_DB,                 /* val */
-        TK_M_IMPORT_CMDLINE,            /* val */
-        TK_M_IMPORT_PARENT,             /* val */
-        TK_M_RESULT,                    /* val */
-        TK_M_MAX,
-
-        TK_A_STRING_ESCAPE_NONE,
-        TK_A_STRING_ESCAPE_REPLACE,
-        TK_A_DB_PERSIST,
-        TK_A_INOTIFY_WATCH,             /* int */
-        TK_A_DEVLINK_PRIO,              /* int */
-        TK_A_OWNER,                     /* val */
-        TK_A_GROUP,                     /* val */
-        TK_A_MODE,                      /* val */
-        TK_A_OWNER_ID,                  /* uid_t */
-        TK_A_GROUP_ID,                  /* gid_t */
-        TK_A_MODE_ID,                   /* mode_t */
-        TK_A_TAG,                       /* val */
-        TK_A_STATIC_NODE,               /* val */
-        TK_A_SECLABEL,                  /* val, attr */
-        TK_A_ENV,                       /* val, attr */
-        TK_A_NAME,                      /* val */
-        TK_A_DEVLINK,                   /* val */
-        TK_A_ATTR,                      /* val, attr */
-        TK_A_SYSCTL,                    /* val, attr */
-        TK_A_RUN_BUILTIN,               /* val, bool */
-        TK_A_RUN_PROGRAM,               /* val, bool */
-        TK_A_GOTO,                      /* size_t */
-
-        TK_END,
-};
-
-/* we try to pack stuff in a way that we take only 12 bytes per token */
-struct token {
-        union {
-                unsigned char type;                /* same in rule and key */
-                struct {
-                        enum token_type type:8;
-                        bool can_set_name:1;
-                        bool has_static_node:1;
-                        unsigned int unused:6;
-                        unsigned short token_count;
-                        unsigned int label_off;
-                        unsigned short filename_off;
-                        unsigned short filename_line;
-                } rule;
-                struct {
-                        enum token_type type:8;
-                        enum operation_type op:8;
-                        enum string_glob_type glob:8;
-                        enum string_subst_type subst:4;
-                        enum string_subst_type attrsubst:4;
-                        unsigned int value_off;
-                        union {
-                                unsigned int attr_off;
-                                unsigned int rule_goto;
-                                mode_t  mode;
-                                uid_t uid;
-                                gid_t gid;
-                                int devlink_prio;
-                                int watch;
-                                enum udev_builtin_cmd builtin_cmd;
-                        };
-                } key;
-        };
-};
-
-#define MAX_TK                64
-struct rule_tmp {
-        struct udev_rules *rules;
-        struct token rule;
-        struct token token[MAX_TK];
-        unsigned int token_cur;
-};
-
-#ifdef DEBUG
-static const char *operation_str(enum operation_type type) {
-        static const char *operation_strs[] = {
-                [OP_UNSET] =            "UNSET",
-                [OP_MATCH] =            "match",
-                [OP_NOMATCH] =          "nomatch",
-                [OP_MATCH_MAX] =        "MATCH_MAX",
-
-                [OP_ADD] =              "add",
-                [OP_REMOVE] =           "remove",
-                [OP_ASSIGN] =           "assign",
-                [OP_ASSIGN_FINAL] =     "assign-final",
-}        ;
-
-        return operation_strs[type];
-}
-
-static const char *string_glob_str(enum string_glob_type type) {
-        static const char *string_glob_strs[] = {
-                [GL_UNSET] =            "UNSET",
-                [GL_PLAIN] =            "plain",
-                [GL_GLOB] =             "glob",
-                [GL_SPLIT] =            "split",
-                [GL_SPLIT_GLOB] =       "split-glob",
-                [GL_SOMETHING] =        "split-glob",
-        };
-
-        return string_glob_strs[type];
-}
-
-static const char *token_str(enum token_type type) {
-        static const char *token_strs[] = {
-                [TK_UNSET] =                    "UNSET",
-                [TK_RULE] =                     "RULE",
-
-                [TK_M_ACTION] =                 "M ACTION",
-                [TK_M_DEVPATH] =                "M DEVPATH",
-                [TK_M_KERNEL] =                 "M KERNEL",
-                [TK_M_DEVLINK] =                "M DEVLINK",
-                [TK_M_NAME] =                   "M NAME",
-                [TK_M_ENV] =                    "M ENV",
-                [TK_M_TAG] =                    "M TAG",
-                [TK_M_SUBSYSTEM] =              "M SUBSYSTEM",
-                [TK_M_DRIVER] =                 "M DRIVER",
-                [TK_M_WAITFOR] =                "M WAITFOR",
-                [TK_M_ATTR] =                   "M ATTR",
-                [TK_M_SYSCTL] =                 "M SYSCTL",
-
-                [TK_M_PARENTS_MIN] =            "M PARENTS_MIN",
-                [TK_M_KERNELS] =                "M KERNELS",
-                [TK_M_SUBSYSTEMS] =             "M SUBSYSTEMS",
-                [TK_M_DRIVERS] =                "M DRIVERS",
-                [TK_M_ATTRS] =                  "M ATTRS",
-                [TK_M_TAGS] =                   "M TAGS",
-                [TK_M_PARENTS_MAX] =            "M PARENTS_MAX",
-
-                [TK_M_TEST] =                   "M TEST",
-                [TK_M_PROGRAM] =                "M PROGRAM",
-                [TK_M_IMPORT_FILE] =            "M IMPORT_FILE",
-                [TK_M_IMPORT_PROG] =            "M IMPORT_PROG",
-                [TK_M_IMPORT_BUILTIN] =         "M IMPORT_BUILTIN",
-                [TK_M_IMPORT_DB] =              "M IMPORT_DB",
-                [TK_M_IMPORT_CMDLINE] =         "M IMPORT_CMDLINE",
-                [TK_M_IMPORT_PARENT] =          "M IMPORT_PARENT",
-                [TK_M_RESULT] =                 "M RESULT",
-                [TK_M_MAX] =                    "M MAX",
-
-                [TK_A_STRING_ESCAPE_NONE] =     "A STRING_ESCAPE_NONE",
-                [TK_A_STRING_ESCAPE_REPLACE] =  "A STRING_ESCAPE_REPLACE",
-                [TK_A_DB_PERSIST] =             "A DB_PERSIST",
-                [TK_A_INOTIFY_WATCH] =          "A INOTIFY_WATCH",
-                [TK_A_DEVLINK_PRIO] =           "A DEVLINK_PRIO",
-                [TK_A_OWNER] =                  "A OWNER",
-                [TK_A_GROUP] =                  "A GROUP",
-                [TK_A_MODE] =                   "A MODE",
-                [TK_A_OWNER_ID] =               "A OWNER_ID",
-                [TK_A_GROUP_ID] =               "A GROUP_ID",
-                [TK_A_STATIC_NODE] =            "A STATIC_NODE",
-                [TK_A_SECLABEL] =               "A SECLABEL",
-                [TK_A_MODE_ID] =                "A MODE_ID",
-                [TK_A_ENV] =                    "A ENV",
-                [TK_A_TAG] =                    "A ENV",
-                [TK_A_NAME] =                   "A NAME",
-                [TK_A_DEVLINK] =                "A DEVLINK",
-                [TK_A_ATTR] =                   "A ATTR",
-                [TK_A_SYSCTL] =                 "A SYSCTL",
-                [TK_A_RUN_BUILTIN] =            "A RUN_BUILTIN",
-                [TK_A_RUN_PROGRAM] =            "A RUN_PROGRAM",
-                [TK_A_GOTO] =                   "A GOTO",
-
-                [TK_END] =                      "END",
-        };
-
-        return token_strs[type];
-}
-
-static void dump_token(struct udev_rules *rules, struct token *token) {
-        enum token_type type = token->type;
-        enum operation_type op = token->key.op;
-        enum string_glob_type glob = token->key.glob;
-        const char *value = str(rules, token->key.value_off);
-        const char *attr = &rules->buf[token->key.attr_off];
-
-        switch (type) {
-        case TK_RULE:
-                {
-                        const char *tks_ptr = (char *)rules->tokens;
-                        const char *tk_ptr = (char *)token;
-                        unsigned int idx = (tk_ptr - tks_ptr) / sizeof(struct token);
-
-                        log_debug("* RULE %s:%u, token: %u, count: %u, label: '%s'",
-                                  &rules->buf[token->rule.filename_off], token->rule.filename_line,
-                                  idx, token->rule.token_count,
-                                  &rules->buf[token->rule.label_off]);
-                        break;
-                }
-        case TK_M_ACTION:
-        case TK_M_DEVPATH:
-        case TK_M_KERNEL:
-        case TK_M_SUBSYSTEM:
-        case TK_M_DRIVER:
-        case TK_M_WAITFOR:
-        case TK_M_DEVLINK:
-        case TK_M_NAME:
-        case TK_M_KERNELS:
-        case TK_M_SUBSYSTEMS:
-        case TK_M_DRIVERS:
-        case TK_M_TAGS:
-        case TK_M_PROGRAM:
-        case TK_M_IMPORT_FILE:
-        case TK_M_IMPORT_PROG:
-        case TK_M_IMPORT_DB:
-        case TK_M_IMPORT_CMDLINE:
-        case TK_M_IMPORT_PARENT:
-        case TK_M_RESULT:
-        case TK_A_NAME:
-        case TK_A_DEVLINK:
-        case TK_A_OWNER:
-        case TK_A_GROUP:
-        case TK_A_MODE:
-        case TK_A_RUN_BUILTIN:
-        case TK_A_RUN_PROGRAM:
-                log_debug("%s %s '%s'(%s)",
-                          token_str(type), operation_str(op), value, string_glob_str(glob));
-                break;
-        case TK_M_IMPORT_BUILTIN:
-                log_debug("%s %i '%s'", token_str(type), token->key.builtin_cmd, value);
-                break;
-        case TK_M_ATTR:
-        case TK_M_SYSCTL:
-        case TK_M_ATTRS:
-        case TK_M_ENV:
-        case TK_A_ATTR:
-        case TK_A_SYSCTL:
-        case TK_A_ENV:
-                log_debug("%s %s '%s' '%s'(%s)",
-                          token_str(type), operation_str(op), attr, value, string_glob_str(glob));
-                break;
-        case TK_M_TAG:
-        case TK_A_TAG:
-                log_debug("%s %s '%s'", token_str(type), operation_str(op), value);
-                break;
-        case TK_A_STRING_ESCAPE_NONE:
-        case TK_A_STRING_ESCAPE_REPLACE:
-        case TK_A_DB_PERSIST:
-                log_debug("%s", token_str(type));
-                break;
-        case TK_M_TEST:
-                log_debug("%s %s '%s'(%s) %#o",
-                          token_str(type), operation_str(op), value, string_glob_str(glob), token->key.mode);
-                break;
-        case TK_A_INOTIFY_WATCH:
-                log_debug("%s %u", token_str(type), token->key.watch);
-                break;
-        case TK_A_DEVLINK_PRIO:
-                log_debug("%s %u", token_str(type), token->key.devlink_prio);
-                break;
-        case TK_A_OWNER_ID:
-                log_debug("%s %s %u", token_str(type), operation_str(op), token->key.uid);
-                break;
-        case TK_A_GROUP_ID:
-                log_debug("%s %s %u", token_str(type), operation_str(op), token->key.gid);
-                break;
-        case TK_A_MODE_ID:
-                log_debug("%s %s %#o", token_str(type), operation_str(op), token->key.mode);
-                break;
-        case TK_A_STATIC_NODE:
-                log_debug("%s '%s'", token_str(type), value);
-                break;
-        case TK_A_SECLABEL:
-                log_debug("%s %s '%s' '%s'", token_str(type), operation_str(op), attr, value);
-                break;
-        case TK_A_GOTO:
-                log_debug("%s '%s' %u", token_str(type), value, token->key.rule_goto);
-                break;
-        case TK_END:
-                log_debug("* %s", token_str(type));
-                break;
-        case TK_M_PARENTS_MIN:
-        case TK_M_PARENTS_MAX:
-        case TK_M_MAX:
-        case TK_UNSET:
-                log_debug("unknown type %u", type);
-                break;
-        }
-}
-
-static void dump_rules(struct udev_rules *rules) {
-        unsigned int i;
-
-        log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings",
-                  rules->token_cur,
-                  rules->token_cur * sizeof(struct token),
-                  rules->buf_count,
-                  rules->buf_cur);
-        for (i = 0; i < rules->token_cur; i++)
-                dump_token(rules, &rules->tokens[i]);
-}
-#else
-static inline void dump_token(struct udev_rules *rules, struct token *token) {}
-static inline void dump_rules(struct udev_rules *rules) {}
-#endif /* DEBUG */
-
-static int add_token(struct udev_rules *rules, struct token *token) {
-        /* grow buffer if needed */
-        if (rules->token_cur+1 >= rules->token_max) {
-                struct token *tokens;
-                unsigned int add;
-
-                /* double the buffer size */
-                add = rules->token_max;
-                if (add < 8)
-                        add = 8;
-
-                tokens = realloc(rules->tokens, (rules->token_max + add ) * sizeof(struct token));
-                if (tokens == NULL)
-                        return -1;
-                rules->tokens = tokens;
-                rules->token_max += add;
-        }
-        memcpy(&rules->tokens[rules->token_cur], token, sizeof(struct token));
-        rules->token_cur++;
-        return 0;
-}
-
-static uid_t add_uid(struct udev_rules *rules, const char *owner) {
-        unsigned int i;
-        uid_t uid = 0;
-        unsigned int off;
-        int r;
-
-        /* lookup, if we know it already */
-        for (i = 0; i < rules->uids_cur; i++) {
-                off = rules->uids[i].name_off;
-                if (streq(rules_str(rules, off), owner)) {
-                        uid = rules->uids[i].uid;
-                        return uid;
-                }
-        }
-        r = get_user_creds(&owner, &uid, NULL, NULL, NULL);
-        if (r < 0) {
-                if (r == -ENOENT || r == -ESRCH)
-                        log_error("specified user '%s' unknown", owner);
-                else
-                        log_error_errno(r, "error resolving user '%s': %m", owner);
-        }
-
-        /* grow buffer if needed */
-        if (rules->uids_cur+1 >= rules->uids_max) {
-                struct uid_gid *uids;
-                unsigned int add;
-
-                /* double the buffer size */
-                add = rules->uids_max;
-                if (add < 1)
-                        add = 8;
-
-                uids = realloc(rules->uids, (rules->uids_max + add ) * sizeof(struct uid_gid));
-                if (uids == NULL)
-                        return uid;
-                rules->uids = uids;
-                rules->uids_max += add;
-        }
-        rules->uids[rules->uids_cur].uid = uid;
-        off = rules_add_string(rules, owner);
-        if (off <= 0)
-                return uid;
-        rules->uids[rules->uids_cur].name_off = off;
-        rules->uids_cur++;
-        return uid;
-}
-
-static gid_t add_gid(struct udev_rules *rules, const char *group) {
-        unsigned int i;
-        gid_t gid = 0;
-        unsigned int off;
-        int r;
-
-        /* lookup, if we know it already */
-        for (i = 0; i < rules->gids_cur; i++) {
-                off = rules->gids[i].name_off;
-                if (streq(rules_str(rules, off), group)) {
-                        gid = rules->gids[i].gid;
-                        return gid;
-                }
-        }
-        r = get_group_creds(&group, &gid);
-        if (r < 0) {
-                if (r == -ENOENT || r == -ESRCH)
-                        log_error("specified group '%s' unknown", group);
-                else
-                        log_error_errno(r, "error resolving group '%s': %m", group);
-        }
-
-        /* grow buffer if needed */
-        if (rules->gids_cur+1 >= rules->gids_max) {
-                struct uid_gid *gids;
-                unsigned int add;
-
-                /* double the buffer size */
-                add = rules->gids_max;
-                if (add < 1)
-                        add = 8;
-
-                gids = realloc(rules->gids, (rules->gids_max + add ) * sizeof(struct uid_gid));
-                if (gids == NULL)
-                        return gid;
-                rules->gids = gids;
-                rules->gids_max += add;
-        }
-        rules->gids[rules->gids_cur].gid = gid;
-        off = rules_add_string(rules, group);
-        if (off <= 0)
-                return gid;
-        rules->gids[rules->gids_cur].name_off = off;
-        rules->gids_cur++;
-        return gid;
-}
-
-static int import_property_from_string(struct udev_device *dev, char *line) {
-        char *key;
-        char *val;
-        size_t len;
-
-        /* find key */
-        key = line;
-        while (isspace(key[0]))
-                key++;
-
-        /* comment or empty line */
-        if (key[0] == '#' || key[0] == '\0')
-                return -1;
-
-        /* split key/value */
-        val = strchr(key, '=');
-        if (val == NULL)
-                return -1;
-        val[0] = '\0';
-        val++;
-
-        /* find value */
-        while (isspace(val[0]))
-                val++;
-
-        /* terminate key */
-        len = strlen(key);
-        if (len == 0)
-                return -1;
-        while (isspace(key[len-1]))
-                len--;
-        key[len] = '\0';
-
-        /* terminate value */
-        len = strlen(val);
-        if (len == 0)
-                return -1;
-        while (isspace(val[len-1]))
-                len--;
-        val[len] = '\0';
-
-        if (len == 0)
-                return -1;
-
-        /* unquote */
-        if (val[0] == '"' || val[0] == '\'') {
-                if (val[len-1] != val[0]) {
-                        log_debug("inconsistent quoting: '%s', skip", line);
-                        return -1;
-                }
-                val[len-1] = '\0';
-                val++;
-        }
-
-        udev_device_add_property(dev, key, val);
-
-        return 0;
-}
-
-static int import_file_into_properties(struct udev_device *dev, const char *filename) {
-        FILE *f;
-        char line[UTIL_LINE_SIZE];
-
-        f = fopen(filename, "re");
-        if (f == NULL)
-                return -1;
-        while (fgets(line, sizeof(line), f) != NULL)
-                import_property_from_string(dev, line);
-        fclose(f);
-        return 0;
-}
-
-static int import_program_into_properties(struct udev_event *event,
-                                          usec_t timeout_usec,
-                                          usec_t timeout_warn_usec,
-                                          const char *program, const sigset_t *sigmask) {
-        struct udev_device *dev = event->dev;
-        char **envp;
-        char result[UTIL_LINE_SIZE];
-        char *line;
-        int err;
-
-        envp = udev_device_get_properties_envp(dev);
-        err = udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, result, sizeof(result));
-        if (err < 0)
-                return err;
-
-        line = result;
-        while (line != NULL) {
-                char *pos;
-
-                pos = strchr(line, '\n');
-                if (pos != NULL) {
-                        pos[0] = '\0';
-                        pos = &pos[1];
-                }
-                import_property_from_string(dev, line);
-                line = pos;
-        }
-        return 0;
-}
-
-static int import_parent_into_properties(struct udev_device *dev, const char *filter) {
-        struct udev_device *dev_parent;
-        struct udev_list_entry *list_entry;
-
-        dev_parent = udev_device_get_parent(dev);
-        if (dev_parent == NULL)
-                return -1;
-
-        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev_parent)) {
-                const char *key = udev_list_entry_get_name(list_entry);
-                const char *val = udev_list_entry_get_value(list_entry);
-
-                if (fnmatch(filter, key, 0) == 0) {
-                        udev_device_add_property(dev, key, val);
-                }
-        }
-        return 0;
-}
-
-#define WAIT_LOOP_PER_SECOND                50
-static int wait_for_file(struct udev_device *dev, const char *file, int timeout) {
-        char filepath[UTIL_PATH_SIZE];
-        char devicepath[UTIL_PATH_SIZE];
-        struct stat stats;
-        int loop = timeout * WAIT_LOOP_PER_SECOND;
-
-        /* a relative path is a device attribute */
-        devicepath[0] = '\0';
-        if (file[0] != '/') {
-                strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL);
-                strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL);
-                file = filepath;
-        }
-
-        while (--loop) {
-                const struct timespec duration = { 0, 1000 * 1000 * 1000 / WAIT_LOOP_PER_SECOND };
-
-                /* lookup file */
-                if (stat(file, &stats) == 0) {
-                        log_debug("file '%s' appeared after %i loops", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
-                        return 0;
-                }
-                /* make sure, the device did not disappear in the meantime */
-                if (devicepath[0] != '\0' && stat(devicepath, &stats) != 0) {
-                        log_debug("device disappeared while waiting for '%s'", file);
-                        return -2;
-                }
-                log_debug("wait for '%s' for %i mseconds", file, 1000 / WAIT_LOOP_PER_SECOND);
-                nanosleep(&duration, NULL);
-        }
-        log_debug("waiting for '%s' failed", file);
-        return -1;
-}
-
-static int attr_subst_subdir(char *attr, size_t len) {
-        bool found = false;
-
-        if (strstr(attr, "/*/")) {
-                char *pos;
-                char dirname[UTIL_PATH_SIZE];
-                const char *tail;
-                DIR *dir;
-
-                strscpy(dirname, sizeof(dirname), attr);
-                pos = strstr(dirname, "/*/");
-                if (pos == NULL)
-                        return -1;
-                pos[0] = '\0';
-                tail = &pos[2];
-                dir = opendir(dirname);
-                if (dir != NULL) {
-                        struct dirent *dent;
-
-                        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
-                                struct stat stats;
-
-                                if (dent->d_name[0] == '.')
-                                        continue;
-                                strscpyl(attr, len, dirname, "/", dent->d_name, tail, NULL);
-                                if (stat(attr, &stats) == 0) {
-                                        found = true;
-                                        break;
-                                }
-                        }
-                        closedir(dir);
-                }
-        }
-
-        return found;
-}
-
-static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value) {
-        char *linepos;
-        char *temp;
-
-        linepos = *line;
-        if (linepos == NULL || linepos[0] == '\0')
-                return -1;
-
-        /* skip whitespace */
-        while (isspace(linepos[0]) || linepos[0] == ',')
-                linepos++;
-
-        /* get the key */
-        if (linepos[0] == '\0')
-                return -1;
-        *key = linepos;
-
-        for (;;) {
-                linepos++;
-                if (linepos[0] == '\0')
-                        return -1;
-                if (isspace(linepos[0]))
-                        break;
-                if (linepos[0] == '=')
-                        break;
-                if ((linepos[0] == '+') || (linepos[0] == '-') || (linepos[0] == '!') || (linepos[0] == ':'))
-                        if (linepos[1] == '=')
-                                break;
-        }
-
-        /* remember end of key */
-        temp = linepos;
-
-        /* skip whitespace after key */
-        while (isspace(linepos[0]))
-                linepos++;
-        if (linepos[0] == '\0')
-                return -1;
-
-        /* get operation type */
-        if (linepos[0] == '=' && linepos[1] == '=') {
-                *op = OP_MATCH;
-                linepos += 2;
-        } else if (linepos[0] == '!' && linepos[1] == '=') {
-                *op = OP_NOMATCH;
-                linepos += 2;
-        } else if (linepos[0] == '+' && linepos[1] == '=') {
-                *op = OP_ADD;
-                linepos += 2;
-        } else if (linepos[0] == '-' && linepos[1] == '=') {
-                *op = OP_REMOVE;
-                linepos += 2;
-        } else if (linepos[0] == '=') {
-                *op = OP_ASSIGN;
-                linepos++;
-        } else if (linepos[0] == ':' && linepos[1] == '=') {
-                *op = OP_ASSIGN_FINAL;
-                linepos += 2;
-        } else
-                return -1;
-
-        /* terminate key */
-        temp[0] = '\0';
-
-        /* skip whitespace after operator */
-        while (isspace(linepos[0]))
-                linepos++;
-        if (linepos[0] == '\0')
-                return -1;
-
-        /* get the value */
-        if (linepos[0] == '"')
-                linepos++;
-        else
-                return -1;
-        *value = linepos;
-
-        /* terminate */
-        temp = strchr(linepos, '"');
-        if (!temp)
-                return -1;
-        temp[0] = '\0';
-        temp++;
-
-        /* move line to next key */
-        *line = temp;
-        return 0;
-}
-
-/* extract possible KEY{attr} */
-static const char *get_key_attribute(struct udev *udev, char *str) {
-        char *pos;
-        char *attr;
-
-        attr = strchr(str, '{');
-        if (attr != NULL) {
-                attr++;
-                pos = strchr(attr, '}');
-                if (pos == NULL) {
-                        log_error("missing closing brace for format");
-                        return NULL;
-                }
-                pos[0] = '\0';
-                return attr;
-        }
-        return NULL;
-}
-
-static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
-                        enum operation_type op,
-                        const char *value, const void *data) {
-        struct token *token = &rule_tmp->token[rule_tmp->token_cur];
-        const char *attr = NULL;
-
-        memzero(token, sizeof(struct token));
-
-        switch (type) {
-        case TK_M_ACTION:
-        case TK_M_DEVPATH:
-        case TK_M_KERNEL:
-        case TK_M_SUBSYSTEM:
-        case TK_M_DRIVER:
-        case TK_M_WAITFOR:
-        case TK_M_DEVLINK:
-        case TK_M_NAME:
-        case TK_M_KERNELS:
-        case TK_M_SUBSYSTEMS:
-        case TK_M_DRIVERS:
-        case TK_M_TAGS:
-        case TK_M_PROGRAM:
-        case TK_M_IMPORT_FILE:
-        case TK_M_IMPORT_PROG:
-        case TK_M_IMPORT_DB:
-        case TK_M_IMPORT_CMDLINE:
-        case TK_M_IMPORT_PARENT:
-        case TK_M_RESULT:
-        case TK_A_OWNER:
-        case TK_A_GROUP:
-        case TK_A_MODE:
-        case TK_A_DEVLINK:
-        case TK_A_NAME:
-        case TK_A_GOTO:
-        case TK_M_TAG:
-        case TK_A_TAG:
-        case TK_A_STATIC_NODE:
-                token->key.value_off = rules_add_string(rule_tmp->rules, value);
-                break;
-        case TK_M_IMPORT_BUILTIN:
-                token->key.value_off = rules_add_string(rule_tmp->rules, value);
-                token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
-                break;
-        case TK_M_ENV:
-        case TK_M_ATTR:
-        case TK_M_SYSCTL:
-        case TK_M_ATTRS:
-        case TK_A_ATTR:
-        case TK_A_SYSCTL:
-        case TK_A_ENV:
-        case TK_A_SECLABEL:
-                attr = data;
-                token->key.value_off = rules_add_string(rule_tmp->rules, value);
-                token->key.attr_off = rules_add_string(rule_tmp->rules, attr);
-                break;
-        case TK_M_TEST:
-                token->key.value_off = rules_add_string(rule_tmp->rules, value);
-                if (data != NULL)
-                        token->key.mode = *(mode_t *)data;
-                break;
-        case TK_A_STRING_ESCAPE_NONE:
-        case TK_A_STRING_ESCAPE_REPLACE:
-        case TK_A_DB_PERSIST:
-                break;
-        case TK_A_RUN_BUILTIN:
-        case TK_A_RUN_PROGRAM:
-                token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
-                token->key.value_off = rules_add_string(rule_tmp->rules, value);
-                break;
-        case TK_A_INOTIFY_WATCH:
-        case TK_A_DEVLINK_PRIO:
-                token->key.devlink_prio = *(int *)data;
-                break;
-        case TK_A_OWNER_ID:
-                token->key.uid = *(uid_t *)data;
-                break;
-        case TK_A_GROUP_ID:
-                token->key.gid = *(gid_t *)data;
-                break;
-        case TK_A_MODE_ID:
-                token->key.mode = *(mode_t *)data;
-                break;
-        case TK_RULE:
-        case TK_M_PARENTS_MIN:
-        case TK_M_PARENTS_MAX:
-        case TK_M_MAX:
-        case TK_END:
-        case TK_UNSET:
-                log_error("wrong type %u", type);
-                return -1;
-        }
-
-        if (value != NULL && type < TK_M_MAX) {
-                /* check if we need to split or call fnmatch() while matching rules */
-                enum string_glob_type glob;
-                int has_split;
-                int has_glob;
-
-                has_split = (strchr(value, '|') != NULL);
-                has_glob = string_is_glob(value);
-                if (has_split && has_glob) {
-                        glob = GL_SPLIT_GLOB;
-                } else if (has_split) {
-                        glob = GL_SPLIT;
-                } else if (has_glob) {
-                        if (streq(value, "?*"))
-                                glob = GL_SOMETHING;
-                        else
-                                glob = GL_GLOB;
-                } else {
-                        glob = GL_PLAIN;
-                }
-                token->key.glob = glob;
-        }
-
-        if (value != NULL && type > TK_M_MAX) {
-                /* check if assigned value has substitution chars */
-                if (value[0] == '[')
-                        token->key.subst = SB_SUBSYS;
-                else if (strchr(value, '%') != NULL || strchr(value, '$') != NULL)
-                        token->key.subst = SB_FORMAT;
-                else
-                        token->key.subst = SB_NONE;
-        }
-
-        if (attr != NULL) {
-                /* check if property/attribute name has substitution chars */
-                if (attr[0] == '[')
-                        token->key.attrsubst = SB_SUBSYS;
-                else if (strchr(attr, '%') != NULL || strchr(attr, '$') != NULL)
-                        token->key.attrsubst = SB_FORMAT;
-                else
-                        token->key.attrsubst = SB_NONE;
-        }
-
-        token->key.type = type;
-        token->key.op = op;
-        rule_tmp->token_cur++;
-        if (rule_tmp->token_cur >= ELEMENTSOF(rule_tmp->token)) {
-                log_error("temporary rule array too small");
-                return -1;
-        }
-        return 0;
-}
-
-static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp) {
-        unsigned int i;
-        unsigned int start = 0;
-        unsigned int end = rule_tmp->token_cur;
-
-        for (i = 0; i < rule_tmp->token_cur; i++) {
-                enum token_type next_val = TK_UNSET;
-                unsigned int next_idx = 0;
-                unsigned int j;
-
-                /* find smallest value */
-                for (j = start; j < end; j++) {
-                        if (rule_tmp->token[j].type == TK_UNSET)
-                                continue;
-                        if (next_val == TK_UNSET || rule_tmp->token[j].type < next_val) {
-                                next_val = rule_tmp->token[j].type;
-                                next_idx = j;
-                        }
-                }
-
-                /* add token and mark done */
-                if (add_token(rules, &rule_tmp->token[next_idx]) != 0)
-                        return -1;
-                rule_tmp->token[next_idx].type = TK_UNSET;
-
-                /* shrink range */
-                if (next_idx == start)
-                        start++;
-                if (next_idx+1 == end)
-                        end--;
-        }
-        return 0;
-}
-
-static int add_rule(struct udev_rules *rules, char *line,
-                    const char *filename, unsigned int filename_off, unsigned int lineno) {
-        char *linepos;
-        const char *attr;
-        struct rule_tmp rule_tmp = {
-                .rules = rules,
-                .rule.type = TK_RULE,
-        };
-
-        /* the offset in the rule is limited to unsigned short */
-        if (filename_off < USHRT_MAX)
-                rule_tmp.rule.rule.filename_off = filename_off;
-        rule_tmp.rule.rule.filename_line = lineno;
-
-        linepos = line;
-        for (;;) {
-                char *key;
-                char *value;
-                enum operation_type op;
-
-                if (get_key(rules->udev, &linepos, &key, &op, &value) != 0) {
-                        /* Avoid erroring on trailing whitespace. This is probably rare
-                         * so save the work for the error case instead of always trying
-                         * to strip the trailing whitespace with strstrip(). */
-                        while (isblank(*linepos))
-                                linepos++;
-
-                        /* If we aren't at the end of the line, this is a parsing error.
-                         * Make a best effort to describe where the problem is. */
-                        if (!strchr(NEWLINE, *linepos)) {
-                                char buf[2] = {*linepos};
-                                _cleanup_free_ char *tmp;
-
-                                tmp = cescape(buf);
-                                log_error("invalid key/value pair in file %s on line %u, starting at character %tu ('%s')",
-                                          filename, lineno, linepos - line + 1, tmp);
-                                if (*linepos == '#')
-                                        log_error("hint: comments can only start at beginning of line");
-                        }
-                        break;
-                }
-
-                if (streq(key, "ACTION")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid ACTION operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_ACTION, op, value, NULL);
-                        continue;
-                }
-
-                if (streq(key, "DEVPATH")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid DEVPATH operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_DEVPATH, op, value, NULL);
-                        continue;
-                }
-
-                if (streq(key, "KERNEL")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid KERNEL operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_KERNEL, op, value, NULL);
-                        continue;
-                }
-
-                if (streq(key, "SUBSYSTEM")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid SUBSYSTEM operation");
-                                goto invalid;
-                        }
-                        /* bus, class, subsystem events should all be the same */
-                        if (streq(value, "subsystem") ||
-                            streq(value, "bus") ||
-                            streq(value, "class")) {
-                                if (streq(value, "bus") || streq(value, "class"))
-                                        log_error("'%s' must be specified as 'subsystem' "
-                                            "please fix it in %s:%u", value, filename, lineno);
-                                rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, "subsystem|class|bus", NULL);
-                        } else
-                                rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, value, NULL);
-                        continue;
-                }
-
-                if (streq(key, "DRIVER")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid DRIVER operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL);
-                        continue;
-                }
-
-                if (startswith(key, "ATTR{")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("ATTR"));
-                        if (attr == NULL) {
-                                log_error("error parsing ATTR attribute");
-                                goto invalid;
-                        }
-                        if (op == OP_REMOVE) {
-                                log_error("invalid ATTR operation");
-                                goto invalid;
-                        }
-                        if (op < OP_MATCH_MAX)
-                                rule_add_key(&rule_tmp, TK_M_ATTR, op, value, attr);
-                        else
-                                rule_add_key(&rule_tmp, TK_A_ATTR, op, value, attr);
-                        continue;
-                }
-
-                if (startswith(key, "SYSCTL{")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("SYSCTL"));
-                        if (attr == NULL) {
-                                log_error("error parsing SYSCTL attribute");
-                                goto invalid;
-                        }
-                        if (op == OP_REMOVE) {
-                                log_error("invalid SYSCTL operation");
-                                goto invalid;
-                        }
-                        if (op < OP_MATCH_MAX)
-                                rule_add_key(&rule_tmp, TK_M_SYSCTL, op, value, attr);
-                        else
-                                rule_add_key(&rule_tmp, TK_A_SYSCTL, op, value, attr);
-                        continue;
-                }
-
-                if (startswith(key, "SECLABEL{")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("SECLABEL"));
-                        if (!attr) {
-                                log_error("error parsing SECLABEL attribute");
-                                goto invalid;
-                        }
-                        if (op == OP_REMOVE) {
-                                log_error("invalid SECLABEL operation");
-                                goto invalid;
-                        }
-
-                        rule_add_key(&rule_tmp, TK_A_SECLABEL, op, value, attr);
-                        continue;
-                }
-
-                if (streq(key, "KERNELS")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid KERNELS operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL);
-                        continue;
-                }
-
-                if (streq(key, "SUBSYSTEMS")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid SUBSYSTEMS operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL);
-                        continue;
-                }
-
-                if (streq(key, "DRIVERS")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid DRIVERS operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_DRIVERS, op, value, NULL);
-                        continue;
-                }
-
-                if (startswith(key, "ATTRS{")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid ATTRS operation");
-                                goto invalid;
-                        }
-                        attr = get_key_attribute(rules->udev, key + strlen("ATTRS"));
-                        if (attr == NULL) {
-                                log_error("error parsing ATTRS attribute");
-                                goto invalid;
-                        }
-                        if (startswith(attr, "device/"))
-                                log_error("the 'device' link may not be available in a future kernel, "
-                                    "please fix it in %s:%u", filename, lineno);
-                        else if (strstr(attr, "../") != NULL)
-                                log_error("do not reference parent sysfs directories directly, "
-                                    "it may break with a future kernel, please fix it in %s:%u", filename, lineno);
-                        rule_add_key(&rule_tmp, TK_M_ATTRS, op, value, attr);
-                        continue;
-                }
-
-                if (streq(key, "TAGS")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid TAGS operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL);
-                        continue;
-                }
-
-                if (startswith(key, "ENV{")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("ENV"));
-                        if (attr == NULL) {
-                                log_error("error parsing ENV attribute");
-                                goto invalid;
-                        }
-                        if (op == OP_REMOVE) {
-                                log_error("invalid ENV operation");
-                                goto invalid;
-                        }
-                        if (op < OP_MATCH_MAX) {
-                                if (rule_add_key(&rule_tmp, TK_M_ENV, op, value, attr) != 0)
-                                        goto invalid;
-                        } else {
-                                static const char *blacklist[] = {
-                                        "ACTION",
-                                        "SUBSYSTEM",
-                                        "DEVTYPE",
-                                        "MAJOR",
-                                        "MINOR",
-                                        "DRIVER",
-                                        "IFINDEX",
-                                        "DEVNAME",
-                                        "DEVLINKS",
-                                        "DEVPATH",
-                                        "TAGS",
-                                };
-                                unsigned int i;
-
-                                for (i = 0; i < ELEMENTSOF(blacklist); i++) {
-                                        if (!streq(attr, blacklist[i]))
-                                                continue;
-                                        log_error("invalid ENV attribute, '%s' can not be set %s:%u", attr, filename, lineno);
-                                        goto invalid;
-                                }
-                                if (rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr) != 0)
-                                        goto invalid;
-                        }
-                        continue;
-                }
-
-                if (streq(key, "TAG")) {
-                        if (op < OP_MATCH_MAX)
-                                rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL);
-                        else
-                                rule_add_key(&rule_tmp, TK_A_TAG, op, value, NULL);
-                        continue;
-                }
-
-                if (streq(key, "PROGRAM")) {
-                        if (op == OP_REMOVE) {
-                                log_error("invalid PROGRAM operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL);
-                        continue;
-                }
-
-                if (streq(key, "RESULT")) {
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid RESULT operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL);
-                        continue;
-                }
-
-                if (startswith(key, "IMPORT")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("IMPORT"));
-                        if (attr == NULL) {
-                                log_error("IMPORT{} type missing, ignoring IMPORT %s:%u", filename, lineno);
-                                continue;
-                        }
-                        if (op == OP_REMOVE) {
-                                log_error("invalid IMPORT operation");
-                                goto invalid;
-                        }
-                        if (streq(attr, "program")) {
-                                /* find known built-in command */
-                                if (value[0] != '/') {
-                                        enum udev_builtin_cmd cmd;
-
-                                        cmd = udev_builtin_lookup(value);
-                                        if (cmd < UDEV_BUILTIN_MAX) {
-                                                log_debug("IMPORT found builtin '%s', replacing %s:%u",
-                                                          value, filename, lineno);
-                                                rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
-                                                continue;
-                                        }
-                                }
-                                rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL);
-                        } else if (streq(attr, "builtin")) {
-                                enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
-
-                                if (cmd < UDEV_BUILTIN_MAX)
-                                        rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
-                                else
-                                        log_error("IMPORT{builtin}: '%s' unknown %s:%u", value, filename, lineno);
-                        } else if (streq(attr, "file")) {
-                                rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL);
-                        } else if (streq(attr, "db")) {
-                                rule_add_key(&rule_tmp, TK_M_IMPORT_DB, op, value, NULL);
-                        } else if (streq(attr, "cmdline")) {
-                                rule_add_key(&rule_tmp, TK_M_IMPORT_CMDLINE, op, value, NULL);
-                        } else if (streq(attr, "parent")) {
-                                rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL);
-                        } else
-                                log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u", filename, lineno);
-                        continue;
-                }
-
-                if (startswith(key, "TEST")) {
-                        mode_t mode = 0;
-
-                        if (op > OP_MATCH_MAX) {
-                                log_error("invalid TEST operation");
-                                goto invalid;
-                        }
-                        attr = get_key_attribute(rules->udev, key + strlen("TEST"));
-                        if (attr != NULL) {
-                                mode = strtol(attr, NULL, 8);
-                                rule_add_key(&rule_tmp, TK_M_TEST, op, value, &mode);
-                        } else {
-                                rule_add_key(&rule_tmp, TK_M_TEST, op, value, NULL);
-                        }
-                        continue;
-                }
-
-                if (startswith(key, "RUN")) {
-                        attr = get_key_attribute(rules->udev, key + strlen("RUN"));
-                        if (attr == NULL)
-                                attr = "program";
-                        if (op == OP_REMOVE) {
-                                log_error("invalid RUN operation");
-                                goto invalid;
-                        }
-
-                        if (streq(attr, "builtin")) {
-                                enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
-
-                                if (cmd < UDEV_BUILTIN_MAX)
-                                        rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd);
-                                else
-                                        log_error("RUN{builtin}: '%s' unknown %s:%u", value, filename, lineno);
-                        } else if (streq(attr, "program")) {
-                                enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX;
-
-                                rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd);
-                        } else {
-                                log_error("RUN{} unknown type, ignoring RUN %s:%u", filename, lineno);
-                        }
-
-                        continue;
-                }
-
-                if (streq(key, "WAIT_FOR") || streq(key, "WAIT_FOR_SYSFS")) {
-                        if (op == OP_REMOVE) {
-                                log_error("invalid WAIT_FOR/WAIT_FOR_SYSFS operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL);
-                        continue;
-                }
-
-                if (streq(key, "LABEL")) {
-                        if (op == OP_REMOVE) {
-                                log_error("invalid LABEL operation");
-                                goto invalid;
-                        }
-                        rule_tmp.rule.rule.label_off = rules_add_string(rules, value);
-                        continue;
-                }
-
-                if (streq(key, "GOTO")) {
-                        if (op == OP_REMOVE) {
-                                log_error("invalid GOTO operation");
-                                goto invalid;
-                        }
-                        rule_add_key(&rule_tmp, TK_A_GOTO, 0, value, NULL);
-                        continue;
-                }
-
-                if (startswith(key, "NAME")) {
-                        if (op == OP_REMOVE) {
-                                log_error("invalid NAME operation");
-                                goto invalid;
-                        }
-                        if (op < OP_MATCH_MAX) {
-                                rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL);
-                        } else {
-                                if (streq(value, "%k")) {
-                                        log_error("NAME=\"%%k\" is ignored, because it breaks kernel supplied names, "
-                                            "please remove it from %s:%u\n", filename, lineno);
-                                        continue;
-                                }
-                                if (value[0] == '\0') {
-                                        log_debug("NAME=\"\" is ignored, because udev will not delete any device nodes, "
-                                                  "please remove it from %s:%u\n", filename, lineno);
-                                        continue;
-                                }
-                                rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL);
-                        }
-                        rule_tmp.rule.rule.can_set_name = true;
-                        continue;
-                }
-
-                if (streq(key, "SYMLINK")) {
-                        if (op == OP_REMOVE) {
-                                log_error("invalid SYMLINK operation");
-                                goto invalid;
-                        }
-                        if (op < OP_MATCH_MAX)
-                                rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL);
-                        else
-                                rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL);
-                        rule_tmp.rule.rule.can_set_name = true;
-                        continue;
-                }
-
-                if (streq(key, "OWNER")) {
-                        uid_t uid;
-                        char *endptr;
-
-                        if (op == OP_REMOVE) {
-                                log_error("invalid OWNER operation");
-                                goto invalid;
-                        }
-
-                        uid = strtoul(value, &endptr, 10);
-                        if (endptr[0] == '\0') {
-                                rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
-                        } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
-                                uid = add_uid(rules, value);
-                                rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
-                        } else if (rules->resolve_names >= 0) {
-                                rule_add_key(&rule_tmp, TK_A_OWNER, op, value, NULL);
-                        }
-                        rule_tmp.rule.rule.can_set_name = true;
-                        continue;
-                }
-
-                if (streq(key, "GROUP")) {
-                        gid_t gid;
-                        char *endptr;
-
-                        if (op == OP_REMOVE) {
-                                log_error("invalid GROUP operation");
-                                goto invalid;
-                        }
-
-                        gid = strtoul(value, &endptr, 10);
-                        if (endptr[0] == '\0') {
-                                rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
-                        } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
-                                gid = add_gid(rules, value);
-                                rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
-                        } else if (rules->resolve_names >= 0) {
-                                rule_add_key(&rule_tmp, TK_A_GROUP, op, value, NULL);
-                        }
-                        rule_tmp.rule.rule.can_set_name = true;
-                        continue;
-                }
-
-                if (streq(key, "MODE")) {
-                        mode_t mode;
-                        char *endptr;
-
-                        if (op == OP_REMOVE) {
-                                log_error("invalid MODE operation");
-                                goto invalid;
-                        }
-
-                        mode = strtol(value, &endptr, 8);
-                        if (endptr[0] == '\0')
-                                rule_add_key(&rule_tmp, TK_A_MODE_ID, op, NULL, &mode);
-                        else
-                                rule_add_key(&rule_tmp, TK_A_MODE, op, value, NULL);
-                        rule_tmp.rule.rule.can_set_name = true;
-                        continue;
-                }
-
-                if (streq(key, "OPTIONS")) {
-                        const char *pos;
-
-                        if (op == OP_REMOVE) {
-                                log_error("invalid OPTIONS operation");
-                                goto invalid;
-                        }
-
-                        pos = strstr(value, "link_priority=");
-                        if (pos != NULL) {
-                                int prio = atoi(&pos[strlen("link_priority=")]);
-
-                                rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
-                        }
-
-                        pos = strstr(value, "string_escape=");
-                        if (pos != NULL) {
-                                pos = &pos[strlen("string_escape=")];
-                                if (startswith(pos, "none"))
-                                        rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_NONE, op, NULL, NULL);
-                                else if (startswith(pos, "replace"))
-                                        rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_REPLACE, op, NULL, NULL);
-                        }
-
-                        pos = strstr(value, "db_persist");
-                        if (pos != NULL)
-                                rule_add_key(&rule_tmp, TK_A_DB_PERSIST, op, NULL, NULL);
-
-                        pos = strstr(value, "nowatch");
-                        if (pos != NULL) {
-                                const int off = 0;
-
-                                rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &off);
-                        } else {
-                                pos = strstr(value, "watch");
-                                if (pos != NULL) {
-                                        const int on = 1;
-
-                                        rule_add_key(&rule_tmp, TK_A_INOTIFY_WATCH, op, NULL, &on);
-                                }
-                        }
-
-                        pos = strstr(value, "static_node=");
-                        if (pos != NULL) {
-                                rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, &pos[strlen("static_node=")], NULL);
-                                rule_tmp.rule.rule.has_static_node = true;
-                        }
-
-                        continue;
-                }
-
-                log_error("unknown key '%s' in %s:%u", key, filename, lineno);
-                goto invalid;
-        }
-
-        /* add rule token */
-        rule_tmp.rule.rule.token_count = 1 + rule_tmp.token_cur;
-        if (add_token(rules, &rule_tmp.rule) != 0)
-                goto invalid;
-
-        /* add tokens to list, sorted by type */
-        if (sort_token(rules, &rule_tmp) != 0)
-                goto invalid;
-
-        return 0;
-invalid:
-        log_error("invalid rule '%s:%u'", filename, lineno);
-        return -1;
-}
-
-static int parse_file(struct udev_rules *rules, const char *filename) {
-        _cleanup_fclose_ FILE *f = NULL;
-        unsigned int first_token;
-        unsigned int filename_off;
-        char line[UTIL_LINE_SIZE];
-        int line_nr = 0;
-        unsigned int i;
-
-        f = fopen(filename, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-                else
-                        return -errno;
-        }
-
-        if (null_or_empty_fd(fileno(f))) {
-                log_debug("Skipping empty file: %s", filename);
-                return 0;
-        } else
-                log_debug("Reading rules file: %s", filename);
-
-        first_token = rules->token_cur;
-        filename_off = rules_add_string(rules, filename);
-
-        while (fgets(line, sizeof(line), f) != NULL) {
-                char *key;
-                size_t len;
-
-                /* skip whitespace */
-                line_nr++;
-                key = line;
-                while (isspace(key[0]))
-                        key++;
-
-                /* comment */
-                if (key[0] == '#')
-                        continue;
-
-                len = strlen(line);
-                if (len < 3)
-                        continue;
-
-                /* continue reading if backslash+newline is found */
-                while (line[len-2] == '\\') {
-                        if (fgets(&line[len-2], (sizeof(line)-len)+2, f) == NULL)
-                                break;
-                        if (strlen(&line[len-2]) < 2)
-                                break;
-                        line_nr++;
-                        len = strlen(line);
-                }
-
-                if (len+1 >= sizeof(line)) {
-                        log_error("line too long '%s':%u, ignored", filename, line_nr);
-                        continue;
-                }
-                add_rule(rules, key, filename, filename_off, line_nr);
-        }
-
-        /* link GOTOs to LABEL rules in this file to be able to fast-forward */
-        for (i = first_token+1; i < rules->token_cur; i++) {
-                if (rules->tokens[i].type == TK_A_GOTO) {
-                        char *label = rules_str(rules, rules->tokens[i].key.value_off);
-                        unsigned int j;
-
-                        for (j = i+1; j < rules->token_cur; j++) {
-                                if (rules->tokens[j].type != TK_RULE)
-                                        continue;
-                                if (rules->tokens[j].rule.label_off == 0)
-                                        continue;
-                                if (!streq(label, rules_str(rules, rules->tokens[j].rule.label_off)))
-                                        continue;
-                                rules->tokens[i].key.rule_goto = j;
-                                break;
-                        }
-                        if (rules->tokens[i].key.rule_goto == 0)
-                                log_error("GOTO '%s' has no matching label in: '%s'", label, filename);
-                }
-        }
-        return 0;
-}
-
-struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) {
-        struct udev_rules *rules;
-        struct udev_list file_list;
-        struct token end_token;
-        char **files, **f;
-        int r;
-
-        rules = new0(struct udev_rules, 1);
-        if (rules == NULL)
-                return NULL;
-        rules->udev = udev;
-        rules->resolve_names = resolve_names;
-        udev_list_init(udev, &file_list, true);
-
-        /* init token array and string buffer */
-        rules->tokens = malloc(PREALLOC_TOKEN * sizeof(struct token));
-        if (rules->tokens == NULL)
-                return udev_rules_unref(rules);
-        rules->token_max = PREALLOC_TOKEN;
-
-        rules->strbuf = strbuf_new();
-        if (!rules->strbuf)
-                return udev_rules_unref(rules);
-
-        udev_rules_check_timestamp(rules);
-
-        r = conf_files_list_strv(&files, ".rules", NULL, rules_dirs);
-        if (r < 0) {
-                log_error_errno(r, "failed to enumerate rules files: %m");
-                return udev_rules_unref(rules);
-        }
-
-        /*
-         * The offset value in the rules strct is limited; add all
-         * rules file names to the beginning of the string buffer.
-         */
-        STRV_FOREACH(f, files)
-                rules_add_string(rules, *f);
-
-        STRV_FOREACH(f, files)
-                parse_file(rules, *f);
-
-        strv_free(files);
-
-        memzero(&end_token, sizeof(struct token));
-        end_token.type = TK_END;
-        add_token(rules, &end_token);
-        log_debug("rules contain %zu bytes tokens (%u * %zu bytes), %zu bytes strings",
-                  rules->token_max * sizeof(struct token), rules->token_max, sizeof(struct token), rules->strbuf->len);
-
-        /* cleanup temporary strbuf data */
-        log_debug("%zu strings (%zu bytes), %zu de-duplicated (%zu bytes), %zu trie nodes used",
-                  rules->strbuf->in_count, rules->strbuf->in_len,
-                  rules->strbuf->dedup_count, rules->strbuf->dedup_len, rules->strbuf->nodes_count);
-        strbuf_complete(rules->strbuf);
-
-        /* cleanup uid/gid cache */
-        free(rules->uids);
-        rules->uids = NULL;
-        rules->uids_cur = 0;
-        rules->uids_max = 0;
-        free(rules->gids);
-        rules->gids = NULL;
-        rules->gids_cur = 0;
-        rules->gids_max = 0;
-
-        dump_rules(rules);
-        return rules;
-}
-
-struct udev_rules *udev_rules_unref(struct udev_rules *rules) {
-        if (rules == NULL)
-                return NULL;
-        free(rules->tokens);
-        strbuf_cleanup(rules->strbuf);
-        free(rules->uids);
-        free(rules->gids);
-        free(rules);
-        return NULL;
-}
-
-bool udev_rules_check_timestamp(struct udev_rules *rules) {
-        if (!rules)
-                return false;
-
-        return paths_check_timestamp(rules_dirs, &rules->dirs_ts_usec, true);
-}
-
-static int match_key(struct udev_rules *rules, struct token *token, const char *val) {
-        char *key_value = rules_str(rules, token->key.value_off);
-        char *pos;
-        bool match = false;
-
-        if (val == NULL)
-                val = "";
-
-        switch (token->key.glob) {
-        case GL_PLAIN:
-                match = (streq(key_value, val));
-                break;
-        case GL_GLOB:
-                match = (fnmatch(key_value, val, 0) == 0);
-                break;
-        case GL_SPLIT:
-                {
-                        const char *s;
-                        size_t len;
-
-                        s = rules_str(rules, token->key.value_off);
-                        len = strlen(val);
-                        for (;;) {
-                                const char *next;
-
-                                next = strchr(s, '|');
-                                if (next != NULL) {
-                                        size_t matchlen = (size_t)(next - s);
-
-                                        match = (matchlen == len && strneq(s, val, matchlen));
-                                        if (match)
-                                                break;
-                                } else {
-                                        match = (streq(s, val));
-                                        break;
-                                }
-                                s = &next[1];
-                        }
-                        break;
-                }
-        case GL_SPLIT_GLOB:
-                {
-                        char value[UTIL_PATH_SIZE];
-
-                        strscpy(value, sizeof(value), rules_str(rules, token->key.value_off));
-                        key_value = value;
-                        while (key_value != NULL) {
-                                pos = strchr(key_value, '|');
-                                if (pos != NULL) {
-                                        pos[0] = '\0';
-                                        pos = &pos[1];
-                                }
-                                match = (fnmatch(key_value, val, 0) == 0);
-                                if (match)
-                                        break;
-                                key_value = pos;
-                        }
-                        break;
-                }
-        case GL_SOMETHING:
-                match = (val[0] != '\0');
-                break;
-        case GL_UNSET:
-                return -1;
-        }
-
-        if (match && (token->key.op == OP_MATCH))
-                return 0;
-        if (!match && (token->key.op == OP_NOMATCH))
-                return 0;
-        return -1;
-}
-
-static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct udev_event *event, struct token *cur) {
-        const char *name;
-        char nbuf[UTIL_NAME_SIZE];
-        const char *value;
-        char vbuf[UTIL_NAME_SIZE];
-        size_t len;
-
-        name = rules_str(rules, cur->key.attr_off);
-        switch (cur->key.attrsubst) {
-        case SB_FORMAT:
-                udev_event_apply_format(event, name, nbuf, sizeof(nbuf));
-                name = nbuf;
-                /* fall through */
-        case SB_NONE:
-                value = udev_device_get_sysattr_value(dev, name);
-                if (value == NULL)
-                        return -1;
-                break;
-        case SB_SUBSYS:
-                if (util_resolve_subsys_kernel(event->udev, name, vbuf, sizeof(vbuf), 1) != 0)
-                        return -1;
-                value = vbuf;
-                break;
-        default:
-                return -1;
-        }
-
-        /* remove trailing whitespace, if not asked to match for it */
-        len = strlen(value);
-        if (len > 0 && isspace(value[len-1])) {
-                const char *key_value;
-                size_t klen;
-
-                key_value = rules_str(rules, cur->key.value_off);
-                klen = strlen(key_value);
-                if (klen > 0 && !isspace(key_value[klen-1])) {
-                        if (value != vbuf) {
-                                strscpy(vbuf, sizeof(vbuf), value);
-                                value = vbuf;
-                        }
-                        while (len > 0 && isspace(vbuf[--len]))
-                                vbuf[len] = '\0';
-                }
-        }
-
-        return match_key(rules, cur, value);
-}
-
-enum escape_type {
-        ESCAPE_UNSET,
-        ESCAPE_NONE,
-        ESCAPE_REPLACE,
-};
-
-int udev_rules_apply_to_event(struct udev_rules *rules,
-                              struct udev_event *event,
-                              usec_t timeout_usec,
-                              usec_t timeout_warn_usec,
-                              struct udev_list *properties_list,
-                              const sigset_t *sigmask) {
-        struct token *cur;
-        struct token *rule;
-        enum escape_type esc = ESCAPE_UNSET;
-        bool can_set_name;
-
-        if (rules->tokens == NULL)
-                return -1;
-
-        can_set_name = ((!streq(udev_device_get_action(event->dev), "remove")) &&
-                        (major(udev_device_get_devnum(event->dev)) > 0 ||
-                         udev_device_get_ifindex(event->dev) > 0));
-
-        /* loop through token list, match, run actions or forward to next rule */
-        cur = &rules->tokens[0];
-        rule = cur;
-        for (;;) {
-                dump_token(rules, cur);
-                switch (cur->type) {
-                case TK_RULE:
-                        /* current rule */
-                        rule = cur;
-                        /* possibly skip rules which want to set NAME, SYMLINK, OWNER, GROUP, MODE */
-                        if (!can_set_name && rule->rule.can_set_name)
-                                goto nomatch;
-                        esc = ESCAPE_UNSET;
-                        break;
-                case TK_M_ACTION:
-                        if (match_key(rules, cur, udev_device_get_action(event->dev)) != 0)
-                                goto nomatch;
-                        break;
-                case TK_M_DEVPATH:
-                        if (match_key(rules, cur, udev_device_get_devpath(event->dev)) != 0)
-                                goto nomatch;
-                        break;
-                case TK_M_KERNEL:
-                        if (match_key(rules, cur, udev_device_get_sysname(event->dev)) != 0)
-                                goto nomatch;
-                        break;
-                case TK_M_DEVLINK: {
-                        struct udev_list_entry *list_entry;
-                        bool match = false;
-
-                        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(event->dev)) {
-                                const char *devlink;
-
-                                devlink =  udev_list_entry_get_name(list_entry) + strlen("/dev/");
-                                if (match_key(rules, cur, devlink) == 0) {
-                                        match = true;
-                                        break;
-                                }
-                        }
-                        if (!match)
-                                goto nomatch;
-                        break;
-                }
-                case TK_M_NAME:
-                        if (match_key(rules, cur, event->name) != 0)
-                                goto nomatch;
-                        break;
-                case TK_M_ENV: {
-                        const char *key_name = rules_str(rules, cur->key.attr_off);
-                        const char *value;
-
-                        value = udev_device_get_property_value(event->dev, key_name);
-
-                        /* check global properties */
-                        if (!value && properties_list) {
-                                struct udev_list_entry *list_entry;
-
-                                list_entry = udev_list_get_entry(properties_list);
-                                list_entry = udev_list_entry_get_by_name(list_entry, key_name);
-                                if (list_entry != NULL)
-                                        value = udev_list_entry_get_value(list_entry);
-                        }
-
-                        if (!value)
-                                value = "";
-                        if (match_key(rules, cur, value))
-                                goto nomatch;
-                        break;
-                }
-                case TK_M_TAG: {
-                        struct udev_list_entry *list_entry;
-                        bool match = false;
-
-                        udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(event->dev)) {
-                                if (streq(rules_str(rules, cur->key.value_off), udev_list_entry_get_name(list_entry))) {
-                                        match = true;
-                                        break;
-                                }
-                        }
-                        if (!match && (cur->key.op != OP_NOMATCH))
-                                goto nomatch;
-                        break;
-                }
-                case TK_M_SUBSYSTEM:
-                        if (match_key(rules, cur, udev_device_get_subsystem(event->dev)) != 0)
-                                goto nomatch;
-                        break;
-                case TK_M_DRIVER:
-                        if (match_key(rules, cur, udev_device_get_driver(event->dev)) != 0)
-                                goto nomatch;
-                        break;
-                case TK_M_WAITFOR: {
-                        char filename[UTIL_PATH_SIZE];
-                        int found;
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename));
-                        found = (wait_for_file(event->dev, filename, 10) == 0);
-                        if (!found && (cur->key.op != OP_NOMATCH))
-                                goto nomatch;
-                        break;
-                }
-                case TK_M_ATTR:
-                        if (match_attr(rules, event->dev, event, cur) != 0)
-                                goto nomatch;
-                        break;
-                case TK_M_SYSCTL: {
-                        char filename[UTIL_PATH_SIZE];
-                        _cleanup_free_ char *value = NULL;
-                        size_t len;
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename));
-                        sysctl_normalize(filename);
-                        if (sysctl_read(filename, &value) < 0)
-                                goto nomatch;
-
-                        len = strlen(value);
-                        while (len > 0 && isspace(value[--len]))
-                                value[len] = '\0';
-                        if (match_key(rules, cur, value) != 0)
-                                goto nomatch;
-                        break;
-                }
-                case TK_M_KERNELS:
-                case TK_M_SUBSYSTEMS:
-                case TK_M_DRIVERS:
-                case TK_M_ATTRS:
-                case TK_M_TAGS: {
-                        struct token *next;
-
-                        /* get whole sequence of parent matches */
-                        next = cur;
-                        while (next->type > TK_M_PARENTS_MIN && next->type < TK_M_PARENTS_MAX)
-                                next++;
-
-                        /* loop over parents */
-                        event->dev_parent = event->dev;
-                        for (;;) {
-                                struct token *key;
-
-                                /* loop over sequence of parent match keys */
-                                for (key = cur; key < next; key++ ) {
-                                        dump_token(rules, key);
-                                        switch(key->type) {
-                                        case TK_M_KERNELS:
-                                                if (match_key(rules, key, udev_device_get_sysname(event->dev_parent)) != 0)
-                                                        goto try_parent;
-                                                break;
-                                        case TK_M_SUBSYSTEMS:
-                                                if (match_key(rules, key, udev_device_get_subsystem(event->dev_parent)) != 0)
-                                                        goto try_parent;
-                                                break;
-                                        case TK_M_DRIVERS:
-                                                if (match_key(rules, key, udev_device_get_driver(event->dev_parent)) != 0)
-                                                        goto try_parent;
-                                                break;
-                                        case TK_M_ATTRS:
-                                                if (match_attr(rules, event->dev_parent, event, key) != 0)
-                                                        goto try_parent;
-                                                break;
-                                        case TK_M_TAGS: {
-                                                bool match = udev_device_has_tag(event->dev_parent, rules_str(rules, cur->key.value_off));
-
-                                                if (match && key->key.op == OP_NOMATCH)
-                                                        goto try_parent;
-                                                if (!match && key->key.op == OP_MATCH)
-                                                        goto try_parent;
-                                                break;
-                                        }
-                                        default:
-                                                goto nomatch;
-                                        }
-                                }
-                                break;
-
-                        try_parent:
-                                event->dev_parent = udev_device_get_parent(event->dev_parent);
-                                if (event->dev_parent == NULL)
-                                        goto nomatch;
-                        }
-                        /* move behind our sequence of parent match keys */
-                        cur = next;
-                        continue;
-                }
-                case TK_M_TEST: {
-                        char filename[UTIL_PATH_SIZE];
-                        struct stat statbuf;
-                        int match;
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename));
-                        if (util_resolve_subsys_kernel(event->udev, filename, filename, sizeof(filename), 0) != 0) {
-                                if (filename[0] != '/') {
-                                        char tmp[UTIL_PATH_SIZE];
-
-                                        strscpy(tmp, sizeof(tmp), filename);
-                                        strscpyl(filename, sizeof(filename),
-                                                      udev_device_get_syspath(event->dev), "/", tmp, NULL);
-                                }
-                        }
-                        attr_subst_subdir(filename, sizeof(filename));
-
-                        match = (stat(filename, &statbuf) == 0);
-                        if (match && cur->key.mode > 0)
-                                match = ((statbuf.st_mode & cur->key.mode) > 0);
-                        if (match && cur->key.op == OP_NOMATCH)
-                                goto nomatch;
-                        if (!match && cur->key.op == OP_MATCH)
-                                goto nomatch;
-                        break;
-                }
-                case TK_M_PROGRAM: {
-                        char program[UTIL_PATH_SIZE];
-                        char **envp;
-                        char result[UTIL_LINE_SIZE];
-
-                        free(event->program_result);
-                        event->program_result = NULL;
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program));
-                        envp = udev_device_get_properties_envp(event->dev);
-                        log_debug("PROGRAM '%s' %s:%u",
-                                  program,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-
-                        if (udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, result, sizeof(result)) < 0) {
-                                if (cur->key.op != OP_NOMATCH)
-                                        goto nomatch;
-                        } else {
-                                int count;
-
-                                util_remove_trailing_chars(result, '\n');
-                                if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) {
-                                        count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT);
-                                        if (count > 0)
-                                                log_debug("%i character(s) replaced" , count);
-                                }
-                                event->program_result = strdup(result);
-                                if (cur->key.op == OP_NOMATCH)
-                                        goto nomatch;
-                        }
-                        break;
-                }
-                case TK_M_IMPORT_FILE: {
-                        char import[UTIL_PATH_SIZE];
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import));
-                        if (import_file_into_properties(event->dev, import) != 0)
-                                if (cur->key.op != OP_NOMATCH)
-                                        goto nomatch;
-                        break;
-                }
-                case TK_M_IMPORT_PROG: {
-                        char import[UTIL_PATH_SIZE];
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import));
-                        log_debug("IMPORT '%s' %s:%u",
-                                  import,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-
-                        if (import_program_into_properties(event, timeout_usec, timeout_warn_usec, import, sigmask) != 0)
-                                if (cur->key.op != OP_NOMATCH)
-                                        goto nomatch;
-                        break;
-                }
-                case TK_M_IMPORT_BUILTIN: {
-                        char command[UTIL_PATH_SIZE];
-
-                        if (udev_builtin_run_once(cur->key.builtin_cmd)) {
-                                /* check if we ran already */
-                                if (event->builtin_run & (1 << cur->key.builtin_cmd)) {
-                                        log_debug("IMPORT builtin skip '%s' %s:%u",
-                                                  udev_builtin_name(cur->key.builtin_cmd),
-                                                  rules_str(rules, rule->rule.filename_off),
-                                                  rule->rule.filename_line);
-                                        /* return the result from earlier run */
-                                        if (event->builtin_ret & (1 << cur->key.builtin_cmd))
-                                        if (cur->key.op != OP_NOMATCH)
-                                                        goto nomatch;
-                                        break;
-                                }
-                                /* mark as ran */
-                                event->builtin_run |= (1 << cur->key.builtin_cmd);
-                        }
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command));
-                        log_debug("IMPORT builtin '%s' %s:%u",
-                                  udev_builtin_name(cur->key.builtin_cmd),
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-
-                        if (udev_builtin_run(event->dev, cur->key.builtin_cmd, command, false) != 0) {
-                                /* remember failure */
-                                log_debug("IMPORT builtin '%s' returned non-zero",
-                                          udev_builtin_name(cur->key.builtin_cmd));
-                                event->builtin_ret |= (1 << cur->key.builtin_cmd);
-                                if (cur->key.op != OP_NOMATCH)
-                                        goto nomatch;
-                        }
-                        break;
-                }
-                case TK_M_IMPORT_DB: {
-                        const char *key = rules_str(rules, cur->key.value_off);
-                        const char *value;
-
-                        value = udev_device_get_property_value(event->dev_db, key);
-                        if (value != NULL)
-                                udev_device_add_property(event->dev, key, value);
-                        else {
-                                if (cur->key.op != OP_NOMATCH)
-                                        goto nomatch;
-                        }
-                        break;
-                }
-                case TK_M_IMPORT_CMDLINE: {
-                        FILE *f;
-                        bool imported = false;
-
-                        f = fopen("/proc/cmdline", "re");
-                        if (f != NULL) {
-                                char cmdline[4096];
-
-                                if (fgets(cmdline, sizeof(cmdline), f) != NULL) {
-                                        const char *key = rules_str(rules, cur->key.value_off);
-                                        char *pos;
-
-                                        pos = strstr(cmdline, key);
-                                        if (pos != NULL) {
-                                                pos += strlen(key);
-                                                if (pos[0] == '\0' || isspace(pos[0])) {
-                                                        /* we import simple flags as 'FLAG=1' */
-                                                        udev_device_add_property(event->dev, key, "1");
-                                                        imported = true;
-                                                } else if (pos[0] == '=') {
-                                                        const char *value;
-
-                                                        pos++;
-                                                        value = pos;
-                                                        while (pos[0] != '\0' && !isspace(pos[0]))
-                                                                pos++;
-                                                        pos[0] = '\0';
-                                                        udev_device_add_property(event->dev, key, value);
-                                                        imported = true;
-                                                }
-                                        }
-                                }
-                                fclose(f);
-                        }
-                        if (!imported && cur->key.op != OP_NOMATCH)
-                                goto nomatch;
-                        break;
-                }
-                case TK_M_IMPORT_PARENT: {
-                        char import[UTIL_PATH_SIZE];
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import));
-                        if (import_parent_into_properties(event->dev, import) != 0)
-                                if (cur->key.op != OP_NOMATCH)
-                                        goto nomatch;
-                        break;
-                }
-                case TK_M_RESULT:
-                        if (match_key(rules, cur, event->program_result) != 0)
-                                goto nomatch;
-                        break;
-                case TK_A_STRING_ESCAPE_NONE:
-                        esc = ESCAPE_NONE;
-                        break;
-                case TK_A_STRING_ESCAPE_REPLACE:
-                        esc = ESCAPE_REPLACE;
-                        break;
-                case TK_A_DB_PERSIST:
-                        udev_device_set_db_persist(event->dev);
-                        break;
-                case TK_A_INOTIFY_WATCH:
-                        if (event->inotify_watch_final)
-                                break;
-                        if (cur->key.op == OP_ASSIGN_FINAL)
-                                event->inotify_watch_final = true;
-                        event->inotify_watch = cur->key.watch;
-                        break;
-                case TK_A_DEVLINK_PRIO:
-                        udev_device_set_devlink_priority(event->dev, cur->key.devlink_prio);
-                        break;
-                case TK_A_OWNER: {
-                        char owner[UTIL_NAME_SIZE];
-                        const char *ow = owner;
-                        int r;
-
-                        if (event->owner_final)
-                                break;
-                        if (cur->key.op == OP_ASSIGN_FINAL)
-                                event->owner_final = true;
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner));
-                        event->owner_set = true;
-                        r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL);
-                        if (r < 0) {
-                                if (r == -ENOENT || r == -ESRCH)
-                                        log_error("specified user '%s' unknown", owner);
-                                else
-                                        log_error_errno(r, "error resolving user '%s': %m", owner);
-
-                                event->uid = 0;
-                        }
-                        log_debug("OWNER %u %s:%u",
-                                  event->uid,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        break;
-                }
-                case TK_A_GROUP: {
-                        char group[UTIL_NAME_SIZE];
-                        const char *gr = group;
-                        int r;
-
-                        if (event->group_final)
-                                break;
-                        if (cur->key.op == OP_ASSIGN_FINAL)
-                                event->group_final = true;
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group));
-                        event->group_set = true;
-                        r = get_group_creds(&gr, &event->gid);
-                        if (r < 0) {
-                                if (r == -ENOENT || r == -ESRCH)
-                                        log_error("specified group '%s' unknown", group);
-                                else
-                                        log_error_errno(r, "error resolving group '%s': %m", group);
-
-                                event->gid = 0;
-                        }
-                        log_debug("GROUP %u %s:%u",
-                                  event->gid,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        break;
-                }
-                case TK_A_MODE: {
-                        char mode_str[UTIL_NAME_SIZE];
-                        mode_t mode;
-                        char *endptr;
-
-                        if (event->mode_final)
-                                break;
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str));
-                        mode = strtol(mode_str, &endptr, 8);
-                        if (endptr[0] != '\0') {
-                                log_error("ignoring invalid mode '%s'", mode_str);
-                                break;
-                        }
-                        if (cur->key.op == OP_ASSIGN_FINAL)
-                                event->mode_final = true;
-                        event->mode_set = true;
-                        event->mode = mode;
-                        log_debug("MODE %#o %s:%u",
-                                  event->mode,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        break;
-                }
-                case TK_A_OWNER_ID:
-                        if (event->owner_final)
-                                break;
-                        if (cur->key.op == OP_ASSIGN_FINAL)
-                                event->owner_final = true;
-                        event->owner_set = true;
-                        event->uid = cur->key.uid;
-                        log_debug("OWNER %u %s:%u",
-                                  event->uid,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        break;
-                case TK_A_GROUP_ID:
-                        if (event->group_final)
-                                break;
-                        if (cur->key.op == OP_ASSIGN_FINAL)
-                                event->group_final = true;
-                        event->group_set = true;
-                        event->gid = cur->key.gid;
-                        log_debug("GROUP %u %s:%u",
-                                  event->gid,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        break;
-                case TK_A_MODE_ID:
-                        if (event->mode_final)
-                                break;
-                        if (cur->key.op == OP_ASSIGN_FINAL)
-                                event->mode_final = true;
-                        event->mode_set = true;
-                        event->mode = cur->key.mode;
-                        log_debug("MODE %#o %s:%u",
-                                  event->mode,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        break;
-                case TK_A_SECLABEL: {
-                        const char *name, *label;
-
-                        name = rules_str(rules, cur->key.attr_off);
-                        label = rules_str(rules, cur->key.value_off);
-                        if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
-                                udev_list_cleanup(&event->seclabel_list);
-                        udev_list_entry_add(&event->seclabel_list, name, label);
-                        log_debug("SECLABEL{%s}='%s' %s:%u",
-                                  name, label,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        break;
-                }
-                case TK_A_ENV: {
-                        const char *name = rules_str(rules, cur->key.attr_off);
-                        char *value = rules_str(rules, cur->key.value_off);
-                        char value_new[UTIL_NAME_SIZE];
-                        const char *value_old = NULL;
-
-                        if (value[0] == '\0') {
-                                if (cur->key.op == OP_ADD)
-                                        break;
-                                udev_device_add_property(event->dev, name, NULL);
-                                break;
-                        }
-
-                        if (cur->key.op == OP_ADD)
-                                value_old = udev_device_get_property_value(event->dev, name);
-                        if (value_old) {
-                                char temp[UTIL_NAME_SIZE];
-
-                                /* append value separated by space */
-                                udev_event_apply_format(event, value, temp, sizeof(temp));
-                                strscpyl(value_new, sizeof(value_new), value_old, " ", temp, NULL);
-                        } else
-                                udev_event_apply_format(event, value, value_new, sizeof(value_new));
-
-                        udev_device_add_property(event->dev, name, value_new);
-                        break;
-                }
-                case TK_A_TAG: {
-                        char tag[UTIL_PATH_SIZE];
-                        const char *p;
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), tag, sizeof(tag));
-                        if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
-                                udev_device_cleanup_tags_list(event->dev);
-                        for (p = tag; *p != '\0'; p++) {
-                                if ((*p >= 'a' && *p <= 'z') ||
-                                    (*p >= 'A' && *p <= 'Z') ||
-                                    (*p >= '0' && *p <= '9') ||
-                                    *p == '-' || *p == '_')
-                                        continue;
-                                log_error("ignoring invalid tag name '%s'", tag);
-                                break;
-                        }
-                        if (cur->key.op == OP_REMOVE)
-                                udev_device_remove_tag(event->dev, tag);
-                        else
-                                udev_device_add_tag(event->dev, tag);
-                        break;
-                }
-                case TK_A_NAME: {
-                        const char *name  = rules_str(rules, cur->key.value_off);
-
-                        char name_str[UTIL_PATH_SIZE];
-                        int count;
-
-                        if (event->name_final)
-                                break;
-                        if (cur->key.op == OP_ASSIGN_FINAL)
-                                event->name_final = true;
-                        udev_event_apply_format(event, name, name_str, sizeof(name_str));
-                        if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) {
-                                count = util_replace_chars(name_str, "/");
-                                if (count > 0)
-                                        log_debug("%i character(s) replaced", count);
-                        }
-                        if (major(udev_device_get_devnum(event->dev)) &&
-                            (!streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/")))) {
-                                log_error("NAME=\"%s\" ignored, kernel device nodes "
-                                    "can not be renamed; please fix it in %s:%u\n", name,
-                                    rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
-                                break;
-                        }
-                        free(event->name);
-                        event->name = strdup(name_str);
-                        log_debug("NAME '%s' %s:%u",
-                                  event->name,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        break;
-                }
-                case TK_A_DEVLINK: {
-                        char temp[UTIL_PATH_SIZE];
-                        char filename[UTIL_PATH_SIZE];
-                        char *pos, *next;
-                        int count = 0;
-
-                        if (event->devlink_final)
-                                break;
-                        if (major(udev_device_get_devnum(event->dev)) == 0)
-                                break;
-                        if (cur->key.op == OP_ASSIGN_FINAL)
-                                event->devlink_final = true;
-                        if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
-                                udev_device_cleanup_devlinks_list(event->dev);
-
-                        /* allow  multiple symlinks separated by spaces */
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), temp, sizeof(temp));
-                        if (esc == ESCAPE_UNSET)
-                                count = util_replace_chars(temp, "/ ");
-                        else if (esc == ESCAPE_REPLACE)
-                                count = util_replace_chars(temp, "/");
-                        if (count > 0)
-                                log_debug("%i character(s) replaced" , count);
-                        pos = temp;
-                        while (isspace(pos[0]))
-                                pos++;
-                        next = strchr(pos, ' ');
-                        while (next != NULL) {
-                                next[0] = '\0';
-                                log_debug("LINK '%s' %s:%u", pos,
-                                          rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
-                                strscpyl(filename, sizeof(filename), "/dev/", pos, NULL);
-                                udev_device_add_devlink(event->dev, filename);
-                                while (isspace(next[1]))
-                                        next++;
-                                pos = &next[1];
-                                next = strchr(pos, ' ');
-                        }
-                        if (pos[0] != '\0') {
-                                log_debug("LINK '%s' %s:%u", pos,
-                                          rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
-                                strscpyl(filename, sizeof(filename), "/dev/", pos, NULL);
-                                udev_device_add_devlink(event->dev, filename);
-                        }
-                        break;
-                }
-                case TK_A_ATTR: {
-                        const char *key_name = rules_str(rules, cur->key.attr_off);
-                        char attr[UTIL_PATH_SIZE];
-                        char value[UTIL_NAME_SIZE];
-                        FILE *f;
-
-                        if (util_resolve_subsys_kernel(event->udev, key_name, attr, sizeof(attr), 0) != 0)
-                                strscpyl(attr, sizeof(attr), udev_device_get_syspath(event->dev), "/", key_name, NULL);
-                        attr_subst_subdir(attr, sizeof(attr));
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value));
-                        log_debug("ATTR '%s' writing '%s' %s:%u", attr, value,
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        f = fopen(attr, "we");
-                        if (f != NULL) {
-                                if (fprintf(f, "%s", value) <= 0)
-                                        log_error_errno(errno, "error writing ATTR{%s}: %m", attr);
-                                fclose(f);
-                        } else {
-                                log_error_errno(errno, "error opening ATTR{%s} for writing: %m", attr);
-                        }
-                        break;
-                }
-                case TK_A_SYSCTL: {
-                        char filename[UTIL_PATH_SIZE];
-                        char value[UTIL_NAME_SIZE];
-                        int r;
-
-                        udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename));
-                        sysctl_normalize(filename);
-                        udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value));
-                        log_debug("SYSCTL '%s' writing '%s' %s:%u", filename, value,
-                                  rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
-                        r = sysctl_write(filename, value);
-                        if (r < 0)
-                                log_error("error writing SYSCTL{%s}='%s': %s", filename, value, strerror(-r));
-                        break;
-                }
-                case TK_A_RUN_BUILTIN:
-                case TK_A_RUN_PROGRAM: {
-                        struct udev_list_entry *entry;
-
-                        if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL)
-                                udev_list_cleanup(&event->run_list);
-                        log_debug("RUN '%s' %s:%u",
-                                  rules_str(rules, cur->key.value_off),
-                                  rules_str(rules, rule->rule.filename_off),
-                                  rule->rule.filename_line);
-                        entry = udev_list_entry_add(&event->run_list, rules_str(rules, cur->key.value_off), NULL);
-                        udev_list_entry_set_num(entry, cur->key.builtin_cmd);
-                        break;
-                }
-                case TK_A_GOTO:
-                        if (cur->key.rule_goto == 0)
-                                break;
-                        cur = &rules->tokens[cur->key.rule_goto];
-                        continue;
-                case TK_END:
-                        return 0;
-
-                case TK_M_PARENTS_MIN:
-                case TK_M_PARENTS_MAX:
-                case TK_M_MAX:
-                case TK_UNSET:
-                        log_error("wrong type %u", cur->type);
-                        goto nomatch;
-                }
-
-                cur++;
-                continue;
-        nomatch:
-                /* fast-forward to next rule */
-                cur = rule + rule->rule.token_count;
-        }
-}
-
-int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
-        struct token *cur;
-        struct token *rule;
-        uid_t uid = 0;
-        gid_t gid = 0;
-        mode_t mode = 0;
-        _cleanup_strv_free_ char **tags = NULL;
-        char **t;
-        FILE *f = NULL;
-        _cleanup_free_ char *path = NULL;
-        int r = 0;
-
-        if (rules->tokens == NULL)
-                return 0;
-
-        cur = &rules->tokens[0];
-        rule = cur;
-        for (;;) {
-                switch (cur->type) {
-                case TK_RULE:
-                        /* current rule */
-                        rule = cur;
-
-                        /* skip rules without a static_node tag */
-                        if (!rule->rule.has_static_node)
-                                goto next;
-
-                        uid = 0;
-                        gid = 0;
-                        mode = 0;
-                        strv_free(tags);
-                        tags = NULL;
-                        break;
-                case TK_A_OWNER_ID:
-                        uid = cur->key.uid;
-                        break;
-                case TK_A_GROUP_ID:
-                        gid = cur->key.gid;
-                        break;
-                case TK_A_MODE_ID:
-                        mode = cur->key.mode;
-                        break;
-                case TK_A_TAG:
-                        r = strv_extend(&tags, rules_str(rules, cur->key.value_off));
-                        if (r < 0)
-                                goto finish;
-
-                        break;
-                case TK_A_STATIC_NODE: {
-                        char device_node[UTIL_PATH_SIZE];
-                        char tags_dir[UTIL_PATH_SIZE];
-                        char tag_symlink[UTIL_PATH_SIZE];
-                        struct stat stats;
-
-                        /* we assure, that the permissions tokens are sorted before the static token */
-
-                        if (mode == 0 && uid == 0 && gid == 0 && tags == NULL)
-                                goto next;
-
-                        strscpyl(device_node, sizeof(device_node), "/dev/", rules_str(rules, cur->key.value_off), NULL);
-                        if (stat(device_node, &stats) != 0)
-                                break;
-                        if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode))
-                                break;
-
-                        /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */
-                        if (tags) {
-                                STRV_FOREACH(t, tags) {
-                                        _cleanup_free_ char *unescaped_filename = NULL;
-
-                                        strscpyl(tags_dir, sizeof(tags_dir), "/run/udev/static_node-tags/", *t, "/", NULL);
-                                        r = mkdir_p(tags_dir, 0755);
-                                        if (r < 0)
-                                                return log_error_errno(r, "failed to create %s: %m", tags_dir);
-
-                                        unescaped_filename = xescape(rules_str(rules, cur->key.value_off), "/.");
-
-                                        strscpyl(tag_symlink, sizeof(tag_symlink), tags_dir, unescaped_filename, NULL);
-                                        r = symlink(device_node, tag_symlink);
-                                        if (r < 0 && errno != EEXIST)
-                                                return log_error_errno(errno, "failed to create symlink %s -> %s: %m",
-                                                                       tag_symlink, device_node);
-                                        else
-                                                r = 0;
-                                }
-                        }
-
-                        /* don't touch the permissions if only the tags were set */
-                        if (mode == 0 && uid == 0 && gid == 0)
-                                break;
-
-                        if (mode == 0) {
-                                if (gid > 0)
-                                        mode = 0660;
-                                else
-                                        mode = 0600;
-                        }
-                        if (mode != (stats.st_mode & 01777)) {
-                                r = chmod(device_node, mode);
-                                if (r < 0) {
-                                        log_error("failed to chmod '%s' %#o", device_node, mode);
-                                        return -errno;
-                                } else
-                                        log_debug("chmod '%s' %#o", device_node, mode);
-                        }
-
-                        if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) {
-                                r = chown(device_node, uid, gid);
-                                if (r < 0) {
-                                        log_error("failed to chown '%s' %u %u ", device_node, uid, gid);
-                                        return -errno;
-                                } else
-                                        log_debug("chown '%s' %u %u", device_node, uid, gid);
-                        }
-
-                        utimensat(AT_FDCWD, device_node, NULL, 0);
-                        break;
-                }
-                case TK_END:
-                        goto finish;
-                }
-
-                cur++;
-                continue;
-next:
-                /* fast-forward to next rule */
-                cur = rule + rule->rule.token_count;
-                continue;
-        }
-
-finish:
-        if (f) {
-                fflush(f);
-                fchmod(fileno(f), 0644);
-                if (ferror(f) || rename(path, "/run/udev/static_node-tags") < 0) {
-                        r = -errno;
-                        unlink("/run/udev/static_node-tags");
-                        unlink(path);
-                }
-                fclose(f);
-        }
-
-        return r;
-}
diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c
deleted file mode 100644 (file)
index 15b76dd..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
- * Copyright (C) 2009 Canonical Ltd.
- * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <sys/inotify.h>
-
-#include "udev.h"
-
-static int inotify_fd = -1;
-
-/* inotify descriptor, will be shared with rules directory;
- * set to cloexec since we need our children to be able to add
- * watches for us
- */
-int udev_watch_init(struct udev *udev) {
-        inotify_fd = inotify_init1(IN_CLOEXEC);
-        if (inotify_fd < 0)
-                log_error_errno(errno, "inotify_init failed: %m");
-        return inotify_fd;
-}
-
-/* move any old watches directory out of the way, and then restore
- * the watches
- */
-void udev_watch_restore(struct udev *udev) {
-        if (inotify_fd < 0)
-                return;
-
-        if (rename("/run/udev/watch", "/run/udev/watch.old") == 0) {
-                DIR *dir;
-                struct dirent *ent;
-
-                dir = opendir("/run/udev/watch.old");
-                if (dir == NULL) {
-                        log_error_errno(errno, "unable to open old watches dir /run/udev/watch.old; old watches will not be restored: %m");
-                        return;
-                }
-
-                for (ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
-                        char device[UTIL_PATH_SIZE];
-                        ssize_t len;
-                        struct udev_device *dev;
-
-                        if (ent->d_name[0] == '.')
-                                continue;
-
-                        len = readlinkat(dirfd(dir), ent->d_name, device, sizeof(device));
-                        if (len <= 0 || len == (ssize_t)sizeof(device))
-                                goto unlink;
-                        device[len] = '\0';
-
-                        dev = udev_device_new_from_device_id(udev, device);
-                        if (dev == NULL)
-                                goto unlink;
-
-                        log_debug("restoring old watch on '%s'", udev_device_get_devnode(dev));
-                        udev_watch_begin(udev, dev);
-                        udev_device_unref(dev);
-unlink:
-                        unlinkat(dirfd(dir), ent->d_name, 0);
-                }
-
-                closedir(dir);
-                rmdir("/run/udev/watch.old");
-
-        } else if (errno != ENOENT) {
-                log_error_errno(errno, "unable to move watches dir /run/udev/watch; old watches will not be restored: %m");
-        }
-}
-
-void udev_watch_begin(struct udev *udev, struct udev_device *dev) {
-        char filename[UTIL_PATH_SIZE];
-        int wd;
-        int r;
-
-        if (inotify_fd < 0)
-                return;
-
-        log_debug("adding watch on '%s'", udev_device_get_devnode(dev));
-        wd = inotify_add_watch(inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
-        if (wd < 0) {
-                log_error_errno(errno, "inotify_add_watch(%d, %s, %o) failed: %m",
-                    inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
-                return;
-        }
-
-        snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
-        mkdir_parents(filename, 0755);
-        unlink(filename);
-        r = symlink(udev_device_get_id_filename(dev), filename);
-        if (r < 0)
-                log_error_errno(errno, "Failed to create symlink %s: %m", filename);
-
-        udev_device_set_watch_handle(dev, wd);
-}
-
-void udev_watch_end(struct udev *udev, struct udev_device *dev) {
-        int wd;
-        char filename[UTIL_PATH_SIZE];
-
-        if (inotify_fd < 0)
-                return;
-
-        wd = udev_device_get_watch_handle(dev);
-        if (wd < 0)
-                return;
-
-        log_debug("removing watch on '%s'", udev_device_get_devnode(dev));
-        inotify_rm_watch(inotify_fd, wd);
-
-        snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
-        unlink(filename);
-
-        udev_device_set_watch_handle(dev, -1);
-}
-
-struct udev_device *udev_watch_lookup(struct udev *udev, int wd) {
-        char filename[UTIL_PATH_SIZE];
-        char device[UTIL_NAME_SIZE];
-        ssize_t len;
-
-        if (inotify_fd < 0 || wd < 0)
-                return NULL;
-
-        snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
-        len = readlink(filename, device, sizeof(device));
-        if (len <= 0 || (size_t)len == sizeof(device))
-                return NULL;
-        device[len] = '\0';
-
-        return udev_device_new_from_device_id(udev, device);
-}
diff --git a/src/udev/udev.conf b/src/udev/udev.conf
deleted file mode 100644 (file)
index 47d1433..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# see udev.conf(5) for details
-
-#udev_log="info"
diff --git a/src/udev/udev.h b/src/udev/udev.h
deleted file mode 100644 (file)
index dece6ec..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <signal.h>
-
-#include "macro.h"
-#include "sd-rtnl.h"
-#include "libudev.h"
-#include "libudev-private.h"
-#include "util.h"
-#include "label.h"
-#include "strv.h"
-
-struct udev_event {
-        struct udev *udev;
-        struct udev_device *dev;
-        struct udev_device *dev_parent;
-        struct udev_device *dev_db;
-        char *name;
-        char *program_result;
-        mode_t mode;
-        uid_t uid;
-        gid_t gid;
-        struct udev_list seclabel_list;
-        struct udev_list run_list;
-        int exec_delay;
-        usec_t birth_usec;
-        int fd_signal;
-        sd_rtnl *rtnl;
-        unsigned int builtin_run;
-        unsigned int builtin_ret;
-        bool sigterm;
-        bool inotify_watch;
-        bool inotify_watch_final;
-        bool group_set;
-        bool group_final;
-        bool owner_set;
-        bool owner_final;
-        bool mode_set;
-        bool mode_final;
-        bool name_final;
-        bool devlink_final;
-        bool run_final;
-};
-
-struct udev_watch {
-        struct udev_list_node node;
-        int handle;
-        char *name;
-};
-
-/* udev-rules.c */
-struct udev_rules;
-struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names);
-struct udev_rules *udev_rules_unref(struct udev_rules *rules);
-bool udev_rules_check_timestamp(struct udev_rules *rules);
-int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
-                              usec_t timeout_usec, usec_t timeout_warn_usec,
-                              struct udev_list *properties_list,
-                              const sigset_t *sigmask);
-int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
-
-/* udev-event.c */
-struct udev_event *udev_event_new(struct udev_device *dev);
-void udev_event_unref(struct udev_event *event);
-size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size);
-int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string,
-                                   char *result, size_t maxsize, int read_value);
-int udev_event_spawn(struct udev_event *event,
-                     usec_t timeout_usec,
-                     usec_t timeout_warn_usec,
-                     const char *cmd, char **envp, const sigset_t *sigmask,
-                     char *result, size_t ressize);
-void udev_event_execute_rules(struct udev_event *event,
-                              usec_t timeout_usec, usec_t timeout_warn_usec,
-                              struct udev_list *properties_list,
-                              struct udev_rules *rules,
-                              const sigset_t *sigset);
-void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, const sigset_t *sigset);
-int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
-
-/* udev-watch.c */
-int udev_watch_init(struct udev *udev);
-void udev_watch_restore(struct udev *udev);
-void udev_watch_begin(struct udev *udev, struct udev_device *dev);
-void udev_watch_end(struct udev *udev, struct udev_device *dev);
-struct udev_device *udev_watch_lookup(struct udev *udev, int wd);
-
-/* udev-node.c */
-void udev_node_add(struct udev_device *dev, bool apply,
-                   mode_t mode, uid_t uid, gid_t gid,
-                   struct udev_list *seclabel_list);
-void udev_node_remove(struct udev_device *dev);
-void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old);
-
-/* udev-ctrl.c */
-struct udev_ctrl;
-struct udev_ctrl *udev_ctrl_new(struct udev *udev);
-struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd);
-int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl);
-struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl);
-int udev_ctrl_cleanup(struct udev_ctrl *uctrl);
-struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl);
-int udev_ctrl_get_fd(struct udev_ctrl *uctrl);
-int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority, int timeout);
-int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl, int timeout);
-int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl, int timeout);
-int udev_ctrl_send_reload(struct udev_ctrl *uctrl, int timeout);
-int udev_ctrl_send_ping(struct udev_ctrl *uctrl, int timeout);
-int udev_ctrl_send_exit(struct udev_ctrl *uctrl, int timeout);
-int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key, int timeout);
-int udev_ctrl_send_set_children_max(struct udev_ctrl *uctrl, int count, int timeout);
-struct udev_ctrl_connection;
-struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl);
-struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn);
-struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn);
-struct udev_ctrl_msg;
-struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn);
-struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg);
-int udev_ctrl_get_set_log_level(struct udev_ctrl_msg *ctrl_msg);
-int udev_ctrl_get_stop_exec_queue(struct udev_ctrl_msg *ctrl_msg);
-int udev_ctrl_get_start_exec_queue(struct udev_ctrl_msg *ctrl_msg);
-int udev_ctrl_get_reload(struct udev_ctrl_msg *ctrl_msg);
-int udev_ctrl_get_ping(struct udev_ctrl_msg *ctrl_msg);
-int udev_ctrl_get_exit(struct udev_ctrl_msg *ctrl_msg);
-const char *udev_ctrl_get_set_env(struct udev_ctrl_msg *ctrl_msg);
-int udev_ctrl_get_set_children_max(struct udev_ctrl_msg *ctrl_msg);
-
-/* built-in commands */
-enum udev_builtin_cmd {
-#ifdef HAVE_BLKID
-        UDEV_BUILTIN_BLKID,
-#endif
-        UDEV_BUILTIN_BTRFS,
-        UDEV_BUILTIN_HWDB,
-        UDEV_BUILTIN_INPUT_ID,
-        UDEV_BUILTIN_KEYBOARD,
-#ifdef HAVE_KMOD
-        UDEV_BUILTIN_KMOD,
-#endif
-        UDEV_BUILTIN_NET_ID,
-        UDEV_BUILTIN_NET_LINK,
-        UDEV_BUILTIN_PATH_ID,
-        UDEV_BUILTIN_USB_ID,
-#ifdef HAVE_ACL
-        UDEV_BUILTIN_UACCESS,
-#endif
-        UDEV_BUILTIN_MAX
-};
-struct udev_builtin {
-        const char *name;
-        int (*cmd)(struct udev_device *dev, int argc, char *argv[], bool test);
-        const char *help;
-        int (*init)(struct udev *udev);
-        void (*exit)(struct udev *udev);
-        bool (*validate)(struct udev *udev);
-        bool run_once;
-};
-#ifdef HAVE_BLKID
-extern const struct udev_builtin udev_builtin_blkid;
-#endif
-extern const struct udev_builtin udev_builtin_btrfs;
-extern const struct udev_builtin udev_builtin_hwdb;
-extern const struct udev_builtin udev_builtin_input_id;
-extern const struct udev_builtin udev_builtin_keyboard;
-#ifdef HAVE_KMOD
-extern const struct udev_builtin udev_builtin_kmod;
-#endif
-extern const struct udev_builtin udev_builtin_net_id;
-extern const struct udev_builtin udev_builtin_net_setup_link;
-extern const struct udev_builtin udev_builtin_path_id;
-extern const struct udev_builtin udev_builtin_usb_id;
-extern const struct udev_builtin udev_builtin_uaccess;
-void udev_builtin_init(struct udev *udev);
-void udev_builtin_exit(struct udev *udev);
-enum udev_builtin_cmd udev_builtin_lookup(const char *command);
-const char *udev_builtin_name(enum udev_builtin_cmd cmd);
-bool udev_builtin_run_once(enum udev_builtin_cmd cmd);
-int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test);
-void udev_builtin_list(struct udev *udev);
-bool udev_builtin_validate(struct udev *udev);
-int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val);
-int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *prefix, const char *modalias,
-                             const char *filter, bool test);
-
-/* udevadm commands */
-struct udevadm_cmd {
-        const char *name;
-        int (*cmd)(struct udev *udev, int argc, char *argv[]);
-        const char *help;
-        int debug;
-};
-extern const struct udevadm_cmd udevadm_info;
-extern const struct udevadm_cmd udevadm_trigger;
-extern const struct udevadm_cmd udevadm_settle;
-extern const struct udevadm_cmd udevadm_control;
-extern const struct udevadm_cmd udevadm_monitor;
-extern const struct udevadm_cmd udevadm_hwdb;
-extern const struct udevadm_cmd udevadm_test;
-extern const struct udevadm_cmd udevadm_test_builtin;
diff --git a/src/udev/udev.pc.in b/src/udev/udev.pc.in
deleted file mode 100644 (file)
index a0c2e82..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Name: udev
-Description: udev
-Version: @VERSION@
-
-udevdir=@udevlibexecdir@
diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c
deleted file mode 100644 (file)
index 7817046..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2005-2011 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#include "udev.h"
-#include "udev-util.h"
-
-static void print_help(void) {
-        printf("%s control COMMAND\n\n"
-               "Control the udev daemon.\n\n"
-               "  -h --help                Show this help\n"
-               "     --version             Show package version\n"
-               "  -e --exit                Instruct the daemon to cleanup and exit\n"
-               "  -l --log-priority=LEVEL  Set the udev log level for the daemon\n"
-               "  -s --stop-exec-queue     Do not execute events, queue only\n"
-               "  -S --start-exec-queue    Execute events, flush queue\n"
-               "  -R --reload              Reload rules and databases\n"
-               "  -p --property=KEY=VALUE  Set a global property for all events\n"
-               "  -m --children-max=N      Maximum number of children\n"
-               "     --timeout=SECONDS     Maximum time to block for a reply\n"
-               , program_invocation_short_name);
-}
-
-static int adm_control(struct udev *udev, int argc, char *argv[]) {
-        _cleanup_udev_ctrl_unref_ struct udev_ctrl *uctrl = NULL;
-        int timeout = 60;
-        int rc = 1, c;
-
-        static const struct option options[] = {
-                { "exit",             no_argument,       NULL, 'e' },
-                { "log-priority",     required_argument, NULL, 'l' },
-                { "stop-exec-queue",  no_argument,       NULL, 's' },
-                { "start-exec-queue", no_argument,       NULL, 'S' },
-                { "reload",           no_argument,       NULL, 'R' },
-                { "reload-rules",     no_argument,       NULL, 'R' }, /* alias for -R */
-                { "property",         required_argument, NULL, 'p' },
-                { "env",              required_argument, NULL, 'p' }, /* alias for -p */
-                { "children-max",     required_argument, NULL, 'm' },
-                { "timeout",          required_argument, NULL, 't' },
-                { "help",             no_argument,       NULL, 'h' },
-                {}
-        };
-
-        if (getuid() != 0) {
-                fprintf(stderr, "root privileges required\n");
-                return 1;
-        }
-
-        uctrl = udev_ctrl_new(udev);
-        if (uctrl == NULL)
-                return 2;
-
-        while ((c = getopt_long(argc, argv, "el:sSRp:m:h", options, NULL)) >= 0)
-                switch (c) {
-                case 'e':
-                        if (udev_ctrl_send_exit(uctrl, timeout) < 0)
-                                rc = 2;
-                        else
-                                rc = 0;
-                        break;
-                case 'l': {
-                        int i;
-
-                        i = util_log_priority(optarg);
-                        if (i < 0) {
-                                fprintf(stderr, "invalid number '%s'\n", optarg);
-                                return rc;
-                        }
-                        if (udev_ctrl_send_set_log_level(uctrl, util_log_priority(optarg), timeout) < 0)
-                                rc = 2;
-                        else
-                                rc = 0;
-                        break;
-                }
-                case 's':
-                        if (udev_ctrl_send_stop_exec_queue(uctrl, timeout) < 0)
-                                rc = 2;
-                        else
-                                rc = 0;
-                        break;
-                case 'S':
-                        if (udev_ctrl_send_start_exec_queue(uctrl, timeout) < 0)
-                                rc = 2;
-                        else
-                                rc = 0;
-                        break;
-                case 'R':
-                        if (udev_ctrl_send_reload(uctrl, timeout) < 0)
-                                rc = 2;
-                        else
-                                rc = 0;
-                        break;
-                case 'p':
-                        if (strchr(optarg, '=') == NULL) {
-                                fprintf(stderr, "expect <KEY>=<value> instead of '%s'\n", optarg);
-                                return rc;
-                        }
-                        if (udev_ctrl_send_set_env(uctrl, optarg, timeout) < 0)
-                                rc = 2;
-                        else
-                                rc = 0;
-                        break;
-                case 'm': {
-                        char *endp;
-                        int i;
-
-                        i = strtoul(optarg, &endp, 0);
-                        if (endp[0] != '\0' || i < 1) {
-                                fprintf(stderr, "invalid number '%s'\n", optarg);
-                                return rc;
-                        }
-                        if (udev_ctrl_send_set_children_max(uctrl, i, timeout) < 0)
-                                rc = 2;
-                        else
-                                rc = 0;
-                        break;
-                }
-                case 't': {
-                        int seconds;
-
-                        seconds = atoi(optarg);
-                        if (seconds >= 0)
-                                timeout = seconds;
-                        else
-                                fprintf(stderr, "invalid timeout value\n");
-                        break;
-                }
-                case 'h':
-                        print_help();
-                        rc = 0;
-                        break;
-                }
-
-        if (optind < argc)
-                fprintf(stderr, "Extraneous argument: %s\n", argv[optind]);
-        else if (optind == 1)
-                fprintf(stderr, "Option missing\n");
-        return rc;
-}
-
-const struct udevadm_cmd udevadm_control = {
-        .name = "control",
-        .cmd = adm_control,
-        .help = "Control the udev daemon",
-};
diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
deleted file mode 100644 (file)
index 00609e3..0000000
+++ /dev/null
@@ -1,689 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2012 Kay Sievers <kay@vrfy.org>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <getopt.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "util.h"
-#include "strbuf.h"
-#include "conf-files.h"
-
-#include "udev.h"
-#include "hwdb-internal.h"
-#include "hwdb-util.h"
-
-/*
- * Generic udev properties, key/value database based on modalias strings.
- * Uses a Patricia/radix trie to index all matches for efficient lookup.
- */
-
-static const char * const conf_file_dirs[] = {
-        "/etc/udev/hwdb.d",
-        UDEVLIBEXECDIR "/hwdb.d",
-        NULL
-};
-
-/* in-memory trie objects */
-struct trie {
-        struct trie_node *root;
-        struct strbuf *strings;
-
-        size_t nodes_count;
-        size_t children_count;
-        size_t values_count;
-};
-
-struct trie_node {
-        /* prefix, common part for all children of this node */
-        size_t prefix_off;
-
-        /* sorted array of pointers to children nodes */
-        struct trie_child_entry *children;
-        uint8_t children_count;
-
-        /* sorted array of key/value pairs */
-        struct trie_value_entry *values;
-        size_t values_count;
-};
-
-/* children array item with char (0-255) index */
-struct trie_child_entry {
-        uint8_t c;
-        struct trie_node *child;
-};
-
-/* value array item with key/value pairs */
-struct trie_value_entry {
-        size_t key_off;
-        size_t value_off;
-};
-
-static int trie_children_cmp(const void *v1, const void *v2) {
-        const struct trie_child_entry *n1 = v1;
-        const struct trie_child_entry *n2 = v2;
-
-        return n1->c - n2->c;
-}
-
-static int node_add_child(struct trie *trie, struct trie_node *node, struct trie_node *node_child, uint8_t c) {
-        struct trie_child_entry *child;
-
-        /* extend array, add new entry, sort for bisection */
-        child = realloc(node->children, (node->children_count + 1) * sizeof(struct trie_child_entry));
-        if (!child)
-                return -ENOMEM;
-
-        node->children = child;
-        trie->children_count++;
-        node->children[node->children_count].c = c;
-        node->children[node->children_count].child = node_child;
-        node->children_count++;
-        qsort(node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
-        trie->nodes_count++;
-
-        return 0;
-}
-
-static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) {
-        struct trie_child_entry *child;
-        struct trie_child_entry search;
-
-        search.c = c;
-        child = bsearch(&search, node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
-        if (child)
-                return child->child;
-        return NULL;
-}
-
-static void trie_node_cleanup(struct trie_node *node) {
-        size_t i;
-
-        for (i = 0; i < node->children_count; i++)
-                trie_node_cleanup(node->children[i].child);
-        free(node->children);
-        free(node->values);
-        free(node);
-}
-
-static int trie_values_cmp(const void *v1, const void *v2, void *arg) {
-        const struct trie_value_entry *val1 = v1;
-        const struct trie_value_entry *val2 = v2;
-        struct trie *trie = arg;
-
-        return strcmp(trie->strings->buf + val1->key_off,
-                      trie->strings->buf + val2->key_off);
-}
-
-static int trie_node_add_value(struct trie *trie, struct trie_node *node,
-                          const char *key, const char *value) {
-        ssize_t k, v;
-        struct trie_value_entry *val;
-
-        k = strbuf_add_string(trie->strings, key, strlen(key));
-        if (k < 0)
-                return k;
-        v = strbuf_add_string(trie->strings, value, strlen(value));
-        if (v < 0)
-                return v;
-
-        if (node->values_count) {
-                struct trie_value_entry search = {
-                        .key_off = k,
-                        .value_off = v,
-                };
-
-                val = xbsearch_r(&search, node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie);
-                if (val) {
-                        /* replace existing earlier key with new value */
-                        val->value_off = v;
-                        return 0;
-                }
-        }
-
-        /* extend array, add new entry, sort for bisection */
-        val = realloc(node->values, (node->values_count + 1) * sizeof(struct trie_value_entry));
-        if (!val)
-                return -ENOMEM;
-        trie->values_count++;
-        node->values = val;
-        node->values[node->values_count].key_off = k;
-        node->values[node->values_count].value_off = v;
-        node->values_count++;
-        qsort_r(node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie);
-        return 0;
-}
-
-static int trie_insert(struct trie *trie, struct trie_node *node, const char *search,
-                       const char *key, const char *value) {
-        size_t i = 0;
-        int err = 0;
-
-        for (;;) {
-                size_t p;
-                uint8_t c;
-                struct trie_node *child;
-
-                for (p = 0; (c = trie->strings->buf[node->prefix_off + p]); p++) {
-                        _cleanup_free_ char *s = NULL;
-                        ssize_t off;
-                        _cleanup_free_ struct trie_node *new_child = NULL;
-
-                        if (c == search[i + p])
-                                continue;
-
-                        /* split node */
-                        new_child = new0(struct trie_node, 1);
-                        if (!new_child)
-                                return -ENOMEM;
-
-                        /* move values from parent to child */
-                        new_child->prefix_off = node->prefix_off + p+1;
-                        new_child->children = node->children;
-                        new_child->children_count = node->children_count;
-                        new_child->values = node->values;
-                        new_child->values_count = node->values_count;
-
-                        /* update parent; use strdup() because the source gets realloc()d */
-                        s = strndup(trie->strings->buf + node->prefix_off, p);
-                        if (!s)
-                                return -ENOMEM;
-
-                        off = strbuf_add_string(trie->strings, s, p);
-                        if (off < 0)
-                                return off;
-
-                        node->prefix_off = off;
-                        node->children = NULL;
-                        node->children_count = 0;
-                        node->values = NULL;
-                        node->values_count = 0;
-                        err = node_add_child(trie, node, new_child, c);
-                        if (err)
-                                return err;
-
-                        new_child = NULL; /* avoid cleanup */
-                        break;
-                }
-                i += p;
-
-                c = search[i];
-                if (c == '\0')
-                        return trie_node_add_value(trie, node, key, value);
-
-                child = node_lookup(node, c);
-                if (!child) {
-                        ssize_t off;
-
-                        /* new child */
-                        child = new0(struct trie_node, 1);
-                        if (!child)
-                                return -ENOMEM;
-
-                        off = strbuf_add_string(trie->strings, search + i+1, strlen(search + i+1));
-                        if (off < 0) {
-                                free(child);
-                                return off;
-                        }
-
-                        child->prefix_off = off;
-                        err = node_add_child(trie, node, child, c);
-                        if (err) {
-                                free(child);
-                                return err;
-                        }
-
-                        return trie_node_add_value(trie, child, key, value);
-                }
-
-                node = child;
-                i++;
-        }
-}
-
-struct trie_f {
-        FILE *f;
-        struct trie *trie;
-        uint64_t strings_off;
-
-        uint64_t nodes_count;
-        uint64_t children_count;
-        uint64_t values_count;
-};
-
-/* calculate the storage space for the nodes, children arrays, value arrays */
-static void trie_store_nodes_size(struct trie_f *trie, struct trie_node *node) {
-        uint64_t i;
-
-        for (i = 0; i < node->children_count; i++)
-                trie_store_nodes_size(trie, node->children[i].child);
-
-        trie->strings_off += sizeof(struct trie_node_f);
-        for (i = 0; i < node->children_count; i++)
-                trie->strings_off += sizeof(struct trie_child_entry_f);
-        for (i = 0; i < node->values_count; i++)
-                trie->strings_off += sizeof(struct trie_value_entry_f);
-}
-
-static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) {
-        uint64_t i;
-        struct trie_node_f n = {
-                .prefix_off = htole64(trie->strings_off + node->prefix_off),
-                .children_count = node->children_count,
-                .values_count = htole64(node->values_count),
-        };
-        struct trie_child_entry_f *children = NULL;
-        int64_t node_off;
-
-        if (node->children_count) {
-                children = new0(struct trie_child_entry_f, node->children_count);
-                if (!children)
-                        return -ENOMEM;
-        }
-
-        /* post-order recursion */
-        for (i = 0; i < node->children_count; i++) {
-                int64_t child_off;
-
-                child_off = trie_store_nodes(trie, node->children[i].child);
-                if (child_off < 0) {
-                        free(children);
-                        return child_off;
-                }
-                children[i].c = node->children[i].c;
-                children[i].child_off = htole64(child_off);
-        }
-
-        /* write node */
-        node_off = ftello(trie->f);
-        fwrite(&n, sizeof(struct trie_node_f), 1, trie->f);
-        trie->nodes_count++;
-
-        /* append children array */
-        if (node->children_count) {
-                fwrite(children, sizeof(struct trie_child_entry_f), node->children_count, trie->f);
-                trie->children_count += node->children_count;
-                free(children);
-        }
-
-        /* append values array */
-        for (i = 0; i < node->values_count; i++) {
-                struct trie_value_entry_f v = {
-                        .key_off = htole64(trie->strings_off + node->values[i].key_off),
-                        .value_off = htole64(trie->strings_off + node->values[i].value_off),
-                };
-
-                fwrite(&v, sizeof(struct trie_value_entry_f), 1, trie->f);
-                trie->values_count++;
-        }
-
-        return node_off;
-}
-
-static int trie_store(struct trie *trie, const char *filename) {
-        struct trie_f t = {
-                .trie = trie,
-        };
-        _cleanup_free_ char *filename_tmp = NULL;
-        int64_t pos;
-        int64_t root_off;
-        int64_t size;
-        struct trie_header_f h = {
-                .signature = HWDB_SIG,
-                .tool_version = htole64(atoi(VERSION)),
-                .header_size = htole64(sizeof(struct trie_header_f)),
-                .node_size = htole64(sizeof(struct trie_node_f)),
-                .child_entry_size = htole64(sizeof(struct trie_child_entry_f)),
-                .value_entry_size = htole64(sizeof(struct trie_value_entry_f)),
-        };
-        int err;
-
-        /* calculate size of header, nodes, children entries, value entries */
-        t.strings_off = sizeof(struct trie_header_f);
-        trie_store_nodes_size(&t, trie->root);
-
-        err = fopen_temporary(filename , &t.f, &filename_tmp);
-        if (err < 0)
-                return err;
-        fchmod(fileno(t.f), 0444);
-
-        /* write nodes */
-        err = fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET);
-        if (err < 0) {
-                fclose(t.f);
-                unlink_noerrno(filename_tmp);
-                return -errno;
-        }
-        root_off = trie_store_nodes(&t, trie->root);
-        h.nodes_root_off = htole64(root_off);
-        pos = ftello(t.f);
-        h.nodes_len = htole64(pos - sizeof(struct trie_header_f));
-
-        /* write string buffer */
-        fwrite(trie->strings->buf, trie->strings->len, 1, t.f);
-        h.strings_len = htole64(trie->strings->len);
-
-        /* write header */
-        size = ftello(t.f);
-        h.file_size = htole64(size);
-        err = fseeko(t.f, 0, SEEK_SET);
-        if (err < 0) {
-                fclose(t.f);
-                unlink_noerrno(filename_tmp);
-                return -errno;
-        }
-        fwrite(&h, sizeof(struct trie_header_f), 1, t.f);
-        err = ferror(t.f);
-        if (err)
-                err = -errno;
-        fclose(t.f);
-        if (err < 0 || rename(filename_tmp, filename) < 0) {
-                unlink_noerrno(filename_tmp);
-                return err < 0 ? err : -errno;
-        }
-
-        log_debug("=== trie on-disk ===");
-        log_debug("size:             %8"PRIi64" bytes", size);
-        log_debug("header:           %8zu bytes", sizeof(struct trie_header_f));
-        log_debug("nodes:            %8"PRIu64" bytes (%8"PRIu64")",
-                  t.nodes_count * sizeof(struct trie_node_f), t.nodes_count);
-        log_debug("child pointers:   %8"PRIu64" bytes (%8"PRIu64")",
-                  t.children_count * sizeof(struct trie_child_entry_f), t.children_count);
-        log_debug("value pointers:   %8"PRIu64" bytes (%8"PRIu64")",
-                  t.values_count * sizeof(struct trie_value_entry_f), t.values_count);
-        log_debug("string store:     %8zu bytes", trie->strings->len);
-        log_debug("strings start:    %8"PRIu64, t.strings_off);
-
-        return 0;
-}
-
-static int insert_data(struct trie *trie, struct udev_list *match_list,
-                       char *line, const char *filename) {
-        char *value;
-        struct udev_list_entry *entry;
-
-        value = strchr(line, '=');
-        if (!value) {
-                log_error("Error, key/value pair expected but got '%s' in '%s':", line, filename);
-                return -EINVAL;
-        }
-
-        value[0] = '\0';
-        value++;
-
-        /* libudev requires properties to start with a space */
-        while (isblank(line[0]) && isblank(line[1]))
-                line++;
-
-        if (line[0] == '\0' || value[0] == '\0') {
-                log_error("Error, empty key or value '%s' in '%s':", line, filename);
-                return -EINVAL;
-        }
-
-        udev_list_entry_foreach(entry, udev_list_get_entry(match_list))
-                trie_insert(trie, trie->root, udev_list_entry_get_name(entry), line, value);
-
-        return 0;
-}
-
-static int import_file(struct udev *udev, struct trie *trie, const char *filename) {
-        enum {
-                HW_MATCH,
-                HW_DATA,
-                HW_NONE,
-        } state = HW_NONE;
-        FILE *f;
-        char line[LINE_MAX];
-        struct udev_list match_list;
-
-        udev_list_init(udev, &match_list, false);
-
-        f = fopen(filename, "re");
-        if (f == NULL)
-                return -errno;
-
-        while (fgets(line, sizeof(line), f)) {
-                size_t len;
-                char *pos;
-
-                /* comment line */
-                if (line[0] == '#')
-                        continue;
-
-                /* strip trailing comment */
-                pos = strchr(line, '#');
-                if (pos)
-                        pos[0] = '\0';
-
-                /* strip trailing whitespace */
-                len = strlen(line);
-                while (len > 0 && isspace(line[len-1]))
-                        len--;
-                line[len] = '\0';
-
-                switch (state) {
-                case HW_NONE:
-                        if (len == 0)
-                                break;
-
-                        if (line[0] == ' ') {
-                                log_error("Error, MATCH expected but got '%s' in '%s':", line, filename);
-                                break;
-                        }
-
-                        /* start of record, first match */
-                        state = HW_MATCH;
-                        udev_list_entry_add(&match_list, line, NULL);
-                        break;
-
-                case HW_MATCH:
-                        if (len == 0) {
-                                log_error("Error, DATA expected but got empty line in '%s':", filename);
-                                state = HW_NONE;
-                                udev_list_cleanup(&match_list);
-                                break;
-                        }
-
-                        /* another match */
-                        if (line[0] != ' ') {
-                                udev_list_entry_add(&match_list, line, NULL);
-                                break;
-                        }
-
-                        /* first data */
-                        state = HW_DATA;
-                        insert_data(trie, &match_list, line, filename);
-                        break;
-
-                case HW_DATA:
-                        /* end of record */
-                        if (len == 0) {
-                                state = HW_NONE;
-                                udev_list_cleanup(&match_list);
-                                break;
-                        }
-
-                        if (line[0] != ' ') {
-                                log_error("Error, DATA expected but got '%s' in '%s':", line, filename);
-                                state = HW_NONE;
-                                udev_list_cleanup(&match_list);
-                                break;
-                        }
-
-                        insert_data(trie, &match_list, line, filename);
-                        break;
-                };
-        }
-
-        fclose(f);
-        udev_list_cleanup(&match_list);
-        return 0;
-}
-
-static void help(void) {
-        printf("Usage: udevadm hwdb OPTIONS\n"
-               "  -u,--update          update the hardware database\n"
-               "  --usr                generate in " UDEVLIBEXECDIR " instead of /etc/udev\n"
-               "  -t,--test=MODALIAS   query database and print result\n"
-               "  -r,--root=PATH       alternative root path in the filesystem\n"
-               "  -h,--help\n\n");
-}
-
-static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
-        enum {
-                ARG_USR = 0x100,
-        };
-
-        static const struct option options[] = {
-                { "update", no_argument,       NULL, 'u' },
-                { "usr",    no_argument,       NULL, ARG_USR },
-                { "test",   required_argument, NULL, 't' },
-                { "root",   required_argument, NULL, 'r' },
-                { "help",   no_argument,       NULL, 'h' },
-                {}
-        };
-        const char *test = NULL;
-        const char *root = "";
-        const char *hwdb_bin_dir = "/etc/udev";
-        bool update = false;
-        struct trie *trie = NULL;
-        int err, c;
-        int rc = EXIT_SUCCESS;
-
-        while ((c = getopt_long(argc, argv, "ut:r:h", options, NULL)) >= 0)
-                switch(c) {
-                case 'u':
-                        update = true;
-                        break;
-                case ARG_USR:
-                        hwdb_bin_dir = UDEVLIBEXECDIR;
-                        break;
-                case 't':
-                        test = optarg;
-                        break;
-                case 'r':
-                        root = optarg;
-                        break;
-                case 'h':
-                        help();
-                        return EXIT_SUCCESS;
-                case '?':
-                        return EXIT_FAILURE;
-                default:
-                        assert_not_reached("Unknown option");
-                }
-
-        if (!update && !test) {
-                log_error("Either --update or --test must be used");
-                return EXIT_FAILURE;
-        }
-
-        if (update) {
-                char **files, **f;
-                _cleanup_free_ char *hwdb_bin = NULL;
-
-                trie = new0(struct trie, 1);
-                if (!trie) {
-                        rc = EXIT_FAILURE;
-                        goto out;
-                }
-
-                /* string store */
-                trie->strings = strbuf_new();
-                if (!trie->strings) {
-                        rc = EXIT_FAILURE;
-                        goto out;
-                }
-
-                /* index */
-                trie->root = new0(struct trie_node, 1);
-                if (!trie->root) {
-                        rc = EXIT_FAILURE;
-                        goto out;
-                }
-                trie->nodes_count++;
-
-                err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs);
-                if (err < 0) {
-                        log_error_errno(err, "failed to enumerate hwdb files: %m");
-                        rc = EXIT_FAILURE;
-                        goto out;
-                }
-                STRV_FOREACH(f, files) {
-                        log_debug("reading file '%s'", *f);
-                        import_file(udev, trie, *f);
-                }
-                strv_free(files);
-
-                strbuf_complete(trie->strings);
-
-                log_debug("=== trie in-memory ===");
-                log_debug("nodes:            %8zu bytes (%8zu)",
-                          trie->nodes_count * sizeof(struct trie_node), trie->nodes_count);
-                log_debug("children arrays:  %8zu bytes (%8zu)",
-                          trie->children_count * sizeof(struct trie_child_entry), trie->children_count);
-                log_debug("values arrays:    %8zu bytes (%8zu)",
-                          trie->values_count * sizeof(struct trie_value_entry), trie->values_count);
-                log_debug("strings:          %8zu bytes",
-                          trie->strings->len);
-                log_debug("strings incoming: %8zu bytes (%8zu)",
-                          trie->strings->in_len, trie->strings->in_count);
-                log_debug("strings dedup'ed: %8zu bytes (%8zu)",
-                          trie->strings->dedup_len, trie->strings->dedup_count);
-
-                hwdb_bin = strjoin(root, "/", hwdb_bin_dir, "/hwdb.bin", NULL);
-                if (!hwdb_bin) {
-                        rc = EXIT_FAILURE;
-                        goto out;
-                }
-                mkdir_parents(hwdb_bin, 0755);
-                err = trie_store(trie, hwdb_bin);
-                if (err < 0) {
-                        log_error_errno(err, "Failure writing database %s: %m", hwdb_bin);
-                        rc = EXIT_FAILURE;
-                }
-        }
-
-        if (test) {
-                _cleanup_hwdb_unref_ sd_hwdb *hwdb = NULL;
-                int r;
-
-                r = sd_hwdb_new(&hwdb);
-                if (r >= 0) {
-                        const char *key, *value;
-
-                        SD_HWDB_FOREACH_PROPERTY(hwdb, test, key, value)
-                                printf("%s=%s\n", key, value);
-                }
-        }
-out:
-        if (trie) {
-                if (trie->root)
-                        trie_node_cleanup(trie->root);
-                strbuf_cleanup(trie->strings);
-                free(trie);
-        }
-        return rc;
-}
-
-const struct udevadm_cmd udevadm_hwdb = {
-        .name = "hwdb",
-        .cmd = adm_hwdb,
-};
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
deleted file mode 100644 (file)
index 352e024..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2004-2009 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <errno.h>
-#include <getopt.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#include "udev.h"
-#include "udev-util.h"
-#include "udevadm-util.h"
-
-static bool skip_attribute(const char *name) {
-        static const char* const skip[] = {
-                "uevent",
-                "dev",
-                "modalias",
-                "resource",
-                "driver",
-                "subsystem",
-                "module",
-        };
-        unsigned int i;
-
-        for (i = 0; i < ELEMENTSOF(skip); i++)
-                if (streq(name, skip[i]))
-                        return true;
-        return false;
-}
-
-static void print_all_attributes(struct udev_device *device, const char *key) {
-        struct udev_list_entry *sysattr;
-
-        udev_list_entry_foreach(sysattr, udev_device_get_sysattr_list_entry(device)) {
-                const char *name;
-                const char *value;
-                size_t len;
-
-                name = udev_list_entry_get_name(sysattr);
-                if (skip_attribute(name))
-                        continue;
-
-                value = udev_device_get_sysattr_value(device, name);
-                if (value == NULL)
-                        continue;
-
-                /* skip any values that look like a path */
-                if (value[0] == '/')
-                        continue;
-
-                /* skip nonprintable attributes */
-                len = strlen(value);
-                while (len > 0 && isprint(value[len-1]))
-                        len--;
-                if (len > 0)
-                        continue;
-
-                printf("    %s{%s}==\"%s\"\n", key, name, value);
-        }
-        printf("\n");
-}
-
-static int print_device_chain(struct udev_device *device) {
-        struct udev_device *device_parent;
-        const char *str;
-
-        printf("\n"
-               "Udevadm info starts with the device specified by the devpath and then\n"
-               "walks up the chain of parent devices. It prints for every device\n"
-               "found, all possible attributes in the udev rules key format.\n"
-               "A rule to match, can be composed by the attributes of the device\n"
-               "and the attributes from one single parent device.\n"
-               "\n");
-
-        printf("  looking at device '%s':\n", udev_device_get_devpath(device));
-        printf("    KERNEL==\"%s\"\n", udev_device_get_sysname(device));
-        str = udev_device_get_subsystem(device);
-        if (str == NULL)
-                str = "";
-        printf("    SUBSYSTEM==\"%s\"\n", str);
-        str = udev_device_get_driver(device);
-        if (str == NULL)
-                str = "";
-        printf("    DRIVER==\"%s\"\n", str);
-        print_all_attributes(device, "ATTR");
-
-        device_parent = device;
-        do {
-                device_parent = udev_device_get_parent(device_parent);
-                if (device_parent == NULL)
-                        break;
-                printf("  looking at parent device '%s':\n", udev_device_get_devpath(device_parent));
-                printf("    KERNELS==\"%s\"\n", udev_device_get_sysname(device_parent));
-                str = udev_device_get_subsystem(device_parent);
-                if (str == NULL)
-                        str = "";
-                printf("    SUBSYSTEMS==\"%s\"\n", str);
-                str = udev_device_get_driver(device_parent);
-                if (str == NULL)
-                        str = "";
-                printf("    DRIVERS==\"%s\"\n", str);
-                print_all_attributes(device_parent, "ATTRS");
-        } while (device_parent != NULL);
-
-        return 0;
-}
-
-static void print_record(struct udev_device *device) {
-        const char *str;
-        int i;
-        struct udev_list_entry *list_entry;
-
-        printf("P: %s\n", udev_device_get_devpath(device));
-
-        str = udev_device_get_devnode(device);
-        if (str != NULL)
-                printf("N: %s\n", str + strlen("/dev/"));
-
-        i = udev_device_get_devlink_priority(device);
-        if (i != 0)
-                printf("L: %i\n", i);
-
-        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device))
-                printf("S: %s\n", udev_list_entry_get_name(list_entry) + strlen("/dev/"));
-
-        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
-                printf("E: %s=%s\n",
-                       udev_list_entry_get_name(list_entry),
-                       udev_list_entry_get_value(list_entry));
-        printf("\n");
-}
-
-static int stat_device(const char *name, bool export, const char *prefix) {
-        struct stat statbuf;
-
-        if (stat(name, &statbuf) != 0)
-                return -1;
-
-        if (export) {
-                if (prefix == NULL)
-                        prefix = "INFO_";
-                printf("%sMAJOR=%u\n"
-                       "%sMINOR=%u\n",
-                       prefix, major(statbuf.st_dev),
-                       prefix, minor(statbuf.st_dev));
-        } else
-                printf("%u:%u\n", major(statbuf.st_dev), minor(statbuf.st_dev));
-        return 0;
-}
-
-static int export_devices(struct udev *udev) {
-        struct udev_enumerate *udev_enumerate;
-        struct udev_list_entry *list_entry;
-
-        udev_enumerate = udev_enumerate_new(udev);
-        if (udev_enumerate == NULL)
-                return -1;
-        udev_enumerate_scan_devices(udev_enumerate);
-        udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
-                struct udev_device *device;
-
-                device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
-                if (device != NULL) {
-                        print_record(device);
-                        udev_device_unref(device);
-                }
-        }
-        udev_enumerate_unref(udev_enumerate);
-        return 0;
-}
-
-static void cleanup_dir(DIR *dir, mode_t mask, int depth) {
-        struct dirent *dent;
-
-        if (depth <= 0)
-                return;
-
-        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
-                struct stat stats;
-
-                if (dent->d_name[0] == '.')
-                        continue;
-                if (fstatat(dirfd(dir), dent->d_name, &stats, AT_SYMLINK_NOFOLLOW) != 0)
-                        continue;
-                if ((stats.st_mode & mask) != 0)
-                        continue;
-                if (S_ISDIR(stats.st_mode)) {
-                        DIR *dir2;
-
-                        dir2 = fdopendir(openat(dirfd(dir), dent->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC));
-                        if (dir2 != NULL) {
-                                cleanup_dir(dir2, mask, depth-1);
-                                closedir(dir2);
-                        }
-                        unlinkat(dirfd(dir), dent->d_name, AT_REMOVEDIR);
-                } else {
-                        unlinkat(dirfd(dir), dent->d_name, 0);
-                }
-        }
-}
-
-static void cleanup_db(struct udev *udev) {
-        DIR *dir;
-
-        unlink("/run/udev/queue.bin");
-
-        dir = opendir("/run/udev/data");
-        if (dir != NULL) {
-                cleanup_dir(dir, S_ISVTX, 1);
-                closedir(dir);
-        }
-
-        dir = opendir("/run/udev/links");
-        if (dir != NULL) {
-                cleanup_dir(dir, 0, 2);
-                closedir(dir);
-        }
-
-        dir = opendir("/run/udev/tags");
-        if (dir != NULL) {
-                cleanup_dir(dir, 0, 2);
-                closedir(dir);
-        }
-
-        dir = opendir("/run/udev/static_node-tags");
-        if (dir != NULL) {
-                cleanup_dir(dir, 0, 2);
-                closedir(dir);
-        }
-
-        dir = opendir("/run/udev/watch");
-        if (dir != NULL) {
-                cleanup_dir(dir, 0, 1);
-                closedir(dir);
-        }
-}
-
-static void help(void) {
-
-        printf("%s info [OPTIONS] [DEVPATH|FILE]\n\n"
-               "Query sysfs or the udev database.\n\n"
-               "  -h --help                   Print this message\n"
-               "     --version                Print version of the program\n"
-               "  -q --query=TYPE             Query device information:\n"
-               "       name                     Name of device node\n"
-               "       symlink                  Pointing to node\n"
-               "       path                     sysfs device path\n"
-               "       property                 The device properties\n"
-               "       all                      All values\n"
-               "  -p --path=SYSPATH           sysfs device path used for query or attribute walk\n"
-               "  -n --name=NAME              Node or symlink name used for query or attribute walk\n"
-               "  -r --root                   Prepend dev directory to path names\n"
-               "  -a --attribute-walk         Print all key matches walking along the chain\n"
-               "                              of parent devices\n"
-               "  -d --device-id-of-file=FILE Print major:minor of device containing this file\n"
-               "  -x --export                 Export key/value pairs\n"
-               "  -P --export-prefix          Export the key name with a prefix\n"
-               "  -e --export-db              Export the content of the udev database\n"
-               "  -c --cleanup-db             Clean up the udev database\n"
-               , program_invocation_short_name);
-}
-
-static int uinfo(struct udev *udev, int argc, char *argv[]) {
-        _cleanup_udev_device_unref_ struct udev_device *device = NULL;
-        bool root = 0;
-        bool export = 0;
-        const char *export_prefix = NULL;
-        char name[UTIL_PATH_SIZE];
-        struct udev_list_entry *list_entry;
-        int c;
-
-        static const struct option options[] = {
-                { "name",              required_argument, NULL, 'n' },
-                { "path",              required_argument, NULL, 'p' },
-                { "query",             required_argument, NULL, 'q' },
-                { "attribute-walk",    no_argument,       NULL, 'a' },
-                { "cleanup-db",        no_argument,       NULL, 'c' },
-                { "export-db",         no_argument,       NULL, 'e' },
-                { "root",              no_argument,       NULL, 'r' },
-                { "device-id-of-file", required_argument, NULL, 'd' },
-                { "export",            no_argument,       NULL, 'x' },
-                { "export-prefix",     required_argument, NULL, 'P' },
-                { "version",           no_argument,       NULL, 'V' },
-                { "help",              no_argument,       NULL, 'h' },
-                {}
-        };
-
-        enum action_type {
-                ACTION_QUERY,
-                ACTION_ATTRIBUTE_WALK,
-                ACTION_DEVICE_ID_FILE,
-        } action = ACTION_QUERY;
-
-        enum query_type {
-                QUERY_NAME,
-                QUERY_PATH,
-                QUERY_SYMLINK,
-                QUERY_PROPERTY,
-                QUERY_ALL,
-        } query = QUERY_ALL;
-
-        while ((c = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL)) >= 0)
-                switch (c) {
-                case 'n': {
-                        if (device != NULL) {
-                                fprintf(stderr, "device already specified\n");
-                                return 2;
-                        }
-
-                        device = find_device(udev, optarg, "/dev/");
-                        if (device == NULL) {
-                                fprintf(stderr, "device node not found\n");
-                                return 2;
-                        }
-                        break;
-                }
-                case 'p':
-                        if (device != NULL) {
-                                fprintf(stderr, "device already specified\n");
-                                return 2;
-                        }
-
-                        device = find_device(udev, optarg, "/sys");
-                        if (device == NULL) {
-                                fprintf(stderr, "syspath not found\n");
-                                return 2;
-                        }
-                        break;
-                case 'q':
-                        action = ACTION_QUERY;
-                        if (streq(optarg, "property") || streq(optarg, "env"))
-                                query = QUERY_PROPERTY;
-                        else if (streq(optarg, "name"))
-                                query = QUERY_NAME;
-                        else if (streq(optarg, "symlink"))
-                                query = QUERY_SYMLINK;
-                        else if (streq(optarg, "path"))
-                                query = QUERY_PATH;
-                        else if (streq(optarg, "all"))
-                                query = QUERY_ALL;
-                        else {
-                                fprintf(stderr, "unknown query type\n");
-                                return 3;
-                        }
-                        break;
-                case 'r':
-                        root = true;
-                        break;
-                case 'd':
-                        action = ACTION_DEVICE_ID_FILE;
-                        strscpy(name, sizeof(name), optarg);
-                        break;
-                case 'a':
-                        action = ACTION_ATTRIBUTE_WALK;
-                        break;
-                case 'e':
-                        export_devices(udev);
-                        return 0;
-                case 'c':
-                        cleanup_db(udev);
-                        return 0;
-                case 'x':
-                        export = true;
-                        break;
-                case 'P':
-                        export_prefix = optarg;
-                        break;
-                case 'V':
-                        printf("%s\n", VERSION);
-                        return 0;
-                case 'h':
-                        help();
-                        return 0;
-                default:
-                        return 1;
-                }
-
-        switch (action) {
-        case ACTION_QUERY:
-                if (!device) {
-                        if (!argv[optind]) {
-                                help();
-                                return 2;
-                        }
-                        device = find_device(udev, argv[optind], NULL);
-                        if (!device) {
-                                fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n");
-                                return 4;
-                        }
-                }
-
-                switch(query) {
-                case QUERY_NAME: {
-                        const char *node = udev_device_get_devnode(device);
-
-                        if (node == NULL) {
-                                fprintf(stderr, "no device node found\n");
-                                return 5;
-                        }
-
-                        if (root)
-                                printf("%s\n", udev_device_get_devnode(device));
-                        else
-                                printf("%s\n", udev_device_get_devnode(device) + strlen("/dev/"));
-                        break;
-                }
-                case QUERY_SYMLINK:
-                        list_entry = udev_device_get_devlinks_list_entry(device);
-                        while (list_entry != NULL) {
-                                if (root)
-                                        printf("%s", udev_list_entry_get_name(list_entry));
-                                else
-                                        printf("%s", udev_list_entry_get_name(list_entry) + strlen("/dev/"));
-                                list_entry = udev_list_entry_get_next(list_entry);
-                                if (list_entry != NULL)
-                                        printf(" ");
-                        }
-                        printf("\n");
-                        break;
-                case QUERY_PATH:
-                        printf("%s\n", udev_device_get_devpath(device));
-                        return 0;
-                case QUERY_PROPERTY:
-                        list_entry = udev_device_get_properties_list_entry(device);
-                        while (list_entry != NULL) {
-                                if (export) {
-                                        const char *prefix = export_prefix;
-
-                                        if (prefix == NULL)
-                                                prefix = "";
-                                        printf("%s%s='%s'\n", prefix,
-                                               udev_list_entry_get_name(list_entry),
-                                               udev_list_entry_get_value(list_entry));
-                                } else {
-                                        printf("%s=%s\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
-                                }
-                                list_entry = udev_list_entry_get_next(list_entry);
-                        }
-                        break;
-                case QUERY_ALL:
-                        print_record(device);
-                        break;
-                default:
-                        assert_not_reached("unknown query type");
-                }
-                break;
-        case ACTION_ATTRIBUTE_WALK:
-                if (!device && argv[optind]) {
-                        device = find_device(udev, argv[optind], NULL);
-                        if (!device) {
-                                fprintf(stderr, "Unknown device, absolute path in /dev/ or /sys expected.\n");
-                                return 4;
-                        }
-                }
-                if (!device) {
-                        fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n");
-                        return 4;
-                }
-                print_device_chain(device);
-                break;
-        case ACTION_DEVICE_ID_FILE:
-                if (stat_device(name, export, export_prefix) != 0)
-                        return 1;
-                break;
-        }
-
-        return 0;
-}
-
-const struct udevadm_cmd udevadm_info = {
-        .name = "info",
-        .cmd = uinfo,
-        .help = "Query sysfs or the udev database",
-};
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
deleted file mode 100644 (file)
index 7ef2e68..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2004-2010 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-#include <getopt.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/epoll.h>
-
-#include "udev.h"
-#include "udev-util.h"
-
-static bool udev_exit;
-
-static void sig_handler(int signum) {
-        if (signum == SIGINT || signum == SIGTERM)
-                udev_exit = true;
-}
-
-static void print_device(struct udev_device *device, const char *source, int prop) {
-        struct timespec ts;
-
-        clock_gettime(CLOCK_MONOTONIC, &ts);
-        printf("%-6s[%"PRI_TIME".%06ld] %-8s %s (%s)\n",
-               source,
-               ts.tv_sec, ts.tv_nsec/1000,
-               udev_device_get_action(device),
-               udev_device_get_devpath(device),
-               udev_device_get_subsystem(device));
-        if (prop) {
-                struct udev_list_entry *list_entry;
-
-                udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
-                        printf("%s=%s\n",
-                               udev_list_entry_get_name(list_entry),
-                               udev_list_entry_get_value(list_entry));
-                printf("\n");
-        }
-}
-
-static void help(void) {
-        printf("%s monitor [--property] [--kernel] [--udev] [--help]\n\n"
-               "Listen to kernel and udev events.\n\n"
-               "  -h --help                                Show this help\n"
-               "     --version                             Show package version\n"
-               "  -p --property                            Print the event properties\n"
-               "  -k --kernel                              Print kernel uevents\n"
-               "  -u --udev                                Print udev events\n"
-               "  -s --subsystem-match=SUBSYSTEM[/DEVTYPE] Filter events by subsystem\n"
-               "  -t --tag-match=TAG                       Filter events by tag\n"
-               , program_invocation_short_name);
-}
-
-static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
-        struct sigaction act = {};
-        sigset_t mask;
-        bool prop = false;
-        bool print_kernel = false;
-        bool print_udev = false;
-        _cleanup_udev_list_cleanup_ struct udev_list subsystem_match_list;
-        _cleanup_udev_list_cleanup_ struct udev_list tag_match_list;
-        _cleanup_udev_monitor_unref_ struct udev_monitor *udev_monitor = NULL;
-        _cleanup_udev_monitor_unref_ struct udev_monitor *kernel_monitor = NULL;
-        _cleanup_close_ int fd_ep = -1;
-        int fd_kernel = -1, fd_udev = -1;
-        struct epoll_event ep_kernel, ep_udev;
-        int c;
-
-        static const struct option options[] = {
-                { "property",        no_argument,       NULL, 'p' },
-                { "environment",     no_argument,       NULL, 'e' }, /* alias for -p */
-                { "kernel",          no_argument,       NULL, 'k' },
-                { "udev",            no_argument,       NULL, 'u' },
-                { "subsystem-match", required_argument, NULL, 's' },
-                { "tag-match",       required_argument, NULL, 't' },
-                { "help",            no_argument,       NULL, 'h' },
-                {}
-        };
-
-        udev_list_init(udev, &subsystem_match_list, true);
-        udev_list_init(udev, &tag_match_list, true);
-
-        while((c = getopt_long(argc, argv, "pekus:t:h", options, NULL)) >= 0)
-                switch (c) {
-                case 'p':
-                case 'e':
-                        prop = true;
-                        break;
-                case 'k':
-                        print_kernel = true;
-                        break;
-                case 'u':
-                        print_udev = true;
-                        break;
-                case 's':
-                        {
-                                char subsys[UTIL_NAME_SIZE];
-                                char *devtype;
-
-                                strscpy(subsys, sizeof(subsys), optarg);
-                                devtype = strchr(subsys, '/');
-                                if (devtype != NULL) {
-                                        devtype[0] = '\0';
-                                        devtype++;
-                                }
-                                udev_list_entry_add(&subsystem_match_list, subsys, devtype);
-                                break;
-                        }
-                case 't':
-                        udev_list_entry_add(&tag_match_list, optarg, NULL);
-                        break;
-                case 'h':
-                        help();
-                        return 0;
-                default:
-                        return 1;
-                }
-
-        if (!print_kernel && !print_udev) {
-                print_kernel = true;
-                print_udev = true;
-        }
-
-        /* set signal handlers */
-        act.sa_handler = sig_handler;
-        act.sa_flags = SA_RESTART;
-        sigaction(SIGINT, &act, NULL);
-        sigaction(SIGTERM, &act, NULL);
-        sigemptyset(&mask);
-        sigaddset(&mask, SIGINT);
-        sigaddset(&mask, SIGTERM);
-        sigprocmask(SIG_UNBLOCK, &mask, NULL);
-
-        fd_ep = epoll_create1(EPOLL_CLOEXEC);
-        if (fd_ep < 0) {
-                log_error_errno(errno, "error creating epoll fd: %m");
-                return 1;
-        }
-
-        printf("monitor will print the received events for:\n");
-        if (print_udev) {
-                struct udev_list_entry *entry;
-
-                udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
-                if (udev_monitor == NULL) {
-                        fprintf(stderr, "error: unable to create netlink socket\n");
-                        return 1;
-                }
-                udev_monitor_set_receive_buffer_size(udev_monitor, 128*1024*1024);
-                fd_udev = udev_monitor_get_fd(udev_monitor);
-
-                udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) {
-                        const char *subsys = udev_list_entry_get_name(entry);
-                        const char *devtype = udev_list_entry_get_value(entry);
-
-                        if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsys, devtype) < 0)
-                                fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys);
-                }
-
-                udev_list_entry_foreach(entry, udev_list_get_entry(&tag_match_list)) {
-                        const char *tag = udev_list_entry_get_name(entry);
-
-                        if (udev_monitor_filter_add_match_tag(udev_monitor, tag) < 0)
-                                fprintf(stderr, "error: unable to apply tag filter '%s'\n", tag);
-                }
-
-                if (udev_monitor_enable_receiving(udev_monitor) < 0) {
-                        fprintf(stderr, "error: unable to subscribe to udev events\n");
-                        return 2;
-                }
-
-                memzero(&ep_udev, sizeof(struct epoll_event));
-                ep_udev.events = EPOLLIN;
-                ep_udev.data.fd = fd_udev;
-                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
-                        log_error_errno(errno, "fail to add fd to epoll: %m");
-                        return 2;
-                }
-
-                printf("UDEV - the event which udev sends out after rule processing\n");
-        }
-
-        if (print_kernel) {
-                struct udev_list_entry *entry;
-
-                kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel");
-                if (kernel_monitor == NULL) {
-                        fprintf(stderr, "error: unable to create netlink socket\n");
-                        return 3;
-                }
-                udev_monitor_set_receive_buffer_size(kernel_monitor, 128*1024*1024);
-                fd_kernel = udev_monitor_get_fd(kernel_monitor);
-
-                udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) {
-                        const char *subsys = udev_list_entry_get_name(entry);
-
-                        if (udev_monitor_filter_add_match_subsystem_devtype(kernel_monitor, subsys, NULL) < 0)
-                                fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys);
-                }
-
-                if (udev_monitor_enable_receiving(kernel_monitor) < 0) {
-                        fprintf(stderr, "error: unable to subscribe to kernel events\n");
-                        return 4;
-                }
-
-                memzero(&ep_kernel, sizeof(struct epoll_event));
-                ep_kernel.events = EPOLLIN;
-                ep_kernel.data.fd = fd_kernel;
-                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_kernel, &ep_kernel) < 0) {
-                        log_error_errno(errno, "fail to add fd to epoll: %m");
-                        return 5;
-                }
-
-                printf("KERNEL - the kernel uevent\n");
-        }
-        printf("\n");
-
-        while (!udev_exit) {
-                int fdcount;
-                struct epoll_event ev[4];
-                int i;
-
-                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1);
-                if (fdcount < 0) {
-                        if (errno != EINTR)
-                                fprintf(stderr, "error receiving uevent message: %m\n");
-                        continue;
-                }
-
-                for (i = 0; i < fdcount; i++) {
-                        if (ev[i].data.fd == fd_kernel && ev[i].events & EPOLLIN) {
-                                struct udev_device *device;
-
-                                device = udev_monitor_receive_device(kernel_monitor);
-                                if (device == NULL)
-                                        continue;
-                                print_device(device, "KERNEL", prop);
-                                udev_device_unref(device);
-                        } else if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
-                                struct udev_device *device;
-
-                                device = udev_monitor_receive_device(udev_monitor);
-                                if (device == NULL)
-                                        continue;
-                                print_device(device, "UDEV", prop);
-                                udev_device_unref(device);
-                        }
-                }
-        }
-
-        return 0;
-}
-
-const struct udevadm_cmd udevadm_monitor = {
-        .name = "monitor",
-        .cmd = adm_monitor,
-        .help = "Listen to kernel and udev events",
-};
diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c
deleted file mode 100644 (file)
index 0d3025e..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Kay Sievers <kay@vrfy.org>
- * Copyright (C) 2009 Canonical Ltd.
- * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-#include <poll.h>
-
-#include "udev.h"
-#include "util.h"
-
-static void help(void) {
-        printf("%s settle OPTIONS\n\n"
-               "Wait for pending udev events.\n\n"
-               "  -h --help                 Show this help\n"
-               "     --version              Show package version\n"
-               "  -t --timeout=SECONDS      Maximum time to wait for events\n"
-               "  -E --exit-if-exists=FILE  Stop waiting if file exists\n"
-               , program_invocation_short_name);
-}
-
-static int adm_settle(struct udev *udev, int argc, char *argv[]) {
-        static const struct option options[] = {
-                { "timeout",        required_argument, NULL, 't' },
-                { "exit-if-exists", required_argument, NULL, 'E' },
-                { "help",           no_argument,       NULL, 'h' },
-                { "seq-start",      required_argument, NULL, 's' }, /* removed */
-                { "seq-end",        required_argument, NULL, 'e' }, /* removed */
-                { "quiet",          no_argument,       NULL, 'q' }, /* removed */
-                {}
-        };
-        const char *exists = NULL;
-        unsigned int timeout = 120;
-        struct pollfd pfd[1] = { {.fd = -1}, };
-        int c;
-        struct udev_queue *queue;
-        int rc = EXIT_FAILURE;
-
-        while ((c = getopt_long(argc, argv, "t:E:hs:e:q", options, NULL)) >= 0) {
-                switch (c) {
-
-                case 't': {
-                        int r;
-
-                        r = safe_atou(optarg, &timeout);
-                        if (r < 0) {
-                                fprintf(stderr, "Invalid timeout value '%s': %s\n",
-                                        optarg, strerror(-r));
-                                exit(EXIT_FAILURE);
-                        };
-                        break;
-                }
-
-                case 'E':
-                        exists = optarg;
-                        break;
-
-                case 'h':
-                        help();
-                        return EXIT_SUCCESS;
-
-                case 's':
-                case 'e':
-                case 'q':
-                        log_info("Option -%c no longer supported.", c);
-                        return EXIT_FAILURE;
-
-                case '?':
-                        return EXIT_FAILURE;
-
-                default:
-                        assert_not_reached("Unknown argument");
-                }
-        }
-
-        if (optind < argc) {
-                fprintf(stderr, "Extraneous argument: '%s'\n", argv[optind]);
-                return EXIT_FAILURE;
-        }
-
-        /* guarantee that the udev daemon isn't pre-processing */
-        if (getuid() == 0) {
-                struct udev_ctrl *uctrl;
-
-                uctrl = udev_ctrl_new(udev);
-                if (uctrl != NULL) {
-                        if (udev_ctrl_send_ping(uctrl, timeout) < 0) {
-                                log_debug("no connection to daemon");
-                                udev_ctrl_unref(uctrl);
-                                return EXIT_SUCCESS;
-                        }
-                        udev_ctrl_unref(uctrl);
-                }
-        }
-
-        queue = udev_queue_new(udev);
-        if (!queue) {
-                log_error("unable to get udev queue");
-                return EXIT_FAILURE;
-        }
-
-        pfd[0].events = POLLIN;
-        pfd[0].fd = udev_queue_get_fd(queue);
-        if (pfd[0].fd < 0) {
-                log_debug("queue is empty, nothing to watch");
-                rc = EXIT_SUCCESS;
-                goto out;
-        }
-
-        for (;;) {
-                if (exists && access(exists, F_OK) >= 0) {
-                        rc = EXIT_SUCCESS;
-                        break;
-                }
-
-                /* exit if queue is empty */
-                if (udev_queue_get_queue_is_empty(queue)) {
-                        rc = EXIT_SUCCESS;
-                        break;
-                }
-
-                /* wake up when queue is empty */
-                if (poll(pfd, 1, MSEC_PER_SEC) > 0 && pfd[0].revents & POLLIN)
-                        udev_queue_flush(queue);
-        }
-
-out:
-        udev_queue_unref(queue);
-        return rc;
-}
-
-const struct udevadm_cmd udevadm_settle = {
-        .name = "settle",
-        .cmd = adm_settle,
-        .help = "Wait for pending udev events",
-};
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
deleted file mode 100644 (file)
index 35a7349..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2011 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "udev.h"
-
-static void help(struct udev *udev) {
-        printf("%s builtin [--help] COMMAND SYSPATH\n\n"
-               "Test a built-in command.\n\n"
-               "  -h --help     Print this message\n"
-               "     --version  Print version of the program\n\n"
-               "Commands:\n"
-               , program_invocation_short_name);
-
-        udev_builtin_list(udev);
-}
-
-static int adm_builtin(struct udev *udev, int argc, char *argv[]) {
-        static const struct option options[] = {
-                { "help", no_argument, NULL, 'h' },
-                {}
-        };
-        char *command = NULL;
-        char *syspath = NULL;
-        char filename[UTIL_PATH_SIZE];
-        struct udev_device *dev = NULL;
-        enum udev_builtin_cmd cmd;
-        int rc = EXIT_SUCCESS, c;
-
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
-                switch (c) {
-                case 'h':
-                        help(udev);
-                        goto out;
-                }
-
-        command = argv[optind++];
-        if (command == NULL) {
-                fprintf(stderr, "command missing\n");
-                help(udev);
-                rc = 2;
-                goto out;
-        }
-
-        syspath = argv[optind++];
-        if (syspath == NULL) {
-                fprintf(stderr, "syspath missing\n");
-                rc = 3;
-                goto out;
-        }
-
-        udev_builtin_init(udev);
-
-        cmd = udev_builtin_lookup(command);
-        if (cmd >= UDEV_BUILTIN_MAX) {
-                fprintf(stderr, "unknown command '%s'\n", command);
-                help(udev);
-                rc = 5;
-                goto out;
-        }
-
-        /* add /sys if needed */
-        if (!startswith(syspath, "/sys"))
-                strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
-        else
-                strscpy(filename, sizeof(filename), syspath);
-        util_remove_trailing_chars(filename, '/');
-
-        dev = udev_device_new_from_syspath(udev, filename);
-        if (dev == NULL) {
-                fprintf(stderr, "unable to open device '%s'\n\n", filename);
-                rc = 4;
-                goto out;
-        }
-
-        rc = udev_builtin_run(dev, cmd, command, true);
-        if (rc < 0) {
-                fprintf(stderr, "error executing '%s', exit code %i\n\n", command, rc);
-                rc = 6;
-        }
-out:
-        udev_device_unref(dev);
-        udev_builtin_exit(udev);
-        return rc;
-}
-
-const struct udevadm_cmd udevadm_test_builtin = {
-        .name = "test-builtin",
-        .cmd = adm_builtin,
-        .help = "Test a built-in command",
-        .debug = true,
-};
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
deleted file mode 100644 (file)
index fe092cf..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2004-2008 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <getopt.h>
-#include <sys/signalfd.h>
-
-#include "udev.h"
-#include "udev-util.h"
-
-static void help(void) {
-
-        printf("%s test OPTIONS <syspath>\n\n"
-               "Test an event run.\n"
-               "  -h --help                            Show this help\n"
-               "     --version                         Show package version\n"
-               "  -a --action=ACTION                   Set action string\n"
-               "  -N --resolve-names=early|late|never  When to resolve names\n"
-               , program_invocation_short_name);
-}
-
-static int adm_test(struct udev *udev, int argc, char *argv[]) {
-        int resolve_names = 1;
-        char filename[UTIL_PATH_SIZE];
-        const char *action = "add";
-        const char *syspath = NULL;
-        struct udev_list_entry *entry;
-        _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL;
-        _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
-        _cleanup_udev_event_unref_ struct udev_event *event = NULL;
-        sigset_t mask, sigmask_orig;
-        int rc = 0, c;
-
-        static const struct option options[] = {
-                { "action", required_argument, NULL, 'a' },
-                { "resolve-names", required_argument, NULL, 'N' },
-                { "help", no_argument, NULL, 'h' },
-                {}
-        };
-
-        log_debug("version %s", VERSION);
-
-        while((c = getopt_long(argc, argv, "a:N:h", options, NULL)) >= 0)
-                switch (c) {
-                case 'a':
-                        action = optarg;
-                        break;
-                case 'N':
-                        if (streq (optarg, "early")) {
-                                resolve_names = 1;
-                        } else if (streq (optarg, "late")) {
-                                resolve_names = 0;
-                        } else if (streq (optarg, "never")) {
-                                resolve_names = -1;
-                        } else {
-                                fprintf(stderr, "resolve-names must be early, late or never\n");
-                                log_error("resolve-names must be early, late or never");
-                                exit(EXIT_FAILURE);
-                        }
-                        break;
-                case 'h':
-                        help();
-                        exit(EXIT_SUCCESS);
-                case '?':
-                        exit(EXIT_FAILURE);
-                default:
-                        assert_not_reached("Unknown option");
-                }
-
-        syspath = argv[optind];
-        if (syspath == NULL) {
-                fprintf(stderr, "syspath parameter missing\n");
-                rc = 2;
-                goto out;
-        }
-
-        printf("This program is for debugging only, it does not run any program\n"
-               "specified by a RUN key. It may show incorrect results, because\n"
-               "some values may be different, or not available at a simulation run.\n"
-               "\n");
-
-        sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);
-
-        udev_builtin_init(udev);
-
-        rules = udev_rules_new(udev, resolve_names);
-        if (rules == NULL) {
-                fprintf(stderr, "error reading rules\n");
-                rc = 3;
-                goto out;
-        }
-
-        /* add /sys if needed */
-        if (!startswith(syspath, "/sys"))
-                strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
-        else
-                strscpy(filename, sizeof(filename), syspath);
-        util_remove_trailing_chars(filename, '/');
-
-        dev = udev_device_new_from_synthetic_event(udev, filename, action);
-        if (dev == NULL) {
-                fprintf(stderr, "unable to open device '%s'\n", filename);
-                rc = 4;
-                goto out;
-        }
-
-        /* don't read info from the db */
-        udev_device_set_info_loaded(dev);
-
-        event = udev_event_new(dev);
-
-        sigfillset(&mask);
-        sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
-        event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
-        if (event->fd_signal < 0) {
-                fprintf(stderr, "error creating signalfd\n");
-                rc = 5;
-                goto out;
-        }
-
-        udev_event_execute_rules(event,
-                                 60 * USEC_PER_SEC, 20 * USEC_PER_SEC,
-                                 NULL,
-                                 rules,
-                                 &sigmask_orig);
-
-        udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
-                printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
-
-        udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) {
-                char program[UTIL_PATH_SIZE];
-
-                udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program));
-                printf("run: '%s'\n", program);
-        }
-out:
-        if (event != NULL && event->fd_signal >= 0)
-                close(event->fd_signal);
-        udev_builtin_exit(udev);
-        return rc;
-}
-
-const struct udevadm_cmd udevadm_test = {
-        .name = "test",
-        .cmd = adm_test,
-        .help = "Test an event run",
-        .debug = true,
-};
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
deleted file mode 100644 (file)
index 11e83f3..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include "udev.h"
-#include "udev-util.h"
-#include "udevadm-util.h"
-#include "util.h"
-
-static int verbose;
-static int dry_run;
-
-static void exec_list(struct udev_enumerate *udev_enumerate, const char *action) {
-        struct udev_list_entry *entry;
-
-        udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(udev_enumerate)) {
-                char filename[UTIL_PATH_SIZE];
-                int fd;
-
-                if (verbose)
-                        printf("%s\n", udev_list_entry_get_name(entry));
-                if (dry_run)
-                        continue;
-                strscpyl(filename, sizeof(filename), udev_list_entry_get_name(entry), "/uevent", NULL);
-                fd = open(filename, O_WRONLY|O_CLOEXEC);
-                if (fd < 0)
-                        continue;
-                if (write(fd, action, strlen(action)) < 0)
-                        log_debug_errno(errno, "error writing '%s' to '%s': %m", action, filename);
-                close(fd);
-        }
-}
-
-static const char *keyval(const char *str, const char **val, char *buf, size_t size) {
-        char *pos;
-
-        strscpy(buf, size,str);
-        pos = strchr(buf, '=');
-        if (pos != NULL) {
-                pos[0] = 0;
-                pos++;
-        }
-        *val = pos;
-        return buf;
-}
-
-static void help(void) {
-        printf("%s trigger OPTIONS\n\n"
-               "Request events from the kernel.\n\n"
-               "  -h --help                         Show this help\n"
-               "     --version                      Show package version\n"
-               "  -v --verbose                      Print the list of devices while running\n"
-               "  -n --dry-run                      Do not actually trigger the events\n"
-               "  -t --type=                        Type of events to trigger\n"
-               "          devices                     sysfs devices (default)\n"
-               "          subsystems                  sysfs subsystems and drivers\n"
-               "  -c --action=ACTION                Event action value, default is \"change\"\n"
-               "  -s --subsystem-match=SUBSYSTEM    Trigger devices from a matching subsystem\n"
-               "  -S --subsystem-nomatch=SUBSYSTEM  Exclude devices from a matching subsystem\n"
-               "  -a --attr-match=FILE[=VALUE]      Trigger devices with a matching attribute\n"
-               "  -A --attr-nomatch=FILE[=VALUE]    Exclude devices with a matching attribute\n"
-               "  -p --property-match=KEY=VALUE     Trigger devices with a matching property\n"
-               "  -g --tag-match=KEY=VALUE          Trigger devices with a matching property\n"
-               "  -y --sysname-match=NAME           Trigger devices with this /sys path\n"
-               "     --name-match=NAME              Trigger devices with this /dev name\n"
-               "  -b --parent-match=NAME            Trigger devices with that parent device\n"
-               , program_invocation_short_name);
-}
-
-static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
-        enum {
-                ARG_NAME = 0x100,
-        };
-
-        static const struct option options[] = {
-                { "verbose",           no_argument,       NULL, 'v'      },
-                { "dry-run",           no_argument,       NULL, 'n'      },
-                { "type",              required_argument, NULL, 't'      },
-                { "action",            required_argument, NULL, 'c'      },
-                { "subsystem-match",   required_argument, NULL, 's'      },
-                { "subsystem-nomatch", required_argument, NULL, 'S'      },
-                { "attr-match",        required_argument, NULL, 'a'      },
-                { "attr-nomatch",      required_argument, NULL, 'A'      },
-                { "property-match",    required_argument, NULL, 'p'      },
-                { "tag-match",         required_argument, NULL, 'g'      },
-                { "sysname-match",     required_argument, NULL, 'y'      },
-                { "name-match",        required_argument, NULL, ARG_NAME },
-                { "parent-match",      required_argument, NULL, 'b'      },
-                { "help",              no_argument,       NULL, 'h'      },
-                {}
-        };
-        enum {
-                TYPE_DEVICES,
-                TYPE_SUBSYSTEMS,
-        } device_type = TYPE_DEVICES;
-        const char *action = "change";
-        _cleanup_udev_enumerate_unref_ struct udev_enumerate *udev_enumerate = NULL;
-        int c;
-
-        udev_enumerate = udev_enumerate_new(udev);
-        if (udev_enumerate == NULL)
-                return 1;
-
-        while ((c = getopt_long(argc, argv, "vno:t:c:s:S:a:A:p:g:y:b:h", options, NULL)) >= 0) {
-                const char *key;
-                const char *val;
-                char buf[UTIL_PATH_SIZE];
-
-                switch (c) {
-                case 'v':
-                        verbose = 1;
-                        break;
-                case 'n':
-                        dry_run = 1;
-                        break;
-                case 't':
-                        if (streq(optarg, "devices"))
-                                device_type = TYPE_DEVICES;
-                        else if (streq(optarg, "subsystems"))
-                                device_type = TYPE_SUBSYSTEMS;
-                        else {
-                                log_error("unknown type --type=%s", optarg);
-                                return 2;
-                        }
-                        break;
-                case 'c':
-                        if (!nulstr_contains("add\0" "remove\0" "change\0", optarg)) {
-                                log_error("unknown action '%s'", optarg);
-                                return 2;
-                        } else
-                                action = optarg;
-
-                        break;
-                case 's':
-                        udev_enumerate_add_match_subsystem(udev_enumerate, optarg);
-                        break;
-                case 'S':
-                        udev_enumerate_add_nomatch_subsystem(udev_enumerate, optarg);
-                        break;
-                case 'a':
-                        key = keyval(optarg, &val, buf, sizeof(buf));
-                        udev_enumerate_add_match_sysattr(udev_enumerate, key, val);
-                        break;
-                case 'A':
-                        key = keyval(optarg, &val, buf, sizeof(buf));
-                        udev_enumerate_add_nomatch_sysattr(udev_enumerate, key, val);
-                        break;
-                case 'p':
-                        key = keyval(optarg, &val, buf, sizeof(buf));
-                        udev_enumerate_add_match_property(udev_enumerate, key, val);
-                        break;
-                case 'g':
-                        udev_enumerate_add_match_tag(udev_enumerate, optarg);
-                        break;
-                case 'y':
-                        udev_enumerate_add_match_sysname(udev_enumerate, optarg);
-                        break;
-                case 'b': {
-                        _cleanup_udev_device_unref_ struct udev_device *dev;
-
-                        dev = find_device(udev, optarg, "/sys");
-                        if (dev == NULL) {
-                                log_error("unable to open the device '%s'", optarg);
-                                return 2;
-                        }
-
-                        udev_enumerate_add_match_parent(udev_enumerate, dev);
-                        break;
-                }
-
-                case ARG_NAME: {
-                        _cleanup_udev_device_unref_ struct udev_device *dev;
-
-                        dev = find_device(udev, optarg, "/dev/");
-                        if (dev == NULL) {
-                                log_error("unable to open the device '%s'", optarg);
-                                return 2;
-                        }
-
-                        udev_enumerate_add_match_parent(udev_enumerate, dev);
-                        break;
-                }
-
-                case 'h':
-                        help();
-                        return 0;
-                case '?':
-                        return 1;
-                default:
-                        assert_not_reached("Unknown option");
-                }
-        }
-
-        for (; optind < argc; optind++) {
-                _cleanup_udev_device_unref_ struct udev_device *dev;
-
-                dev = find_device(udev, argv[optind], NULL);
-                if (dev == NULL) {
-                        log_error("unable to open the device '%s'", argv[optind]);
-                        return 2;
-                }
-
-                udev_enumerate_add_match_parent(udev_enumerate, dev);
-        }
-
-        switch (device_type) {
-        case TYPE_SUBSYSTEMS:
-                udev_enumerate_scan_subsystems(udev_enumerate);
-                exec_list(udev_enumerate, action);
-                return 0;
-        case TYPE_DEVICES:
-                udev_enumerate_scan_devices(udev_enumerate);
-                exec_list(udev_enumerate, action);
-                return 0;
-        default:
-                assert_not_reached("device_type");
-        }
-}
-
-const struct udevadm_cmd udevadm_trigger = {
-        .name = "trigger",
-        .cmd = adm_trigger,
-        .help = "Request events from the kernel",
-};
diff --git a/src/udev/udevadm-util.c b/src/udev/udevadm-util.c
deleted file mode 100644 (file)
index 3f0e45e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "udevadm-util.h"
-
-struct udev_device *find_device(struct udev *udev,
-                                const char *id,
-                                const char *prefix) {
-
-        assert(udev);
-        assert(id);
-
-        if (prefix && !startswith(id, prefix))
-                id = strjoina(prefix, id);
-
-        if (startswith(id, "/dev/")) {
-                struct stat statbuf;
-                char type;
-
-                if (stat(id, &statbuf) < 0)
-                        return NULL;
-
-                if (S_ISBLK(statbuf.st_mode))
-                        type = 'b';
-                else if (S_ISCHR(statbuf.st_mode))
-                        type = 'c';
-                else
-                        return NULL;
-
-                return udev_device_new_from_devnum(udev, type, statbuf.st_rdev);
-        } else if (startswith(id, "/sys/"))
-                return udev_device_new_from_syspath(udev, id);
-        else
-                return NULL;
-}
diff --git a/src/udev/udevadm-util.h b/src/udev/udevadm-util.h
deleted file mode 100644 (file)
index 37e4fe8..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2014 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include "udev.h"
-
-struct udev_device *find_device(struct udev *udev,
-                                const char *id,
-                                const char *prefix);
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
deleted file mode 100644 (file)
index b86d892..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-/*
- * Copyright (C) 2007-2012 Kay Sievers <kay@vrfy.org>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "selinux-util.h"
-#include "udev.h"
-
-static int adm_version(struct udev *udev, int argc, char *argv[]) {
-        printf("%s\n", VERSION);
-        return 0;
-}
-
-static const struct udevadm_cmd udevadm_version = {
-        .name = "version",
-        .cmd = adm_version,
-};
-
-static int adm_help(struct udev *udev, int argc, char *argv[]);
-
-static const struct udevadm_cmd udevadm_help = {
-        .name = "help",
-        .cmd = adm_help,
-};
-
-static const struct udevadm_cmd *udevadm_cmds[] = {
-        &udevadm_info,
-        &udevadm_trigger,
-        &udevadm_settle,
-        &udevadm_control,
-        &udevadm_monitor,
-        &udevadm_hwdb,
-        &udevadm_test,
-        &udevadm_test_builtin,
-        &udevadm_version,
-        &udevadm_help,
-};
-
-static int adm_help(struct udev *udev, int argc, char *argv[]) {
-        unsigned int i;
-
-        printf("%s [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n\n"
-               "Send control commands or test the device manager.\n\n"
-               "Commands:\n"
-               , program_invocation_short_name);
-
-        for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++)
-                if (udevadm_cmds[i]->help != NULL)
-                        printf("  %-12s  %s\n", udevadm_cmds[i]->name, udevadm_cmds[i]->help);
-        return 0;
-}
-
-static int run_command(struct udev *udev, const struct udevadm_cmd *cmd, int argc, char *argv[]) {
-        if (cmd->debug)
-                log_set_max_level(LOG_DEBUG);
-        log_debug("calling: %s", cmd->name);
-        return cmd->cmd(udev, argc, argv);
-}
-
-int main(int argc, char *argv[]) {
-        struct udev *udev;
-        static const struct option options[] = {
-                { "debug", no_argument, NULL, 'd' },
-                { "help", no_argument, NULL, 'h' },
-                { "version", no_argument, NULL, 'V' },
-                {}
-        };
-        const char *command;
-        unsigned int i;
-        int rc = 1, c;
-
-        udev = udev_new();
-        if (udev == NULL)
-                goto out;
-
-        log_parse_environment();
-        log_open();
-        mac_selinux_init("/dev");
-
-        while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
-                switch (c) {
-
-                case 'd':
-                        log_set_max_level(LOG_DEBUG);
-                        break;
-
-                case 'h':
-                        rc = adm_help(udev, argc, argv);
-                        goto out;
-
-                case 'V':
-                        rc = adm_version(udev, argc, argv);
-                        goto out;
-
-                default:
-                        goto out;
-                }
-
-        command = argv[optind];
-
-        if (command != NULL)
-                for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++)
-                        if (streq(udevadm_cmds[i]->name, command)) {
-                                argc -= optind;
-                                argv += optind;
-                                /* we need '0' here to reset the internal state */
-                                optind = 0;
-                                rc = run_command(udev, udevadm_cmds[i], argc, argv);
-                                goto out;
-                        }
-
-        fprintf(stderr, "%s: missing or unknown command\n", program_invocation_short_name);
-        rc = 2;
-out:
-        mac_selinux_finish();
-        udev_unref(udev);
-        log_close();
-        return rc;
-}
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
deleted file mode 100644 (file)
index 8eaf2cd..0000000
+++ /dev/null
@@ -1,1553 +0,0 @@
-/*
- * Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
- * Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
- * Copyright (C) 2009 Canonical Ltd.
- * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
- *
- * 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 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stddef.h>
-#include <signal.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/signalfd.h>
-#include <sys/epoll.h>
-#include <sys/mount.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/inotify.h>
-
-#include "sd-daemon.h"
-#include "rtnl-util.h"
-#include "cgroup-util.h"
-#include "dev-setup.h"
-#include "fileio.h"
-#include "selinux-util.h"
-#include "udev.h"
-#include "udev-util.h"
-
-static struct udev_rules *rules;
-static struct udev_ctrl *udev_ctrl;
-static struct udev_monitor *monitor;
-static int worker_watch[2] = { -1, -1 };
-static int fd_signal = -1;
-static int fd_ep = -1;
-static int fd_inotify = -1;
-static bool stop_exec_queue;
-static bool reload;
-static int children;
-static bool arg_debug = false;
-static int arg_daemonize = false;
-static int arg_resolve_names = 1;
-static int arg_children_max;
-static int arg_exec_delay;
-static usec_t arg_event_timeout_usec = 180 * USEC_PER_SEC;
-static usec_t arg_event_timeout_warn_usec = 180 * USEC_PER_SEC / 3;
-static sigset_t sigmask_orig;
-static UDEV_LIST(event_list);
-static UDEV_LIST(worker_list);
-static char *udev_cgroup;
-static struct udev_list properties_list;
-static bool udev_exit;
-
-enum event_state {
-        EVENT_UNDEF,
-        EVENT_QUEUED,
-        EVENT_RUNNING,
-};
-
-struct event {
-        struct udev_list_node node;
-        struct udev *udev;
-        struct udev_device *dev;
-        struct udev_device *dev_kernel;
-        enum event_state state;
-        int exitcode;
-        unsigned long long int delaying_seqnum;
-        unsigned long long int seqnum;
-        const char *devpath;
-        size_t devpath_len;
-        const char *devpath_old;
-        dev_t devnum;
-        int ifindex;
-        bool is_block;
-};
-
-static inline struct event *node_to_event(struct udev_list_node *node) {
-        return container_of(node, struct event, node);
-}
-
-static void event_queue_cleanup(struct udev *udev, enum event_state type);
-
-enum worker_state {
-        WORKER_UNDEF,
-        WORKER_RUNNING,
-        WORKER_IDLE,
-        WORKER_KILLED,
-};
-
-struct worker {
-        struct udev_list_node node;
-        struct udev *udev;
-        int refcount;
-        pid_t pid;
-        struct udev_monitor *monitor;
-        enum worker_state state;
-        struct event *event;
-        usec_t event_start_usec;
-        bool event_warned;
-};
-
-/* passed from worker to main process */
-struct worker_message {
-        pid_t pid;
-        int exitcode;
-};
-
-static inline struct worker *node_to_worker(struct udev_list_node *node) {
-        return container_of(node, struct worker, node);
-}
-
-static void event_queue_delete(struct event *event) {
-        udev_list_node_remove(&event->node);
-        udev_device_unref(event->dev);
-        udev_device_unref(event->dev_kernel);
-        free(event);
-}
-
-static struct worker *worker_ref(struct worker *worker) {
-        worker->refcount++;
-        return worker;
-}
-
-static void worker_cleanup(struct worker *worker) {
-        udev_list_node_remove(&worker->node);
-        udev_monitor_unref(worker->monitor);
-        children--;
-        free(worker);
-}
-
-static void worker_unref(struct worker *worker) {
-        worker->refcount--;
-        if (worker->refcount > 0)
-                return;
-        log_debug("worker ["PID_FMT"] cleaned up", worker->pid);
-        worker_cleanup(worker);
-}
-
-static void worker_list_cleanup(struct udev *udev) {
-        struct udev_list_node *loop, *tmp;
-
-        udev_list_node_foreach_safe(loop, tmp, &worker_list) {
-                struct worker *worker = node_to_worker(loop);
-
-                worker_cleanup(worker);
-        }
-}
-
-static void worker_new(struct event *event) {
-        struct udev *udev = event->udev;
-        struct worker *worker;
-        struct udev_monitor *worker_monitor;
-        pid_t pid;
-
-        /* listen for new events */
-        worker_monitor = udev_monitor_new_from_netlink(udev, NULL);
-        if (worker_monitor == NULL)
-                return;
-        /* allow the main daemon netlink address to send devices to the worker */
-        udev_monitor_allow_unicast_sender(worker_monitor, monitor);
-        udev_monitor_enable_receiving(worker_monitor);
-
-        worker = new0(struct worker, 1);
-        if (worker == NULL) {
-                udev_monitor_unref(worker_monitor);
-                return;
-        }
-        /* worker + event reference */
-        worker->refcount = 2;
-        worker->udev = udev;
-
-        pid = fork();
-        switch (pid) {
-        case 0: {
-                struct udev_device *dev = NULL;
-                int fd_monitor;
-                _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
-                struct epoll_event ep_signal, ep_monitor;
-                sigset_t mask;
-                int rc = EXIT_SUCCESS;
-
-                /* take initial device from queue */
-                dev = event->dev;
-                event->dev = NULL;
-
-                free(worker);
-                worker_list_cleanup(udev);
-                event_queue_cleanup(udev, EVENT_UNDEF);
-                udev_monitor_unref(monitor);
-                udev_ctrl_unref(udev_ctrl);
-                close(fd_signal);
-                close(fd_ep);
-                close(worker_watch[READ_END]);
-
-                sigfillset(&mask);
-                fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
-                if (fd_signal < 0) {
-                        log_error_errno(errno, "error creating signalfd %m");
-                        rc = 2;
-                        goto out;
-                }
-
-                fd_ep = epoll_create1(EPOLL_CLOEXEC);
-                if (fd_ep < 0) {
-                        log_error_errno(errno, "error creating epoll fd: %m");
-                        rc = 3;
-                        goto out;
-                }
-
-                memzero(&ep_signal, sizeof(struct epoll_event));
-                ep_signal.events = EPOLLIN;
-                ep_signal.data.fd = fd_signal;
-
-                fd_monitor = udev_monitor_get_fd(worker_monitor);
-                memzero(&ep_monitor, sizeof(struct epoll_event));
-                ep_monitor.events = EPOLLIN;
-                ep_monitor.data.fd = fd_monitor;
-
-                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
-                    epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_monitor, &ep_monitor) < 0) {
-                        log_error_errno(errno, "fail to add fds to epoll: %m");
-                        rc = 4;
-                        goto out;
-                }
-
-                /* request TERM signal if parent exits */
-                prctl(PR_SET_PDEATHSIG, SIGTERM);
-
-                /* reset OOM score, we only protect the main daemon */
-                write_string_file("/proc/self/oom_score_adj", "0");
-
-                for (;;) {
-                        struct udev_event *udev_event;
-                        struct worker_message msg;
-                        int fd_lock = -1;
-                        int err = 0;
-
-                        log_debug("seq %llu running", udev_device_get_seqnum(dev));
-                        udev_event = udev_event_new(dev);
-                        if (udev_event == NULL) {
-                                rc = 5;
-                                goto out;
-                        }
-
-                        /* needed for SIGCHLD/SIGTERM in spawn() */
-                        udev_event->fd_signal = fd_signal;
-
-                        if (arg_exec_delay > 0)
-                                udev_event->exec_delay = arg_exec_delay;
-
-                        /*
-                         * Take a shared lock on the device node; this establishes
-                         * a concept of device "ownership" to serialize device
-                         * access. External processes holding an exclusive lock will
-                         * cause udev to skip the event handling; in the case udev
-                         * acquired the lock, the external process can block until
-                         * udev has finished its event handling.
-                         */
-                        if (!streq_ptr(udev_device_get_action(dev), "remove") &&
-                            streq_ptr("block", udev_device_get_subsystem(dev)) &&
-                            !startswith(udev_device_get_sysname(dev), "dm-") &&
-                            !startswith(udev_device_get_sysname(dev), "md")) {
-                                struct udev_device *d = dev;
-
-                                if (streq_ptr("partition", udev_device_get_devtype(d)))
-                                        d = udev_device_get_parent(d);
-
-                                if (d) {
-                                        fd_lock = open(udev_device_get_devnode(d), O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
-                                        if (fd_lock >= 0 && flock(fd_lock, LOCK_SH|LOCK_NB) < 0) {
-                                                log_debug_errno(errno, "Unable to flock(%s), skipping event handling: %m", udev_device_get_devnode(d));
-                                                err = -EAGAIN;
-                                                fd_lock = safe_close(fd_lock);
-                                                goto skip;
-                                        }
-                                }
-                        }
-
-                        /* needed for renaming netifs */
-                        udev_event->rtnl = rtnl;
-
-                        /* apply rules, create node, symlinks */
-                        udev_event_execute_rules(udev_event,
-                                                 arg_event_timeout_usec, arg_event_timeout_warn_usec,
-                                                 &properties_list,
-                                                 rules,
-                                                 &sigmask_orig);
-
-                        udev_event_execute_run(udev_event,
-                                               arg_event_timeout_usec, arg_event_timeout_warn_usec,
-                                               &sigmask_orig);
-
-                        if (udev_event->rtnl)
-                                /* in case rtnl was initialized */
-                                rtnl = sd_rtnl_ref(udev_event->rtnl);
-
-                        /* apply/restore inotify watch */
-                        if (udev_event->inotify_watch) {
-                                udev_watch_begin(udev, dev);
-                                udev_device_update_db(dev);
-                        }
-
-                        safe_close(fd_lock);
-
-                        /* send processed event back to libudev listeners */
-                        udev_monitor_send_device(worker_monitor, NULL, dev);
-
-skip:
-                        /* send udevd the result of the event execution */
-                        memzero(&msg, sizeof(struct worker_message));
-                        msg.exitcode = err;
-                        msg.pid = getpid();
-                        send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0);
-
-                        log_debug("seq %llu processed with %i", udev_device_get_seqnum(dev), err);
-
-                        udev_device_unref(dev);
-                        dev = NULL;
-
-                        if (udev_event->sigterm) {
-                                udev_event_unref(udev_event);
-                                goto out;
-                        }
-
-                        udev_event_unref(udev_event);
-
-                        /* wait for more device messages from main udevd, or term signal */
-                        while (dev == NULL) {
-                                struct epoll_event ev[4];
-                                int fdcount;
-                                int i;
-
-                                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1);
-                                if (fdcount < 0) {
-                                        if (errno == EINTR)
-                                                continue;
-                                        log_error_errno(errno, "failed to poll: %m");
-                                        goto out;
-                                }
-
-                                for (i = 0; i < fdcount; i++) {
-                                        if (ev[i].data.fd == fd_monitor && ev[i].events & EPOLLIN) {
-                                                dev = udev_monitor_receive_device(worker_monitor);
-                                                break;
-                                        } else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN) {
-                                                struct signalfd_siginfo fdsi;
-                                                ssize_t size;
-
-                                                size = read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
-                                                if (size != sizeof(struct signalfd_siginfo))
-                                                        continue;
-                                                switch (fdsi.ssi_signo) {
-                                                case SIGTERM:
-                                                        goto out;
-                                                }
-                                        }
-                                }
-                        }
-                }
-out:
-                udev_device_unref(dev);
-                safe_close(fd_signal);
-                safe_close(fd_ep);
-                close(fd_inotify);
-                close(worker_watch[WRITE_END]);
-                udev_rules_unref(rules);
-                udev_builtin_exit(udev);
-                udev_monitor_unref(worker_monitor);
-                udev_unref(udev);
-                log_close();
-                exit(rc);
-        }
-        case -1:
-                udev_monitor_unref(worker_monitor);
-                event->state = EVENT_QUEUED;
-                free(worker);
-                log_error_errno(errno, "fork of child failed: %m");
-                break;
-        default:
-                /* close monitor, but keep address around */
-                udev_monitor_disconnect(worker_monitor);
-                worker->monitor = worker_monitor;
-                worker->pid = pid;
-                worker->state = WORKER_RUNNING;
-                worker->event_start_usec = now(CLOCK_MONOTONIC);
-                worker->event_warned = false;
-                worker->event = event;
-                event->state = EVENT_RUNNING;
-                udev_list_node_append(&worker->node, &worker_list);
-                children++;
-                log_debug("seq %llu forked new worker ["PID_FMT"]", udev_device_get_seqnum(event->dev), pid);
-                break;
-        }
-}
-
-static void event_run(struct event *event) {
-        struct udev_list_node *loop;
-
-        udev_list_node_foreach(loop, &worker_list) {
-                struct worker *worker = node_to_worker(loop);
-                ssize_t count;
-
-                if (worker->state != WORKER_IDLE)
-                        continue;
-
-                count = udev_monitor_send_device(monitor, worker->monitor, event->dev);
-                if (count < 0) {
-                        log_error_errno(errno, "worker ["PID_FMT"] did not accept message %zi (%m), kill it",
-                                        worker->pid, count);
-                        kill(worker->pid, SIGKILL);
-                        worker->state = WORKER_KILLED;
-                        continue;
-                }
-                worker_ref(worker);
-                worker->event = event;
-                worker->state = WORKER_RUNNING;
-                worker->event_start_usec = now(CLOCK_MONOTONIC);
-                worker->event_warned = false;
-                event->state = EVENT_RUNNING;
-                return;
-        }
-
-        if (children >= arg_children_max) {
-                if (arg_children_max > 1)
-                        log_debug("maximum number (%i) of children reached", children);
-                return;
-        }
-
-        /* start new worker and pass initial device */
-        worker_new(event);
-}
-
-static int event_queue_insert(struct udev_device *dev) {
-        struct event *event;
-
-        event = new0(struct event, 1);
-        if (event == NULL)
-                return -1;
-
-        event->udev = udev_device_get_udev(dev);
-        event->dev = dev;
-        event->dev_kernel = udev_device_shallow_clone(dev);
-        udev_device_copy_properties(event->dev_kernel, dev);
-        event->seqnum = udev_device_get_seqnum(dev);
-        event->devpath = udev_device_get_devpath(dev);
-        event->devpath_len = strlen(event->devpath);
-        event->devpath_old = udev_device_get_devpath_old(dev);
-        event->devnum = udev_device_get_devnum(dev);
-        event->is_block = streq("block", udev_device_get_subsystem(dev));
-        event->ifindex = udev_device_get_ifindex(dev);
-
-        log_debug("seq %llu queued, '%s' '%s'", udev_device_get_seqnum(dev),
-             udev_device_get_action(dev), udev_device_get_subsystem(dev));
-
-        event->state = EVENT_QUEUED;
-        udev_list_node_append(&event->node, &event_list);
-        return 0;
-}
-
-static void worker_kill(struct udev *udev) {
-        struct udev_list_node *loop;
-
-        udev_list_node_foreach(loop, &worker_list) {
-                struct worker *worker = node_to_worker(loop);
-
-                if (worker->state == WORKER_KILLED)
-                        continue;
-
-                worker->state = WORKER_KILLED;
-                kill(worker->pid, SIGTERM);
-        }
-}
-
-/* lookup event for identical, parent, child device */
-static bool is_devpath_busy(struct event *event) {
-        struct udev_list_node *loop;
-        size_t common;
-
-        /* check if queue contains events we depend on */
-        udev_list_node_foreach(loop, &event_list) {
-                struct event *loop_event = node_to_event(loop);
-
-                /* we already found a later event, earlier can not block us, no need to check again */
-                if (loop_event->seqnum < event->delaying_seqnum)
-                        continue;
-
-                /* event we checked earlier still exists, no need to check again */
-                if (loop_event->seqnum == event->delaying_seqnum)
-                        return true;
-
-                /* found ourself, no later event can block us */
-                if (loop_event->seqnum >= event->seqnum)
-                        break;
-
-                /* check major/minor */
-                if (major(event->devnum) != 0 && event->devnum == loop_event->devnum && event->is_block == loop_event->is_block)
-                        return true;
-
-                /* check network device ifindex */
-                if (event->ifindex != 0 && event->ifindex == loop_event->ifindex)
-                        return true;
-
-                /* check our old name */
-                if (event->devpath_old != NULL && streq(loop_event->devpath, event->devpath_old)) {
-                        event->delaying_seqnum = loop_event->seqnum;
-                        return true;
-                }
-
-                /* compare devpath */
-                common = MIN(loop_event->devpath_len, event->devpath_len);
-
-                /* one devpath is contained in the other? */
-                if (memcmp(loop_event->devpath, event->devpath, common) != 0)
-                        continue;
-
-                /* identical device event found */
-                if (loop_event->devpath_len == event->devpath_len) {
-                        /* devices names might have changed/swapped in the meantime */
-                        if (major(event->devnum) != 0 && (event->devnum != loop_event->devnum || event->is_block != loop_event->is_block))
-                                continue;
-                        if (event->ifindex != 0 && event->ifindex != loop_event->ifindex)
-                                continue;
-                        event->delaying_seqnum = loop_event->seqnum;
-                        return true;
-                }
-
-                /* parent device event found */
-                if (event->devpath[common] == '/') {
-                        event->delaying_seqnum = loop_event->seqnum;
-                        return true;
-                }
-
-                /* child device event found */
-                if (loop_event->devpath[common] == '/') {
-                        event->delaying_seqnum = loop_event->seqnum;
-                        return true;
-                }
-
-                /* no matching device */
-                continue;
-        }
-
-        return false;
-}
-
-static void event_queue_start(struct udev *udev) {
-        struct udev_list_node *loop;
-
-        udev_list_node_foreach(loop, &event_list) {
-                struct event *event = node_to_event(loop);
-
-                if (event->state != EVENT_QUEUED)
-                        continue;
-
-                /* do not start event if parent or child event is still running */
-                if (is_devpath_busy(event))
-                        continue;
-
-                event_run(event);
-        }
-}
-
-static void event_queue_cleanup(struct udev *udev, enum event_state match_type) {
-        struct udev_list_node *loop, *tmp;
-
-        udev_list_node_foreach_safe(loop, tmp, &event_list) {
-                struct event *event = node_to_event(loop);
-
-                if (match_type != EVENT_UNDEF && match_type != event->state)
-                        continue;
-
-                event_queue_delete(event);
-        }
-}
-
-static void worker_returned(int fd_worker) {
-        for (;;) {
-                struct worker_message msg;
-                ssize_t size;
-                struct udev_list_node *loop;
-
-                size = recv(fd_worker, &msg, sizeof(struct worker_message), MSG_DONTWAIT);
-                if (size != sizeof(struct worker_message))
-                        break;
-
-                /* lookup worker who sent the signal */
-                udev_list_node_foreach(loop, &worker_list) {
-                        struct worker *worker = node_to_worker(loop);
-
-                        if (worker->pid != msg.pid)
-                                continue;
-
-                        /* worker returned */
-                        if (worker->event) {
-                                worker->event->exitcode = msg.exitcode;
-                                event_queue_delete(worker->event);
-                                worker->event = NULL;
-                        }
-                        if (worker->state != WORKER_KILLED)
-                                worker->state = WORKER_IDLE;
-                        worker_unref(worker);
-                        break;
-                }
-        }
-}
-
-/* receive the udevd message from userspace */
-static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl) {
-        struct udev *udev = udev_ctrl_get_udev(uctrl);
-        struct udev_ctrl_connection *ctrl_conn;
-        struct udev_ctrl_msg *ctrl_msg = NULL;
-        const char *str;
-        int i;
-
-        ctrl_conn = udev_ctrl_get_connection(uctrl);
-        if (ctrl_conn == NULL)
-                goto out;
-
-        ctrl_msg = udev_ctrl_receive_msg(ctrl_conn);
-        if (ctrl_msg == NULL)
-                goto out;
-
-        i = udev_ctrl_get_set_log_level(ctrl_msg);
-        if (i >= 0) {
-                log_debug("udevd message (SET_LOG_LEVEL) received, log_priority=%i", i);
-                log_set_max_level(i);
-                worker_kill(udev);
-        }
-
-        if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) {
-                log_debug("udevd message (STOP_EXEC_QUEUE) received");
-                stop_exec_queue = true;
-        }
-
-        if (udev_ctrl_get_start_exec_queue(ctrl_msg) > 0) {
-                log_debug("udevd message (START_EXEC_QUEUE) received");
-                stop_exec_queue = false;
-        }
-
-        if (udev_ctrl_get_reload(ctrl_msg) > 0) {
-                log_debug("udevd message (RELOAD) received");
-                reload = true;
-        }
-
-        str = udev_ctrl_get_set_env(ctrl_msg);
-        if (str != NULL) {
-                char *key;
-
-                key = strdup(str);
-                if (key != NULL) {
-                        char *val;
-
-                        val = strchr(key, '=');
-                        if (val != NULL) {
-                                val[0] = '\0';
-                                val = &val[1];
-                                if (val[0] == '\0') {
-                                        log_debug("udevd message (ENV) received, unset '%s'", key);
-                                        udev_list_entry_add(&properties_list, key, NULL);
-                                } else {
-                                        log_debug("udevd message (ENV) received, set '%s=%s'", key, val);
-                                        udev_list_entry_add(&properties_list, key, val);
-                                }
-                        } else {
-                                log_error("wrong key format '%s'", key);
-                        }
-                        free(key);
-                }
-                worker_kill(udev);
-        }
-
-        i = udev_ctrl_get_set_children_max(ctrl_msg);
-        if (i >= 0) {
-                log_debug("udevd message (SET_MAX_CHILDREN) received, children_max=%i", i);
-                arg_children_max = i;
-        }
-
-        if (udev_ctrl_get_ping(ctrl_msg) > 0)
-                log_debug("udevd message (SYNC) received");
-
-        if (udev_ctrl_get_exit(ctrl_msg) > 0) {
-                log_debug("udevd message (EXIT) received");
-                udev_exit = true;
-                /* keep reference to block the client until we exit */
-                udev_ctrl_connection_ref(ctrl_conn);
-        }
-out:
-        udev_ctrl_msg_unref(ctrl_msg);
-        return udev_ctrl_connection_unref(ctrl_conn);
-}
-
-static int synthesize_change(struct udev_device *dev) {
-        char filename[UTIL_PATH_SIZE];
-        int r;
-
-        if (streq_ptr("block", udev_device_get_subsystem(dev)) &&
-            streq_ptr("disk", udev_device_get_devtype(dev)) &&
-            !startswith(udev_device_get_sysname(dev), "dm-")) {
-                bool part_table_read = false;
-                bool has_partitions = false;
-                int fd;
-                struct udev *udev = udev_device_get_udev(dev);
-                _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
-                struct udev_list_entry *item;
-
-                /*
-                 * Try to re-read the partition table. This only succeeds if
-                 * none of the devices is busy. The kernel returns 0 if no
-                 * partition table is found, and we will not get an event for
-                 * the disk.
-                 */
-                fd = open(udev_device_get_devnode(dev), O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
-                if (fd >= 0) {
-                        r = flock(fd, LOCK_EX|LOCK_NB);
-                        if (r >= 0)
-                                r = ioctl(fd, BLKRRPART, 0);
-
-                        close(fd);
-                        if (r >= 0)
-                                part_table_read = true;
-                }
-
-                /* search for partitions */
-                e = udev_enumerate_new(udev);
-                if (!e)
-                        return -ENOMEM;
-
-                r = udev_enumerate_add_match_parent(e, dev);
-                if (r < 0)
-                        return r;
-
-                r = udev_enumerate_add_match_subsystem(e, "block");
-                if (r < 0)
-                        return r;
-
-                r = udev_enumerate_scan_devices(e);
-                if (r < 0)
-                        return r;
-
-                udev_list_entry_foreach(item, udev_enumerate_get_list_entry(e)) {
-                        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
-
-                        d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
-                        if (!d)
-                                continue;
-
-                        if (!streq_ptr("partition", udev_device_get_devtype(d)))
-                                continue;
-
-                        has_partitions = true;
-                        break;
-                }
-
-                /*
-                 * We have partitions and re-read the table, the kernel already sent
-                 * out a "change" event for the disk, and "remove/add" for all
-                 * partitions.
-                 */
-                if (part_table_read && has_partitions)
-                        return 0;
-
-                /*
-                 * We have partitions but re-reading the partition table did not
-                 * work, synthesize "change" for the disk and all partitions.
-                 */
-                log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev));
-                strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
-                write_string_file(filename, "change");
-
-                udev_list_entry_foreach(item, udev_enumerate_get_list_entry(e)) {
-                        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
-
-                        d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
-                        if (!d)
-                                continue;
-
-                        if (!streq_ptr("partition", udev_device_get_devtype(d)))
-                                continue;
-
-                        log_debug("device %s closed, synthesising partition '%s' 'change'",
-                                  udev_device_get_devnode(dev), udev_device_get_devnode(d));
-                        strscpyl(filename, sizeof(filename), udev_device_get_syspath(d), "/uevent", NULL);
-                        write_string_file(filename, "change");
-                }
-
-                return 0;
-        }
-
-        log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev));
-        strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
-        write_string_file(filename, "change");
-
-        return 0;
-}
-
-static int handle_inotify(struct udev *udev) {
-        union inotify_event_buffer buffer;
-        struct inotify_event *e;
-        ssize_t l;
-
-        l = read(fd_inotify, &buffer, sizeof(buffer));
-        if (l < 0) {
-                if (errno == EAGAIN || errno == EINTR)
-                        return 0;
-
-                return log_error_errno(errno, "Failed to read inotify fd: %m");
-        }
-
-        FOREACH_INOTIFY_EVENT(e, buffer, l) {
-                struct udev_device *dev;
-
-                dev = udev_watch_lookup(udev, e->wd);
-                if (!dev)
-                        continue;
-
-                log_debug("inotify event: %x for %s", e->mask, udev_device_get_devnode(dev));
-                if (e->mask & IN_CLOSE_WRITE)
-                        synthesize_change(dev);
-                else if (e->mask & IN_IGNORED)
-                        udev_watch_end(udev, dev);
-
-                udev_device_unref(dev);
-        }
-
-        return 0;
-}
-
-static void handle_signal(struct udev *udev, int signo) {
-        switch (signo) {
-        case SIGINT:
-        case SIGTERM:
-                udev_exit = true;
-                break;
-        case SIGCHLD:
-                for (;;) {
-                        pid_t pid;
-                        int status;
-                        struct udev_list_node *loop, *tmp;
-
-                        pid = waitpid(-1, &status, WNOHANG);
-                        if (pid <= 0)
-                                break;
-
-                        udev_list_node_foreach_safe(loop, tmp, &worker_list) {
-                                struct worker *worker = node_to_worker(loop);
-
-                                if (worker->pid != pid)
-                                        continue;
-                                log_debug("worker ["PID_FMT"] exit", pid);
-
-                                if (WIFEXITED(status)) {
-                                        if (WEXITSTATUS(status) != 0)
-                                                log_error("worker ["PID_FMT"] exit with return code %i",
-                                                          pid, WEXITSTATUS(status));
-                                } else if (WIFSIGNALED(status)) {
-                                        log_error("worker ["PID_FMT"] terminated by signal %i (%s)",
-                                                  pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
-                                } else if (WIFSTOPPED(status)) {
-                                        log_error("worker ["PID_FMT"] stopped", pid);
-                                } else if (WIFCONTINUED(status)) {
-                                        log_error("worker ["PID_FMT"] continued", pid);
-                                } else {
-                                        log_error("worker ["PID_FMT"] exit with status 0x%04x", pid, status);
-                                }
-
-                                if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
-                                        if (worker->event) {
-                                                log_error("worker ["PID_FMT"] failed while handling '%s'",
-                                                          pid, worker->event->devpath);
-                                                worker->event->exitcode = -32;
-                                                /* delete state from disk */
-                                                udev_device_delete_db(worker->event->dev);
-                                                udev_device_tag_index(worker->event->dev, NULL, false);
-                                                /* forward kernel event without ammending it */
-                                                udev_monitor_send_device(monitor, NULL, worker->event->dev_kernel);
-                                                event_queue_delete(worker->event);
-
-                                                /* drop reference taken for state 'running' */
-                                                worker_unref(worker);
-                                        }
-                                }
-                                worker_unref(worker);
-                                break;
-                        }
-                }
-                break;
-        case SIGHUP:
-                reload = true;
-                break;
-        }
-}
-
-static void event_queue_update(void) {
-        int r;
-
-        if (!udev_list_node_is_empty(&event_list)) {
-                r = touch("/run/udev/queue");
-                if (r < 0)
-                        log_warning_errno(r, "could not touch /run/udev/queue: %m");
-        } else {
-                r = unlink("/run/udev/queue");
-                if (r < 0 && errno != ENOENT)
-                        log_warning("could not unlink /run/udev/queue: %m");
-        }
-}
-
-static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink) {
-        int ctrl = -1, netlink = -1;
-        int fd, n;
-
-        n = sd_listen_fds(true);
-        if (n <= 0)
-                return -1;
-
-        for (fd = SD_LISTEN_FDS_START; fd < n + SD_LISTEN_FDS_START; fd++) {
-                if (sd_is_socket(fd, AF_LOCAL, SOCK_SEQPACKET, -1)) {
-                        if (ctrl >= 0)
-                                return -1;
-                        ctrl = fd;
-                        continue;
-                }
-
-                if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1)) {
-                        if (netlink >= 0)
-                                return -1;
-                        netlink = fd;
-                        continue;
-                }
-
-                return -1;
-        }
-
-        if (ctrl < 0 || netlink < 0)
-                return -1;
-
-        log_debug("ctrl=%i netlink=%i", ctrl, netlink);
-        *rctrl = ctrl;
-        *rnetlink = netlink;
-        return 0;
-}
-
-/*
- * read the kernel command line, in case we need to get into debug mode
- *   udev.log-priority=<level>              syslog priority
- *   udev.children-max=<number of workers>  events are fully serialized if set to 1
- *   udev.exec-delay=<number of seconds>    delay execution of every executed program
- */
-static void kernel_cmdline_options(struct udev *udev) {
-        _cleanup_free_ char *line = NULL;
-        const char *word, *state;
-        size_t l;
-        int r;
-
-        r = proc_cmdline(&line);
-        if (r < 0) {
-                log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m");
-                return;
-        }
-
-        FOREACH_WORD_QUOTED(word, l, line, state) {
-                char *s, *opt, *value;
-
-                s = strndup(word, l);
-                if (!s)
-                        break;
-
-                /* accept the same options for the initrd, prefixed with "rd." */
-                if (in_initrd() && startswith(s, "rd."))
-                        opt = s + 3;
-                else
-                        opt = s;
-
-                if ((value = startswith(opt, "udev.log-priority="))) {
-                        int prio;
-
-                        prio = util_log_priority(value);
-                        log_set_max_level(prio);
-                } else if ((value = startswith(opt, "udev.children-max="))) {
-                        r = safe_atoi(value, &arg_children_max);
-                        if (r < 0)
-                                log_warning("Invalid udev.children-max ignored: %s", value);
-                } else if ((value = startswith(opt, "udev.exec-delay="))) {
-                        r = safe_atoi(value, &arg_exec_delay);
-                        if (r < 0)
-                                log_warning("Invalid udev.exec-delay ignored: %s", value);
-                } else if ((value = startswith(opt, "udev.event-timeout="))) {
-                        r = safe_atou64(value, &arg_event_timeout_usec);
-                        if (r < 0) {
-                                log_warning("Invalid udev.event-timeout ignored: %s", value);
-                                break;
-                        }
-                        arg_event_timeout_usec *= USEC_PER_SEC;
-                        arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
-                }
-
-                free(s);
-        }
-}
-
-static void help(void) {
-        printf("%s [OPTIONS...]\n\n"
-               "Manages devices.\n\n"
-               "  -h --help                   Print this message\n"
-               "     --version                Print version of the program\n"
-               "     --daemon                 Detach and run in the background\n"
-               "     --debug                  Enable debug output\n"
-               "     --children-max=INT       Set maximum number of workers\n"
-               "     --exec-delay=SECONDS     Seconds to wait before executing RUN=\n"
-               "     --event-timeout=SECONDS  Seconds to wait before terminating an event\n"
-               "     --resolve-names=early|late|never\n"
-               "                              When to resolve users and groups\n"
-               , program_invocation_short_name);
-}
-
-static int parse_argv(int argc, char *argv[]) {
-        static const struct option options[] = {
-                { "daemon",             no_argument,            NULL, 'd' },
-                { "debug",              no_argument,            NULL, 'D' },
-                { "children-max",       required_argument,      NULL, 'c' },
-                { "exec-delay",         required_argument,      NULL, 'e' },
-                { "event-timeout",      required_argument,      NULL, 't' },
-                { "resolve-names",      required_argument,      NULL, 'N' },
-                { "help",               no_argument,            NULL, 'h' },
-                { "version",            no_argument,            NULL, 'V' },
-                {}
-        };
-
-        int c;
-
-        assert(argc >= 0);
-        assert(argv);
-
-        while ((c = getopt_long(argc, argv, "c:de:DtN:hV", options, NULL)) >= 0) {
-                int r;
-
-                switch (c) {
-
-                case 'd':
-                        arg_daemonize = true;
-                        break;
-                case 'c':
-                        r = safe_atoi(optarg, &arg_children_max);
-                        if (r < 0)
-                                log_warning("Invalid --children-max ignored: %s", optarg);
-                        break;
-                case 'e':
-                        r = safe_atoi(optarg, &arg_exec_delay);
-                        if (r < 0)
-                                log_warning("Invalid --exec-delay ignored: %s", optarg);
-                        break;
-                case 't':
-                        r = safe_atou64(optarg, &arg_event_timeout_usec);
-                        if (r < 0)
-                                log_warning("Invalid --event-timeout ignored: %s", optarg);
-                        else {
-                                arg_event_timeout_usec *= USEC_PER_SEC;
-                                arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1;
-                        }
-                        break;
-                case 'D':
-                        arg_debug = true;
-                        break;
-                case 'N':
-                        if (streq(optarg, "early")) {
-                                arg_resolve_names = 1;
-                        } else if (streq(optarg, "late")) {
-                                arg_resolve_names = 0;
-                        } else if (streq(optarg, "never")) {
-                                arg_resolve_names = -1;
-                        } else {
-                                log_error("resolve-names must be early, late or never");
-                                return 0;
-                        }
-                        break;
-                case 'h':
-                        help();
-                        return 0;
-                case 'V':
-                        printf("%s\n", VERSION);
-                        return 0;
-                case '?':
-                        return -EINVAL;
-                default:
-                        assert_not_reached("Unhandled option");
-
-                }
-        }
-
-        return 1;
-}
-
-int main(int argc, char *argv[]) {
-        struct udev *udev;
-        sigset_t mask;
-        int fd_ctrl = -1;
-        int fd_netlink = -1;
-        int fd_worker = -1;
-        struct epoll_event ep_ctrl = { .events = EPOLLIN };
-        struct epoll_event ep_inotify = { .events = EPOLLIN };
-        struct epoll_event ep_signal = { .events = EPOLLIN };
-        struct epoll_event ep_netlink = { .events = EPOLLIN };
-        struct epoll_event ep_worker = { .events = EPOLLIN };
-        struct udev_ctrl_connection *ctrl_conn = NULL;
-        int rc = 1, r;
-
-        udev = udev_new();
-        if (udev == NULL)
-                goto exit;
-
-        log_set_target(LOG_TARGET_AUTO);
-        log_parse_environment();
-        log_open();
-
-        r = parse_argv(argc, argv);
-        if (r <= 0)
-                goto exit;
-
-        kernel_cmdline_options(udev);
-
-        if (arg_debug)
-                log_set_max_level(LOG_DEBUG);
-
-        if (getuid() != 0) {
-                log_error("root privileges required");
-                goto exit;
-        }
-
-        r = mac_selinux_init("/dev");
-        if (r < 0) {
-                log_error_errno(r, "could not initialize labelling: %m");
-                goto exit;
-        }
-
-        /* set umask before creating any file/directory */
-        r = chdir("/");
-        if (r < 0) {
-                log_error_errno(errno, "could not change dir to /: %m");
-                goto exit;
-        }
-
-        umask(022);
-
-        udev_list_init(udev, &properties_list, true);
-
-        r = mkdir("/run/udev", 0755);
-        if (r < 0 && errno != EEXIST) {
-                log_error_errno(errno, "could not create /run/udev: %m");
-                goto exit;
-        }
-
-        dev_setup(NULL);
-
-        /* before opening new files, make sure std{in,out,err} fds are in a sane state */
-        if (arg_daemonize) {
-                int fd;
-
-                fd = open("/dev/null", O_RDWR);
-                if (fd >= 0) {
-                        if (write(STDOUT_FILENO, 0, 0) < 0)
-                                dup2(fd, STDOUT_FILENO);
-                        if (write(STDERR_FILENO, 0, 0) < 0)
-                                dup2(fd, STDERR_FILENO);
-                        if (fd > STDERR_FILENO)
-                                close(fd);
-                } else {
-                        log_error("cannot open /dev/null");
-                }
-        }
-
-        if (systemd_fds(udev, &fd_ctrl, &fd_netlink) >= 0) {
-                /* get control and netlink socket from systemd */
-                udev_ctrl = udev_ctrl_new_from_fd(udev, fd_ctrl);
-                if (udev_ctrl == NULL) {
-                        log_error("error taking over udev control socket");
-                        rc = 1;
-                        goto exit;
-                }
-
-                monitor = udev_monitor_new_from_netlink_fd(udev, "kernel", fd_netlink);
-                if (monitor == NULL) {
-                        log_error("error taking over netlink socket");
-                        rc = 3;
-                        goto exit;
-                }
-
-                /* get our own cgroup, we regularly kill everything udev has left behind */
-                if (cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &udev_cgroup) < 0)
-                        udev_cgroup = NULL;
-        } else {
-                /* open control and netlink socket */
-                udev_ctrl = udev_ctrl_new(udev);
-                if (udev_ctrl == NULL) {
-                        log_error("error initializing udev control socket");
-                        rc = 1;
-                        goto exit;
-                }
-                fd_ctrl = udev_ctrl_get_fd(udev_ctrl);
-
-                monitor = udev_monitor_new_from_netlink(udev, "kernel");
-                if (monitor == NULL) {
-                        log_error("error initializing netlink socket");
-                        rc = 3;
-                        goto exit;
-                }
-                fd_netlink = udev_monitor_get_fd(monitor);
-
-                udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
-        }
-
-        if (udev_monitor_enable_receiving(monitor) < 0) {
-                log_error("error binding netlink socket");
-                rc = 3;
-                goto exit;
-        }
-
-        if (udev_ctrl_enable_receiving(udev_ctrl) < 0) {
-                log_error("error binding udev control socket");
-                rc = 1;
-                goto exit;
-        }
-
-        log_info("starting version " VERSION);
-
-        udev_builtin_init(udev);
-
-        rules = udev_rules_new(udev, arg_resolve_names);
-        if (rules == NULL) {
-                log_error("error reading rules");
-                goto exit;
-        }
-
-        rc = udev_rules_apply_static_dev_perms(rules);
-        if (rc < 0)
-                log_error_errno(rc, "failed to apply permissions on static device nodes - %m");
-
-        if (arg_daemonize) {
-                pid_t pid;
-
-                pid = fork();
-                switch (pid) {
-                case 0:
-                        break;
-                case -1:
-                        log_error_errno(errno, "fork of daemon failed: %m");
-                        rc = 4;
-                        goto exit;
-                default:
-                        rc = EXIT_SUCCESS;
-                        goto exit_daemonize;
-                }
-
-                setsid();
-
-                write_string_file("/proc/self/oom_score_adj", "-1000");
-        } else {
-                sd_notify(1, "READY=1");
-        }
-
-        if (arg_children_max <= 0) {
-                cpu_set_t cpu_set;
-
-                arg_children_max = 8;
-
-                if (sched_getaffinity(0, sizeof (cpu_set), &cpu_set) == 0) {
-                        arg_children_max +=  CPU_COUNT(&cpu_set) * 2;
-                }
-        }
-        log_debug("set children_max to %u", arg_children_max);
-
-        udev_list_node_init(&event_list);
-        udev_list_node_init(&worker_list);
-
-        fd_inotify = udev_watch_init(udev);
-        if (fd_inotify < 0) {
-                log_error("error initializing inotify");
-                rc = 4;
-                goto exit;
-        }
-        udev_watch_restore(udev);
-
-        /* block and listen to all signals on signalfd */
-        sigfillset(&mask);
-        sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
-        fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
-        if (fd_signal < 0) {
-                log_error("error creating signalfd");
-                rc = 5;
-                goto exit;
-        }
-
-        /* unnamed socket from workers to the main daemon */
-        if (socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, worker_watch) < 0) {
-                log_error("error creating socketpair");
-                rc = 6;
-                goto exit;
-        }
-        fd_worker = worker_watch[READ_END];
-
-        ep_ctrl.data.fd = fd_ctrl;
-        ep_inotify.data.fd = fd_inotify;
-        ep_signal.data.fd = fd_signal;
-        ep_netlink.data.fd = fd_netlink;
-        ep_worker.data.fd = fd_worker;
-
-        fd_ep = epoll_create1(EPOLL_CLOEXEC);
-        if (fd_ep < 0) {
-                log_error_errno(errno, "error creating epoll fd: %m");
-                goto exit;
-        }
-        if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_ctrl, &ep_ctrl) < 0 ||
-            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_inotify, &ep_inotify) < 0 ||
-            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
-            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_netlink, &ep_netlink) < 0 ||
-            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_worker, &ep_worker) < 0) {
-                log_error_errno(errno, "fail to add fds to epoll: %m");
-                goto exit;
-        }
-
-        for (;;) {
-                static usec_t last_usec;
-                struct epoll_event ev[8];
-                int fdcount;
-                int timeout;
-                bool is_worker, is_signal, is_inotify, is_netlink, is_ctrl;
-                int i;
-
-                if (udev_exit) {
-                        /* close sources of new events and discard buffered events */
-                        if (fd_ctrl >= 0) {
-                                epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_ctrl, NULL);
-                                fd_ctrl = -1;
-                        }
-                        if (monitor != NULL) {
-                                epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_netlink, NULL);
-                                udev_monitor_unref(monitor);
-                                monitor = NULL;
-                        }
-                        if (fd_inotify >= 0) {
-                                epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_inotify, NULL);
-                                close(fd_inotify);
-                                fd_inotify = -1;
-                        }
-
-                        /* discard queued events and kill workers */
-                        event_queue_cleanup(udev, EVENT_QUEUED);
-                        worker_kill(udev);
-
-                        /* exit after all has cleaned up */
-                        if (udev_list_node_is_empty(&event_list) && children == 0)
-                                break;
-
-                        /* timeout at exit for workers to finish */
-                        timeout = 30 * MSEC_PER_SEC;
-                } else if (udev_list_node_is_empty(&event_list) && children == 0) {
-                        /* we are idle */
-                        timeout = -1;
-
-                        /* cleanup possible left-over processes in our cgroup */
-                        if (udev_cgroup)
-                                cg_kill(SYSTEMD_CGROUP_CONTROLLER, udev_cgroup, SIGKILL, false, true, NULL);
-                } else {
-                        /* kill idle or hanging workers */
-                        timeout = 3 * MSEC_PER_SEC;
-                }
-
-                /* tell settle that we are busy or idle */
-                event_queue_update();
-
-                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
-                if (fdcount < 0)
-                        continue;
-
-                if (fdcount == 0) {
-                        struct udev_list_node *loop;
-
-                        /* timeout */
-                        if (udev_exit) {
-                                log_error("timeout, giving up waiting for workers to finish");
-                                break;
-                        }
-
-                        /* kill idle workers */
-                        if (udev_list_node_is_empty(&event_list)) {
-                                log_debug("cleanup idle workers");
-                                worker_kill(udev);
-                        }
-
-                        /* check for hanging events */
-                        udev_list_node_foreach(loop, &worker_list) {
-                                struct worker *worker = node_to_worker(loop);
-                                usec_t ts;
-
-                                if (worker->state != WORKER_RUNNING)
-                                        continue;
-
-                                ts = now(CLOCK_MONOTONIC);
-
-                                if ((ts - worker->event_start_usec) > arg_event_timeout_warn_usec) {
-                                        if ((ts - worker->event_start_usec) > arg_event_timeout_usec) {
-                                                log_error("worker ["PID_FMT"] %s timeout; kill it", worker->pid, worker->event->devpath);
-                                                kill(worker->pid, SIGKILL);
-                                                worker->state = WORKER_KILLED;
-
-                                                log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
-                                                worker->event->exitcode = -64;
-                                        } else if (!worker->event_warned) {
-                                                log_warning("worker ["PID_FMT"] %s is taking a long time", worker->pid, worker->event->devpath);
-                                                worker->event_warned = true;
-                                        }
-                                }
-                        }
-
-                }
-
-                is_worker = is_signal = is_inotify = is_netlink = is_ctrl = false;
-                for (i = 0; i < fdcount; i++) {
-                        if (ev[i].data.fd == fd_worker && ev[i].events & EPOLLIN)
-                                is_worker = true;
-                        else if (ev[i].data.fd == fd_netlink && ev[i].events & EPOLLIN)
-                                is_netlink = true;
-                        else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN)
-                                is_signal = true;
-                        else if (ev[i].data.fd == fd_inotify && ev[i].events & EPOLLIN)
-                                is_inotify = true;
-                        else if (ev[i].data.fd == fd_ctrl && ev[i].events & EPOLLIN)
-                                is_ctrl = true;
-                }
-
-                /* check for changed config, every 3 seconds at most */
-                if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * USEC_PER_SEC) {
-                        if (udev_rules_check_timestamp(rules))
-                                reload = true;
-                        if (udev_builtin_validate(udev))
-                                reload = true;
-
-                        last_usec = now(CLOCK_MONOTONIC);
-                }
-
-                /* reload requested, HUP signal received, rules changed, builtin changed */
-                if (reload) {
-                        worker_kill(udev);
-                        rules = udev_rules_unref(rules);
-                        udev_builtin_exit(udev);
-                        reload = false;
-                }
-
-                /* event has finished */
-                if (is_worker)
-                        worker_returned(fd_worker);
-
-                if (is_netlink) {
-                        struct udev_device *dev;
-
-                        dev = udev_monitor_receive_device(monitor);
-                        if (dev) {
-                                udev_device_ensure_usec_initialized(dev, NULL);
-                                if (event_queue_insert(dev) < 0)
-                                        udev_device_unref(dev);
-                        }
-                }
-
-                /* start new events */
-                if (!udev_list_node_is_empty(&event_list) && !udev_exit && !stop_exec_queue) {
-                        udev_builtin_init(udev);
-                        if (rules == NULL)
-                                rules = udev_rules_new(udev, arg_resolve_names);
-                        if (rules != NULL)
-                                event_queue_start(udev);
-                }
-
-                if (is_signal) {
-                        struct signalfd_siginfo fdsi;
-                        ssize_t size;
-
-                        size = read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
-                        if (size == sizeof(struct signalfd_siginfo))
-                                handle_signal(udev, fdsi.ssi_signo);
-                }
-
-                /* we are shutting down, the events below are not handled anymore */
-                if (udev_exit)
-                        continue;
-
-                /* device node watch */
-                if (is_inotify)
-                        handle_inotify(udev);
-
-                /* tell settle that we are busy or idle, this needs to be before the
-                 * PING handling
-                 */
-                event_queue_update();
-
-                /*
-                 * This needs to be after the inotify handling, to make sure,
-                 * that the ping is send back after the possibly generated
-                 * "change" events by the inotify device node watch.
-                 *
-                 * A single time we may receive a client connection which we need to
-                 * keep open to block the client. It will be closed right before we
-                 * exit.
-                 */
-                if (is_ctrl)
-                        ctrl_conn = handle_ctrl_msg(udev_ctrl);
-        }
-
-        rc = EXIT_SUCCESS;
-exit:
-        udev_ctrl_cleanup(udev_ctrl);
-        unlink("/run/udev/queue");
-exit_daemonize:
-        if (fd_ep >= 0)
-                close(fd_ep);
-        worker_list_cleanup(udev);
-        event_queue_cleanup(udev, EVENT_UNDEF);
-        udev_rules_unref(rules);
-        udev_builtin_exit(udev);
-        if (fd_signal >= 0)
-                close(fd_signal);
-        if (worker_watch[READ_END] >= 0)
-                close(worker_watch[READ_END]);
-        if (worker_watch[WRITE_END] >= 0)
-                close(worker_watch[WRITE_END]);
-        udev_monitor_unref(monitor);
-        udev_ctrl_connection_unref(ctrl_conn);
-        udev_ctrl_unref(udev_ctrl);
-        udev_list_cleanup(&properties_list);
-        mac_selinux_finish();
-        udev_unref(udev);
-        log_close();
-        return rc;
-}
diff --git a/src/udev/v4l_id/Makefile b/src/udev/v4l_id/Makefile
deleted file mode 120000 (symlink)
index d0b0e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/src/udev/v4l_id/v4l_id.c b/src/udev/v4l_id/v4l_id.c
deleted file mode 100644 (file)
index 5c57db4..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2009 Kay Sievers <kay@vrfy.org>
- * Copyright (c) 2009 Filippo Argiolas <filippo.argiolas@gmail.com>
- *
- * 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 of the
- * License, 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:
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <linux/videodev2.h>
-
-#include "util.h"
-
-int main(int argc, char *argv[]) {
-        static const struct option options[] = {
-                { "help", no_argument, NULL, 'h' },
-                {}
-        };
-        _cleanup_close_ int fd = -1;
-        char *device;
-        struct v4l2_capability v2cap;
-        int c;
-
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
-
-                switch (c) {
-                case 'h':
-                        printf("%s [-h,--help] <device file>\n\n"
-                               "Video4Linux device identification.\n\n"
-                               "  -h  Print this message\n"
-                               , program_invocation_short_name);
-                        return 0;
-                case '?':
-                        return -EINVAL;
-
-                default:
-                        assert_not_reached("Unhandled option");
-                }
-
-        device = argv[optind];
-        if (device == NULL)
-                return 2;
-
-        fd = open(device, O_RDONLY);
-        if (fd < 0)
-                return 3;
-
-        if (ioctl(fd, VIDIOC_QUERYCAP, &v2cap) == 0) {
-                printf("ID_V4L_VERSION=2\n");
-                printf("ID_V4L_PRODUCT=%s\n", v2cap.card);
-                printf("ID_V4L_CAPABILITIES=:");
-                if ((v2cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0)
-                        printf("capture:");
-                if ((v2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) > 0)
-                        printf("video_output:");
-                if ((v2cap.capabilities & V4L2_CAP_VIDEO_OVERLAY) > 0)
-                        printf("video_overlay:");
-                if ((v2cap.capabilities & V4L2_CAP_AUDIO) > 0)
-                        printf("audio:");
-                if ((v2cap.capabilities & V4L2_CAP_TUNER) > 0)
-                        printf("tuner:");
-                if ((v2cap.capabilities & V4L2_CAP_RADIO) > 0)
-                        printf("radio:");
-                printf("\n");
-        }
-
-        return 0;
-}