+/**
+ * udev_device_get_seqnum:
+ * @udev_device: udev device
+ *
+ * This is only valid if the device was received through a monitor. Devices read from
+ * sys do not have a sequence number.
+ *
+ * Returns: the kernel event sequence number, or 0 if there is no sequence number available.
+ **/
+UDEV_EXPORT unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device)
+{
+ if (udev_device == NULL)
+ return 0;
+ return udev_device->seqnum;
+}
+
+static int udev_device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum)
+{
+ char num[32];
+
+ udev_device->seqnum = seqnum;
+ snprintf(num, sizeof(num), "%llu", seqnum);
+ udev_device_add_property(udev_device, "SEQNUM", num);
+ return 0;
+}
+
+int udev_device_get_ifindex(struct udev_device *udev_device)
+{
+ if (!udev_device->info_loaded)
+ udev_device_read_uevent_file(udev_device);
+ return udev_device->ifindex;
+}
+
+static int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex)
+{
+ char num[32];
+
+ udev_device->ifindex = ifindex;
+ snprintf(num, sizeof(num), "%u", ifindex);
+ udev_device_add_property(udev_device, "IFINDEX", num);
+ return 0;
+}
+
+/**
+ * udev_device_get_devnum:
+ * @udev_device: udev device
+ *
+ * Returns: the device major/minor number.
+ **/
+UDEV_EXPORT dev_t udev_device_get_devnum(struct udev_device *udev_device)
+{
+ if (udev_device == NULL)
+ return makedev(0, 0);
+ if (!udev_device->info_loaded)
+ udev_device_read_uevent_file(udev_device);
+ return udev_device->devnum;
+}
+
+static int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum)
+{
+ char num[32];
+
+ udev_device->devnum = devnum;
+
+ snprintf(num, sizeof(num), "%u", major(devnum));
+ udev_device_add_property(udev_device, "MAJOR", num);
+ snprintf(num, sizeof(num), "%u", minor(devnum));
+ udev_device_add_property(udev_device, "MINOR", num);
+ return 0;
+}
+
+int udev_device_get_timeout(struct udev_device *udev_device)
+{
+ return udev_device->timeout;
+}
+
+static int udev_device_set_timeout(struct udev_device *udev_device, int timeout)
+{
+ char num[32];
+
+ udev_device->timeout = timeout;
+ snprintf(num, sizeof(num), "%u", timeout);
+ udev_device_add_property(udev_device, "TIMEOUT", num);
+ return 0;
+}
+
+const char *udev_device_get_knodename(struct udev_device *udev_device)
+{
+ return udev_device->knodename;
+}
+
+static int udev_device_set_knodename(struct udev_device *udev_device, const char *knodename)
+{
+ free(udev_device->knodename);
+ udev_device->knodename = strdup(knodename);
+ if (udev_device->knodename == NULL)
+ return -ENOMEM;
+ /* do not overwrite the udev property with the kernel property */
+ if (udev_device->devnode == NULL)
+ udev_device_add_property(udev_device, "DEVNAME", udev_device->knodename);
+ return 0;
+}
+
+const char *udev_device_get_devpath_old(struct udev_device *udev_device)
+{
+ return udev_device->devpath_old;
+}
+
+static int udev_device_set_devpath_old(struct udev_device *udev_device, const char *devpath_old)
+{
+ const char *pos;
+
+ free(udev_device->devpath_old);
+ udev_device->devpath_old = strdup(devpath_old);
+ if (udev_device->devpath_old == NULL)
+ return -ENOMEM;
+ udev_device_add_property(udev_device, "DEVPATH_OLD", udev_device->devpath_old);
+
+ pos = strrchr(udev_device->devpath_old, '/');
+ if (pos == NULL)
+ return -EINVAL;
+ return 0;
+}
+
+/**
+ * udev_device_get_driver:
+ * @udev_device: udev device
+ *
+ * Returns: the driver string, or #NULL if there is no driver attached.
+ **/
+UDEV_EXPORT const char *udev_device_get_driver(struct udev_device *udev_device)
+{
+ char driver[UTIL_NAME_SIZE];
+
+ if (udev_device == NULL)
+ return NULL;
+ if (!udev_device->driver_set) {
+ udev_device->driver_set = true;
+ if (util_get_sys_core_link_value(udev_device->udev, "driver", udev_device->syspath, driver, sizeof(driver)) > 0)
+ udev_device->driver = strdup(driver);
+ }
+ return udev_device->driver;
+}
+
+static int udev_device_set_driver(struct udev_device *udev_device, const char *driver)
+{
+ free(udev_device->driver);
+ udev_device->driver = strdup(driver);
+ if (udev_device->driver == NULL)
+ return -ENOMEM;
+ udev_device->driver_set = true;
+ udev_device_add_property(udev_device, "DRIVER", udev_device->driver);
+ return 0;
+}
+
+/**
+ * udev_device_get_devtype:
+ * @udev_device: udev device
+ *
+ * Retrieve the devtype string of the udev device.
+ *
+ * Returns: the devtype name of the udev device, or #NULL if it can not be determined
+ **/
+UDEV_EXPORT const char *udev_device_get_devtype(struct udev_device *udev_device)
+{
+ if (udev_device == NULL)
+ return NULL;
+ if (!udev_device->devtype_set) {
+ udev_device->devtype_set = true;
+ udev_device_read_uevent_file(udev_device);
+ }
+ return udev_device->devtype;
+}
+
+static int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype)
+{
+ free(udev_device->devtype);
+ udev_device->devtype = strdup(devtype);
+ if (udev_device->devtype == NULL)
+ return -ENOMEM;
+ udev_device->devtype_set = true;
+ udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype);
+ return 0;
+}
+
+static int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem)
+{
+ free(udev_device->subsystem);
+ udev_device->subsystem = strdup(subsystem);
+ if (udev_device->subsystem == NULL)
+ return -ENOMEM;
+ udev_device->subsystem_set = true;
+ udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem);
+ return 0;
+}
+
+/**
+ * udev_device_get_subsystem:
+ * @udev_device: udev device
+ *
+ * Retrieve the subsystem string of the udev device. The string does not
+ * contain any "/".
+ *
+ * Returns: the subsystem name of the udev device, or #NULL if it can not be determined
+ **/
+UDEV_EXPORT const char *udev_device_get_subsystem(struct udev_device *udev_device)
+{
+ char subsystem[UTIL_NAME_SIZE];
+
+ if (udev_device == NULL)
+ return NULL;
+ if (!udev_device->subsystem_set) {
+ udev_device->subsystem_set = true;
+ /* read "subsystem" link */
+ if (util_get_sys_core_link_value(udev_device->udev, "subsystem", udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
+ udev_device_set_subsystem(udev_device, subsystem);
+ return udev_device->subsystem;
+ }
+ /* implicit names */
+ if (strncmp(udev_device->devpath, "/module/", 8) == 0) {
+ udev_device_set_subsystem(udev_device, "module");
+ return udev_device->subsystem;
+ }
+ if (strstr(udev_device->devpath, "/drivers/") != NULL) {
+ udev_device_set_subsystem(udev_device, "drivers");
+ return udev_device->subsystem;
+ }
+ if (strncmp(udev_device->devpath, "/subsystem/", 11) == 0 ||
+ strncmp(udev_device->devpath, "/class/", 7) == 0 ||
+ strncmp(udev_device->devpath, "/bus/", 5) == 0) {
+ udev_device_set_subsystem(udev_device, "subsystem");
+ return udev_device->subsystem;
+ }
+ }
+ return udev_device->subsystem;
+}
+
+mode_t udev_device_get_devnode_mode(struct udev_device *udev_device)
+{
+ if (!udev_device->info_loaded)
+ udev_device_read_uevent_file(udev_device);
+ return udev_device->devnode_mode;
+}
+
+static int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t mode)
+{
+ char num[32];
+
+ udev_device->devnode_mode = mode;
+ snprintf(num, sizeof(num), "%#o", mode);
+ udev_device_add_property(udev_device, "DEVMODE", num);
+ return 0;
+}
+