static int builtin_net_setup_link(sd_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)
                return log_device_error_errno(dev, EINVAL, "This program takes no arguments.");

        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)
                        return log_device_debug_errno(dev, r, "No matching link configuration found.");

                return log_device_error_errno(dev, r, "Failed to get link config: %m");
        }

        r = link_config_apply(ctx, link, dev, &name);
        if (r < 0)
                log_device_warning_errno(dev, r, "Could not apply link config, ignoring: %m");

        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 0;
}
Esempio n. 2
0
/* key like devices */
static bool 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;
        bool ret = false;

        /* do we have any KEY_* capability? */
        if (!test_bit(EV_KEY, bitmask_ev)) {
                log_debug("test_key: no EV_KEY capability");
                return false;
        }

        /* 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 blocks */
        if (!found) {
                unsigned block;
                for (block = 0; block < (sizeof(high_key_blocks) / sizeof(struct range)); ++block) {
                        for (i = high_key_blocks[block].start; i < high_key_blocks[block].end; ++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");
                ret = true;
        }

        /* 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");
                ret = true;
        }

        return ret;
}
Esempio n. 3
0
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)];
        unsigned long bitmask_props[NBITS(INPUT_PROP_MAX)];
        const char *sysname, *devnode;
        bool is_pointer;
        bool is_key;

        assert(dev);

        /* 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);
                get_cap_mask(dev, pdev, "properties", bitmask_props, sizeof(bitmask_props), test);
                is_pointer = test_pointers(dev, bitmask_ev, bitmask_abs,
                                           bitmask_key, bitmask_rel,
                                           bitmask_props, test);
                is_key = test_key(dev, bitmask_ev, bitmask_key, test);
                /* Some evdev nodes have only a scrollwheel */
                if (!is_pointer && !is_key && test_bit(EV_REL, bitmask_ev) &&
                    (test_bit(REL_WHEEL, bitmask_rel) || test_bit(REL_HWHEEL, bitmask_rel)))
                        udev_builtin_add_property(dev, test, "ID_INPUT_KEY", "1");
                if (test_bit(EV_SW, bitmask_ev))
                        udev_builtin_add_property(dev, test, "ID_INPUT_SWITCH", "1");

        }

        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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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)];

        /* 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);

        /* not an "input" class device */
        if (pdev == NULL)
                return EXIT_SUCCESS;

        /* 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);
        return EXIT_SUCCESS;
}
Esempio n. 6
0
int udev_builtin_hwdb_lookup(struct udev_device *dev,
                             const char *prefix, const char *modalias,
                             const char *filter, bool test) {
        struct udev_list_entry *list;
        struct udev_list_entry *entry;
        int n = 0;

        if (!hwdb)
                return -ENOENT;

        if (prefix) {
                _cleanup_free_ const char *lookup;

                lookup = strjoin(prefix, modalias, NULL);
                if (!lookup)
                        return -ENOMEM;
                list = udev_hwdb_get_properties_list_entry(hwdb, lookup, 0);
        } else
                list = udev_hwdb_get_properties_list_entry(hwdb, modalias, 0);

        udev_list_entry_foreach(entry, list) {
                if (filter && fnmatch(filter, udev_list_entry_get_name(entry), FNM_NOESCAPE) != 0)
                        continue;

                if (udev_builtin_add_property(dev, test,
                                              udev_list_entry_get_name(entry),
                                              udev_list_entry_get_value(entry)) < 0)
                        return -ENOMEM;
                n++;
        }
        return n;
}
/* key like devices */
static void test_key (struct udev_device *dev,
		      const unsigned long* bitmask_ev,
		      const unsigned long* bitmask_key,
		      bool test)
{
	struct udev *udev = udev_device_get_udev(dev);
	unsigned i;
	unsigned long found;
	unsigned long mask;

	/* do we have any KEY_* capability? */
	if (!test_bit (EV_KEY, bitmask_ev)) {
		info(udev, "test_key: no EV_KEY capability\n");
		return;
	}

	/* only consider KEY_* here, not BTN_* */
	found = 0;
	for (i = 0; i < BTN_MISC/BITS_PER_LONG; ++i) {
		found |= bitmask_key[i];
		info(udev, "test_key: checking bit block %lu for any keys; found=%i\n", 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)) {
				info(udev, "test_key: Found key %x in high block\n", 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");
}
Esempio n. 8
0
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);
}
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;
}
/* 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");
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
static int builtin_btrfs(sd_device *dev, int argc, char *argv[], bool test) {
        struct btrfs_ioctl_vol_args args = {};
        _cleanup_close_ int fd = -1;
        int r;

        if (argc != 3 || !streq(argv[1], "ready"))
                return log_device_error_errno(dev, EINVAL, "Invalid arguments");

        fd = open("/dev/btrfs-control", O_RDWR|O_CLOEXEC);
        if (fd < 0)
                return log_device_debug_errno(dev, errno, "Failed to open /dev/btrfs-control: %m");

        strscpy(args.name, sizeof(args.name), argv[2]);
        r = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args);
        if (r < 0)
                return log_device_debug_errno(dev, errno, "Failed to call BTRFS_IOC_DEVICES_READY: %m");

        udev_builtin_add_property(dev, test, "ID_BTRFS_READY", one_zero(r == 0));
        return 0;
}
Esempio n. 13
0
/* 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_TRIGGER, bitmask_key) ||
                         test_bit (BTN_A, bitmask_key) ||
                         test_bit (BTN_1, bitmask_key))
                        udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "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");
        }

        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");
}
Esempio n. 14
0
static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool test)
{
        struct  btrfs_ioctl_vol_args args;
        int fd;
        int err;

        if (argc != 3 || !streq(argv[1], "ready"))
                return EXIT_FAILURE;

        fd = open("/dev/btrfs-control", O_RDWR);
        if (fd < 0)
                return EXIT_FAILURE;

        util_strscpy(args.name, sizeof(args.name), argv[2]);
        err = ioctl(fd, BTRFS_IOC_DEVICES_READY, &args);
        close(fd);
        if (err < 0)
                return EXIT_FAILURE;

        udev_builtin_add_property(dev, test, "ID_BTRFS_READY", err == 0 ? "1" : "0");
        return EXIT_SUCCESS;
}
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 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;
    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);

    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=%llu",
              udev_device_get_devnode(dev),
              noraid ? "no" : "", (unsigned long long) offset);

    err = probe_superblocks(pr);
    if (err < 0)
        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;
}
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;
}
Esempio n. 18
0
/* pointer devices */
static bool 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,
                          const unsigned long* bitmask_props,
                          bool test) {
        int button, axis;
        bool has_abs_coordinates = false;
        bool has_rel_coordinates = false;
        bool has_mt_coordinates = false;
        bool has_joystick_axes_or_buttons = false;
        bool is_direct = false;
        bool has_touch = false;
        bool has_3d_coordinates = false;
        bool has_keys = false;
        bool stylus_or_pen = false;
        bool finger_but_no_pen = false;
        bool has_mouse_button = false;
        bool is_mouse = false;
        bool is_touchpad = false;
        bool is_touchscreen = false;
        bool is_tablet = false;
        bool is_joystick = false;
        bool is_accelerometer = false;
        bool is_pointing_stick= false;

        has_keys = test_bit(EV_KEY, bitmask_ev);
        has_abs_coordinates = test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs);
        has_3d_coordinates = has_abs_coordinates && test_bit(ABS_Z, bitmask_abs);
        is_accelerometer = test_bit(INPUT_PROP_ACCELEROMETER, bitmask_props);

        if (!has_keys && has_3d_coordinates)
                is_accelerometer = true;

        if (is_accelerometer) {
                udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1");
                return true;
        }

        is_pointing_stick = test_bit(INPUT_PROP_POINTING_STICK, bitmask_props);
        stylus_or_pen = test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key);
        finger_but_no_pen = test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key);
        for (button = BTN_MOUSE; button < BTN_JOYSTICK && !has_mouse_button; button++)
                has_mouse_button = test_bit(button, bitmask_key);
        has_rel_coordinates = test_bit(EV_REL, bitmask_ev) && test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel);
        has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);

        /* unset has_mt_coordinates if devices claims to have all abs axis */
        if (has_mt_coordinates && test_bit(ABS_MT_SLOT, bitmask_abs) && test_bit(ABS_MT_SLOT - 1, bitmask_abs))
                has_mt_coordinates = false;
        is_direct = test_bit(INPUT_PROP_DIRECT, bitmask_props);
        has_touch = test_bit(BTN_TOUCH, bitmask_key);

        /* joysticks don't necessarily have buttons; e. g.
         * rudders/pedals are joystick-like, but buttonless; they have
         * other fancy axes. Others have buttons only but no axes.
         *
         * The BTN_JOYSTICK range starts after the mouse range, so a mouse
         * with more than 16 buttons runs into the joystick range (e.g. Mad
         * Catz Mad Catz M.M.O.TE). Skip those.
         */
        if (!test_bit(BTN_JOYSTICK - 1, bitmask_key)) {
                for (button = BTN_JOYSTICK; button < BTN_DIGI && !has_joystick_axes_or_buttons; button++)
                        has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
                for (button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40 && !has_joystick_axes_or_buttons; button++)
                        has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
                for (button = BTN_DPAD_UP; button <= BTN_DPAD_RIGHT && !has_joystick_axes_or_buttons; button++)
                        has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
        }
        for (axis = ABS_RX; axis < ABS_PRESSURE && !has_joystick_axes_or_buttons; axis++)
                has_joystick_axes_or_buttons = test_bit(axis, bitmask_abs);

        if (has_abs_coordinates) {
                if (stylus_or_pen)
                        is_tablet = true;
                else if (finger_but_no_pen && !is_direct)
                        is_touchpad = true;
                else if (has_mouse_button)
                        /* This path is taken by VMware's USB mouse, which has
                         * absolute axes, but no touch/pressure button. */
                        is_mouse = true;
                else if (has_touch || is_direct)
                        is_touchscreen = true;
                else if (has_joystick_axes_or_buttons)
                        is_joystick = true;
        } else if (has_joystick_axes_or_buttons) {
                is_joystick = true;
        }

        if (has_mt_coordinates) {
                if (stylus_or_pen)
                        is_tablet = true;
                else if (finger_but_no_pen && !is_direct)
                        is_touchpad = true;
                else if (has_touch || is_direct)
                        is_touchscreen = true;
        }

        if (!is_tablet && !is_touchpad && !is_joystick &&
            has_mouse_button &&
            (has_rel_coordinates ||
            !has_abs_coordinates)) /* mouse buttons and no axis */
                is_mouse = true;

        if (is_pointing_stick)
                udev_builtin_add_property(dev, test, "ID_INPUT_POINTINGSTICK", "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");
        if (is_touchscreen)
                udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1");
        if (is_joystick)
                udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
        if (is_tablet)
                udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1");

        return is_tablet || is_mouse || is_touchpad || is_touchscreen || is_joystick || is_pointing_stick;
}
Esempio n. 19
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 devices */
        s = udev_device_get_sysattr_value(dev, "type");
        if (!s)
                return EXIT_FAILURE;
        i = strtoul(s, NULL, 0);
        if (i != 1)
                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 (strcmp(s, p) != 0)
                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 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;
}
Esempio n. 20
0
/* pointer devices */
static bool 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,
                          const unsigned long* bitmask_props,
                          bool test) {
        bool has_abs_coordinates = false;
        bool has_rel_coordinates = false;
        bool has_mt_coordinates = false;
        bool has_joystick_axes_or_buttons = false;
        bool is_direct = false;
        bool has_touch = false;
        bool has_3d_coordinates = false;
        bool has_keys = false;
        bool stylus_or_pen = false;
        bool finger_but_no_pen = false;
        bool has_mouse_button = false;
        bool is_mouse = false;
        bool is_touchpad = false;
        bool is_touchscreen = false;
        bool is_tablet = false;
        bool is_joystick = false;
        bool is_accelerometer = false;
        bool is_pointing_stick= false;

        has_keys = test_bit(EV_KEY, bitmask_ev);
        has_abs_coordinates = test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs);
        has_3d_coordinates = has_abs_coordinates && test_bit(ABS_Z, bitmask_abs);
        is_accelerometer = test_bit(INPUT_PROP_ACCELEROMETER, bitmask_props);

        if (!has_keys && has_3d_coordinates)
                is_accelerometer = true;

        if (is_accelerometer) {
                udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1");
                return true;
        }

        is_pointing_stick = test_bit(INPUT_PROP_POINTING_STICK, bitmask_props);
        stylus_or_pen = test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key);
        finger_but_no_pen = test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key);
        has_mouse_button = test_bit(BTN_LEFT, bitmask_key);
        has_rel_coordinates = test_bit(EV_REL, bitmask_ev) && test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel);
        has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);

        /* unset has_mt_coordinates if devices claims to have all abs axis */
        if(has_mt_coordinates && test_bit(ABS_MT_SLOT, bitmask_abs) && test_bit(ABS_MT_SLOT - 1, bitmask_abs))
                has_mt_coordinates = false;
        is_direct = test_bit(INPUT_PROP_DIRECT, bitmask_props);
        has_touch = test_bit(BTN_TOUCH, bitmask_key);
        /* joysticks don't necessarily have buttons; e. g.
         * rudders/pedals are joystick-like, but buttonless; they have
         * other fancy axes */
        has_joystick_axes_or_buttons = 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);

        if (has_abs_coordinates) {
                if (stylus_or_pen)
                        is_tablet = true;
                else if (finger_but_no_pen && !is_direct)
                        is_touchpad = true;
                else if (has_mouse_button)
                        /* This path is taken by VMware's USB mouse, which has
                         * absolute axes, but no touch/pressure button. */
                        is_mouse = true;
                else if (has_touch)
                        is_touchscreen = true;
                else if (has_joystick_axes_or_buttons)
                        is_joystick = true;
        }
        if (has_mt_coordinates && is_direct)
                is_touchscreen = true;

        if (has_rel_coordinates && has_mouse_button)
                is_mouse = true;

        if (is_pointing_stick)
                udev_builtin_add_property(dev, test, "ID_INPUT_POINTINGSTICK", "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");
        if (is_touchscreen)
                udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1");
        if (is_joystick)
                udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
        if (is_tablet)
                udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1");

        return is_tablet || is_mouse || is_touchpad || is_touchscreen || is_joystick || is_pointing_stick;
}
/*
 * 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;
}
Esempio n. 22
0
static void print_property(struct udev_device *dev, bool test, const char *name, const char *value)
{
        char s[265];

        s[0] = '\0';

        if (!strcmp(name, "TYPE")) {
                udev_builtin_add_property(dev, test, "ID_FS_TYPE", value);

        } else if (!strcmp(name, "USAGE")) {
                udev_builtin_add_property(dev, test, "ID_FS_USAGE", value);

        } else if (!strcmp(name, "VERSION")) {
                udev_builtin_add_property(dev, test, "ID_FS_VERSION", value);

        } else if (!strcmp(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 (!strcmp(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 (!strcmp(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 (!strcmp(name, "PTTYPE")) {
                udev_builtin_add_property(dev, test, "ID_PART_TABLE_TYPE", value);

        } else if (!strcmp(name, "PART_ENTRY_NAME")) {
                blkid_encode_string(value, s, sizeof(s));
                udev_builtin_add_property(dev, test, "ID_PART_ENTRY_NAME", s);

        } else if (!strcmp(name, "PART_ENTRY_TYPE")) {
                blkid_encode_string(value, s, sizeof(s));
                udev_builtin_add_property(dev, test, "ID_PART_ENTRY_TYPE", s);

        } else if (!strncmp(name, "PART_ENTRY_", 11)) {
                util_strscpyl(s, sizeof(s), "ID_", name, NULL);
                udev_builtin_add_property(dev, test, s, value);
        }
}