diff options
author | Danny Kukawka <danny.kukawka@web.de> | 2009-09-22 11:19:55 +0200 |
---|---|---|
committer | Danny Kukawka <danny.kukawka@web.de> | 2009-09-22 11:19:55 +0200 |
commit | 4f4ccbdd31edd14bd328d3cefc2fb906223202e1 (patch) | |
tree | 090af12bcc8c592c882050fbb1f9a1c9d65a1d30 | |
parent | 74bf2659a02c5c0cf96121a8d58f0ee530fe9599 (diff) | |
parent | 2e5eed0af0761ab6f7a15659ec1efa1f66ef1ea8 (diff) | |
download | hal-4f4ccbdd31edd14bd328d3cefc2fb906223202e1.tar.gz |
Merge branch 'master' of ssh://dkukawka@git.freedesktop.org/git/hal
30 files changed, 2105 insertions, 187 deletions
diff --git a/configure.in b/configure.in index 2e947a7a..e8aa021e 100644 --- a/configure.in +++ b/configure.in @@ -15,6 +15,7 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) glib_module="glib-2.0 >= 2.10.0 gobject-2.0 > 2.10.0 dbus-glib-1 >= 0.61" dbus_module="dbus-1 >= 0.61" blkid_module="blkid >= 2.15" +volume_id_module="libvolume_id >= 0.77" polkit_module="polkit >= 0.5" # libtool versioning - this applies to libhal and libhal-storage @@ -478,6 +479,9 @@ if test "x$with_libpci" != xno ; then fi AM_CONDITIONAL([HAVE_LIBPCI], [test "x$USE_LIBPCI" = "xyes"]) +USE_LIBUSB20=no +USE_LIBUSB=no +LIBUSB20_LIBS="" AC_ARG_WITH([backend], AS_HELP_STRING([--with-backend=<name>], [backend to use (linux/solaris/freebsd/dummy)]), @@ -505,6 +509,22 @@ AM_CONDITIONAL(HALD_COMPILE_LINUX, [test x$HALD_BACKEND = xlinux], [Compiling fo AM_CONDITIONAL(HALD_COMPILE_FREEBSD, [test x$HALD_BACKEND = xfreebsd], [Compiling for FreeBSD]) AM_CONDITIONAL(HALD_COMPILE_SOLARIS, [test x$HALD_BACKEND = xsolaris], [Compiling for Solaris]) AC_SUBST(HALD_BACKEND) +if test "x$HALD_BACKEND" = "xfreebsd"; then + AC_CHECK_LIB([usb20], [libusb20_dev_get_info], [USE_LIBUSB20=yes], [USE_LIBUSB20=no]) +fi +if test "x$USE_LIBUSB20" = "xno"; then + AC_CHECK_LIB([usb], [libusb20_dev_get_info], [USE_LIBUSB=yes], [USE_LIBUSB=no]) +fi +AM_CONDITIONAL([HAVE_LIBUSB20],[test "x$USE_LIBUSB20" = "xyes"]) +AM_CONDITIONAL([HAVE_LIBUSB20],[test "x$USE_LIBUSB" = "xyes"]) +if test "x$USE_LIBUSB20" = "xyes"; then + AC_DEFINE(HAVE_LIBUSB20, 1, [Set if we need libusb20]) + LIBUSB20_LIBS="-lusb20" +elif test "x$USE_LIBUSB" = "xyes"; then + AC_DEFINE(HAVE_LIBUSB20, 1, [Set if we need libsub20]) + LIBUSB20_LIBS="-lusb" +fi +AC_SUBST(LIBUSB20_LIBS) dnl DBUS API is subject to changes AC_DEFINE_UNQUOTED(DBUS_API_SUBJECT_TO_CHANGE, [], [DBUS API is subject to change]) @@ -686,8 +706,20 @@ else fi AC_MSG_RESULT($have_glib_2_14) +case "$host" in + *-*-freebsd*) + PKG_CHECK_MODULES(VOLUME_ID, [$volume_id_module]) + AC_SUBST(VOLUME_ID_CFLAGS) + AC_SUBST(VOLUME_ID_LIBS) + ;; + *) + ;; +esac + # blkid (util-linux-ng) case "$host" in +*-*-freebsd*) + ;; *-*-solaris*) ;; *) diff --git a/hald/freebsd/Makefile.am b/hald/freebsd/Makefile.am index 95d40d46..d3aff6e9 100644 --- a/hald/freebsd/Makefile.am +++ b/hald/freebsd/Makefile.am @@ -54,4 +54,11 @@ libhald_freebsd_la_SOURCES = \ libhald_freebsd_la_LDFLAGS = -lcam +if HAVE_LIBUSB20 +libhald_freebsd_la_SOURCES += \ + hf-usb2.c \ + hf-usb2.h +libhald_freebsd_la_LDFLAGS += @LIBUSB20_LIBS@ +endif + EXTRA_DIST = README TODO diff --git a/hald/freebsd/addons/Makefile.am b/hald/freebsd/addons/Makefile.am index 25cf0df1..c2a68ba0 100644 --- a/hald/freebsd/addons/Makefile.am +++ b/hald/freebsd/addons/Makefile.am @@ -8,9 +8,17 @@ AM_CPPFLAGS = \ @DBUS_CFLAGS@ if HALD_COMPILE_FREEBSD -libexec_PROGRAMS = hald-addon-storage +libexec_PROGRAMS = hald-addon-storage \ + hald-addon-mouse-sysmouse endif hald_addon_storage_SOURCES = addon-storage.c hald_addon_storage_LDADD = \ $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la + +hald_addon_mouse_sysmouse_SOURCES = addon-mouse.c +hald_addon_mouse_sysmouse_CFLAGS = $(AM_CPPFLAGS) @GLIB_CFLAGS@ +hald_addon_mouse_sysmouse_LDADD = \ + @GLIB_LIBS@ \ + -lutil \ + $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la diff --git a/hald/freebsd/addons/addon-mouse.c b/hald/freebsd/addons/addon-mouse.c new file mode 100644 index 00000000..51194cac --- /dev/null +++ b/hald/freebsd/addons/addon-mouse.c @@ -0,0 +1,371 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * addon-mouse.c : poll mice to disable moused(8) owned devices + * + * Copyright (C) 2008 Joe Marcus Clarke + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/event.h> +#include <sys/time.h> +#include <sys/proc.h> +#if __FreeBSD_version >= 800058 +#include <sys/types.h> +#include <sys/user.h> +#include <sys/sysctl.h> +#include <libutil.h> +#endif +#include <string.h> +#include <stdlib.h> +#include <assert.h> +#include <unistd.h> +#include <glib.h> + +#include "libhal/libhal.h" + +#include "../libprobe/hfp.h" + +#if __FreeBSD_version < 800058 +#define CMD "/usr/bin/fstat %s" +#endif + +#define MOUSED_DEVICE "/dev/sysmouse" +#define MOUSED_PROC_NAME "moused" +#define XORG_PROC_NAME "Xorg" +#define NO_PID -1 + +static struct +{ + const struct timespec update_interval; + char *device_file; + struct timespec next_update; +} addon = { { 2, 0 } }; + +static int kd = -1; + +#if __FreeBSD_version >= 800058 +static struct kinfo_proc * +hfp_kinfo_getproc (int *cntp) +{ + int mib[3]; + int error; + int cnt; + size_t len; + char *buf, *bp, *eb; + struct kinfo_proc *kip, *kp, *ki; + + *cntp = 0; + + len = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PROC; + + error = sysctl(mib, 3, NULL, &len, NULL, 0); + if (error) + return NULL; + + len = len * 4 / 3; + buf = (char *) g_malloc(len); + if (buf == NULL) + return NULL; + + error = sysctl(mib, 3, buf, &len, NULL, 0); + if (error) + { + g_free(buf); + return NULL; + } + + cnt = 0; + bp = buf; + eb = buf + len; + while (bp < eb) + { + ki = (struct kinfo_proc *) (uintptr_t) bp; + bp += ki->ki_structsize; + cnt++; + } + + kip = calloc(cnt, sizeof (*kip)); + if (kip == NULL) + { + g_free(buf); + return NULL; + } + + bp = buf; + eb = buf + len; + kp = kip; + while (bp < eb) + { + ki = (struct kinfo_proc *) (uintptr_t) bp; + memcpy(kp, ki, ki->ki_structsize); + bp += ki->ki_structsize; + kp->ki_structsize = sizeof(*kp); + kp++; + } + + g_free(buf); + *cntp = cnt; + return kip; +} + +static gboolean +device_opened_by_proc (const char *device, const char *proc, pid_t *pid) +{ + struct kinfo_proc *kip, *pfreep; + int cnt, i; + + *pid = NO_PID; + + pfreep = hfp_kinfo_getproc(&cnt); + if (pfreep == NULL) + return FALSE; + + for (i = 0; i < cnt; i++) + { + kip = &pfreep[i]; + + if (! strcmp(kip->ki_comm, proc)) + { + struct kinfo_file *kif, *ffreep; + int fcnt, j; + + ffreep = kinfo_getfile(kip->ki_pid, &fcnt); + if (ffreep == NULL) + continue; + for (j = 0; j < fcnt; j++) + { + kif = &ffreep[j]; + + if (kif->kf_type == KF_TYPE_VNODE && + ! strcmp(kif->kf_path, device)) + { + *pid = kip->ki_pid; + g_free(ffreep); + g_free(pfreep); + return TRUE; + } + } + g_free(ffreep); + } + } + g_free(pfreep); + + return FALSE; +} +#else +static gboolean +device_opened_by_proc (const char *device, const char *proc, pid_t *pid) +{ + char **lines; + char *output = NULL; + char *cmd; + int i; + gboolean found = FALSE; + + cmd = g_strdup_printf(CMD, device); + *pid = NO_PID; + + if (! g_spawn_command_line_sync(cmd, &output, NULL, NULL, NULL)) + { + g_free(cmd); + goto done; + } + g_free(cmd); + + if (! output || strlen(output) == 0) + goto done; + + lines = g_strsplit(output, "\n", 0); + if (g_strv_length(lines) < 2) + { + g_strfreev(lines); + goto done; + } + + for (i = 1; lines[i]; i++) + { + char **fields; + guint len; + guint j; + + fields = g_strsplit_set(lines[i], " ", 0); + len = g_strv_length(fields); + if (len < 3) + { + g_strfreev(fields); + continue; + } + for (j = 1; j < len && fields[j] && *fields[j] == '\0'; j++) + ; + if (j < len && fields[j] && ! strcmp(fields[j], proc)) + { + found = TRUE; + for (++j; j < len && fields[j] && *fields[j] == '\0'; j++) + ; + if (j < len && fields[j]) + *pid = atoi(fields[j]); + g_strfreev(fields); + break; + } + g_strfreev(fields); + } + + g_strfreev(lines); + +done: + g_free(output); + + return found; +} +#endif + +static const char * +get_mouse_device (const char *device, pid_t *pid) +{ + if (device_opened_by_proc(device, MOUSED_PROC_NAME, pid)) + return MOUSED_DEVICE; + + return device; +} + +static void +poll_for_moused (void) +{ + struct kevent ev; + const char *device; + gboolean found; + pid_t pid; + char *owner = NULL; + char *prev_owner = NULL; + +again: + device = get_mouse_device(addon.device_file, &pid); + if (pid != NO_PID) + { + EV_SET(&ev, pid, EVFILT_PROC, EV_ADD | EV_ENABLE, NOTE_EXIT, 0, NULL); + if (kevent(kd, &ev, 1, NULL, 0, NULL) < 0) + return; + g_free(owner); + owner = g_strdup(MOUSED_PROC_NAME); + } + else + { + found = device_opened_by_proc(device, XORG_PROC_NAME, &pid); + if (found && pid != NO_PID) + { + EV_SET(&ev, pid, EVFILT_PROC, EV_ADD | EV_ENABLE, NOTE_EXIT, 0, NULL); + if (kevent(kd, &ev, 1, NULL, 0, NULL) < 0) + return; + g_free(owner); + owner = g_strdup(XORG_PROC_NAME); + } + else + goto out; + } + + if (owner && prev_owner && strcmp(owner, prev_owner)) + goto out; + + if (kevent(kd, NULL, 0, &ev, 1, NULL) < 0) + return; + + sleep(3); + g_free(prev_owner); + prev_owner = NULL; + if (owner) + prev_owner = g_strdup(owner); + goto again; + +out: + if (owner) + { + libhal_device_reprobe(hfp_ctx, hfp_udi, &hfp_error); + dbus_error_free(&hfp_error); + } + g_free(owner); + g_free(prev_owner); +} + +int +main (int argc, char **argv) +{ + DBusConnection *connection; + + if (! hfp_init(argc, argv)) + goto end; + + addon.device_file = getenv("HAL_PROP_FREEBSD_DEVICE_FILE"); + if (! addon.device_file) + goto end; + + setproctitle("%s", addon.device_file); + + if (! libhal_device_addon_is_ready(hfp_ctx, hfp_udi, &hfp_error)) + goto end; + dbus_error_free(&hfp_error); + + connection = libhal_ctx_get_dbus_connection(hfp_ctx); + assert(connection != NULL); + + kd = kqueue(); + assert(kd > -1); + + while (TRUE) + { + /* process dbus traffic until update interval has elapsed */ + while (TRUE) + { + struct timespec now; + + hfp_clock_gettime(&now); + if (hfp_timespeccmp(&now, &addon.next_update, <)) + { + struct timespec timeout; + + timeout = addon.next_update; + hfp_timespecsub(&timeout, &now); + + if (timeout.tv_sec < 0) /* current time went backwards */ + timeout = addon.update_interval; + + dbus_connection_read_write_dispatch(connection, timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000); + if (! dbus_connection_get_is_connected(connection)) + goto end; + } + else + break; + } + + poll_for_moused(); + + hfp_clock_gettime(&addon.next_update); + hfp_timespecadd(&addon.next_update, &addon.update_interval); + } + + end: + return 0; +} diff --git a/hald/freebsd/addons/addon-storage.c b/hald/freebsd/addons/addon-storage.c index dcd9cdc9..31250373 100644 --- a/hald/freebsd/addons/addon-storage.c +++ b/hald/freebsd/addons/addon-storage.c @@ -36,17 +36,24 @@ #include "../libprobe/hfp.h" #include "../libprobe/hfp-cdrom.h" +static boolean is_locked_by_hal = FALSE; +static boolean check_lock_state = TRUE; +static boolean polling_disabled = FALSE; + static struct { - const struct timeval update_interval; + const struct timespec update_interval; char *device_file; char *parent; boolean is_cdrom; boolean is_scsi_removable; boolean had_media; - struct timeval next_update; + struct timespec next_update; } addon = { { 2, 0 } }; +static void update_proc_title (const char *device); +static void unmount_volumes (void); + /* see MMC-3 Working Draft Revision 10 */ static boolean hf_addon_storage_cdrom_eject_pressed (HFPCDROM *cdrom) @@ -144,18 +151,148 @@ hf_addon_storage_update (void) } } - hfp_gettimeofday(&addon.next_update); - hfp_timevaladd(&addon.next_update, &addon.update_interval); - return has_media; } +static void +unmount_volumes (void) +{ + int num_volumes; + char **volumes; + + if ((volumes = libhal_manager_find_device_string_match(hfp_ctx, + "block.storage_device", + hfp_udi, + &num_volumes, + &hfp_error)) != NULL) + { + int i; + + dbus_error_free(&hfp_error); + + for (i = 0; i < num_volumes; i++) + { + char *vol_udi; + + vol_udi = volumes[i]; + + if (libhal_device_get_property_bool(hfp_ctx, vol_udi, "volume.is_mounted", &hfp_error)) + { + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + DBusConnection *dbus_connection; + unsigned int num_options = 0; + char **options = NULL; + char *devfile; + + dbus_error_free(&hfp_error); + hfp_info("Forcing unmount of volume '%s'", vol_udi); + + dbus_connection = libhal_ctx_get_dbus_connection(hfp_ctx); + msg = dbus_message_new_method_call("org.freedesktop.Hal", vol_udi, + "org.freedesktop.Hal.Device.Volume", + "Unmount"); + if (msg == NULL) + { + hfp_warning("Could not create dbus message for %s", vol_udi); + continue; + } + + options = calloc(1, sizeof (char *)); + if (options == NULL) + { + hfp_warning("Could not allocation memory for options"); + dbus_message_unref(msg); + continue; + } + + options[0] = "force"; + num_options = 1; + + devfile = libhal_device_get_property_string(hfp_ctx, vol_udi, "block.device", NULL); + if (devfile != NULL) + { + hfp_info("Forcibly attempting to unmount %s as media was removed", devfile); + libhal_free_string(devfile); + } + + if (! dbus_message_append_args(msg, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options, DBUS_TYPE_INVALID)) + { + hfp_warning("Could not append args to dbus message for %s", vol_udi); + free(options); + dbus_message_unref(msg); + continue; + } + + if (! (reply = dbus_connection_send_with_reply_and_block(dbus_connection, msg, -1, &hfp_error))) + { + hfp_warning("Unmount failed for %s: %s: %s", vol_udi, hfp_error.name, hfp_error.message); + dbus_error_free(&hfp_error); + free(options); + dbus_message_unref(msg); + continue; + } + + if (dbus_error_is_set(&hfp_error)) + { + hfp_warning("Unmount failed for %s: %s : %s", vol_udi, hfp_error.name, hfp_error.message); + dbus_error_free(&hfp_error); + free(options); + dbus_message_unref(msg); + dbus_message_unref(reply); + continue; + } + + hfp_info("Successfully unmounted udi '%s'", vol_udi); + free(options); + dbus_message_unref(msg); + dbus_message_unref(reply); + } + } + libhal_free_string_array(volumes); + } +} + static boolean -poll_for_media (void) +poll_for_media (boolean check_only, boolean force) { boolean has_media; + if (check_lock_state) + { + boolean should_poll; + + check_lock_state = FALSE; + + hfp_info("Checking whether device %s is locked by HAL", addon.device_file); + if (libhal_device_is_locked_by_others(hfp_ctx, hfp_udi, "org.freedesktop.Hal.Device.Storage", &hfp_error)) + { + hfp_info("... device %s is locked by HAL", addon.device_file); + dbus_error_free(&hfp_error); + is_locked_by_hal = TRUE; + update_proc_title(addon.device_file); + goto skip_check; + } + else + { + hfp_info("... device %s is not locked by HAL", addon.device_file); + is_locked_by_hal = FALSE; + } + dbus_error_free(&hfp_error); + + should_poll = libhal_device_get_property_bool(hfp_ctx, hfp_udi, "storage.media_check_enabled", &hfp_error); + dbus_error_free(&hfp_error); + polling_disabled = ! should_poll; + update_proc_title(addon.device_file); + } + + if (! force && polling_disabled) + goto skip_check; + has_media = hf_addon_storage_update(); + if (check_only) + return has_media; + if (has_media != addon.had_media) { /* @@ -168,6 +305,14 @@ poll_for_media (void) * then hung while rebooting and did not unmount my other * filesystems. */ +#if __FreeBSD_version >= 800066 + /* + * With newusb, it is safe to force unmount volumes. This may be + * safe on newer versions of the old USB stack, but we'll be + * extra cautious. + */ + unmount_volumes(); +#endif libhal_device_rescan(hfp_ctx, hfp_udi, &hfp_error); dbus_error_free(&hfp_error); @@ -175,20 +320,33 @@ poll_for_media (void) return TRUE; } + +skip_check: + return FALSE; } static void -update_proc_title (const char *device, boolean polling_enabled) +update_proc_title (const char *device) { - if (polling_enabled) - setproctitle("%s", device); - else + if (polling_disabled) setproctitle("no polling on %s because it is explicitly disabled", device); + else if (is_locked_by_hal) + setproctitle("no polling on %s because it is locked by HAL", device); + else + setproctitle("%s", device); } static DBusHandlerResult -filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) +dbus_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) +{ + check_lock_state = TRUE; + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +direct_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) { if (dbus_message_is_method_call(message, "org.freedesktop.Hal.Device.Storage.Removable", @@ -199,7 +357,7 @@ filter_function (DBusConnection *connection, DBusMessage *message, void *user_da hfp_info("Forcing poll for media becusse CheckForMedia() was called"); - had_effect = poll_for_media(); + had_effect = poll_for_media(FALSE, TRUE); reply = dbus_message_new_method_return (message); dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &had_effect, DBUS_TYPE_INVALID); @@ -217,8 +375,9 @@ main (int argc, char **argv) char *removable; char *bus; char *driver; - boolean should_poll; + char *filter_str; DBusConnection *connection; + DBusConnection *syscon; if (! hfp_init(argc, argv)) goto end; @@ -251,16 +410,41 @@ main (int argc, char **argv) addon.is_scsi_removable = (! strcmp(bus, "scsi") || (! strcmp(bus, "usb") && (! strcmp(driver, "da") || ! strcmp(driver, "sa") || ! strcmp(driver, "cd")))) && ! strcmp(removable, "true"); - addon.had_media = hf_addon_storage_update(); + addon.had_media = poll_for_media(TRUE, FALSE); if (! libhal_device_addon_is_ready(hfp_ctx, hfp_udi, &hfp_error)) goto end; dbus_error_free(&hfp_error); + syscon = dbus_bus_get(DBUS_BUS_SYSTEM, &hfp_error); + dbus_error_free(&hfp_error); + assert(syscon != NULL); + dbus_connection_set_exit_on_disconnect(syscon, 0); + + dbus_bus_add_match(syscon, + "type='signal'" + ",interface='org.freedesktop.Hal.Manager'" + ",sender='org.freedesktop.Hal'", + NULL); + dbus_bus_add_match(syscon, + "type='signal'" + ",interface='org.freedesktop.Hal.Manager'" + ",sender='org.freedesktop.Hal'", + NULL); + filter_str = hfp_strdup_printf("type='signal'" + ",interface='org.freedesktop.Hal.Device'" + ",sender='org.freedesktop.Hal'" + ",path='%s'", + hfp_udi); + dbus_bus_add_match(syscon, filter_str, NULL); + hfp_free(filter_str); + + dbus_connection_add_filter(syscon, dbus_filter_function, NULL, NULL); + connection = libhal_ctx_get_dbus_connection(hfp_ctx); assert(connection != NULL); dbus_connection_set_exit_on_disconnect(connection, 0); - dbus_connection_add_filter(connection, filter_function, NULL, NULL); + dbus_connection_add_filter(connection, direct_filter_function, NULL, NULL); if (! libhal_device_claim_interface(hfp_ctx, hfp_udi, @@ -280,40 +464,32 @@ main (int argc, char **argv) /* process dbus traffic until update interval has elapsed */ while (TRUE) { - struct timeval now; + struct timespec now; - hfp_gettimeofday(&now); - if (hfp_timevalcmp(&now, &addon.next_update, <)) + hfp_clock_gettime(&now); + if (hfp_timespeccmp(&now, &addon.next_update, <)) { - struct timeval timeout; + struct timespec timeout; timeout = addon.next_update; - hfp_timevalsub(&timeout, &now); + hfp_timespecsub(&timeout, &now); if (timeout.tv_sec < 0) /* current time went backwards */ timeout = addon.update_interval; - dbus_connection_read_write_dispatch(connection, timeout.tv_sec * 1000 + timeout.tv_usec / 1000); - if (! dbus_connection_get_is_connected(connection)) + dbus_connection_read_write_dispatch(connection, (int) ((timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000) / 2)); + dbus_connection_read_write_dispatch(syscon, (int) ((timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000) / 2)); + if (! dbus_connection_get_is_connected(connection) || + ! dbus_connection_get_is_connected(syscon)) goto end; } else break; } - should_poll = libhal_device_get_property_bool(hfp_ctx, hfp_udi, "storage.media_check_enabled", &hfp_error); - dbus_error_free(&hfp_error); - update_proc_title(addon.device_file, should_poll); - - if (should_poll) - { - poll_for_media(); - } - else - { - hfp_gettimeofday(&addon.next_update); - hfp_timevaladd(&addon.next_update, &addon.update_interval); - } + poll_for_media(FALSE, FALSE); + hfp_clock_gettime(&addon.next_update); + hfp_timespecadd(&addon.next_update, &addon.update_interval); } end: diff --git a/hald/freebsd/hf-acpi.c b/hald/freebsd/hf-acpi.c index 89243df8..023a4fed 100644 --- a/hald/freebsd/hf-acpi.c +++ b/hald/freebsd/hf-acpi.c @@ -54,6 +54,7 @@ static const struct laptop_panel_type { char *access; char *name; + char *get_sysctl; char *max_sysctl; int max_levels; #define HF_ACPI_IBM_MAX_LEVELS 8 @@ -64,17 +65,29 @@ static const struct laptop_panel_type { #define HF_ACPI_FUJITSU_MAX_LEVELS 8 /* NOTE: Each new type must also be added to hf-devtree.c */ } laptop_panel_types[] = { - { "ibm", "IBM", NULL, + { "ibm", "IBM", + "dev.acpi_ibm.0.lcd_brightness", + NULL, HF_ACPI_IBM_MAX_LEVELS }, - { "toshiba", "Toshiba", NULL, + { "toshiba", "Toshiba", + "hw.acpi.toshiba.lcd_brightness", + NULL, HF_ACPI_TOSHIBA_MAX_LEVELS }, - { "sony", "Sony", NULL, + { "sony", "Sony", + "dev.acpi_sony.0.brightness", + NULL, HF_ACPI_SONY_MAX_LEVELS }, - { "panasonic", "Panasonic", "hw.acpi.panasonic.lcd_brightness_max", + { "panasonic", "Panasonic", + "hw.acpi.panasonic.lcd_brightness", + "hw.acpi.panasonic.lcd_brightness_max", HF_ACPI_PANASONIC_MAX_LEVELS }, - { "asus", "Asus", NULL, + { "asus", "Asus", + "hw.acpi.asus.lcd_brightness", + NULL, HF_ACPI_ASUS_MAX_LEVELS }, - { "fujitsu", "Fujitsu", NULL, + { "fujitsu", "Fujitsu", + "hw.acpi.fujitsu.lcd_brightness", + NULL, HF_ACPI_FUJITSU_MAX_LEVELS } }; @@ -105,6 +118,9 @@ hf_acpi_poll_batt (HalDevice *device) gboolean ispresent; union acpi_battery_ioctl_arg battif, battst, battinfo; + if (! hf_has_sysctl("hw.acpi.battery.units")) + return; + battif.unit = battst.unit = battinfo.unit = hal_device_property_get_int(device, "freebsd.unit"); @@ -497,13 +513,15 @@ hf_acpi_video_device_new (HalDevice *parent, const char *type) static HalDevice * hf_acpi_laptop_panel_new (HalDevice *parent, int max_levels, - const char *max_sysctl, const char *access, - const char *name) + const char *get_sysctl, const char *max_sysctl, + const char *access, const char *name) { HalDevice *device; g_return_val_if_fail(HAL_IS_DEVICE(parent), NULL); + if (get_sysctl == NULL || ! hf_has_sysctl(get_sysctl)) + return NULL; device = hf_device_new(parent); hf_device_property_set_string_printf(device, "info.product", "Laptop Panel (%s)", name); @@ -593,11 +611,13 @@ hf_acpi_probe (void) HalDevice *panel_device; panel_device = hf_acpi_laptop_panel_new(parent, - laptop_panel_types[i].max_levels, + laptop_panel_types[i].max_levels, + laptop_panel_types[i].get_sysctl, laptop_panel_types[i].max_sysctl, laptop_panel_types[i].access, laptop_panel_types[i].name); - hf_device_preprobe_and_add(panel_device); + if (panel_device) + hf_device_preprobe_and_add(panel_device); } } } diff --git a/hald/freebsd/hf-computer.c b/hald/freebsd/hf-computer.c index 7e9b9de1..e0e53ecb 100644 --- a/hald/freebsd/hf-computer.c +++ b/hald/freebsd/hf-computer.c @@ -26,6 +26,7 @@ # include <config.h> #endif +#include <stdio.h> #include <string.h> #include <sys/utsname.h> @@ -133,11 +134,11 @@ hf_computer_device_add (void) if (PACKAGE_VERSION) { int major, minor, micro; - hal_device_property_set_string (root, "org.freedesktop.Hal.version", PACKAGE_VERSION); + hal_device_property_set_string (device, "org.freedesktop.Hal.version", PACKAGE_VERSION); if ( sscanf( PACKAGE_VERSION, "%d.%d.%d", &major, &minor, µ ) == 3 ) { - hal_device_property_set_int (root, "org.freedesktop.Hal.version.major", major); - hal_device_property_set_int (root, "org.freedesktop.Hal.version.minor", minor); - hal_device_property_set_int (root, "org.freedesktop.Hal.version.micro", micro); + hal_device_property_set_int (device, "org.freedesktop.Hal.version.major", major); + hal_device_property_set_int (device, "org.freedesktop.Hal.version.minor", minor); + hal_device_property_set_int (device, "org.freedesktop.Hal.version.micro", micro); } } diff --git a/hald/freebsd/hf-devd.c b/hald/freebsd/hf-devd.c index d878a458..dbf0202d 100644 --- a/hald/freebsd/hf-devd.c +++ b/hald/freebsd/hf-devd.c @@ -28,6 +28,7 @@ #include <string.h> #include <errno.h> #include <unistd.h> +#include <sys/param.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> @@ -40,7 +41,11 @@ #include "hf-acpi.h" #include "hf-net.h" #include "hf-pcmcia.h" +#include "hf-storage.h" #include "hf-usb.h" +#ifdef HAVE_LIBUSB20 +#include "hf-usb2.h" +#endif #include "hf-util.h" #define HF_DEVD_SOCK_PATH "/var/run/devd.pipe" @@ -51,10 +56,16 @@ #define HF_DEVD_EVENT_NOMATCH '?' static HFDevdHandler *handlers[] = { +#ifdef HAVE_LIBUSB20 + &hf_usb2_devd_handler, +#endif +#if __FreeBSD_version < 800092 &hf_usb_devd_handler, +#endif &hf_net_devd_handler, &hf_acpi_devd_handler, - &hf_pcmcia_devd_handler + &hf_pcmcia_devd_handler, + &hf_storage_devd_handler }; static gboolean hf_devd_inited = FALSE; @@ -381,13 +392,13 @@ hf_devd_event_cb (GIOChannel *source, GIOCondition condition, status = g_io_channel_read_line(source, &event, NULL, &terminator, NULL); - if (status != G_IO_STATUS_NORMAL) + if (status == G_IO_STATUS_NORMAL) { event[terminator] = 0; hf_devd_process_event(event); g_free(event); } - else if (status != G_IO_STATUS_AGAIN) + else if (status == G_IO_STATUS_AGAIN) { hf_devd_init(); if (hf_devd_inited) diff --git a/hald/freebsd/hf-devtree.c b/hald/freebsd/hf-devtree.c index 01203f05..7a54feb5 100644 --- a/hald/freebsd/hf-devtree.c +++ b/hald/freebsd/hf-devtree.c @@ -86,7 +86,11 @@ hf_devtree_cpu_can_throttle (int cpu) gboolean can = FALSE; char *levels; +#ifdef notyet levels = hf_get_string_sysctl(NULL, "dev.cpu.%i.freq_levels", cpu); +#else + levels = hf_get_string_sysctl(NULL, "dev.cpu.0.freq_levels"); +#endif if (levels) { char **toks; @@ -109,7 +113,11 @@ hf_devtree_cpu_get_maxfreq (int cpu) char *levels; int freq = -1; +#ifdef notyet levels = hf_get_string_sysctl(NULL, "dev.cpu.%i.freq_levels", cpu); +#else + levels = hf_get_string_sysctl(NULL, "dev.cpu.0.freq_levels"); +#endif if (levels) { sscanf(levels, "%i/", &freq); @@ -186,7 +194,7 @@ hf_devtree_fd_set_properties (HalDevice *device) static void hf_devtree_atkbd_set_properties (HalDevice *device) { - hf_device_set_input(device, "keyboard", NULL); + hf_device_set_input(device, "keyboard", "keys", NULL); } static void @@ -195,7 +203,7 @@ hf_devtree_psm_set_properties (HalDevice *device) char *devname; devname = hf_devtree_device_get_name(device); - hf_device_set_input(device, "mouse", devname); + hf_device_set_input(device, "mouse", NULL, devname); g_free(devname); } @@ -205,7 +213,7 @@ hf_devtree_joy_set_properties (HalDevice *device) char *devname; devname = hf_devtree_device_get_name(device); - hf_device_set_input(device, "joystick", devname); + hf_device_set_input(device, "joystick", NULL, devname); g_free(devname); if (! hal_device_has_property(device, "info.product")) @@ -379,7 +387,8 @@ static Handler handlers[] = { { "pcm", NULL }, { "psm", hf_devtree_psm_set_properties }, { "sio", NULL }, - { "speaker", NULL } + { "speaker", NULL }, + { "usbus", NULL } }; static void @@ -426,7 +435,13 @@ hf_devtree_probe (void) HalDevice *device; device = hf_devtree_device_new(parent, info->handler, info->unit); - hf_device_preprobe_and_add(device); + if (hf_device_preprobe(device)) + { + if (hal_device_has_capability(device, "input.mouse")) + hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL); + + hf_device_add(device); + } } devices = g_slist_delete_link(devices, root); @@ -434,6 +449,17 @@ hf_devtree_probe (void) } } +static gboolean +hf_devtree_rescan (HalDevice *device) +{ + if (hal_device_has_capability(device, "input.mouse")) + { + hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL); + return TRUE; + } + return FALSE; +} + HalDevice * hf_devtree_find_from_name (HalDeviceStore *store, const char *name) { @@ -597,5 +623,6 @@ hf_devtree_is_driver (const char *name, const char *driver) } HFHandler hf_devtree_handler = { - .probe = hf_devtree_probe + .probe = hf_devtree_probe, + .device_rescan = hf_devtree_rescan }; diff --git a/hald/freebsd/hf-scsi.c b/hald/freebsd/hf-scsi.c index 7ab753cd..527bc518 100644 --- a/hald/freebsd/hf-scsi.c +++ b/hald/freebsd/hf-scsi.c @@ -549,7 +549,7 @@ hf_scsi_probe (void) break; /* only use the first peripheral */ match = &ccb.cdm.matches[i].result.periph_result; - if ((int) match->path_id == -1 || ! strcmp(match->periph_name, "pass")) + if ((int) match->path_id == -1 || ! strcmp(match->periph_name, "pass") || ! strcmp(match->periph_name, "probe")) break; pending_devname = g_strdup_printf("%s%i", match->periph_name, match->unit_number); diff --git a/hald/freebsd/hf-storage.c b/hald/freebsd/hf-storage.c index b901d9d3..3bc5ab92 100644 --- a/hald/freebsd/hf-storage.c +++ b/hald/freebsd/hf-storage.c @@ -30,6 +30,7 @@ #include <limits.h> #include <inttypes.h> #include <string.h> +#include <sys/param.h> #include <sys/types.h> #include <sys/disklabel.h> @@ -38,6 +39,7 @@ #include "hf-storage.h" #include "hf-block.h" +#include "hf-devd.h" #include "hf-devtree.h" #include "hf-volume.h" #include "hf-util.h" @@ -64,7 +66,7 @@ typedef struct static GNode *hf_storage_geom_tree = NULL; static GHashTable *hf_storage_geom_hash = NULL; -static void hf_storage_init_geom (void); +static void hf_storage_init_geom (gboolean force); static gboolean hf_storage_device_has_addon (HalDevice *device); static void @@ -104,6 +106,8 @@ hf_storage_class_is_partitionable (const char *geom_class) { return (! strcmp(geom_class, "MBR") || ! strcmp(geom_class, "MBREXT") || + ! strcmp(geom_class, "PART") || + ! strcmp(geom_class, "JOURNAL") || ! strcmp(geom_class, "GPT") || ! strcmp(geom_class, "APPLE") || ! strcmp(geom_class, "SUN")); } @@ -117,6 +121,7 @@ hf_storage_geom_has_partitions (const Geom_Object *geom_obj, GNode *node) if (g_node_n_children(node) > 0) return TRUE; + /* if (hf_storage_class_is_partitionable(geom_obj->class) && g_node_next_sibling(node) != NULL) { @@ -135,6 +140,7 @@ hf_storage_geom_has_partitions (const Geom_Object *geom_obj, GNode *node) return TRUE; } } + */ return FALSE; } @@ -294,7 +300,7 @@ hf_storage_device_probe (HalDevice *device, gboolean only_media) { g_return_if_fail(HAL_IS_DEVICE(device)); - hf_storage_init_geom(); + hf_storage_init_geom(TRUE); if (hf_runner_run_sync(device, 0, "hald-probe-storage", "HF_HAS_CHILDREN", HF_BOOL_TO_STRING(hf_storage_device_has_partitions(device)), @@ -403,13 +409,20 @@ hf_storage_parse_conftxt (const char *conftxt) continue; } + depth = atoi(fields[0]); + hash = g_str_hash(fields[2]); + if (g_hash_table_lookup(table, GUINT_TO_POINTER(hash)) != NULL) + { + g_strfreev(fields); + curr_depth = depth; + continue; + } + geom_obj = g_new0(Geom_Object, 1); - depth = atoi(fields[0]); geom_obj->class = g_strdup(fields[1]); geom_obj->dev = g_strdup(fields[2]); geom_obj->type = -1; /* We use -1 here to denote a missing type. */ - hash = g_str_hash(geom_obj->dev); geom_obj->hash = hash; if (g_strv_length(fields) >= 5) @@ -433,6 +446,30 @@ hf_storage_parse_conftxt (const char *conftxt) if (! strcmp (geom_obj->class, "GPT") || ! strcmp (geom_obj->class, "APPLE")) geom_obj->str_type = g_strdup(fields[10]); + else if (! strcmp (geom_obj->class, "PART")) + { + geom_obj->str_type = g_strdup(fields[10]); + if (g_strv_length(fields) >= 15) + { + if (! strcmp(fields[13], "xt")) + { + geom_obj->type = atoi(fields[14]); + if (! strcmp(fields[11], "xs")) + { + g_free(geom_obj->class); + geom_obj->class = g_strdup(fields[12]); + } + } + } + } + else if (fields[10][0] == '!') + { + char *nottype; + + nottype = fields[10]; + nottype++; + geom_obj->type = atoi(nottype); + } else geom_obj->type = atoi(fields[10]); } @@ -541,15 +578,20 @@ hf_storage_device_rescan_real (HalDevice *device) } static gboolean -hf_storage_conftxt_timeout_cb (gpointer data) +hf_storage_devd_notify (const char *system, + const char *subsystem, + const char *type, + const char *data) { static GSList *disks = NULL; static gboolean first = TRUE; + gboolean handled = FALSE; char *conftxt; GSList *new_disks; - if (hf_is_waiting) - return TRUE; + if (strcmp(system, "DEVFS") || strcmp(subsystem, "CDEV") || + (strcmp(type, "CREATE") && strcmp(type, "DESTROY"))) + return FALSE; conftxt = hf_get_string_sysctl(NULL, "kern.geom.conftxt"); new_disks = hf_storage_parse_conftxt(conftxt); @@ -572,6 +614,7 @@ hf_storage_conftxt_timeout_cb (gpointer data) if (! hf_storage_find_disk(disks, disk->name)) { osspec_probe(); /* catch new disk(s) */ + handled = TRUE; break; } } @@ -593,7 +636,10 @@ hf_storage_conftxt_timeout_cb (gpointer data) device = hf_devtree_find_from_name(hald_get_gdl(), disk->name); if (device && hal_device_has_capability(device, "storage") && ! hf_storage_device_has_addon(device)) - hf_storage_device_rescan_real(device); + { + hf_storage_device_rescan_real(device); + handled = TRUE; + } } } else @@ -601,7 +647,10 @@ hf_storage_conftxt_timeout_cb (gpointer data) /* disk removed */ device = hf_devtree_find_from_name(hald_get_gdl(), disk->name); if (device && hal_device_has_capability(device, "storage")) - hf_device_remove_tree(device); + { + hf_device_remove_tree(device); + handled = TRUE; + } } } } @@ -610,17 +659,30 @@ hf_storage_conftxt_timeout_cb (gpointer data) g_slist_free(disks); disks = new_disks; + return handled; +} + +#if __FreeBSD_version < 700110 +static gboolean +hf_storage_conftxt_timeout_cb (gpointer data) +{ + if (hf_is_waiting) + return TRUE; + + hf_storage_devd_notify("DEVFS", "CDEV", "CREATE", NULL); + return TRUE; } +#endif static void -hf_storage_init_geom (void) +hf_storage_init_geom (gboolean force) { char *conftxt; static gboolean inited = FALSE; GSList *disks; - if (inited) + if (inited && ! force) return; conftxt = hf_get_string_sysctl(NULL, "kern.geom.conftxt"); @@ -636,8 +698,10 @@ hf_storage_init_geom (void) static void hf_storage_init (void) { - hf_storage_init_geom(); + hf_storage_init_geom(FALSE); +#if __FreeBSD_version < 700110 g_timeout_add(3000, hf_storage_conftxt_timeout_cb, NULL); +#endif } void @@ -719,8 +783,6 @@ hf_storage_device_add (HalDevice *device) { g_return_if_fail(HAL_IS_DEVICE(device)); - hf_storage_init_geom(); - if (hf_device_preprobe(device)) { hf_storage_device_probe(device, FALSE); @@ -738,7 +800,7 @@ hf_storage_get_geoms (const char *devname) g_return_val_if_fail(devname != NULL, NULL); - hf_storage_init_geom(); + hf_storage_init_geom(FALSE); hash = g_str_hash(devname); node = g_node_find(hf_storage_geom_tree, G_PRE_ORDER, G_TRAVERSE_ALL, @@ -801,3 +863,7 @@ HFHandler hf_storage_handler = { .probe = hf_storage_probe, .device_rescan = hf_storage_device_rescan }; + +HFDevdHandler hf_storage_devd_handler = { + .notify = hf_storage_devd_notify +}; diff --git a/hald/freebsd/hf-storage.h b/hald/freebsd/hf-storage.h index d8b2ff08..0915f1f0 100644 --- a/hald/freebsd/hf-storage.h +++ b/hald/freebsd/hf-storage.h @@ -29,8 +29,10 @@ #endif #include "hf-osspec.h" +#include "hf-devd.h" extern HFHandler hf_storage_handler; +extern HFDevdHandler hf_storage_devd_handler; void hf_storage_device_enable (HalDevice *device); void hf_storage_device_enable_tape (HalDevice *device); diff --git a/hald/freebsd/hf-usb.c b/hald/freebsd/hf-usb.c index d04f7f29..280e0dbd 100644 --- a/hald/freebsd/hf-usb.c +++ b/hald/freebsd/hf-usb.c @@ -25,13 +25,20 @@ # include <config.h> #endif +#include <sys/param.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <unistd.h> +#if __FreeBSD_version < 800092 +#if __FreeBSD_version >= 800064 +#include <legacy/dev/usb/usb.h> +#else #include <dev/usb/usb.h> +#endif +#endif #include "../logger.h" #include "../osspec.h" @@ -40,7 +47,13 @@ #include "hf-devtree.h" #include "hf-util.h" +#if __FreeBSD_version < 800092 #define HF_USB_DEVICE "/dev/usb" +#if __FreeBSD_version < 800066 +#define HF_USB2_DEVICE "/dev/usb " +#else +#define HF_USB2_DEVICE "/dev/usbctl" +#endif typedef struct { @@ -227,51 +240,6 @@ hf_usb_get_full_config_descriptor (int fd, return NULL; } -/* - * Adapted from usb_compute_udi() in linux2/physdev.c and - * usbclass_compute_udi() in linux2/classdev.c. - */ -static void -hf_usb_device_compute_udi (HalDevice *device) -{ - g_return_if_fail(HAL_IS_DEVICE(device)); - - if (hal_device_has_capability(device, "hiddev")) - hf_device_set_full_udi(device, "%s_hiddev", - hal_device_property_get_string(device, "info.parent")); - else if (hal_device_has_capability(device, "video4linux")) - hf_device_set_full_udi(device, "%s_video4linux", - hal_device_property_get_string(device, "info.parent")); - else if (hal_device_has_property(device, "usb.interface.number")) - hf_device_set_full_udi(device, "%s_if%i", - hal_device_property_get_string(device, "info.parent"), - hal_device_property_get_int(device, "usb.interface.number")); - else - hf_device_set_udi(device, "usb_device_%x_%x_%s", - hal_device_property_get_int(device, "usb_device.vendor_id"), - hal_device_property_get_int(device, "usb_device.product_id"), - hal_device_has_property(device, "usb_device.serial") - ? hal_device_property_get_string(device, "usb_device.serial") - : "noserial"); -} - -static void -hf_usb_add_webcam_properties (HalDevice *device) -{ - int unit; - - g_return_if_fail(HAL_IS_DEVICE(device)); - - unit = hal_device_property_get_int(device, "freebsd.unit"); - if (unit < 0) - unit = 0; - - hal_device_property_set_string(device, "info.category", "video4linux"); - hal_device_add_capability(device, "video4linux"); - hf_device_property_set_string_printf(device, "video4linux.device", "/dev/video%i", unit); - hal_device_property_set_string(device, "info.product", "Video Device"); -} - /* adapted from usbif_set_name() in linux2/physdev.c */ static const char * hf_usb_get_interface_name (const usb_interface_descriptor_t *desc) @@ -424,9 +392,9 @@ hf_usb_device_new (HalDevice *parent, hf_devtree_device_set_name(device, di->udi_devnames[0]); if ((devname = hf_usb_get_devname(di, "ukbd"))) /* USB keyboard */ - hf_device_set_input(device, "keyboard", devname); + hf_device_set_input(device, "keyboard", "keys", devname); else if ((devname = hf_usb_get_devname(di, "ums"))) /* USB mouse */ - hf_device_set_input(device, "mouse", devname); + hf_device_set_input(device, "mouse", NULL, devname); else if ((devname = hf_usb_get_devname(di, "uhid"))) /* UHID device */ { hal_device_property_set_string(device, "info.category", "hiddev"); @@ -575,6 +543,8 @@ hf_usb_probe_device (HalDevice *parent, { if (hal_device_has_capability(device, "hiddev")) hf_runner_run_sync(device, 0, "hald-probe-hiddev", NULL); + if (hal_device_has_capability(device, "input.mouse")) + hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL); hf_device_add(device); } @@ -633,9 +603,18 @@ hf_usb_privileged_init (void) { int i; + if (g_file_test(HF_USB2_DEVICE, G_FILE_TEST_EXISTS)) + { + hf_usb_fd = -1; + return; + } + hf_usb_fd = open(HF_USB_DEVICE, O_RDONLY); if (hf_usb_fd < 0) - HAL_INFO(("unable to open %s: %s", HF_USB_DEVICE, g_strerror(errno))); + { + HAL_INFO(("unable to open %s: %s", HF_USB_DEVICE, g_strerror(errno))); + return; + } for (i = 0; i < 16; i++) { @@ -885,3 +864,50 @@ HFDevdHandler hf_usb_devd_handler = { .add = hf_usb_devd_add, .remove = hf_usb_devd_remove }; +#endif + +/* + * Adapted from usb_compute_udi() in linux2/physdev.c and + * usbclass_compute_udi() in linux2/classdev.c. + */ +void +hf_usb_device_compute_udi (HalDevice *device) +{ + g_return_if_fail(HAL_IS_DEVICE(device)); + + if (hal_device_has_capability(device, "hiddev")) + hf_device_set_full_udi(device, "%s_hiddev", + hal_device_property_get_string(device, "info.parent")); + else if (hal_device_has_capability(device, "video4linux")) + hf_device_set_full_udi(device, "%s_video4linux", + hal_device_property_get_string(device, "info.parent")); + else if (hal_device_has_property(device, "usb.interface.number")) + hf_device_set_full_udi(device, "%s_if%i", + hal_device_property_get_string(device, "info.parent"), + hal_device_property_get_int(device, "usb.interface.number")); + else + hf_device_set_udi(device, "usb_device_%x_%x_%s", + hal_device_property_get_int(device, "usb_device.vendor_id"), + hal_device_property_get_int(device, "usb_device.product_id"), + (hal_device_has_property(device, "usb_device.serial") && + strcmp(hal_device_property_get_string(device, "usb_device.serial"), "")) + ? hal_device_property_get_string(device, "usb_device.serial") + : "noserial"); +} + +void +hf_usb_add_webcam_properties (HalDevice *device) +{ + int unit; + + g_return_if_fail(HAL_IS_DEVICE(device)); + + unit = hal_device_property_get_int(device, "freebsd.unit"); + if (unit < 0) + unit = 0; + + hal_device_property_set_string(device, "info.category", "video4linux"); + hal_device_add_capability(device, "video4linux"); + hf_device_property_set_string_printf(device, "video4linux.device", "/dev/video%i", unit); + hal_device_property_set_string(device, "info.product", "Video Device"); +} diff --git a/hald/freebsd/hf-usb.h b/hald/freebsd/hf-usb.h index edc9c6cc..37acedc6 100644 --- a/hald/freebsd/hf-usb.h +++ b/hald/freebsd/hf-usb.h @@ -34,4 +34,7 @@ extern HFHandler hf_usb_handler; extern HFDevdHandler hf_usb_devd_handler; +void hf_usb_device_compute_udi(HalDevice *device); +void hf_usb_add_webcam_properties(HalDevice *device); + #endif /* _HF_USB_H */ diff --git a/hald/freebsd/hf-usb2.c b/hald/freebsd/hf-usb2.c new file mode 100644 index 00000000..fff49e0a --- /dev/null +++ b/hald/freebsd/hf-usb2.c @@ -0,0 +1,287 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * hf-usb.c : USB support + * + * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <string.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <libusb20.h> + +#include "../logger.h" +#include "../osspec.h" + +#include "hf-usb.h" +#include "hf-usb2.h" +#include "hf-devtree.h" +#include "hf-util.h" + +static struct libusb20_backend *hf_usb2_be = NULL; + +static void +hf_usb2_copy_parent (HalDevice *parent, + const char *key, + gpointer user_data) +{ + HalDevice *device; + + g_return_if_fail(HAL_IS_DEVICE(parent)); + g_return_if_fail(HAL_IS_DEVICE(user_data)); + + device = HAL_DEVICE(user_data); + + if (! strncmp(key, "usb_device.", strlen("usb_device."))) + hal_device_copy_property(parent, key, device, key); +} + +static void +hf_usb2_probe_interfaces(HalDevice *parent) +{ + int num_interfaces; + int i; + + g_return_if_fail(HAL_IS_DEVICE(parent)); + + if (hal_device_property_get_bool(parent, "info.ignore")) + return; + + num_interfaces = hal_device_property_get_int(parent, + "usb_device.num_interfaces"); + + for (i = 0; i < num_interfaces; i++) + { + HalDevice *device; + + device = hf_device_new(parent); + + hal_device_property_set_string(device, "info.subsystem", "usb"); + hal_device_property_set_int(device, "usb.interface.number", i); + hal_device_property_foreach(parent, hf_usb2_copy_parent, device); + hal_device_copy_property(parent, "info.product", device, "info.product"); + hal_device_copy_property(parent, "info.vendor", device, "info.vendor"); + + if (hf_device_preprobe(device)) + { + const char *driver, *devname; + + hf_runner_run_sync(device, 0, "hald-probe-usb2-interface", NULL); + + devname = hal_device_property_get_string(device, + "usb.freebsd.devname"); + if (devname) + hf_devtree_device_set_name(device, devname); + + driver = hal_device_property_get_string(device, "freebsd.driver"); + if (driver) + { + if (! strcmp(driver, "ukbd")) + hf_device_set_input(device, "keyboard", NULL); + else if (! strcmp(driver, "ums")) + { + hf_device_set_input(device, "mouse", devname); + hf_runner_run_sync(device, 0, "hald-probe-mouse", NULL); + } + else if (! strcmp(driver, "uhid")) + { + hal_device_property_set_string(device, "info.category", + "hiddev"); + hal_device_add_capability(device, "hiddev"); + hf_device_property_set_string_printf(device, "hiddev.device", + "/dev/%s", devname); + hal_device_copy_property(device, "info.product", device, + "hiddev.product"); + hf_runner_run_sync(device, 0, "hald-probe-hiddev", NULL); + } + else if (! strcmp(driver, "ldev")) + { + /* Linux driver (webcam) */ + + /* + * XXX This is a hack. Currently, all ldev devices are + * webcams. That may not always be the case. Hopefully, + * when other Linux driver support is added, there will be + * a sysctl or some other way to determine device class. + */ + hf_usb_add_webcam_properties(device); + } + else if (! strcmp(driver, "pwc")) + { + /* Phillips Web Cam */ + hf_usb_add_webcam_properties(device); + } + } + + hf_usb_device_compute_udi(device); + hf_device_add(device); + } + } +} + +static void +hf_usb2_probe_device (HalDevice *parent, int bus, int addr) +{ + HalDevice *device; + + g_return_if_fail(HAL_IS_DEVICE(parent)); + + device = hf_device_new(parent); + + hal_device_property_set_string(device, "info.subsystem", "usb_device"); + hal_device_property_set_int(device, "usb_device.bus_number", bus); + hal_device_property_set_int(device, "usb_device.level_number", addr - 1); + hal_device_property_set_int(device, "usb_device.port_number", addr); + + if (hf_device_preprobe(device)) + { + hf_runner_run_sync(device, 0, "hald-probe-usb2-device", NULL); + hf_usb_device_compute_udi(device); + + hf_device_add(device); + } + else + return; + + hf_usb2_probe_interfaces(device); +} + +static void +hf_usb2_privileged_init (void) +{ + hf_usb2_be = libusb20_be_alloc_default(); + if (hf_usb2_be == NULL) + HAL_INFO(("unable to open USB backend: %s", g_strerror(errno))); +} + +static void +hf_usb2_probe (void) +{ + struct libusb20_device *pdev = NULL; + + if (hf_usb2_be == NULL) + return; + + while ((pdev = libusb20_be_device_foreach(hf_usb2_be, pdev))) + { + HalDevice *parent; + int bus, addr; + + bus = libusb20_dev_get_bus_number(pdev); + addr = libusb20_dev_get_address(pdev); + + if (addr == 1) + parent = hf_devtree_find_parent_from_info(hald_get_gdl(), "usbus", bus); + else + parent = hf_device_store_match(hald_get_gdl(), "usb_device.bus_number", + HAL_PROPERTY_TYPE_INT32, bus, "usb_device.port_number", + HAL_PROPERTY_TYPE_INT32, addr - 1, NULL); + if (! parent || hal_device_property_get_bool(parent, "info.ignore")) + continue; + + hf_usb2_probe_device(parent, bus, addr); + } + + libusb20_be_free(hf_usb2_be); + hf_usb2_be = NULL; +} + +static gboolean +hf_usb2_devd_add (const char *name, + GHashTable *params, + GHashTable *at, + const char *parent) +{ + HalDevice *parent_device; + int bus, addr, pbus, paddr; + + if (strncmp(name, "ugen", strlen("ugen"))) + return FALSE; + else if (strncmp(parent, "ugen", strlen("ugen"))) + return TRUE; + + if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2) + return FALSE; + + if (sscanf(parent, "ugen%i.%i", &pbus, &paddr) != 2) + return FALSE; + + HAL_INFO(("received devd add event for device '%s' with parent '%s'", + name, parent)); + + parent_device = hf_device_store_match(hald_get_gdl(), + "usb_device.bus_number", HAL_PROPERTY_TYPE_INT32, pbus, + "usb_device.port_number", HAL_PROPERTY_TYPE_INT32, paddr, NULL); + + if (parent_device && ! hal_device_property_get_bool(parent_device, + "info.ignore")) + { + hf_usb2_probe_device(parent_device, bus, addr); + return TRUE; + } + + return FALSE; +} + +static gboolean +hf_usb2_devd_remove (const char *name, + GHashTable *params, + GHashTable *at, + const char *parent) +{ + HalDevice *device; + int bus, addr; + + if (strncmp(name, "ugen", strlen("ugen"))) + return FALSE; + else if (strncmp(parent, "ugen", strlen("ugen"))) + return TRUE; + + if (sscanf(name, "ugen%i.%i", &bus, &addr) != 2) + return FALSE; + + HAL_INFO(("received devd remove event, device %s", name)); + + device = hf_device_store_match(hald_get_gdl(), "usb_device.bus_number", + HAL_PROPERTY_TYPE_INT32, bus, "usb_device.port_number", + HAL_PROPERTY_TYPE_INT32, addr, NULL); + + if (device) + { + hf_device_remove_tree(device); + return TRUE; + } + + return FALSE; +} + +HFHandler hf_usb2_handler = { + .privileged_init = hf_usb2_privileged_init, + .probe = hf_usb2_probe +}; + +HFDevdHandler hf_usb2_devd_handler = { + .add = hf_usb2_devd_add, + .remove = hf_usb2_devd_remove +}; diff --git a/hald/freebsd/hf-usb2.h b/hald/freebsd/hf-usb2.h new file mode 100644 index 00000000..0c2c03bd --- /dev/null +++ b/hald/freebsd/hf-usb2.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * hf-usb.h : USB support + * + * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifndef _HF_USB2_H +#define _HF_USB2_H + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "hf-osspec.h" +#include "hf-devd.h" + +extern HFHandler hf_usb2_handler; +extern HFDevdHandler hf_usb2_devd_handler; + +#endif /* _HF_USB2_H */ diff --git a/hald/freebsd/hf-util.c b/hald/freebsd/hf-util.c index 96063601..aa54f578 100644 --- a/hald/freebsd/hf-util.c +++ b/hald/freebsd/hf-util.c @@ -326,24 +326,31 @@ hf_device_property_set_string_printf (HalDevice *device, void hf_device_set_input (HalDevice *device, - const char *class, + const char *capability1, + const char *capability2, const char *devname) { g_return_if_fail(HAL_IS_DEVICE(device)); hal_device_add_capability(device, "input"); + if (capability1) + { + char *capability; - if (class) + capability = g_strdup_printf("input.%s", capability1); + hal_device_add_capability(device, capability); + g_free(capability); + } + if (capability2) { - char *category; + char *capability; - category = g_strdup_printf("input.%s", class); - hal_device_property_set_string(device, "info.category", category); - hal_device_add_capability(device, category); - g_free(category); + capability = g_strdup_printf("input.%s", capability2); + hal_device_add_capability(device, capability); + g_free(capability); } - else - hal_device_property_set_string(device, "info.category", "input"); + + hal_device_property_set_string(device, "info.category", "input"); if (devname) hf_device_property_set_string_printf(device, "input.device", "/dev/%s", devname); diff --git a/hald/freebsd/hf-util.h b/hald/freebsd/hf-util.h index d4590ce6..3ac34b11 100644 --- a/hald/freebsd/hf-util.h +++ b/hald/freebsd/hf-util.h @@ -87,7 +87,8 @@ void hf_device_property_set_string_printf (HalDevice *device, ...) G_GNUC_PRINTF(3, 4); void hf_device_set_input (HalDevice *device, - const char *class, + const char *capability1, + const char *capability2, const char *devname); HalDevice *hf_device_store_get_parent (HalDeviceStore *store, diff --git a/hald/freebsd/hf-volume.c b/hald/freebsd/hf-volume.c index 3512a8aa..249d2bd1 100644 --- a/hald/freebsd/hf-volume.c +++ b/hald/freebsd/hf-volume.c @@ -45,6 +45,7 @@ #include "hf-util.h" #define PROBE_VOLUME_TIMEOUT (HAL_HELPER_TIMEOUT * 6) +#define HF_VOLUME_FUSE_DB "/tmp/.fuse-mnts" static void hf_volume_get_mounts (struct statfs **mounts, int *n_mounts) @@ -60,6 +61,55 @@ hf_volume_get_mounts (struct statfs **mounts, int *n_mounts) } } +static char * +hf_volume_resolve_fuse (const char *special) +{ + gchar *contents; + gchar **lines; + gsize len; + int i; + + g_return_val_if_fail(special != NULL, NULL); + + if (! g_file_get_contents(HF_VOLUME_FUSE_DB, &contents, &len, NULL)) + return g_strdup(special); + + lines = g_strsplit(contents, "\n", 0); + g_free(contents); + + for (i = 0; lines && lines[i]; i++) + { + gchar **fields; + + fields = g_strsplit(lines[i], "=", 2); + if (fields && g_strv_length(fields) == 2) + { + if (strcmp(fields[0], special) == 0) + { + g_strfreev(fields); + g_strfreev(lines); + return g_strdup(fields[1]); + } + } + g_strfreev(fields); + } + + g_strfreev(lines); + + return g_strdup(special); +} + +static char * +hf_volume_resolve_special (const char *special) +{ + g_return_val_if_fail(special != NULL, NULL); + + if (strstr(special, "fuse")) + return hf_volume_resolve_fuse(special); + + return g_strdup(special); +} + static const struct statfs * hf_volume_mounts_find (const struct statfs *mounts, int n_mounts, @@ -71,8 +121,18 @@ hf_volume_mounts_find (const struct statfs *mounts, g_return_val_if_fail(special != NULL, NULL); for (i = 0; i < n_mounts; i++) - if (! strcmp(mounts[i].f_mntfromname, special)) - return &mounts[i]; + { + char *resolved; + + resolved = hf_volume_resolve_special(mounts[i].f_mntfromname); + if (! strcmp(resolved, special)) + { + g_free(resolved); + return &mounts[i]; + } + + g_free(resolved); + } return NULL; } @@ -92,7 +152,13 @@ hf_volume_device_update_mount_properties (HalDevice *device, special = hal_device_property_get_string(device, "block.device"); if (special) - mount = hf_volume_mounts_find(mounts, n_mounts, special); + { + mount = hf_volume_mounts_find(mounts, n_mounts, special); + if (mount && strcmp(special, mount->f_mntfromname)) + hal_device_property_set_string(device, "volume.freebsd.real_mounted_device", mount->f_mntfromname); + else + hal_device_property_remove(device, "volume.freebsd.real_mounted_device"); + } } hal_device_property_set_bool(device, "volume.is_mounted", mount != NULL); diff --git a/hald/freebsd/libprobe/hfp.c b/hald/freebsd/libprobe/hfp.c index 7d16bae9..3c34b756 100644 --- a/hald/freebsd/libprobe/hfp.c +++ b/hald/freebsd/libprobe/hfp.c @@ -216,55 +216,59 @@ hfp_getenv_bool (const char *variable) } void -hfp_gettimeofday (struct timeval *t) +hfp_clock_gettime (struct timespec *t) { int status; assert(t != NULL); - status = gettimeofday(t, NULL); +#ifdef CLOCK_MONOTONIC_FAST + status = clock_gettime(CLOCK_MONOTONIC_FAST, t); +#else + status = clock_gettime(CLOCK_MONOTONIC, t); +#endif assert(status == 0); } -/* timeval functions from sys/kern/kern_time.c */ +/* timespec functions from sys/kern/kern_time.c */ static void -hfp_timevalfix (struct timeval *t) +hfp_timespecfix (struct timespec *t) { assert(t != NULL); - if (t->tv_usec < 0) + if (t->tv_nsec < 0) { t->tv_sec--; - t->tv_usec += 1000000; + t->tv_nsec += 1000000000; } - if (t->tv_usec >= 1000000) + if (t->tv_nsec >= 1000000000) { t->tv_sec++; - t->tv_usec -= 1000000; + t->tv_nsec -= 1000000000; } } void -hfp_timevaladd (struct timeval *t1, const struct timeval *t2) +hfp_timespecadd (struct timespec *t1, const struct timespec *t2) { assert(t1 != NULL); assert(t2 != NULL); t1->tv_sec += t2->tv_sec; - t1->tv_usec += t2->tv_usec; + t1->tv_nsec += t2->tv_nsec; - hfp_timevalfix(t1); + hfp_timespecfix(t1); } void -hfp_timevalsub (struct timeval *t1, const struct timeval *t2) +hfp_timespecsub (struct timespec *t1, const struct timespec *t2) { assert(t1 != NULL); assert(t2 != NULL); t1->tv_sec -= t2->tv_sec; - t1->tv_usec -= t2->tv_usec; + t1->tv_nsec -= t2->tv_nsec; - hfp_timevalfix(t1); + hfp_timespecfix(t1); } diff --git a/hald/freebsd/libprobe/hfp.h b/hald/freebsd/libprobe/hfp.h index 1d958110..2332588c 100644 --- a/hald/freebsd/libprobe/hfp.h +++ b/hald/freebsd/libprobe/hfp.h @@ -29,8 +29,12 @@ #endif #include <stdarg.h> +#include <time.h> #include <sys/types.h> +#include <sys/param.h> +#if __FreeBSD_version < 600000 #include <sys/time.h> +#endif #include "libhal/libhal.h" @@ -84,14 +88,14 @@ void volume_id_log (const char *format, ...) HFP_GNUC_PRINTF(1, 2); boolean hfp_getenv_bool (const char *variable); -void hfp_gettimeofday (struct timeval *t); -void hfp_timevaladd (struct timeval *t1, const struct timeval *t2); -void hfp_timevalsub (struct timeval *t1, const struct timeval *t2); +void hfp_clock_gettime (struct timespec *t); +void hfp_timespecadd (struct timespec *t1, const struct timespec *t2); +void hfp_timespecsub (struct timespec *t1, const struct timespec *t2); /* from sys/time.h (_KERNEL) */ -#define hfp_timevalcmp(t1, t2, cmp) \ +#define hfp_timespeccmp(t1, t2, cmp) \ (((t1)->tv_sec == (t2)->tv_sec \ - ? ((t1)->tv_usec cmp (t2)->tv_usec) \ + ? ((t1)->tv_nsec cmp (t2)->tv_nsec) \ : ((t1)->tv_sec cmp (t2)->tv_sec))) #endif /* _HFP_H */ diff --git a/hald/freebsd/osspec.c b/hald/freebsd/osspec.c index 38ab1813..0d35ac58 100644 --- a/hald/freebsd/osspec.c +++ b/hald/freebsd/osspec.c @@ -25,6 +25,7 @@ # include <config.h> #endif +#include <sys/param.h> #include <string.h> #include "../ids.h" @@ -46,13 +47,21 @@ #include "hf-sound.h" #include "hf-storage.h" #include "hf-usb.h" +#ifdef HAVE_LIBUSB20 +#include "hf-usb2.h" +#endif #include "hf-volume.h" /* the order matters: PCI devices must be created before their children, etc */ static HFHandler *handlers[] = { &hf_pci_handler, &hf_devtree_handler, +#if __FreeBSD_version < 800092 &hf_usb_handler, +#endif +#ifdef HAVE_LIBUSB20 + &hf_usb2_handler, +#endif &hf_ata_handler, &hf_scsi_handler, &hf_storage_handler, diff --git a/hald/freebsd/probing/Makefile.am b/hald/freebsd/probing/Makefile.am index fdba1eb7..3e439b5f 100644 --- a/hald/freebsd/probing/Makefile.am +++ b/hald/freebsd/probing/Makefile.am @@ -9,11 +9,18 @@ AM_CPPFLAGS = \ if HALD_COMPILE_FREEBSD libexec_PROGRAMS = \ - hald-probe-hiddev \ - hald-probe-scsi \ - hald-probe-smbios \ - hald-probe-storage \ + hald-probe-hiddev \ + hald-probe-mouse \ + hald-probe-scsi \ + hald-probe-smbios \ + hald-probe-storage \ hald-probe-volume + +if HAVE_LIBUSB20 +libexec_PROGRAMS += \ + hald-probe-usb2-device \ + hald-probe-usb2-interface +endif endif hald_probe_hiddev_SOURCES = probe-hiddev.c @@ -21,6 +28,25 @@ hald_probe_hiddev_LDADD = \ $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la \ -lusbhid +if HAVE_LIBUSB20 +hald_probe_usb2_device_SOURCES = probe-usb2-device.c +hald_probe_usb2_device_LDADD = \ + $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la \ + @LIBUSB20_LIBS@ + +hald_probe_usb2_interface_SOURCES = probe-usb2-interface.c +hald_probe_usb2_interface_LDADD = \ + $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la \ + @LIBUSB20_LIBS@ +endif + +hald_probe_mouse_SOURCES = probe-mouse.c +hald_probe_mouse_CPPFLAGS = $(AM_CPPFLAGS) @GLIB_CFLAGS@ +hald_probe_mouse_LDADD = \ + @GLIB_LIBS@ \ + $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la \ + -lutil + hald_probe_smbios_SOURCES = probe-smbios.c hald_probe_smbios_LDADD = \ $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la @@ -41,4 +67,5 @@ hald_probe_volume_CPPFLAGS = $(AM_CPPFLAGS) @GLIB_CFLAGS@ @VOLUME_ID_CFLAGS@ hald_probe_volume_LDADD = \ @GLIB_LIBS@ \ @VOLUME_ID_LIBS@ \ + -lufs \ $(top_builddir)/hald/freebsd/libprobe/libhald_freebsd_probe.la diff --git a/hald/freebsd/probing/probe-hiddev.c b/hald/freebsd/probing/probe-hiddev.c index e9b5016b..f0c598b3 100644 --- a/hald/freebsd/probing/probe-hiddev.c +++ b/hald/freebsd/probing/probe-hiddev.c @@ -25,12 +25,21 @@ # include <config.h> #endif +#include <sys/param.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> +#ifndef HAVE_LIBUSB20 #include <sys/ioctl.h> #include <dev/usb/usb.h> #include <dev/usb/usbhid.h> +#else +#if __FreeBSD_version >= 800064 +#include <dev/usb/usbhid.h> +#else +#include <dev/usb2/include/usb2_hid.h> +#endif +#endif #include <usbhid.h> #include "../libprobe/hfp.h" @@ -65,7 +74,12 @@ main (int argc, char **argv) /* give a meaningful process title for ps(1) */ setproctitle("%s", device_file); +#ifdef HAVE_LIBUSB20 + report_id = hid_get_report_id(fd); + if (report_id == -1) +#else if (ioctl(fd, USB_GET_REPORT_ID, &report_id) < 0) +#endif goto end; hid_init(NULL); @@ -118,30 +132,22 @@ main (int argc, char **argv) hid_dispose_report_desc(report_desc); - if (is_keyboard || is_mouse || is_joystick) + if (is_keyboard || is_mouse || is_joystick || is_keypad) { libhal_device_add_capability(hfp_ctx, hfp_udi, "input", &hfp_error); + libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input", &hfp_error); libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.device", device_file, &hfp_error); } if (is_keyboard) - { libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keyboard", &hfp_error); - libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input.keyboard", &hfp_error); - } if (is_keypad) libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keypad", &hfp_error); if (is_keyboard || is_keypad) libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keys", &hfp_error); if (is_mouse) - { libhal_device_add_capability(hfp_ctx, hfp_udi, "input.mouse", &hfp_error); - libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input.mouse", &hfp_error); - } if (is_joystick) - { libhal_device_add_capability(hfp_ctx, hfp_udi, "input.joystick", &hfp_error); - libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input.joystick", &hfp_error); - } end: return 0; diff --git a/hald/freebsd/probing/probe-mouse.c b/hald/freebsd/probing/probe-mouse.c new file mode 100644 index 00000000..a2cffc10 --- /dev/null +++ b/hald/freebsd/probing/probe-mouse.c @@ -0,0 +1,312 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * probe-hiddev.c : Mouse prober + * + * Copyright (C) 2008 Joe Marcus Clarke <marcus@FreeBSD.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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/param.h> +#if __FreeBSD_version >= 800058 +#include <sys/types.h> +#include <sys/user.h> +#include <sys/sysctl.h> +#include <libutil.h> +#endif +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <glib.h> + +#include "../libprobe/hfp.h" + +#if __FreeBSD_version < 800058 +#define CMD "/usr/bin/fstat %s" +#endif + +#define MOUSE_DRIVER "mouse" +#define MOUSED_DEVICE "/dev/sysmouse" +#define MOUSED_PROC_NAME "moused" +#define XORG_PROC_NAME "Xorg" + +#if __FreeBSD_version >= 800058 +static struct kinfo_proc * +hfp_kinfo_getproc (int *cntp) +{ + int mib[3]; + int error; + int cnt; + size_t len; + char *buf, *bp, *eb; + struct kinfo_proc *kip, *kp, *ki; + + *cntp = 0; + + len = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PROC; + + error = sysctl(mib, 3, NULL, &len, NULL, 0); + if (error) + return NULL; + + len = len * 4 / 3; + buf = (char *) g_malloc(len); + if (buf == NULL) + return NULL; + + error = sysctl(mib, 3, buf, &len, NULL, 0); + if (error) + { + g_free(buf); + return NULL; + } + + cnt = 0; + bp = buf; + eb = buf + len; + while (bp < eb) + { + ki = (struct kinfo_proc *) (uintptr_t) bp; + bp += ki->ki_structsize; + cnt++; + } + + kip = calloc(cnt, sizeof (*kip)); + if (kip == NULL) + { + g_free(buf); + return NULL; + } + + bp = buf; + eb = buf + len; + kp = kip; + while (bp < eb) + { + ki = (struct kinfo_proc *) (uintptr_t) bp; + memcpy(kp, ki, ki->ki_structsize); + bp += ki->ki_structsize; + kp->ki_structsize = sizeof(*kp); + kp++; + } + + g_free(buf); + *cntp = cnt; + return kip; +} + +static gboolean +device_opened_by_proc (const char *device, const char *proc) +{ + struct kinfo_proc *kip, *pfreep; + int cnt, i; + + pfreep = hfp_kinfo_getproc(&cnt); + if (pfreep == NULL) + return FALSE; + + for (i = 0; i < cnt; i++) + { + kip = &pfreep[i]; + + if (! strcmp(kip->ki_comm, proc)) + { + struct kinfo_file *kif, *ffreep; + int fcnt, j; + + ffreep = kinfo_getfile(kip->ki_pid, &fcnt); + if (ffreep == NULL) + continue; + for (j = 0; j < fcnt; j++) + { + kif = &ffreep[j]; + + if (kif->kf_type == KF_TYPE_VNODE && + ! strcmp(kif->kf_path, device)) + { + g_free(ffreep); + g_free(pfreep); + return TRUE; + } + } + g_free(ffreep); + } + } + g_free(pfreep); + + return FALSE; +} +#else +static gboolean +device_opened_by_proc (const char *device, const char *proc) +{ + char **lines; + char *output = NULL; + char *cmd; + int i; + gboolean found = FALSE; + + cmd = g_strdup_printf(CMD, device); + + if (! g_spawn_command_line_sync(cmd, &output, NULL, NULL, NULL)) + { + g_free(cmd); + goto done; + } + g_free(cmd); + + if (! output || strlen(output) == 0) + goto done; + + lines = g_strsplit(output, "\n", 0); + if (g_strv_length(lines) < 2) + { + g_strfreev(lines); + goto done; + } + + for (i = 1; lines[i]; i++) + { + char **fields; + guint len; + guint j; + + fields = g_strsplit_set(lines[i], " ", 0); + len = g_strv_length(fields); + if (len < 3) + { + g_strfreev(fields); + continue; + } + for (j = 1; j < len && fields[j] && *fields[j] == '\0'; j++) + ; + if (j < len && fields[j] && ! strcmp(fields[j], proc)) + { + found = TRUE; + g_strfreev(fields); + break; + } + g_strfreev(fields); + } + + g_strfreev(lines); + +done: + g_free(output); + + return found; +} +#endif + +static void +probe_mouse (const char *device_file) +{ + gboolean found; + char **udis; + char *driver; + int num_udis; + + driver = libhal_device_get_property_string(hfp_ctx, hfp_udi, + "input.x11_driver", &hfp_error); + dbus_error_free(&hfp_error); + + found = device_opened_by_proc(device_file, XORG_PROC_NAME); + if (found) + { + if (driver) + { + libhal_device_remove_property(hfp_ctx, hfp_udi, "input.x11_driver", + &hfp_error); + dbus_error_free(&hfp_error); + g_free(driver); + } + return; + } + + found = device_opened_by_proc(device_file, MOUSED_PROC_NAME); + if (found) + { + libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.device", + MOUSED_DEVICE, &hfp_error); + dbus_error_free(&hfp_error); + found = device_opened_by_proc(MOUSED_DEVICE, XORG_PROC_NAME); + if (! found) + { + udis = libhal_manager_find_device_string_match(hfp_ctx, + "input.device", + MOUSED_DEVICE, + &num_udis, + &hfp_error); + dbus_error_free(&hfp_error); + if (num_udis > 0 && udis != NULL && !strcmp(udis[0], hfp_udi)) { + libhal_device_set_property_string(hfp_ctx, hfp_udi, + "input.x11_driver", + MOUSE_DRIVER, &hfp_error); + dbus_error_free(&hfp_error); + libhal_free_string_array(udis); + } + } + else if (driver) + { + libhal_device_remove_property(hfp_ctx, hfp_udi, "input.x11_driver", + &hfp_error); + dbus_error_free(&hfp_error); + } + } + else + { + libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.device", + device_file, &hfp_error); + dbus_error_free(&hfp_error); + libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.x11_driver", + MOUSE_DRIVER, &hfp_error); + dbus_error_free(&hfp_error); + } + + g_free(driver); +} + +int +main (int argc, char **argv) +{ + char *device_file; + + if (! hfp_init(argc, argv)) + goto end; + + device_file = getenv("HAL_PROP_FREEBSD_DEVICE_FILE"); + if (! device_file) + goto end; + + /* give a meaningful process title for ps(1) */ + setproctitle("%s", device_file); + + /* Sleep for a second to give moused a chance to connect. */ + sleep(1); + probe_mouse(device_file); + + end: + return 0; +} diff --git a/hald/freebsd/probing/probe-storage.c b/hald/freebsd/probing/probe-storage.c index b9498c4d..a0e7f773 100644 --- a/hald/freebsd/probing/probe-storage.c +++ b/hald/freebsd/probing/probe-storage.c @@ -31,6 +31,8 @@ #include <unistd.h> #include <errno.h> #include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/disk.h> #include <netinet/in.h> #include <glib.h> #include <libvolume_id.h> @@ -211,7 +213,26 @@ main (int argc, char **argv) goto end; if (hfp_cdrom_test_unit_ready(cdrom)) - ret = 2; /* has media */ + { + int fd; + off_t size; + + libhal_device_set_property_bool(hfp_ctx, hfp_udi, "storage.removable.media_available", TRUE, &hfp_error); + fd = open(device_file, O_RDONLY | O_NONBLOCK); + if (fd > -1) + { + if (ioctl (fd, DIOCGMEDIASIZE, &size) == 0) + { + libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "storage.removable.media_size", size, &hfp_error); + } + close(fd); + } + ret = 2; /* has media */ + } + else + { + libhal_device_set_property_bool(hfp_ctx, hfp_udi, "storage.removable.media_available", FALSE, &hfp_error); + } hfp_cdrom_free(cdrom); } diff --git a/hald/freebsd/probing/probe-usb2-device.c b/hald/freebsd/probing/probe-usb2-device.c new file mode 100644 index 00000000..129a1b1f --- /dev/null +++ b/hald/freebsd/probing/probe-usb2-device.c @@ -0,0 +1,208 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * probe-usb2-device.c : USB2 Device poller + * + * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/param.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <libusb20_desc.h> +#include <libusb20.h> +#if __FreeBSD_version >= 800064 +#include <dev/usb/usb_ioctl.h> +#else +#include <dev/usb2/include/usb2_standard.h> +#include <dev/usb2/include/usb2_ioctl.h> +#endif + +#include "../libprobe/hfp.h" + +int +main(int argc, char **argv) +{ + struct libusb20_backend *pbe = NULL; + struct libusb20_device *pdev = NULL; + char *busstr, *addrstr; + int bus, addr; + + if (! hfp_init(argc, argv)) + goto end; + + pbe = libusb20_be_alloc_default(); + if (pbe == NULL) + goto end; + + busstr = getenv("HAL_PROP_USB_DEVICE_BUS_NUMBER"); + if (! busstr) + goto end; + + addrstr = getenv("HAL_PROP_USB_DEVICE_PORT_NUMBER"); + if (! addrstr) + goto end; + + bus = atoi(busstr); + addr = atoi(addrstr); + + while ((pdev = libusb20_be_device_foreach(pbe, pdev))) + { + struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; + struct LIBUSB20_CONFIG_DESC_DECODED *cdesc; +#if __FreeBSD_version >= 800092 + struct usb_device_info di; +#else + struct usb2_device_info di; +#endif + struct libusb20_config *pcfg = NULL; + int curr_config; + int bcdspeed = 0; + uint8_t temp_string[256]; + double speed = 0.0; + double version = 1.0; + + if (libusb20_dev_get_bus_number(pdev) != bus || + libusb20_dev_get_address(pdev) != addr) + continue; + + if (libusb20_dev_open(pdev, 0)) + continue; + + ddesc = libusb20_dev_get_device_desc(pdev); + curr_config = libusb20_dev_get_config_index(pdev); + pcfg = libusb20_dev_alloc_config(pdev, curr_config); + cdesc = &(pcfg->desc); + + if (pcfg == NULL || libusb20_dev_get_info(pdev, &di)) + { + free(pcfg); + continue; + } + + memset(temp_string, 0, sizeof(temp_string)); + + if (cdesc->iConfiguration !=0) + libusb20_dev_req_string_simple_sync(pdev, cdesc->iConfiguration, + temp_string, sizeof(temp_string)); + + libhal_device_set_property_string(hfp_ctx, hfp_udi, + "usb_device.configuration", (char *) temp_string, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.configuration_value", cdesc->bConfigurationValue, + &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.num_configurations", ddesc->bNumConfigurations, + &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.device_class", di.udi_class, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.device_subclass", di.udi_subclass, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.device_protocol", di.udi_protocol, &hfp_error); + libhal_device_set_property_bool(hfp_ctx, hfp_udi, + "usb_device.is_self_powered", + di.udi_power == 0 ? TRUE : FALSE, &hfp_error); + libhal_device_set_property_bool(hfp_ctx, hfp_udi, + "usb_device.can_wake_up", + (cdesc->bmAttributes & UC_REMOTE_WAKEUP) != 0 ? TRUE : FALSE, + &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.max_power", di.udi_power, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.num_interfaces", pcfg->num_interface, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.num_ports", di.udi_nports, &hfp_error); + + switch (libusb20_dev_get_speed(pdev)) + { + case LIBUSB20_SPEED_LOW: + speed = 1.5; + bcdspeed = 0x00150; + break; + case LIBUSB20_SPEED_FULL: + speed = 12.0; + bcdspeed = 0x01200; + break; + case LIBUSB20_SPEED_HIGH: + speed = 480.0; + bcdspeed = 0x48000; + break; + case LIBUSB20_SPEED_SUPER: + speed = 4800.0; + bcdspeed = 0x480000; + break; + default: + ; + } + + libhal_device_set_property_double(hfp_ctx, hfp_udi, "usb_device.speed", + speed, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, "usb_device.speed_bcd", + bcdspeed, &hfp_error); + + switch (ddesc->bcdUSB) + { + case UD_USB_2_0: + version = 2.0; + break; + case UD_USB_3_0: + version = 3.0; + break; + default: + version = 1.0; + break; + } + + libhal_device_set_property_double(hfp_ctx, hfp_udi, + "usb_device.version", version, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.product_id", di.udi_productNo, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.vendor_id", di.udi_vendorNo, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb_device.device_revision_bcd", ddesc->bcdUSB, &hfp_error); + libhal_device_set_property_string(hfp_ctx, hfp_udi, + "usb_device.serial", di.udi_serial, &hfp_error); + libhal_device_set_property_string(hfp_ctx, hfp_udi, + "usb_device.product", di.udi_product, &hfp_error); + libhal_device_set_property_string(hfp_ctx, hfp_udi, + "usb_device.vendor", di.udi_vendor, &hfp_error); + + libhal_device_set_property_string(hfp_ctx, hfp_udi, + "info.product", di.udi_product, &hfp_error); + libhal_device_set_property_string(hfp_ctx, hfp_udi, + "info.vendor", di.udi_vendor, &hfp_error); + + libusb20_dev_close(pdev); + free(pcfg); + } +end: + if (pbe) + libusb20_be_free(pbe); + + return 0; +} diff --git a/hald/freebsd/probing/probe-usb2-interface.c b/hald/freebsd/probing/probe-usb2-interface.c new file mode 100644 index 00000000..f57bb77a --- /dev/null +++ b/hald/freebsd/probing/probe-usb2-interface.c @@ -0,0 +1,140 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * probe-usb2-interface.c : USB2 Interface poller + * + * Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + **************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/param.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <libusb20_desc.h> +#include <libusb20.h> +#if __FreeBSD_version >= 800064 +#include <dev/usb/usb_ioctl.h> +#else +#include <dev/usb2/include/usb2_standard.h> +#include <dev/usb2/include/usb2_ioctl.h> +#endif + +#include "../libprobe/hfp.h" + +int +main(int argc, char **argv) +{ + struct libusb20_backend *pbe = NULL; + struct libusb20_device *pdev = NULL; + char *busstr, *addrstr, *ifacestr; + int bus, addr, iface; + + if (! hfp_init(argc, argv)) + goto end; + + pbe = libusb20_be_alloc_default(); + if (pbe == NULL) + goto end; + + busstr = getenv("HAL_PROP_USB_DEVICE_BUS_NUMBER"); + if (! busstr) + goto end; + + addrstr = getenv("HAL_PROP_USB_DEVICE_PORT_NUMBER"); + if (! addrstr) + goto end; + + ifacestr = getenv("HAL_PROP_USB_INTERFACE_NUMBER"); + if (! ifacestr) + goto end; + + bus = atoi(busstr); + addr = atoi(addrstr); + iface = atoi(ifacestr); + + while ((pdev = libusb20_be_device_foreach(pbe, pdev))) + { + struct LIBUSB20_INTERFACE_DESC_DECODED *idesc; + struct libusb20_config *pcfg = NULL; + struct libusb20_interface *pif; + uint8_t temp_string[256]; + char ifdrv[128]; + int curr_config; + + if (libusb20_dev_get_bus_number(pdev) != bus || + libusb20_dev_get_address(pdev) != addr) + continue; + + if (libusb20_dev_open(pdev, 0)) + continue; + + curr_config = libusb20_dev_get_config_index(pdev); + pcfg = libusb20_dev_alloc_config(pdev, curr_config); + if (! pcfg) + continue; + + pif = pcfg->interface + iface; + + idesc = &pif->desc; + + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb.interface.class", idesc->bInterfaceClass, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb.interface.subclass", idesc->bInterfaceSubClass, &hfp_error); + libhal_device_set_property_int(hfp_ctx, hfp_udi, + "usb.interface.protocol", idesc->bInterfaceProtocol, &hfp_error); + + memset(temp_string, 0, sizeof(temp_string)); + if (idesc->iInterface != 0) + libusb20_dev_req_string_simple_sync(pdev, idesc->iInterface, + temp_string, sizeof(temp_string)); + + libhal_device_set_property_string(hfp_ctx, hfp_udi, + "usb.interface.description", (char *) temp_string, &hfp_error); + + memset(ifdrv, 0, sizeof(ifdrv)); + libusb20_dev_get_iface_desc(pdev, iface, ifdrv, sizeof(ifdrv)); + if (ifdrv[0] != '\0') + { + char *ifdesc; + + ifdesc = strchr(ifdrv, ':'); + if (ifdesc) + { + *ifdesc = '\0'; + libhal_device_set_property_string(hfp_ctx, hfp_udi, + "usb.freebsd.devname", ifdrv, &hfp_error); + } + } + + free(pcfg); + } + +end: + if (pbe) + libusb20_be_free(pbe); + + return 0; +} diff --git a/hald/freebsd/probing/probe-volume.c b/hald/freebsd/probing/probe-volume.c index ee019279..73e03182 100644 --- a/hald/freebsd/probing/probe-volume.c +++ b/hald/freebsd/probing/probe-volume.c @@ -36,7 +36,12 @@ #include <sys/disk.h> #include <sys/cdio.h> #include <sys/param.h> +#include <sys/mount.h> #include <sys/types.h> +#include <ufs/ufs/ufsmount.h> +#include <ufs/ufs/dinode.h> +#include <ufs/ffs/fs.h> +#include <libufs.h> #include <isofs/cd9660/iso.h> #include <glib.h> #include <libvolume_id.h> @@ -59,7 +64,7 @@ struct iso_path_table_entry }; #define ISO_PATH_TABLE_ENTRY_SIZE 8 -#if __FreeBSD_version < 600101 +#if (__FreeBSD_version < 600101) && (__FreeBSD_kernel_version < 600101) static uint32_t isonum_731(unsigned char *p) { @@ -502,7 +507,8 @@ main (int argc, char **argv) hfp_cdrom_free(cdrom); } - if (has_data) + if (has_data && vid && (! strcmp(vid->type, "iso9660") || + ! strcmp(vid->type, "udf"))) hf_probe_volume_advanced_disc_detect(fd); } else @@ -555,6 +561,46 @@ main (int argc, char **argv) libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", has_children || is_swap, &hfp_error); + if (vid && ! strcmp (vid->type, "ufs")) + { + struct uufsd ufsdisk; + + if (ufs_disk_fillout(&ufsdisk, device_file) == 0) + { + char ufsid[64]; + char **ufs_devs = NULL; + int num_udis; + int i; + + snprintf(ufsid, sizeof(ufsid), "%08x%08x", ufsdisk.d_fs.fs_id[0], ufsdisk.d_fs.fs_id[1]); + libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.freebsd.ufsid", ufsid, &hfp_error); + ufs_devs = libhal_manager_find_device_string_match(hfp_ctx, + "volume.freebsd.ufsid", + ufsid, + &num_udis, + &hfp_error); + dbus_error_free(&hfp_error); + for (i = 0; i < num_udis; i++) + { + if (ufs_devs[i] != NULL) + { + gboolean mounted; + + mounted = libhal_device_get_property_bool(hfp_ctx, ufs_devs[i], "volume.is_mounted", &hfp_error); + dbus_error_free(&hfp_error); + if (mounted) + { + libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", TRUE, &hfp_error); + dbus_error_free(&hfp_error); + } + } + } + if (ufs_devs) + libhal_free_string_array(ufs_devs); + ufs_disk_close(&ufsdisk); + } + } + if (has_children) usage = "partitiontable"; else if (is_swap) diff --git a/hald/hald.c b/hald/hald.c index cc47567a..a7f9c3ad 100644 --- a/hald/hald.c +++ b/hald/hald.c @@ -538,8 +538,6 @@ main (int argc, char *argv[]) { GMainLoop *loop; guint sigterm_iochn_listener_source_id; - char *path; - char newpath[512]; guint opt_child_timeout; #ifdef HAVE_POLKIT PolKitError *p_error; @@ -574,20 +572,15 @@ main (int argc, char *argv[]) * to include this at the end (since we want to overide in * run-hald.sh and friends) */ - path = getenv ("PATH"); - if (path != NULL) { - g_strlcpy (newpath, path, sizeof (newpath)); - g_strlcat (newpath, ":", sizeof (newpath)); - } else { - /* No PATH was set */ - newpath[0] = '\0'; - } - - g_strlcat (newpath, PACKAGE_LIBEXEC_DIR, sizeof (newpath)); - g_strlcat (newpath, ":", sizeof (newpath)); - g_strlcat (newpath, PACKAGE_SCRIPT_DIR, sizeof (newpath)); + GString *path = g_string_new(getenv("PATH")); + if ( path->len > 0 ) { + g_string_append_c(path, ':'); + } + + g_string_append_printf(path, "%s:%s", PACKAGE_LIBEXEC_DIR, PACKAGE_SCRIPT_DIR); - setenv ("PATH", newpath, TRUE); + setenv ("PATH", path->str, TRUE); + g_string_free(path, TRUE); /* set the default child timeout to 250 seconds */ opt_child_timeout = 250; |