diff options
Diffstat (limited to 'package')
| -rw-r--r-- | package/hotplug2/Makefile | 7 | ||||
| -rw-r--r-- | package/hotplug2/src/udevtrigger.c | 345 | ||||
| -rw-r--r-- | package/udevtrigger/Makefile | 44 | ||||
| -rw-r--r-- | package/udevtrigger/patches/001-no_debug.patch | 20 | ||||
| -rw-r--r-- | package/udevtrigger/patches/002-udevtrigger_no_config.patch | 10 | 
5 files changed, 351 insertions, 75 deletions
| diff --git a/package/hotplug2/Makefile b/package/hotplug2/Makefile index de4633250..7e1dda7a0 100644 --- a/package/hotplug2/Makefile +++ b/package/hotplug2/Makefile @@ -25,7 +25,6 @@ include $(INCLUDE_DIR)/package.mk  define Package/hotplug2    SECTION:=base    CATEGORY:=Base system -  DEPENDS:=+udevtrigger    VERSION:=1.0-beta-$(PKG_RELEASE)    TITLE:=Version 1.0 Dynamic device management subsystem for embedded systems    URL:=http://isteve.bofh.cz/~isteve/hotplug2/ @@ -45,10 +44,16 @@ MAKE_FLAGS += \  	COPTS="$(TARGET_CFLAGS)" \  	STATIC_WORKER="fork" +define Build/Compile +	$(call Build/Compile/Default) +	$(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/udevtrigger src/udevtrigger.c +endef +  define Package/hotplug2/install  	$(INSTALL_DIR) $(1)/etc  	$(INSTALL_DATA) ./files/hotplug2.rules $(1)/etc/  	$(INSTALL_DIR) $(1)/sbin +	$(INSTALL_BIN) $(PKG_BUILD_DIR)/udevtrigger $(1)/sbin/  	$(INSTALL_BIN) $(PKG_BUILD_DIR)/hotplug2 $(1)/sbin/  endef diff --git a/package/hotplug2/src/udevtrigger.c b/package/hotplug2/src/udevtrigger.c new file mode 100644 index 000000000..297e64cc9 --- /dev/null +++ b/package/hotplug2/src/udevtrigger.c @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2004-2006 Kay Sievers <kay@vrfy.org> + * Copyright (C) 2006 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 version 2 of the License. + *  + *	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 <stdlib.h> +#include <stddef.h> +#include <stdarg.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <getopt.h> +#include <errno.h> +#include <dirent.h> +#include <fcntl.h> +#include <syslog.h> +#include <sys/stat.h> +#include <sys/types.h> + +#define PATH_SIZE 512 + +static int verbose; +static int dry_run; + +void log_message(int priority, const char *format, ...) +{ +	va_list args; + +	va_start(args, format); +	vsyslog(priority, format, args); +	va_end(args); +} + +#undef err +#define err(format, arg...)                         \ +    do {                                    \ +        log_message(LOG_ERR ,"%s: " format ,__FUNCTION__ ,## arg);  \ +    } while (0) + +#undef info +#define info(format, arg...)                            \ +    do {                                    \ +        log_message(LOG_INFO ,"%s: " format ,__FUNCTION__ ,## arg); \ +    } while (0) + +#ifdef DEBUG +#undef dbg +#define dbg(format, arg...)                         \ +    do {                                    \ +        log_message(LOG_DEBUG ,"%s: " format ,__FUNCTION__ ,## arg);    \ +    } while (0) +#else +#define dbg(...) do {} while(0) +#endif + + +static void trigger_uevent(const char *devpath) +{ +	char filename[PATH_SIZE]; +	int fd; + +	strlcpy(filename, "/sys", sizeof(filename)); +	strlcat(filename, devpath, sizeof(filename)); +	strlcat(filename, "/uevent", sizeof(filename)); + +	if (verbose) +		printf("%s\n", devpath); + +	if (dry_run) +		return; + +	fd = open(filename, O_WRONLY); +	if (fd < 0) { +		dbg("error on opening %s: %s\n", filename, strerror(errno)); +		return; +	} + +	if (write(fd, "add", 3) < 0) +		info("error on triggering %s: %s\n", filename, strerror(errno)); + +	close(fd); +} + +static int sysfs_resolve_link(char *devpath, size_t size) +{ +	char link_path[PATH_SIZE]; +	char link_target[PATH_SIZE]; +	int len; +	int i; +	int back; + +	strlcpy(link_path, "/sys", sizeof(link_path)); +	strlcat(link_path, devpath, sizeof(link_path)); +	len = readlink(link_path, link_target, sizeof(link_target)); +	if (len <= 0) +		return -1; +	link_target[len] = '\0'; +	dbg("path link '%s' points to '%s'", devpath, link_target); + +	for (back = 0; strncmp(&link_target[back * 3], "../", 3) == 0; back++) +		; +	dbg("base '%s', tail '%s', back %i", devpath, &link_target[back * 3], back); +	for (i = 0; i <= back; i++) { +		char *pos = strrchr(devpath, '/'); + +		if (pos == NULL) +			return -1; +		pos[0] = '\0'; +	} +	dbg("after moving back '%s'", devpath); +	strlcat(devpath, "/", size); +	strlcat(devpath, &link_target[back * 3], size); +	return 0; +} + + +static int device_list_insert(const char *path) +{ +	char filename[PATH_SIZE]; +	char devpath[PATH_SIZE]; +	struct stat statbuf; + +	dbg("add '%s'" , path); + +	/* we only have a device, if we have an uevent file */ +	strlcpy(filename, path, sizeof(filename)); +	strlcat(filename, "/uevent", sizeof(filename)); +	if (stat(filename, &statbuf) < 0) +		return -1; +	if (!(statbuf.st_mode & S_IWUSR)) +		return -1; + +	strlcpy(devpath, &path[4], sizeof(devpath)); + +	/* resolve possible link to real target */ +	if (lstat(path, &statbuf) < 0) +		return -1; +	if (S_ISLNK(statbuf.st_mode)) +		if (sysfs_resolve_link(devpath, sizeof(devpath)) != 0) +			return -1; + +	trigger_uevent(devpath); +	return 0; +} + + +static void scan_subsystem(const char *subsys) +{ +	char base[PATH_SIZE]; +	DIR *dir; +	struct dirent *dent; + +	strlcpy(base, "/sys/", sizeof(base)); +	strlcat(base, subsys, sizeof(base)); + +	dir = opendir(base); +	if (dir != NULL) { +		for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { +			char dirname[PATH_SIZE]; +			DIR *dir2; +			struct dirent *dent2; + +			if (dent->d_name[0] == '.') +				continue; + +			strlcpy(dirname, base, sizeof(dirname)); +			strlcat(dirname, "/", sizeof(dirname)); +			strlcat(dirname, dent->d_name, sizeof(dirname)); +			strlcat(dirname, "/devices", sizeof(dirname)); + +			/* look for devices */ +			dir2 = opendir(dirname); +			if (dir2 != NULL) { +				for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { +					char dirname2[PATH_SIZE]; + +					if (dent2->d_name[0] == '.') +						continue; + +					strlcpy(dirname2, dirname, sizeof(dirname2)); +					strlcat(dirname2, "/", sizeof(dirname2)); +					strlcat(dirname2, dent2->d_name, sizeof(dirname2)); +					device_list_insert(dirname2); +				} +				closedir(dir2); +			} +		} +		closedir(dir); +	} +} + +static void scan_block(void) +{ +	char base[PATH_SIZE]; +	DIR *dir; +	struct dirent *dent; + +	strlcpy(base, "/sys/block", sizeof(base)); + +	dir = opendir(base); +	if (dir != NULL) { +		for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { +			char dirname[PATH_SIZE]; +			DIR *dir2; +			struct dirent *dent2; + +			if (dent->d_name[0] == '.') +				continue; + +			strlcpy(dirname, base, sizeof(dirname)); +			strlcat(dirname, "/", sizeof(dirname)); +			strlcat(dirname, dent->d_name, sizeof(dirname)); +			if (device_list_insert(dirname) != 0) +				continue; + +			/* look for partitions */ +			dir2 = opendir(dirname); +			if (dir2 != NULL) { +				for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { +					char dirname2[PATH_SIZE]; + +					if (dent2->d_name[0] == '.') +						continue; + +					if (!strcmp(dent2->d_name,"device")) +						continue; + +					strlcpy(dirname2, dirname, sizeof(dirname2)); +					strlcat(dirname2, "/", sizeof(dirname2)); +					strlcat(dirname2, dent2->d_name, sizeof(dirname2)); +					device_list_insert(dirname2); +				} +				closedir(dir2); +			} +		} +		closedir(dir); +	} +} + +static void scan_class(void) +{ +	char base[PATH_SIZE]; +	DIR *dir; +	struct dirent *dent; + +	strlcpy(base, "/sys/class", sizeof(base)); + +	dir = opendir(base); +	if (dir != NULL) { +		for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { +			char dirname[PATH_SIZE]; +			DIR *dir2; +			struct dirent *dent2; + +			if (dent->d_name[0] == '.') +				continue; + +			strlcpy(dirname, base, sizeof(dirname)); +			strlcat(dirname, "/", sizeof(dirname)); +			strlcat(dirname, dent->d_name, sizeof(dirname)); +			dir2 = opendir(dirname); +			if (dir2 != NULL) { +				for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { +					char dirname2[PATH_SIZE]; + +					if (dent2->d_name[0] == '.') +						continue; + +					if (!strcmp(dent2->d_name, "device")) +						continue; + +					strlcpy(dirname2, dirname, sizeof(dirname2)); +					strlcat(dirname2, "/", sizeof(dirname2)); +					strlcat(dirname2, dent2->d_name, sizeof(dirname2)); +					device_list_insert(dirname2); +				} +				closedir(dir2); +			} +		} +		closedir(dir); +	} +} + +int main(int argc, char *argv[], char *envp[]) +{ +	char base[PATH_SIZE]; +	struct stat statbuf; +	int failed = 0; +	int option; + +	openlog("udevtrigger", LOG_PID | LOG_CONS, LOG_DAEMON); + +	while (1) { +		option = getopt(argc, argv, "vnh"); +		if (option == -1) +			break; + +		switch (option) { +		case 'v': +			verbose = 1; +			break; +		case 'n': +			dry_run = 1; +			break; +		case 'h': +			printf("Usage: udevtrigger OPTIONS\n" +			       "  -v                     print the list of devices while running\n" +			       "  -n                     do not actually trigger the events\n" +			       "  -h                     print this text\n" +			       "\n"); +			goto exit; +		default: +			goto exit; +		} +	} + + +	/* if we have /sys/subsystem, forget all the old stuff */ +	scan_subsystem("bus"); +	scan_class(); + +	/* scan "block" if it isn't a "class" */ +	strlcpy(base, "/sys/class/block", sizeof(base)); +	if (stat(base, &statbuf) != 0) +		scan_block(); + +exit: + +	closelog(); +	return 0; +} diff --git a/package/udevtrigger/Makefile b/package/udevtrigger/Makefile deleted file mode 100644 index e64433959..000000000 --- a/package/udevtrigger/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright (C) 2006-2008 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=udevtrigger -PKG_VERSION:=106 -PKG_RELEASE:=1 - -PKG_SOURCE:=udev-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_URL:=@KERNEL/linux/utils/kernel/hotplug/ -PKG_MD5SUM:=320ccd2d0f4540d10e021bafa14f8985 - -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/udev-$(PKG_VERSION) - -include $(INCLUDE_DIR)/package.mk - -define Package/udevtrigger -  SECTION:=base -  CATEGORY:=Base system -  TITLE:=Small utility to request kernel devices events for coldplug -  URL:=http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html -  MAINTAINER:=Geoff Levand <geoffrey.levand@am.sony.com> -endef - -define Build/Compile -	$(MAKE) -C $(PKG_BUILD_DIR) \ -		CROSS_COMPILE="$(TARGET_CROSS)" \ -		STRIP="/bin/true" \ -		DESTDIR="$(PKG_INSTALL_DIR)" \ -		OPTFLAGS="$(TARGET_CFLAGS)" \ - 		udevtrigger -endef - -define Package/udevtrigger/install -	$(INSTALL_DIR) $(1)/sbin -	$(INSTALL_BIN) $(PKG_BUILD_DIR)/udevtrigger $(1)/sbin/ -endef - -$(eval $(call BuildPackage,udevtrigger)) diff --git a/package/udevtrigger/patches/001-no_debug.patch b/package/udevtrigger/patches/001-no_debug.patch deleted file mode 100644 index 9f3ddd08d..000000000 --- a/package/udevtrigger/patches/001-no_debug.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -113,7 +113,7 @@ LD = $(CROSS_COMPILE)gcc - AR = $(CROSS_COMPILE)ar - RANLIB = $(CROSS_COMPILE)ranlib -  --CFLAGS		= -g -Wall -pipe -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -+CFLAGS		= -Wall -pipe -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 - WARNINGS	= -Wstrict-prototypes -Wsign-compare -Wshadow \ - 		  -Wchar-subscripts -Wmissing-declarations -Wnested-externs \ - 		  -Wpointer-arith -Wcast-align -Wsign-compare -Wmissing-prototypes -@@ -130,7 +130,7 @@ endif -  - # if DEBUG is enabled, then we do not strip - ifeq ($(strip $(DEBUG)),true) --	CFLAGS  += -DDEBUG -+	CFLAGS  += -g -DDEBUG - endif -  - ifeq ($(strip $(USE_GCOV)),true) diff --git a/package/udevtrigger/patches/002-udevtrigger_no_config.patch b/package/udevtrigger/patches/002-udevtrigger_no_config.patch deleted file mode 100644 index f5d6a1c4f..000000000 --- a/package/udevtrigger/patches/002-udevtrigger_no_config.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/udevtrigger.c -+++ b/udevtrigger.c -@@ -446,7 +446,6 @@ int main(int argc, char *argv[], char *e - 	}; -  - 	logging_init("udevtrigger"); --	udev_config_init(); - 	dbg("version %s", UDEV_VERSION); - 	sysfs_init(); -  | 
