#include <errno.h>
#include <string.h>
#include <ctype.h>
+#include <time.h>
#include "libudev.h"
#include "libudev-private.h"
void *userdata;
char *sys_path;
char *dev_path;
- char *rules_path;
- char *run_config_path;
+ char *rules_path[4];
+ unsigned long long rules_path_ts[4];
+ int rules_path_count;
char *run_path;
- struct udev_list_node properties_list;
+ struct udev_list properties_list;
int log_priority;
};
*
* Returns: stored userdata
**/
-void *udev_get_userdata(struct udev *udev)
+UDEV_EXPORT void *udev_get_userdata(struct udev *udev)
{
if (udev == NULL)
return NULL;
*
* Store custom @userdata in the library context.
**/
-void udev_set_userdata(struct udev *udev, void *userdata)
+UDEV_EXPORT void udev_set_userdata(struct udev *udev, void *userdata)
{
if (udev == NULL)
return;
*
* Returns: a new udev library context
**/
-struct udev *udev_new(void)
+UDEV_EXPORT struct udev *udev_new(void)
{
struct udev *udev;
const char *env;
udev->refcount = 1;
udev->log_fn = log_stderr;
udev->log_priority = LOG_ERR;
- udev_list_init(&udev->properties_list);
+ udev_list_init(udev, &udev->properties_list, true);
/* custom config file */
env = getenv("UDEV_CONFIG_FILE");
if (env != NULL) {
- udev_add_property(udev, "UDEV_CONFIG_FILE", udev->dev_path);
if (set_value(&config_file, env) == NULL)
goto err;
+ udev_add_property(udev, "UDEV_CONFIG_FILE", config_file);
}
/* default config file */
continue;
}
if (strcmp(key, "udev_run") == 0) {
- set_value(&udev->run_config_path, val);
+ set_value(&udev->run_path, val);
+ continue;
+ }
+ if (strcmp(key, "udev_sys") == 0) {
+ set_value(&udev->sys_path, val);
continue;
}
if (strcmp(key, "udev_rules") == 0) {
- set_value(&udev->rules_path, val);
+ set_value(&udev->rules_path[0], val);
+ udev->rules_path_count = 1;
continue;
}
}
if (env != NULL)
udev_set_log_priority(udev, util_log_priority(env));
- env = getenv("UDEV_ROOT");
- if (env != NULL) {
- set_value(&udev->dev_path, env);
- udev_add_property(udev, "UDEV_ROOT", udev->dev_path);
- }
-
- env = getenv("SYSFS_PATH");
- if (env != NULL) {
- set_value(&udev->sys_path, env);
- udev_add_property(udev, "SYSFS_PATH", udev->sys_path);
- }
-
/* set defaults */
if (udev->dev_path == NULL)
if (set_value(&udev->dev_path, "/dev") == NULL)
if (set_value(&udev->sys_path, "/sys") == NULL)
goto err;
- if (udev->run_config_path == NULL)
- if (set_value(&udev->run_config_path, "/run/udev") == NULL)
+ if (udev->run_path == NULL)
+ if (set_value(&udev->run_path, "/run/udev") == NULL)
+ goto err;
+
+ if (udev->rules_path[0] == NULL) {
+ /* /usr/lib/udev -- system rules */
+ udev->rules_path[0] = strdup(LIBEXECDIR "/rules.d");
+ if (!udev->rules_path[0])
+ goto err;
+
+ /* /etc/udev -- local administration rules */
+ udev->rules_path[1] = strdup(SYSCONFDIR "/udev/rules.d");
+ if (!udev->rules_path[1])
+ goto err;
+
+ /* /run/udev -- runtime rules */
+ if (asprintf(&udev->rules_path[2], "%s/rules.d", udev->run_path) < 0)
goto err;
+ udev->rules_path_count = 3;
+ }
+
dbg(udev, "context %p created\n", udev);
dbg(udev, "log_priority=%d\n", udev->log_priority);
dbg(udev, "config_file='%s'\n", config_file);
dbg(udev, "dev_path='%s'\n", udev->dev_path);
dbg(udev, "sys_path='%s'\n", udev->sys_path);
- dbg(udev, "run_path='%s'\n", udev->run_config_path);
- if (udev->rules_path != NULL)
- dbg(udev, "rules_path='%s'\n", udev->rules_path);
+ dbg(udev, "run_path='%s'\n", udev->run_path);
+ dbg(udev, "rules_path='%s':'%s':'%s'\n", udev->rules_path[0], udev->rules_path[1], udev->rules_path[2]);
free(config_file);
return udev;
err:
*
* Returns: the passed udev library context
**/
-struct udev *udev_ref(struct udev *udev)
+UDEV_EXPORT struct udev *udev_ref(struct udev *udev)
{
if (udev == NULL)
return NULL;
* reaches zero, the resources of the context will be released.
*
**/
-void udev_unref(struct udev *udev)
+UDEV_EXPORT void udev_unref(struct udev *udev)
{
if (udev == NULL)
return;
udev->refcount--;
if (udev->refcount > 0)
return;
- udev_list_cleanup_entries(udev, &udev->properties_list);
+ udev_list_cleanup(&udev->properties_list);
free(udev->dev_path);
free(udev->sys_path);
- free(udev->rules_path);
+ free(udev->rules_path[0]);
+ free(udev->rules_path[1]);
+ free(udev->rules_path[2]);
free(udev->run_path);
- free(udev->run_config_path);
dbg(udev, "context %p released\n", udev);
free(udev);
}
* into the users' logging functionality.
*
**/
-void udev_set_log_fn(struct udev *udev,
+UDEV_EXPORT void udev_set_log_fn(struct udev *udev,
void (*log_fn)(struct udev *udev,
int priority, const char *file, int line, const char *fn,
const char *format, va_list args))
{
udev->log_fn = log_fn;
- info(udev, "custom logging function %p registered\n", udev);
+ info(udev, "custom logging function %p registered\n", log_fn);
}
/**
*
* Returns: the current logging priority
**/
-int udev_get_log_priority(struct udev *udev)
+UDEV_EXPORT int udev_get_log_priority(struct udev *udev)
{
return udev->log_priority;
}
* Set the current logging priority. The value controls which messages
* are logged.
**/
-void udev_set_log_priority(struct udev *udev, int priority)
+UDEV_EXPORT void udev_set_log_priority(struct udev *udev, int priority)
{
char num[32];
udev_add_property(udev, "UDEV_LOG", num);
}
-const char *udev_get_rules_path(struct udev *udev)
+int udev_get_rules_path(struct udev *udev, char **path[], unsigned long long *stamp_usec[])
{
- return udev->rules_path;
+ *path = udev->rules_path;
+ if (stamp_usec)
+ *stamp_usec = udev->rules_path_ts;
+ return udev->rules_path_count;
}
/**
* @udev: udev library context
*
* Retrieve the sysfs mount point. The default is "/sys". For
- * testing purposes, it can be overridden with the environment
- * variable SYSFS_PATH.
+ * testing purposes, it can be overridden with udev_sys=
+ * in the udev configuration file.
*
* Returns: the sys mount point
**/
-const char *udev_get_sys_path(struct udev *udev)
+UDEV_EXPORT const char *udev_get_sys_path(struct udev *udev)
{
if (udev == NULL)
return NULL;
*
* Returns: the device directory path
**/
-const char *udev_get_dev_path(struct udev *udev)
+UDEV_EXPORT const char *udev_get_dev_path(struct udev *udev)
{
if (udev == NULL)
return NULL;
return udev->dev_path;
}
-const char *udev_get_run_config_path(struct udev *udev)
-{
- return udev->run_config_path;
-}
-
/**
* udev_get_run_path:
* @udev: udev library context
*
* Returns: the runtime directory path
**/
-const char *udev_get_run_path(struct udev *udev)
+UDEV_EXPORT const char *udev_get_run_path(struct udev *udev)
{
- if (udev->run_path != NULL)
- return udev->run_path;
-
- /* check if configured path exists */
- if (access(udev->run_config_path, F_OK) < 0) {
- char filename[UTIL_PATH_SIZE];
-
- /* fall back to /dev/.udev if that exists */
- util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev", NULL);
- if (access(filename, F_OK) >= 0)
- if (set_value(&udev->run_path, filename) != NULL)
- return udev->run_path;
- }
-
- /* use default path */
- set_value(&udev->run_path, udev->run_config_path);
- if (udev->run_path == NULL)
- return udev->run_config_path;
+ if (udev == NULL)
+ return NULL;
return udev->run_path;
}
-const char *udev_set_run_path(struct udev *udev, const char *path)
-{
- return set_value(&udev->run_path, path);
-}
-
struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value)
{
if (value == NULL) {
udev_list_entry_delete(list_entry);
return NULL;
}
- return udev_list_entry_add(udev, &udev->properties_list, key, value, UDEV_LIST_UNIQUE);
+ return udev_list_entry_add(&udev->properties_list, key, value);
}
struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev)